From 8cd567c63156a50724d6a754bfcd5ccfb0e83bb4 Mon Sep 17 00:00:00 2001 From: jermbo Date: Sat, 31 May 2025 08:00:24 -0400 Subject: [PATCH 01/26] docs: update contributing guidelines and add product requirements document --- CONTRIBUTING.md | 62 ++++++++++++++-- docs/PRD.md | 187 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 243 insertions(+), 6 deletions(-) create mode 100644 docs/PRD.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eeb8324..3acbc2e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -51,11 +51,13 @@ In this section we'll learn how to add a new dataset (or "endpoint" as we'll cal Each endpoint needs three files. Here's a [example of a new PR adding just a new endpoint](https://github.com/jermbo/SampleAPIs/pull/89) Here are the official steps to add an endpoint -1) Create a endpointName.json file (eg. baseball.json for `api.SampleApis.com/baseball`) with a value for each "collection" (so for "homeRuns" we end up with `https://api.sampleapis.com/baseball/homeRuns` because there's a array for the parameter "homeRuns" see [api/baseball.json](/server/api/baseball.json) for more details) -2) Create a ".backup" file which is a copy of the original endpointName.json file (in our example it would be [baseball.json.backup](/server/api/baseball.json.backup) ) -3) Ensure you newly created json file has a `metaData` key at the top of the file. + +1. Create a endpointName.json file (eg. baseball.json for `api.SampleApis.com/baseball`) with a value for each "collection" (so for "homeRuns" we end up with `https://api.sampleapis.com/baseball/homeRuns` because there's a array for the parameter "homeRuns" see [api/baseball.json](/server/api/baseball.json) for more details) +2. Create a ".backup" file which is a copy of the original endpointName.json file (in our example it would be [baseball.json.backup](/server/api/baseball.json.backup) ) +3. Ensure you newly created json file has a `metaData` key at the top of the file. The JSON file should look something like: + ```JavaScript { "metaData": [ @@ -93,8 +95,56 @@ The first level children of the JSON Object will be your main entry points for t This API will have `characters`, `questions`, and `inventory` for its available sources. Resulting in `https://api.sampleapis.com/fav-show/characters`, `https://api.sampleapis.com/fav-show/questions`, and `https://api.sampleapis.com/fav-show/inventory`. -***We strip out `metaData` from the available endpoints list, as we use this for populating the website. But you can still reach the data if you wanted to.*** +**_We strip out `metaData` from the available endpoints list, as we use this for populating the website. But you can still reach the data if you wanted to._** + +_Important:_ JSON GraphQL Server requires the data in the first level keys be an array of objects. The objects in the array can be whatever they need to be, and they need to be consistent. + +_Important:_ Both JSON Server and JSON GraphQL Server requires each object in the dataset have a unique id. + +### API Documentation + +When adding a new endpoint, please include the following information in your PR: + +1. **Endpoint Overview** + + - Brief description of the data + - Example use case + - Any special considerations + +2. **Example Request/Response** + + ```javascript + // Example: Fetching data + const response = await fetch("https://api.sampleapis.com/your-endpoint/collection"); + const data = await response.json(); + console.log(data); + ``` + +3. **Available Operations** + + - GET: Retrieve data + - POST: Add new items + - PUT: Update existing items + - DELETE: Remove items + +4. **Query Parameters** + + - `_page`: Pagination (e.g., `?_page=1`) + - `_limit`: Limit results (e.g., `?_limit=10`) + - `_sort`: Sort by field (e.g., `?_sort=name`) + - `_order`: Sort order (e.g., `?_order=asc`) + - Custom filters (e.g., `?field=value`) -*Important:* JSON GraphQL Server requires the data in the first level keys be an array of objects. The objects in the array can be whatever they need to be, and they need to be consistent. +5. **Response Format** + ```json + { + "data": [ + { + "id": 1, + "field": "value" + } + ] + } + ``` -*Important:* Both JSON Server and JSON GraphQL Server requires each object in the dataset have a unique id. +For more details on available features, refer to the [JSON-Server documentation](https://github.com/typicode/json-server). diff --git a/docs/PRD.md b/docs/PRD.md new file mode 100644 index 0000000..c59bc48 --- /dev/null +++ b/docs/PRD.md @@ -0,0 +1,187 @@ +# SampleAPIs - Product Requirements Document (PRD) + +## 1. Introduction + +### 1.1 Purpose + +SampleAPIs is an educational platform providing a collection of RESTful API endpoints for developers to learn and experiment with API interactions. The service offers various endpoints with full CRUD capabilities, making it an ideal sandbox for learning API development and testing. + +### 1.2 Target Audience + +- Junior developers learning API development +- Students studying RESTful API concepts +- Developers testing API integration +- Educators teaching API development +- Anyone interested in experimenting with API endpoints + +## 2. Product Overview + +### 2.1 Product Description + +SampleAPIs provides a collection of themed RESTful API endpoints that developers can use to learn and experiment with API interactions. Each endpoint offers full CRUD capabilities and follows RESTful design principles. + +### 2.2 Key Features + +- Multiple themed endpoints (e.g., Futurama, Movies, etc.) +- Full CRUD operations support +- Search functionality across endpoints +- Query parameter support +- No authentication required +- Free to use + +## 3. Functional Requirements + +### 3.1 API Endpoints + +- JSON-Server based RESTful architecture +- JSON-GraphQL-Server support +- JSON response format +- HTTP methods support (GET, POST, PUT, DELETE) +- Query parameter filtering +- CORS enabled + +### 3.2 Data Management + +- Weekly data reset to maintain consistency +- Persistent data through pull requests +- Educational data sets +- No sensitive or production data + +### 3.3 Developer Experience + +- Simple and intuitive API structure +- Clear documentation +- Example code snippets +- No authentication required + +## 4. Non-Functional Requirements + +### 4.1 Performance + +- Response time < 500ms +- 99.9% uptime +- Weekly data reset +- Basic rate limiting + +### 4.2 Security + +- No authentication required +- CORS enabled +- Input validation +- Basic rate limiting +- No sensitive data storage + +### 4.3 Reliability + +- Regular data backups +- Weekly data reset +- Error handling +- Health monitoring + +## 5. Technical Specifications + +### 5.1 API Structure + +```javascript +// Example: Fetching Futurama characters +const baseURL = "https://api.sampleapis.com/futurama/characters"; +fetch(baseURL) + .then((resp) => resp.json()) + .then((data) => console.log(data)); + +// Example: Searching for specific character +fetch(`${baseURL}?name.first=Bender`) + .then((resp) => resp.json()) + .then((data) => console.log(data)); +``` + +### 5.2 Response Format + +```json +{ + "data": [ + { + "id": 1, + "name": "Example" + } + ] +} +``` + +### 5.3 Error Codes + +- 200: Success +- 400: Bad Request +- 404: Not Found +- 500: Server Error + +## 6. Constraints and Limitations + +### 6.1 Technical Constraints + +- JSON-Server limitations +- JSON-GraphQL-Server limitations +- Basic rate limiting +- Weekly data reset + +### 6.2 Usage Limitations + +- Educational use only +- No sensitive data +- No authentication +- Basic rate limiting + +## 7. Success Criteria + +### 7.1 Performance Metrics + +- Response time < 500ms +- 99.9% uptime +- Error rate < 1% + +### 7.2 Usage Metrics + +- Number of active users +- Number of successful CRUD operations +- User feedback and satisfaction +- Number of contributions + +## 8. Maintenance and Support + +### 8.1 Regular Maintenance + +- Weekly data reset +- Security updates +- Performance optimization +- Documentation updates +- Bug fixes + +### 8.2 Support Channels + +- GitHub Issues +- Documentation +- Community contributions +- Code of Conduct enforcement + +## 9. Legal and Compliance + +### 9.1 Terms of Service + +- Educational use only +- No warranty +- Data ownership +- Usage limitations +- Liability disclaimers + +### 9.2 Data Privacy + +- No personal data collection +- No sensitive information +- Data reset policy +- Usage tracking policy + +## 10. References + +- [CONTRIBUTING.md](../CONTRIBUTING.md) +- [JSON-Server Documentation](https://github.com/typicode/json-server) +- [JSON-GraphQL-Server Documentation](https://github.com/marmelab/json-graphql-server) From a1626ebe21339ec2281d84b12c12cb03ef439af1 Mon Sep 17 00:00:00 2001 From: jermbo Date: Sat, 31 May 2025 08:23:03 -0400 Subject: [PATCH 02/26] feat: add docker setup for client and server containers --- client/Dockerfile | 26 ++++ client/package.json | 2 +- docker-compose.yml | 41 ++++++ docs/docker-setup.md | 297 +++++++++++++++++++++++++++++++++++++++++++ server/Dockerfile | 20 +++ 5 files changed, 385 insertions(+), 1 deletion(-) create mode 100644 client/Dockerfile create mode 100644 docker-compose.yml create mode 100644 docs/docker-setup.md create mode 100644 server/Dockerfile diff --git a/client/Dockerfile b/client/Dockerfile new file mode 100644 index 0000000..69056b8 --- /dev/null +++ b/client/Dockerfile @@ -0,0 +1,26 @@ +# Use Node.js 22 +FROM node:22-alpine + +# Set working directory +WORKDIR /app + +# Install necessary tools +RUN apk add --no-cache wget + +# Copy package files +COPY package*.json ./ + +# Install dependencies +RUN npm install + +# Copy the rest of the application +COPY . . + +# Build the application +RUN npm run build + +# Expose port 4444 +EXPOSE 4444 + +# Start the application +CMD ["npm", "run", "dev"] diff --git a/client/package.json b/client/package.json index 5cb20e7..67c1f27 100644 --- a/client/package.json +++ b/client/package.json @@ -4,7 +4,7 @@ "version": "0.0.0", "type": "module", "scripts": { - "dev": "vite --open --port=4444", + "dev": "vite --host --port=4444", "build": "tsc && vite build", "preview": "vite preview" }, diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..038a945 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,41 @@ +services: + client: + build: + context: ./client + dockerfile: Dockerfile + ports: + - "4444:4444" + volumes: + - ./client:/app + - /app/node_modules + environment: + - NODE_ENV=development + depends_on: + server: + condition: service_healthy + networks: + - app-network + + server: + build: + context: ./server + dockerfile: Dockerfile + ports: + - "5555:5555" + volumes: + - ./server:/app + - /app/node_modules + environment: + - NODE_ENV=development + - PORT=5555 + healthcheck: + test: ["CMD", "wget", "--spider", "http://localhost:5555"] + interval: 10s + timeout: 5s + retries: 3 + networks: + - app-network + +networks: + app-network: + driver: bridge diff --git a/docs/docker-setup.md b/docs/docker-setup.md new file mode 100644 index 0000000..05c118f --- /dev/null +++ b/docs/docker-setup.md @@ -0,0 +1,297 @@ +# Docker Setup Documentation + +This document outlines the Docker configuration for the SampleAPIs project, explaining the setup, configuration, and best practices used. + +## Project Structure + +``` +. +├── client/ +│ ├── Dockerfile +│ └── package.json +├── server/ +│ ├── Dockerfile +│ └── package.json +└── docker-compose.yml +``` + +## Container Configuration + +### Client Container + +The client container runs a Vite-based React application. + +**Dockerfile (client/Dockerfile)** + +```dockerfile +# Use Node.js 22 +FROM node:22-alpine + +# Set working directory +WORKDIR /app + +# Install necessary tools +RUN apk add --no-cache wget + +# Copy package files +COPY package*.json ./ + +# Install dependencies +RUN npm install + +# Copy the rest of the application +COPY . . + +# Build the application +RUN npm run build + +# Expose port 4444 +EXPOSE 4444 + +# Start the application +CMD ["npm", "run", "dev"] +``` + +Key points: + +- Uses Node.js 22 Alpine for a smaller image size +- Installs `wget` for health checks +- Exposes port 4444 for the Vite development server +- Uses development mode for hot-reloading + +### Server Container + +The server container runs an Express.js application. + +**Dockerfile (server/Dockerfile)** + +```dockerfile +# Use Node.js 22 +FROM node:22-alpine + +# Set working directory +WORKDIR /app + +# Copy package files +COPY package*.json ./ + +# Install dependencies +RUN npm install + +# Copy the rest of the application +COPY . . + +# Expose port 5555 +EXPOSE 5555 + +# Start the application in development mode +CMD ["npm", "run", "server"] +``` + +Key points: + +- Uses Node.js 22 Alpine +- Exposes port 5555 for the Express server +- Runs in development mode with nodemon for auto-reloading + +## Docker Compose Configuration + +The `docker-compose.yml` file orchestrates both containers and their interactions: + +```yaml +services: + client: + build: + context: ./client + dockerfile: Dockerfile + ports: + - "4444:4444" + volumes: + - ./client:/app + - /app/node_modules + environment: + - NODE_ENV=development + depends_on: + server: + condition: service_healthy + networks: + - app-network + + server: + build: + context: ./server + dockerfile: Dockerfile + ports: + - "5555:5555" + volumes: + - ./server:/app + - /app/node_modules + environment: + - NODE_ENV=development + - PORT=5555 + healthcheck: + test: ["CMD", "wget", "--spider", "http://localhost:5555"] + interval: 10s + timeout: 5s + retries: 3 + networks: + - app-network + +networks: + app-network: + driver: bridge +``` + +### Key Features + +1. **Volume Mounts** + + - Mounts local directories for hot-reloading + - Preserves node_modules in containers + - Enables real-time code changes + +2. **Networking** + + - Uses a dedicated bridge network + - Enables container-to-container communication + - Isolates the application network + +3. **Environment Variables** + - Sets development environment + - Configures server port + - API URL is managed through Config.ts in the client application + +## API Configuration + +The client application manages API URLs through `Config.ts`: + +```typescript +export const URLS = { + API_LINK: process.env.NODE_ENV === "production" ? "https://api.sampleapis.com" : "http://localhost:5555", +}; +``` + +This configuration: + +- Uses `http://localhost:5555` in development mode +- Uses `https://api.sampleapis.com` in production mode +- Automatically switches based on the NODE_ENV environment variable + +## Health Checks + +Health checks are crucial for ensuring service reliability and proper startup order. + +### Server Health Check Configuration + +```yaml +healthcheck: + test: ["CMD", "wget", "--spider", "http://localhost:5555"] + interval: 10s + timeout: 5s + retries: 3 +``` + +### How Health Checks Work + +1. **Purpose** + + - Verifies if the server is truly ready to accept connections + - Ensures proper startup sequence + - Prevents client from connecting to an unprepared server + +2. **Configuration Details** + + - `test`: Uses `wget --spider` to check server availability + - `interval`: Runs check every 10 seconds + - `timeout`: Fails if check takes longer than 5 seconds + - `retries`: Requires 3 consecutive failures to mark unhealthy + +3. **Dependency Management** + ```yaml + depends_on: + server: + condition: service_healthy + ``` + - Client only starts when server is healthy + - Prevents connection attempts to unprepared server + +## Usage + +### Starting the Application + +```bash +docker compose up --build +``` + +### Accessing the Application + +- Client: http://localhost:4444 +- Server: http://localhost:5555 + +### Stopping the Application + +```bash +docker compose down +``` + +## Best Practices + +1. **Development Mode** + + - Uses volume mounts for hot-reloading + - Preserves node_modules in containers + - Enables real-time code changes + +2. **Security** + + - Uses Alpine-based images for smaller attack surface + - Implements proper network isolation + - Avoids running as root + +3. **Performance** + + - Uses multi-stage builds where appropriate + - Implements proper caching strategies + - Optimizes layer ordering + +4. **Maintainability** + - Clear separation of concerns + - Well-documented configuration + - Consistent naming conventions + +## Troubleshooting + +### Common Issues + +1. **Container Not Starting** + + - Check health check logs + - Verify port availability + - Check volume mount permissions + +2. **Hot Reload Not Working** + + - Verify volume mounts + - Check file permissions + - Ensure proper node_modules handling + +3. **Network Issues** + - Verify network configuration + - Check container connectivity + - Validate port mappings + +### Debugging Commands + +```bash +# View container logs +docker compose logs + +# Check container status +docker compose ps + +# Inspect container details +docker inspect + +# Check network configuration +docker network inspect app-network +``` diff --git a/server/Dockerfile b/server/Dockerfile new file mode 100644 index 0000000..020cacc --- /dev/null +++ b/server/Dockerfile @@ -0,0 +1,20 @@ +# Use Node.js 22 +FROM node:22-alpine + +# Set working directory +WORKDIR /app + +# Copy package files +COPY package*.json ./ + +# Install dependencies +RUN npm install + +# Copy the rest of the application +COPY . . + +# Expose port 5555 (actual server port) +EXPOSE 5555 + +# Start the application in development mode +CMD ["npm", "run", "server"] From 518f448d2cb654fe15e10b1610091e0498baf959 Mon Sep 17 00:00:00 2001 From: jermbo Date: Sat, 31 May 2025 14:20:45 -0400 Subject: [PATCH 03/26] docs: add client and server documentation for SampleAPIs --- docs/client-documentation.md | 218 +++++++++++++++++++++++++++++++++++ docs/server-documentation.md | 195 +++++++++++++++++++++++++++++++ 2 files changed, 413 insertions(+) create mode 100644 docs/client-documentation.md create mode 100644 docs/server-documentation.md diff --git a/docs/client-documentation.md b/docs/client-documentation.md new file mode 100644 index 0000000..4bd550e --- /dev/null +++ b/docs/client-documentation.md @@ -0,0 +1,218 @@ +# SampleAPIs Client Documentation + +## Overview + +The SampleAPIs client is a modern React application built with TypeScript and Vite. It provides a user-friendly interface for interacting with the SampleAPIs server, featuring a code playground, API documentation, and interactive testing capabilities. + +## Key Features + +- Modern React with TypeScript +- Interactive code playground using Sandpack +- Responsive design with SASS +- Client-side routing with React Router +- Font Awesome icons integration +- Hot module replacement with Vite +- Type-safe development environment + +## Technology Stack + +- React 18 +- TypeScript +- Vite +- React Router DOM +- SASS +- Sandpack (Code Playground) +- Font Awesome + +## Folder Structure + +``` +client/ +├── src/ +│ ├── components/ # Reusable UI components +│ ├── context/ # React context providers +│ ├── hooks/ # Custom React hooks +│ ├── pages/ # Page components +│ ├── router/ # Route configurations +│ ├── styles/ # Global styles and SASS files +│ ├── utils/ # Utility functions +│ ├── App.tsx # Root component +│ └── main.tsx # Application entry point +├── public/ # Static assets +├── templates/ # Template files +├── dist/ # Build output +└── vite.config.ts # Vite configuration +``` + +## Development Guidelines + +### Code Style + +- Use TypeScript for all components and utilities +- Follow functional component patterns +- Implement proper TypeScript interfaces +- Use proper type definitions +- Follow React best practices +- Use proper error boundaries +- Implement proper loading states + +### Component Structure + +- Use functional components with TypeScript +- Implement proper prop types +- Use proper state management +- Follow component composition patterns +- Implement proper error handling +- Use proper loading states + +### State Management + +- Use React Context for global state +- Implement proper state updates +- Use proper state initialization +- Follow proper state patterns +- Implement proper state cleanup + +### Styling Guidelines + +- Use SASS for styling +- Follow BEM naming convention +- Use proper CSS variables +- Implement responsive design +- Use proper CSS modules +- Follow proper CSS organization + +## Getting Started + +### Prerequisites + +- Node.js (v14 or higher) +- npm or yarn + +### Installation + +```bash +npm install +``` + +### Development + +```bash +npm run dev +``` + +### Building + +```bash +npm run build +``` + +### Preview + +```bash +npm run preview +``` + +## Component Documentation + +### Core Components + +- App - Root component +- Router - Route configuration +- Layout - Page layout components +- Navigation - Navigation components +- CodePlayground - Interactive code editor +- APIList - API documentation list +- APIDetails - API endpoint details + +### Page Components + +- Home - Landing page +- Documentation - API documentation +- Playground - Code playground +- About - About page + +## Routing + +The application uses React Router for client-side routing: + +- `/` - Home page +- `/docs` - Documentation +- `/playground` - Code playground +- `/about` - About page + +## State Management + +- Global state managed through React Context +- Local state managed through React hooks +- Proper state initialization and cleanup +- Proper state updates and side effects + +## Styling + +- SASS for styling +- CSS variables for theming +- Responsive design +- Mobile-first approach +- Proper CSS organization + +## Performance Optimization + +1. Code splitting +2. Lazy loading +3. Proper caching +4. Bundle optimization +5. Image optimization + +## Testing + +- Component testing +- Integration testing +- E2E testing +- Performance testing +- Accessibility testing + +## Best Practices + +1. Use TypeScript for type safety +2. Follow React best practices +3. Implement proper error handling +4. Use proper loading states +5. Follow proper state management +6. Implement proper testing +7. Follow proper styling guidelines +8. Use proper documentation +9. Follow proper Git workflow +10. Keep dependencies updated + +## Common Issues and Solutions + +1. TypeScript errors - Check type definitions +2. Routing issues - Check route configuration +3. State management - Check context providers +4. Styling issues - Check SASS compilation +5. Build issues - Check Vite configuration + +## Performance Optimization + +1. Code splitting +2. Lazy loading +3. Proper caching +4. Bundle optimization +5. Image optimization + +## Future Improvements + +1. Enhanced code playground +2. Improved documentation +3. Additional features +4. Better testing coverage +5. Performance optimizations + +## Contributing + +Please refer to the CONTRIBUTING.md file for contribution guidelines. + +## License + +MIT License - See LICENSE file for details diff --git a/docs/server-documentation.md b/docs/server-documentation.md new file mode 100644 index 0000000..5c4e4ea --- /dev/null +++ b/docs/server-documentation.md @@ -0,0 +1,195 @@ +# SampleAPIs Server Documentation + +## Overview + +SampleAPIs is a RESTful API server designed for learning and testing purposes. It provides a collection of sample APIs that can be used for development, testing, and educational purposes. + +## Key Features + +- RESTful API endpoints with JSON responses +- GraphQL support via json-graphql-server +- Rate limiting and request throttling +- CORS enabled for cross-origin requests +- Static file serving +- Pug template engine for views +- API list generation and management +- Reset functionality for testing +- Test API endpoints + +## Technology Stack + +- Node.js +- Express.js +- Pug (Template Engine) +- JSON Server +- JSON GraphQL Server +- Jest (Testing) + +## Folder Structure + +``` +server/ +├── api/ # API endpoint implementations +├── routes/ # Express route handlers +├── utils/ # Utility functions +├── views/ # Pug templates +├── public/ # Static assets +├── tests/ # Test files +├── sampleapis.js # Main application file +├── apiList.js # API list configuration +└── GeneratedAPIList.js # Generated API endpoints +``` + +## API Structure + +The server provides several types of endpoints: + +1. Base APIs - Core functionality endpoints +2. Test APIs - Endpoints for testing purposes +3. Custom APIs - User-created endpoints +4. GraphQL endpoints - GraphQL interface for the APIs + +## Development Guidelines + +### Code Style + +- Use ES6+ features +- Follow Express.js best practices +- Implement proper error handling +- Use async/await for asynchronous operations +- Keep routes modular and organized + +### API Design Principles + +- RESTful conventions +- Consistent response format +- Proper HTTP status codes +- Clear endpoint naming +- Version control for APIs + +### Testing + +- Write unit tests using Jest +- Test API endpoints +- Implement integration tests +- Follow TDD practices where applicable + +### Security Considerations + +- Rate limiting implemented +- CORS configuration +- Input validation +- Error handling +- Request throttling + +## Getting Started + +### Prerequisites + +- Node.js (v14 or higher) +- npm or yarn + +### Installation + +```bash +npm install +``` + +### Running the Server + +Development mode: + +```bash +npm run server +``` + +Production mode: + +```bash +npm start +``` + +### Testing + +```bash +npm test +``` + +## API Documentation + +### Base Endpoints + +- `GET /` - Main page +- `GET /resetit` - Reset API state +- `POST /create` - Create new API endpoints +- `GET /generate` - Generate new API list +- `GET /test` - Test API endpoints + +### Response Format + +```json +{ + "response": 200, + "data": { + // Response data + } +} +``` + +## Docker Support + +The server includes Docker configuration for containerized deployment: + +- Dockerfile for building the image +- docker-compose.yml for orchestration + +## Contributing + +Please refer to the CONTRIBUTING.md file for contribution guidelines. + +## License + +MIT License - See LICENSE file for details + +## Best Practices + +1. Keep routes modular and organized +2. Implement proper error handling +3. Use middleware for common functionality +4. Follow RESTful conventions +5. Write comprehensive tests +6. Document API changes +7. Use environment variables for configuration +8. Implement proper logging +9. Follow security best practices +10. Keep dependencies updated + +## Common Issues and Solutions + +1. CORS issues - Check CORS configuration +2. Rate limiting - Adjust rate limit settings +3. API generation - Clear cache and regenerate +4. Testing - Ensure proper test environment setup + +## Performance Optimization + +1. Use proper caching strategies +2. Implement request throttling +3. Optimize database queries +4. Use compression middleware +5. Implement proper error handling + +## Monitoring and Logging + +- Use Morgan for HTTP request logging +- Implement proper error logging +- Monitor API performance +- Track rate limiting and throttling + +## Future Improvements + +1. Enhanced GraphQL support +2. Improved documentation +3. Additional API endpoints +4. Better testing coverage +5. Performance optimizations From fa2ccfdce738a188dba2ac644814938e8bc734b7 Mon Sep 17 00:00:00 2001 From: jermbo Date: Sat, 31 May 2025 14:33:09 -0400 Subject: [PATCH 04/26] docs: add application flow documentation for SampleAPIs --- docs/app-flow.md | 242 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 docs/app-flow.md diff --git a/docs/app-flow.md b/docs/app-flow.md new file mode 100644 index 0000000..7e8b5bf --- /dev/null +++ b/docs/app-flow.md @@ -0,0 +1,242 @@ +# SampleAPIs Application Flow Documentation + +## Overview + +This document outlines the various user journeys and application flows within the SampleAPIs platform. It provides a comprehensive view of how users interact with the system and the different paths they can take. + +## User Journeys + +### 1. First-Time Visitor Journey + +```mermaid +graph TD + A[Land on Home Page] --> B{Choose Path} + B -->|Documentation| C[Browse APIs] + B -->|About| D[Learn About] + C --> E[View API List] + E --> F[View API Details] + F --> G[Try API Calls] +``` + +1. **Landing Page** + + - User arrives at the home page + - Views platform overview + - Can access documentation or about page + +2. **Documentation Exploration** + - Browse available APIs + - View API details + - Try API calls + +### 2. API Testing Journey + +```mermaid +sequenceDiagram + participant U as User + participant L as API List + participant D as API Details + participant A as API + + U->>L: Select API + L->>D: View Details + D->>A: Make Request + A->>D: Return Response + D->>U: Display Results +``` + +1. **API Selection** + + - Choose specific API + - View endpoint documentation + - Understand request parameters + +2. **Request Building** + + - Configure request parameters + - Choose HTTP method + +3. **Response Analysis** + - View response data + - Check status codes + +### 3. Code Playground Journey + +```mermaid +stateDiagram-v2 + [*] --> Idle + Idle --> Running: Execute + Running --> Success: Complete + Running --> Error: Fail + Success --> Idle: Reset + Error --> Idle: Reset +``` + +1. **Code Execution** + + - Write API integration code + - Run code in playground + - View console output + +2. **Error Handling** + - View syntax errors in editor + - See runtime errors in console + - Handle network errors + +### 4. Documentation Reference Journey + +```mermaid +graph TD + A[Start] --> B[View Documentation] + B --> C[Read Purpose] + B --> D[Learn Usage] + B --> E[View Examples] + B --> F[Read Disclaimers] +``` + +1. **Documentation Overview** + + - View platform purpose + - Learn about RESTful APIs + - Understand authentication-free approach + +2. **Usage Guide** + + - Learn how to use endpoints + - View example API calls + - Understand CRUD operations + - Learn about data reset policy + +3. **Examples** + + - View code snippets + - Learn fetch examples + - Understand query parameters + - Access video tutorial + +4. **Important Information** + - Educational purpose notice + - Data reset policy + - Terms of service + - Contribution guidelines + +## Navigation Flows + +### 1. Main Navigation + +```mermaid +graph LR + A[Home] --> B[API List] + A --> C[About] + A --> D[Docs] + B --> E[API Details] + + style A fill:#f9f,stroke:#333,stroke-width:2px,color:#000 + style B fill:#bbf,stroke:#333,stroke-width:2px,color:#000 + style C fill:#bbf,stroke:#333,stroke-width:2px,color:#000 + style D fill:#bbf,stroke:#333,stroke-width:2px,color:#000 + style E fill:#bbf,stroke:#333,stroke-width:2px,color:#000 +``` + +- Home → API List +- Home → About +- Home → Docs +- API List → API Details + +## Error Handling Flows + +### 1. API Errors + +The API uses a combination of middleware and validation for error handling: + +1. **Request Validation** + + - Validates request body against expected data structure + - Checks for required fields in POST/PUT requests + - Validates field types and formats + - Returns 400 error with expected vs received data + +2. **Rate Limiting** + + - Limits requests to 5000 per 15 minutes + - Returns 429 error when limit exceeded + - Whitelist for specific IPs + +3. **Response Format** + + ```json + { + "error": 400, + "message": "Error description", + "expected": { "field": "type" }, + "received": { "field": "value" } + } + ``` + +4. **Common Error Codes** + - 400: Bad Request (Invalid data) + - 404: Not Found + - 429: Too Many Requests + - 500: Server Error + +### 2. Playground Errors + +The playground uses Sandpack (CodeSandbox's React component) for code execution. Error handling is managed by Sandpack itself: + +1. **Code Execution** + + - Syntax errors are shown in the editor + - Runtime errors are displayed in the console + - Network errors are handled in the try/catch block + - Response errors are shown in the UI + +2. **Error Display** + - Errors are shown in the Sandpack console + - Network errors are displayed in the UI + - Syntax errors are highlighted in the editor + - Runtime errors are logged to the console + +## State Management + +### Frontend State Management + +The frontend uses React Context for global state management through `GlobalContext`: + +```typescript +interface iGlobal { + navVisible: boolean; + setNavVisible: Dispatch; + apiList: APIData[]; + setAPIList: Dispatch; + appState: AppStateEnum; + setAppState: Dispatch; + isLoggedIn: boolean; + setIsLoggedIn: Dispatch; + apiCategories: string[]; + setApiCategories: Dispatch; +} +``` + +Key state features: + +- Navigation visibility state +- API list and categories +- Application state (initial, loading, ready, error) +- Authentication state + +### Backend State Management + +The backend is stateless and uses: + +- JSON files for data storage +- Express middleware for request handling +- Rate limiting for API protection +- Data validation middleware + +Key features: + +- No session state +- File-based data storage +- Request validation +- Rate limiting +- Error handling middleware From dcfd53f66ddcd2bd5bd3a3c2bd1ca75484a2eed7 Mon Sep 17 00:00:00 2001 From: jermbo Date: Wed, 8 Jul 2026 22:05:14 -0400 Subject: [PATCH 05/26] feat: integrate TanStack Query for data management and refactor GlobalContext - Added TanStack Query for managing server state, replacing the previous useFetch hook and related logic in GlobalContext. - Updated package dependencies to use specific versions, including React 19 and TanStack libraries. - Refactored API data fetching to utilize new hooks (useApiList, useApiCategories) for improved data handling. - Removed obsolete useFetch hook and cleaned up GlobalContext to only manage UI state. - Adjusted TypeScript configuration for module resolution and updated engine requirements in package.json. - Documented the modernization plan for the frontend, outlining future phases for routing and styling improvements. --- client/package.json | 35 ++++--- client/src/context/GlobalContext.tsx | 59 ++--------- client/src/hooks/useApiList.ts | 37 +++++++ client/src/hooks/useFetch.tsx | 36 ------- client/src/main.tsx | 25 ++++- client/src/pages/APIDetails/APIDetails.tsx | 8 +- client/src/pages/APIList/APIList.tsx | 7 +- client/src/pages/Home/Home.tsx | 6 +- client/src/utils/Config.ts | 6 +- client/src/utils/Interfaces.ts | 9 -- client/tsconfig.json | 3 +- client/tsconfig.node.json | 2 +- docs/frontend-modernization-plan.md | 114 +++++++++++++++++++++ 13 files changed, 217 insertions(+), 130 deletions(-) create mode 100644 client/src/hooks/useApiList.ts delete mode 100644 client/src/hooks/useFetch.tsx create mode 100644 docs/frontend-modernization-plan.md diff --git a/client/package.json b/client/package.json index 67c1f27..eb134b0 100644 --- a/client/package.json +++ b/client/package.json @@ -3,28 +3,33 @@ "private": true, "version": "0.0.0", "type": "module", + "engines": { + "node": ">=20.19.0" + }, "scripts": { "dev": "vite --host --port=4444", "build": "tsc && vite build", "preview": "vite preview" }, "dependencies": { - "@codesandbox/sandpack-react": "^2.13.10", - "@codesandbox/sandpack-themes": "^2.0.21", - "@fortawesome/fontawesome-svg-core": "^6.5.2", - "@fortawesome/free-solid-svg-icons": "^6.5.2", - "@fortawesome/react-fontawesome": "^0.2.2", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-router-dom": "^6.23.1", - "sass": "^1.77.2" + "@codesandbox/sandpack-react": "2.20.0", + "@codesandbox/sandpack-themes": "2.0.21", + "@fortawesome/fontawesome-svg-core": "6.5.2", + "@fortawesome/free-solid-svg-icons": "6.5.2", + "@fortawesome/react-fontawesome": "0.2.2", + "@tanstack/react-query": "5.101.2", + "@tanstack/react-query-devtools": "5.101.2", + "react": "19.2.7", + "react-dom": "19.2.7", + "react-router-dom": "6.23.1", + "sass": "1.77.2" }, "devDependencies": { - "@types/node": "^20.12.12", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "@vitejs/plugin-react-swc": "^3.7.0", - "typescript": "^5.4.5", - "vite": "^5.2.11" + "@types/node": "26.1.1", + "@types/react": "19.2.17", + "@types/react-dom": "19.2.3", + "@vitejs/plugin-react-swc": "4.3.1", + "typescript": "7.0.2", + "vite": "8.1.3" } } diff --git a/client/src/context/GlobalContext.tsx b/client/src/context/GlobalContext.tsx index cec51df..775a3aa 100644 --- a/client/src/context/GlobalContext.tsx +++ b/client/src/context/GlobalContext.tsx @@ -1,20 +1,9 @@ -import React, { createContext, useEffect, useState } from "react"; -import useFetch from "../hooks/useFetch"; - -import { AppStateEnum } from "../utils/Enums"; -import { APIData, APIListResponse, FetchState, iGlobal } from "../utils/Interfaces"; +import React, { createContext, useState } from "react"; +import { iGlobal } from "../utils/Interfaces"; export const initialValues: iGlobal = { navVisible: false, setNavVisible: () => {}, - apiList: [] as APIData[], - setAPIList: () => [], - appState: AppStateEnum.initial, - setAppState: () => {}, - isLoggedIn: false, - setIsLoggedIn: () => {}, - apiCategories: [], - setApiCategories: () => {}, }; export const GlobalContext = createContext(initialValues); @@ -23,51 +12,19 @@ interface Props { children?: React.ReactNode; } -const BASE_URL = - process.env.NODE_ENV === "production" ? "https://api.sampleapis.com" : "http://localhost:5555"; - +/** + * Holds UI-only global state. Server state (the API list, categories) + * now lives in TanStack Query — see `hooks/useApiList`. + */ const GlobalProvider: React.FC = ({ children }) => { const [navVisible, setNavVisible] = useState(initialValues.navVisible); - const [appState, setAppState] = useState(initialValues.appState); - const [apiList, setAPIList] = useState(initialValues.apiList); - const [isLoggedIn, setIsLoggedIn] = useState(false); - const [apiCategories, setApiCategories] = useState(initialValues.apiCategories); - - const { state: APIState, data } = useFetch>(`${BASE_URL}/frontend`); - - const generateCategories = (list: APIData[]) => { - const allCategories = list.reduce((acc: string[], item) => { - return [...acc, ...item.metaData.categories]; - }, []); - setApiCategories(Array.from(new Set(allCategories))); - }; - - useEffect(() => { - if (APIState === AppStateEnum.ready) { - const list = data?.data?.APIListData || ([] as APIData[]); - setAPIList(list); - generateCategories(list); - return; - } - }, [APIState, data?.data?.APIListData]); const values = { navVisible, setNavVisible, - apiList, - setAPIList, - appState, - setAppState, - isLoggedIn, - setIsLoggedIn, - apiCategories, - setApiCategories, }; - return ( - - <>{children} - - ); + + return {children}; }; export default GlobalProvider; diff --git a/client/src/hooks/useApiList.ts b/client/src/hooks/useApiList.ts new file mode 100644 index 0000000..1da46bf --- /dev/null +++ b/client/src/hooks/useApiList.ts @@ -0,0 +1,37 @@ +import { useQuery } from "@tanstack/react-query"; +import { URLS } from "../utils/Config"; +import { APIData, APIListResponse, FetchState } from "../utils/Interfaces"; + +const fetchApiList = async (): Promise => { + const resp = await fetch(`${URLS.API_LINK}/frontend`); + if (!resp.ok) { + throw new Error(`Failed to load API list (${resp.status})`); + } + const json: FetchState = await resp.json(); + return json.data?.APIListData ?? []; +}; + +/** + * Server state for the full list of available sample APIs. + * Backed by TanStack Query, so callers get caching, dedup, and + * loading/error state without any provider wiring. + */ +export const useApiList = () => + useQuery({ + queryKey: ["apiList"], + queryFn: fetchApiList, + }); + +/** + * Derived list of unique categories across every API. + * Shares the cached `apiList` query and only re-derives when it changes. + */ +export const useApiCategories = () => + useQuery({ + queryKey: ["apiList"], + queryFn: fetchApiList, + select: (list) => { + const all = list.flatMap((item) => item.metaData.categories); + return Array.from(new Set(all)); + }, + }); diff --git a/client/src/hooks/useFetch.tsx b/client/src/hooks/useFetch.tsx deleted file mode 100644 index d43b0b0..0000000 --- a/client/src/hooks/useFetch.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { useEffect, useState } from "react"; -import { AppStateEnum } from "../utils/Enums"; - -type ReturnState = { - state: AppStateEnum; - data: T | null; -}; - -function useFetch(url: string): ReturnState { - const [data, setData] = useState(null); - const [state, setState] = useState(AppStateEnum.initial); - - const getData = async () => { - setState(AppStateEnum.loading); - try { - const resp = await fetch(url); - const json = await resp.json(); - setData(json); - setState(AppStateEnum.ready); - } catch (err) { - console.log(err); - setState(AppStateEnum.error); - } - }; - - useEffect(() => { - if (state === AppStateEnum.initial) { - getData(); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return { state, data }; -} - -export default useFetch; diff --git a/client/src/main.tsx b/client/src/main.tsx index 8707b5a..195e2dd 100644 --- a/client/src/main.tsx +++ b/client/src/main.tsx @@ -1,18 +1,33 @@ import React from "react"; import { createRoot } from "react-dom/client"; import { BrowserRouter } from "react-router-dom"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import GlobalProvider from "./context/GlobalContext"; import App from "./App"; const container = document.getElementById("root"); const root = createRoot(container!); +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + staleTime: 5 * 60 * 1000, + retry: 1, + refetchOnWindowFocus: false, + }, + }, +}); + root.render( - - - - - + + + + + + + + , ); diff --git a/client/src/pages/APIDetails/APIDetails.tsx b/client/src/pages/APIDetails/APIDetails.tsx index 6fc56a0..961f7e5 100644 --- a/client/src/pages/APIDetails/APIDetails.tsx +++ b/client/src/pages/APIDetails/APIDetails.tsx @@ -1,8 +1,8 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { Link, useParams } from "react-router-dom"; import APICategories from "../../components/APICategories/APICategories"; import APIEndpoints from "../../components/Endpoints/Endpoints"; -import { GlobalContext } from "../../context/GlobalContext"; +import { useApiList } from "../../hooks/useApiList"; import { APIData, Example } from "../../utils/Interfaces"; import { URLS } from "../../utils/Config"; import { faLink } from "@fortawesome/free-solid-svg-icons"; @@ -15,7 +15,7 @@ interface Props {} const APIDetails: React.FC = () => { const { id } = useParams(); - const { apiList } = useContext(GlobalContext); + const { data: apiList = [] } = useApiList(); const [singleAPI, setSingleAPI] = useState({} as APIData); const [singleEndpoint, setSingleEndpoint] = useState(""); const [thisApiEndpoint, setThisApiEndpoint] = useState(""); @@ -46,7 +46,7 @@ export default function App() { const [data, setData] = useState(""); const getData = async () => { try { - const resp = await fetch('${URLS.API_LINK}/${singleAPI.link}/${singleEndpoint}'); + const resp = await fetch('${URLS.PUBLIC_API_LINK}/${singleAPI.link}/${singleEndpoint}'); const json = await resp.json(); setData(json); } catch (err) { diff --git a/client/src/pages/APIList/APIList.tsx b/client/src/pages/APIList/APIList.tsx index 5afb2e9..97a78ec 100644 --- a/client/src/pages/APIList/APIList.tsx +++ b/client/src/pages/APIList/APIList.tsx @@ -1,14 +1,15 @@ -import React, { ChangeEvent, useContext, useEffect, useState } from "react"; +import React, { ChangeEvent, useEffect, useState } from "react"; import APICard from "../../components/APICard/APICard"; import APIFilter from "../../components/APIFilter/APIFilter"; import APISearch from "../../components/APISearch/APISearch"; import PageHeaderActions from "../../components/PageHeaderActions/PageHeaderActions"; -import { GlobalContext } from "../../context/GlobalContext"; +import { useApiCategories, useApiList } from "../../hooks/useApiList"; interface Props {} const APIList: React.FC = () => { - const { apiList, apiCategories } = useContext(GlobalContext); + const { data: apiList = [] } = useApiList(); + const { data: apiCategories = [] } = useApiCategories(); const [selectedCategory, setSelectedCategory] = useState("all"); const [searchWord, setSearchWord] = useState(""); const [filteredList, setFilteredList] = useState(apiList); diff --git a/client/src/pages/Home/Home.tsx b/client/src/pages/Home/Home.tsx index 0f30665..b44d4b8 100644 --- a/client/src/pages/Home/Home.tsx +++ b/client/src/pages/Home/Home.tsx @@ -1,15 +1,15 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import "./Home.scss"; import APICard from "../../components/APICard/APICard"; -import { GlobalContext } from "../../context/GlobalContext"; +import { useApiList } from "../../hooks/useApiList"; import { APIData } from "../../utils/Interfaces"; import PageHeaderActions from "../../components/PageHeaderActions/PageHeaderActions"; interface Props { } const Home: React.FC = () => { - const { apiList } = useContext(GlobalContext); + const { data: apiList = [] } = useApiList(); const [featuredAPIs, setFeatureAPIs] = useState([] as APIData[]); diff --git a/client/src/utils/Config.ts b/client/src/utils/Config.ts index 0c87e39..9409245 100644 --- a/client/src/utils/Config.ts +++ b/client/src/utils/Config.ts @@ -1,3 +1,7 @@ export const URLS = { - API_LINK: process.env.NODE_ENV === "production" ? "https://api.sampleapis.com" : "http://localhost:5555" + // Target for the app's own requests. Points at the local server in dev. + API_LINK: process.env.NODE_ENV === "production" ? "https://api.sampleapis.com" : "http://localhost:5555", + // Always the public API. Used inside runnable code samples (Sandpack), which + // execute in a public sandbox iframe and cannot reach a localhost/loopback URL. + PUBLIC_API_LINK: "https://api.sampleapis.com" }; diff --git a/client/src/utils/Interfaces.ts b/client/src/utils/Interfaces.ts index 2daf77e..db510b4 100644 --- a/client/src/utils/Interfaces.ts +++ b/client/src/utils/Interfaces.ts @@ -1,17 +1,8 @@ import { Dispatch } from "react"; -import { AppStateEnum } from "./Enums"; export interface iGlobal { navVisible: boolean; setNavVisible: Dispatch; - apiList: APIData[]; - setAPIList: Dispatch; - appState: AppStateEnum; - setAppState: Dispatch; - isLoggedIn: boolean; - setIsLoggedIn: Dispatch; - apiCategories: string[]; - setApiCategories: Dispatch; } export interface FetchState { diff --git a/client/tsconfig.json b/client/tsconfig.json index 3d0a51a..7244a72 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -5,12 +5,11 @@ "lib": ["DOM", "DOM.Iterable", "ESNext"], "allowJs": false, "skipLibCheck": true, - "esModuleInterop": false, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, "module": "ESNext", - "moduleResolution": "Node", + "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, diff --git a/client/tsconfig.node.json b/client/tsconfig.node.json index 9d31e2a..a535f7d 100644 --- a/client/tsconfig.node.json +++ b/client/tsconfig.node.json @@ -2,7 +2,7 @@ "compilerOptions": { "composite": true, "module": "ESNext", - "moduleResolution": "Node", + "moduleResolution": "bundler", "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] diff --git a/docs/frontend-modernization-plan.md b/docs/frontend-modernization-plan.md new file mode 100644 index 0000000..c4a71af --- /dev/null +++ b/docs/frontend-modernization-plan.md @@ -0,0 +1,114 @@ +# Frontend Modernization Plan + +> Scope: **client only** (`client/`). Backend work is planned separately and comes after this. +> Goal: adopt the TanStack ecosystem, remove Sass in favor of modern CSS, and bring tooling current — without changing the app's behavior for users. + +## Guiding decisions + +- **Routing:** TanStack Router, **file-based** routes (Vite plugin generates the type-safe route tree). `pages/` becomes `routes/`. +- **Data:** TanStack Query owns all server state. `useFetch` and the fetch logic in `GlobalContext` are retired. +- **Styling:** Delete the Sass pipeline entirely. Tokens become hand-written CSS custom properties; components use native CSS (nesting, `clamp()`, `color-mix()`, `light-dark()`, container queries). +- **No intermediate React Router 7 bump** — we skip straight to TanStack Router. +- Each phase should land as its own PR (or small stack of PRs) and stay green on lint + typecheck. + +## Current state (baseline) + +| Area | Now | +|---|---| +| Framework | Vite 5.2 + React 18.3 + TS 5.4 + SWC | +| Routing | `react-router-dom` 6.23, hand-rolled `routes.tsx` array + `.map()` in `App.tsx` | +| Server state | `useFetch.tsx` (no abort, no refetch-on-url-change) + `GlobalContext` | +| Styling | Sass — 23 `.scss` files, `vars/` + `mixins/` + `functions/`, custom-property generation from Sass maps | +| State | `GlobalContext` holds both server data (apiList, categories) and UI state (navVisible) | + +Known issues to fix along the way: +- `useFetch` never re-fetches when `url` changes and has no `AbortController` cleanup. +- Routes are untyped (`route: any`, untyped `:id` param). +- Sass is largely used to emit CSS custom properties that modern CSS provides natively. + +--- + +## Phase 1 — Tooling + TanStack Query (data layer) + +Do the data layer first so routing migration in Phase 2 can lean on Query loaders. + +1. **Bump tooling:** Vite 5→8, TypeScript to latest, `@types/*`, `@vitejs/plugin-react-swc`. Pin `engines.node` (Vite 8 raises the minimum Node version — confirm and pin accordingly). Confirm build + dev still run. +2. **Add TanStack Query:** install `@tanstack/react-query` (+ devtools). Wrap the app in `QueryClientProvider`. +3. **Replace `useFetch`:** create typed query hooks (e.g. `useApiList`, `useApiDetails`) that call `fetch` with proper typing and error handling. Delete `hooks/useFetch.tsx`. +4. **Shrink `GlobalContext`:** move the `/frontend` fetch + category derivation into a Query (`select` derives categories). Context keeps **only** UI state (`navVisible`), or move that to a small `useState`/store. Retire the server-state half of the context. +5. Verify: API list, details, and category filter all still work off Query. + +**Exit criteria:** no component imports `useFetch`; server state flows through Query; app behaves identically. + +## Phase 2 — TanStack Router (file-based) + +1. **Install** `@tanstack/react-router` + `@tanstack/router-plugin` (Vite) + devtools. Wire the plugin into `vite.config.ts`. +2. **Restructure** `src/pages/*` → `src/routes/*` in the file-based convention: + - `/` → `routes/index.tsx` + - `/about`, `/docs`, `/style-guide`, `/api-list` → matching route files + - `/api-list/:id` → `routes/api-list/$id.tsx` (typed param) + - 404 → `routes/__root.tsx` notFound / catch-all +3. **Root layout:** move `Header` + `
` shell from `App.tsx` into `__root.tsx`. Code-splitting is automatic; drop the manual `lazy()` + `` map. +4. **Loaders + Query:** use route loaders that prefetch via the QueryClient so data is ready on navigation (kills the loading flash on the details page). +5. **Remove** `react-router-dom`, `router/routes.tsx`, and the `.map()` in `App.tsx`. Update all ``/navigation to TanStack equivalents (now type-checked). + +**Exit criteria:** `react-router-dom` uninstalled; all routes/params type-safe; generated `routeTree.gen.ts` committed/ignored per convention. + +## Phase 3 — Sass removal → modern CSS + +1. **Tokens:** convert `styles/vars/_colors.scss`, `_fonts.scss`, `_screens.scss` and `_custom-properties.scss` into a single hand-written `styles/tokens.css` `:root` block of custom properties. (The Sass maps were only generating these anyway.) +2. **Global styles:** convert `_base.scss`, `_typography.scss`, `styles.scss` → plain CSS, organized with `@layer` (reset / tokens / base / components / utilities). +3. **Per-component CSS:** convert each `components/**/**.scss` and `routes/**/**.css`: + - Sass nesting → **native CSS nesting** + - mixins/functions → custom properties + `clamp()`, `min()`/`max()`, `color-mix()` + - `vars/_screens` breakpoints → media/**container queries** +4. **Enhancements while in here:** add `light-dark()` theming and a documented token layer (feeds the existing `StyleGuide` page). +5. **Remove** `sass` from dependencies; delete `styles/vars/`, `mixins/`, `functions/` and all `.scss` files. Confirm no `@use`/`@import` of Sass remains. + +**Exit criteria:** zero `.scss` files; `sass` uninstalled; visual parity confirmed against current UI. + +## Phase 4 — TanStack Table + Form (feature polish) + +Optional-but-planned; unlocks nicer UX and pairs with the future backend pagination/filtering. + +1. **TanStack Table** for the API browser (`APIList` + `APIFilter` + `APISearch`): client-side sort/filter/paginate now, ready to switch to server-side when the backend gains pagination. +2. **TanStack Form** for any search/CRUD forms (typed + validated), staged for when the backend exposes writes. + +**Exit criteria:** endpoint browser uses TanStack Table; forms (if any) use TanStack Form. + +--- + +## Dependency summary + +**Add:** `@tanstack/react-query`, `@tanstack/react-query-devtools`, `@tanstack/react-router`, `@tanstack/router-plugin`, `@tanstack/react-router-devtools`, later `@tanstack/react-table`, `@tanstack/react-form`. + +**Remove:** `react-router-dom`, `sass`. + +**Upgrade:** `vite`, `typescript`, `@types/*`, `@vitejs/plugin-react-swc`. + +## Sequencing rationale + +Query before Router (Router loaders depend on the QueryClient). Routing before Sass removal (avoids restyling files that are about to move `pages/` → `routes/`). Table/Form last (feature layer on a stable foundation). + +## Known caveat: Sandpack examples can't hit local data + +The runnable code examples on the API details page execute inside a Sandpack iframe +served from a **public HTTPS origin** (`https://…sandpack.codesandbox.io`). Browsers +(Chrome's **Private Network Access** policy) block a public origin from fetching a +loopback address like `http://localhost:5555`, so the examples point at the live public +API (`PUBLIC_API_LINK` in `utils/Config.ts`), not the dev server. + +- This is a **browser policy**, not caused by the React/Vite/Sandpack upgrades — PNA + enforcement has been tightening in Chrome independently. +- **Consequence:** while developing against local/new server data, the live Sandpack + examples still show **production** data. The clickable "Endpoint:" link on the page + does use the local dev server, so that path is testable. +- If we ever need examples to exercise local data in dev, options are: expose the dev + server over a public HTTPS tunnel (ngrok/cloudflared) and feed that URL to the sample, + or render examples non-interactively (static code) in dev. Revisit if it becomes a pain. + +## Out of scope (tracked for backend plan) + +- Replacing `json-server` (Express 5 handlers vs. Prisma + SQLite). +- API pagination/filtering/sorting endpoints (Table will consume these later). +- Auth / API keys / usage metering. From eb5a0b16e17ca4a30fd2b8552e9c17d6b4cbe774 Mon Sep 17 00:00:00 2001 From: jermbo Date: Wed, 8 Jul 2026 22:12:26 -0400 Subject: [PATCH 06/26] refactor: migrate to TanStack Router and restructure routing - Integrated TanStack Router, replacing React Router for improved routing capabilities. - Removed the previous App component and routes configuration, transitioning to a file-based routing structure. - Updated components to utilize the new routing system, including Link and useParams from TanStack Router. - Added route definitions for main application pages, enhancing type safety and maintainability. - Introduced a generated route tree for better organization and access to routes. - Updated package.json to include necessary TanStack Router dependencies. --- client/package.json | 4 +- client/src/App.tsx | 32 ---- client/src/components/APICard/APICard.tsx | 4 +- client/src/components/Header/Header.tsx | 2 +- client/src/components/Nav/Nav.tsx | 27 ++- .../PageHeaderActions/PageHeaderActions.tsx | 4 +- client/src/main.tsx | 21 ++- client/src/pages/APIDetails/APIDetails.tsx | 4 +- client/src/routeTree.gen.ts | 157 ++++++++++++++++++ client/src/router/routes.tsx | 35 ---- client/src/routes/__root.tsx | 18 ++ client/src/routes/about.tsx | 6 + client/src/routes/api-list/$id.tsx | 6 + client/src/routes/api-list/index.tsx | 6 + client/src/routes/docs.tsx | 6 + client/src/routes/index.tsx | 6 + client/src/routes/style-guide.tsx | 6 + client/vite.config.ts | 7 +- 18 files changed, 253 insertions(+), 98 deletions(-) delete mode 100644 client/src/App.tsx create mode 100644 client/src/routeTree.gen.ts delete mode 100644 client/src/router/routes.tsx create mode 100644 client/src/routes/__root.tsx create mode 100644 client/src/routes/about.tsx create mode 100644 client/src/routes/api-list/$id.tsx create mode 100644 client/src/routes/api-list/index.tsx create mode 100644 client/src/routes/docs.tsx create mode 100644 client/src/routes/index.tsx create mode 100644 client/src/routes/style-guide.tsx diff --git a/client/package.json b/client/package.json index eb134b0..4ca67cb 100644 --- a/client/package.json +++ b/client/package.json @@ -19,12 +19,14 @@ "@fortawesome/react-fontawesome": "0.2.2", "@tanstack/react-query": "5.101.2", "@tanstack/react-query-devtools": "5.101.2", + "@tanstack/react-router": "1.170.17", + "@tanstack/react-router-devtools": "1.167.0", "react": "19.2.7", "react-dom": "19.2.7", - "react-router-dom": "6.23.1", "sass": "1.77.2" }, "devDependencies": { + "@tanstack/router-plugin": "^1.168.19", "@types/node": "26.1.1", "@types/react": "19.2.17", "@types/react-dom": "19.2.3", diff --git a/client/src/App.tsx b/client/src/App.tsx deleted file mode 100644 index 4518c64..0000000 --- a/client/src/App.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { Suspense } from "react"; - -import { Route, Routes } from "react-router-dom"; -import "./styles/styles.scss"; - -import AppRoutes from "./router/routes"; -import Header from "./components/Header/Header"; - -const App: React.FC = () => { - return ( - <> -
-
- - {AppRoutes.map((route: any) => ( - - - - } - /> - ))} - -
- - ); -}; - -export default App; diff --git a/client/src/components/APICard/APICard.tsx b/client/src/components/APICard/APICard.tsx index d5c2918..fe8c4fe 100644 --- a/client/src/components/APICard/APICard.tsx +++ b/client/src/components/APICard/APICard.tsx @@ -1,7 +1,7 @@ import { faLink, faStar } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import React from "react"; -import { Link } from "react-router-dom"; +import { Link } from "@tanstack/react-router"; import { APIData } from "../../utils/Interfaces"; import APICategories from "../APICategories/APICategories"; @@ -16,7 +16,7 @@ const APICard: React.FC = ({ api, featured = false }) => {
- +

{api.metaData.title}

  diff --git a/client/src/components/Header/Header.tsx b/client/src/components/Header/Header.tsx index 776681a..851fd6e 100644 --- a/client/src/components/Header/Header.tsx +++ b/client/src/components/Header/Header.tsx @@ -1,5 +1,5 @@ import React, { useContext } from "react"; -import { Link } from "react-router-dom"; +import { Link } from "@tanstack/react-router"; import { GlobalContext } from "../../context/GlobalContext"; import Nav from "../Nav/Nav"; diff --git a/client/src/components/Nav/Nav.tsx b/client/src/components/Nav/Nav.tsx index 3cede47..5c20349 100644 --- a/client/src/components/Nav/Nav.tsx +++ b/client/src/components/Nav/Nav.tsx @@ -1,48 +1,45 @@ import React, { useContext, useEffect } from "react"; -import { NavLink, useLocation } from "react-router-dom"; +import { Link, useLocation } from "@tanstack/react-router"; import { GlobalContext } from "../../context/GlobalContext"; const Nav: React.FC = () => { const { setNavVisible } = useContext(GlobalContext); - let location = useLocation(); + const location = useLocation(); useEffect(() => { document.body.classList.remove("-nav-visible"); setNavVisible(false); - }, [location]); + }, [location.pathname]); - const setActive = (navData: { isActive: boolean; isPending: boolean }) => { - return navData.isActive ? "active" : ""; - }; + const activeProps = { className: "active" }; return (
  • - + Home - +
  • - + About - +
  • - + API List - +
  • - + Docs - +
); }; -// export default withRouter(Nav); export default Nav; diff --git a/client/src/components/PageHeaderActions/PageHeaderActions.tsx b/client/src/components/PageHeaderActions/PageHeaderActions.tsx index ded6e9e..6edea67 100644 --- a/client/src/components/PageHeaderActions/PageHeaderActions.tsx +++ b/client/src/components/PageHeaderActions/PageHeaderActions.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Link } from "react-router-dom"; +import { Link } from "@tanstack/react-router"; import { faBook, faCodeBranch, faInfoCircle, faList } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -27,7 +27,7 @@ const PageHeaderActions: React.FC = ({ currentPage }) => { icon: faBook, show: currentPage === "docs", }, - ]; + ] as const; return (
{links.map((link) => { diff --git a/client/src/main.tsx b/client/src/main.tsx index 195e2dd..900b3ba 100644 --- a/client/src/main.tsx +++ b/client/src/main.tsx @@ -1,10 +1,10 @@ import React from "react"; import { createRoot } from "react-dom/client"; -import { BrowserRouter } from "react-router-dom"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; +import { createRouter, RouterProvider } from "@tanstack/react-router"; +import { routeTree } from "./routeTree.gen"; import GlobalProvider from "./context/GlobalContext"; -import App from "./App"; const container = document.getElementById("root"); const root = createRoot(container!); @@ -19,14 +19,21 @@ const queryClient = new QueryClient({ }, }); +const router = createRouter({ routeTree }); + +// Register the router instance for type-safety across the app. +declare module "@tanstack/react-router" { + interface Register { + router: typeof router; + } +} + root.render( - - - - - + + + , diff --git a/client/src/pages/APIDetails/APIDetails.tsx b/client/src/pages/APIDetails/APIDetails.tsx index 961f7e5..d3be0e4 100644 --- a/client/src/pages/APIDetails/APIDetails.tsx +++ b/client/src/pages/APIDetails/APIDetails.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from "react"; -import { Link, useParams } from "react-router-dom"; +import { Link, useParams } from "@tanstack/react-router"; import APICategories from "../../components/APICategories/APICategories"; import APIEndpoints from "../../components/Endpoints/Endpoints"; import { useApiList } from "../../hooks/useApiList"; @@ -14,7 +14,7 @@ import { nightOwl } from "@codesandbox/sandpack-themes"; interface Props {} const APIDetails: React.FC = () => { - const { id } = useParams(); + const { id } = useParams({ from: "/api-list/$id" }); const { data: apiList = [] } = useApiList(); const [singleAPI, setSingleAPI] = useState({} as APIData); const [singleEndpoint, setSingleEndpoint] = useState(""); diff --git a/client/src/routeTree.gen.ts b/client/src/routeTree.gen.ts new file mode 100644 index 0000000..0e367e0 --- /dev/null +++ b/client/src/routeTree.gen.ts @@ -0,0 +1,157 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as StyleGuideRouteImport } from './routes/style-guide' +import { Route as DocsRouteImport } from './routes/docs' +import { Route as AboutRouteImport } from './routes/about' +import { Route as IndexRouteImport } from './routes/index' +import { Route as ApiListIndexRouteImport } from './routes/api-list/index' +import { Route as ApiListIdRouteImport } from './routes/api-list/$id' + +const StyleGuideRoute = StyleGuideRouteImport.update({ + id: '/style-guide', + path: '/style-guide', + getParentRoute: () => rootRouteImport, +} as any) +const DocsRoute = DocsRouteImport.update({ + id: '/docs', + path: '/docs', + getParentRoute: () => rootRouteImport, +} as any) +const AboutRoute = AboutRouteImport.update({ + id: '/about', + path: '/about', + getParentRoute: () => rootRouteImport, +} as any) +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) +const ApiListIndexRoute = ApiListIndexRouteImport.update({ + id: '/api-list/', + path: '/api-list/', + getParentRoute: () => rootRouteImport, +} as any) +const ApiListIdRoute = ApiListIdRouteImport.update({ + id: '/api-list/$id', + path: '/api-list/$id', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute + '/about': typeof AboutRoute + '/docs': typeof DocsRoute + '/style-guide': typeof StyleGuideRoute + '/api-list/$id': typeof ApiListIdRoute + '/api-list/': typeof ApiListIndexRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute + '/about': typeof AboutRoute + '/docs': typeof DocsRoute + '/style-guide': typeof StyleGuideRoute + '/api-list/$id': typeof ApiListIdRoute + '/api-list': typeof ApiListIndexRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute + '/about': typeof AboutRoute + '/docs': typeof DocsRoute + '/style-guide': typeof StyleGuideRoute + '/api-list/$id': typeof ApiListIdRoute + '/api-list/': typeof ApiListIndexRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: + '/' | '/about' | '/docs' | '/style-guide' | '/api-list/$id' | '/api-list/' + fileRoutesByTo: FileRoutesByTo + to: '/' | '/about' | '/docs' | '/style-guide' | '/api-list/$id' | '/api-list' + id: + | '__root__' + | '/' + | '/about' + | '/docs' + | '/style-guide' + | '/api-list/$id' + | '/api-list/' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute + AboutRoute: typeof AboutRoute + DocsRoute: typeof DocsRoute + StyleGuideRoute: typeof StyleGuideRoute + ApiListIdRoute: typeof ApiListIdRoute + ApiListIndexRoute: typeof ApiListIndexRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/style-guide': { + id: '/style-guide' + path: '/style-guide' + fullPath: '/style-guide' + preLoaderRoute: typeof StyleGuideRouteImport + parentRoute: typeof rootRouteImport + } + '/docs': { + id: '/docs' + path: '/docs' + fullPath: '/docs' + preLoaderRoute: typeof DocsRouteImport + parentRoute: typeof rootRouteImport + } + '/about': { + id: '/about' + path: '/about' + fullPath: '/about' + preLoaderRoute: typeof AboutRouteImport + parentRoute: typeof rootRouteImport + } + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + '/api-list/': { + id: '/api-list/' + path: '/api-list' + fullPath: '/api-list/' + preLoaderRoute: typeof ApiListIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/api-list/$id': { + id: '/api-list/$id' + path: '/api-list/$id' + fullPath: '/api-list/$id' + preLoaderRoute: typeof ApiListIdRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, + AboutRoute: AboutRoute, + DocsRoute: DocsRoute, + StyleGuideRoute: StyleGuideRoute, + ApiListIdRoute: ApiListIdRoute, + ApiListIndexRoute: ApiListIndexRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() diff --git a/client/src/router/routes.tsx b/client/src/router/routes.tsx deleted file mode 100644 index acdd7b6..0000000 --- a/client/src/router/routes.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { lazy } from "react"; - -const AppRoutes = [ - { - path: "/", - component: lazy(() => import("../pages/Home/Home")), - }, - { - path: "/style-guide", - component: lazy(() => import("../pages/StyleGuide/StyleGuide")), - }, - { - path: "/about", - component: lazy(() => import("../pages/About/About")), - }, - { - path: "/docs", - component: lazy(() => import("../pages/Docs/Docs")), - }, - { - path: "/api-list", - component: lazy(() => import("../pages/APIList/APIList")), - }, - { - path: "/api-list/:id", - component: lazy(() => import("../pages/APIDetails/APIDetails")), - }, - { - path: "/", - exact: false, - component: lazy(() => import("../pages/NotFound/NotFound")), - }, -]; - -export default AppRoutes; diff --git a/client/src/routes/__root.tsx b/client/src/routes/__root.tsx new file mode 100644 index 0000000..75e32f5 --- /dev/null +++ b/client/src/routes/__root.tsx @@ -0,0 +1,18 @@ +import { createRootRoute, Outlet } from "@tanstack/react-router"; +import Header from "../components/Header/Header"; +import NotFound from "../pages/NotFound/NotFound"; +import "../styles/styles.scss"; + +export const Route = createRootRoute({ + component: RootLayout, + notFoundComponent: NotFound, +}); + +function RootLayout() { + return ( +
+
+ +
+ ); +} diff --git a/client/src/routes/about.tsx b/client/src/routes/about.tsx new file mode 100644 index 0000000..32bf66a --- /dev/null +++ b/client/src/routes/about.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import About from "../pages/About/About"; + +export const Route = createFileRoute("/about")({ + component: About, +}); diff --git a/client/src/routes/api-list/$id.tsx b/client/src/routes/api-list/$id.tsx new file mode 100644 index 0000000..effbd94 --- /dev/null +++ b/client/src/routes/api-list/$id.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import APIDetails from "../../pages/APIDetails/APIDetails"; + +export const Route = createFileRoute("/api-list/$id")({ + component: APIDetails, +}); diff --git a/client/src/routes/api-list/index.tsx b/client/src/routes/api-list/index.tsx new file mode 100644 index 0000000..ddb4740 --- /dev/null +++ b/client/src/routes/api-list/index.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import APIList from "../../pages/APIList/APIList"; + +export const Route = createFileRoute("/api-list/")({ + component: APIList, +}); diff --git a/client/src/routes/docs.tsx b/client/src/routes/docs.tsx new file mode 100644 index 0000000..7f239ec --- /dev/null +++ b/client/src/routes/docs.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import Docs from "../pages/Docs/Docs"; + +export const Route = createFileRoute("/docs")({ + component: Docs, +}); diff --git a/client/src/routes/index.tsx b/client/src/routes/index.tsx new file mode 100644 index 0000000..2d74510 --- /dev/null +++ b/client/src/routes/index.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import Home from "../pages/Home/Home"; + +export const Route = createFileRoute("/")({ + component: Home, +}); diff --git a/client/src/routes/style-guide.tsx b/client/src/routes/style-guide.tsx new file mode 100644 index 0000000..4e64e85 --- /dev/null +++ b/client/src/routes/style-guide.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import StyleGuide from "../pages/StyleGuide/StyleGuide"; + +export const Route = createFileRoute("/style-guide")({ + component: StyleGuide, +}); diff --git a/client/vite.config.ts b/client/vite.config.ts index 861b04b..23cc8c0 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -1,7 +1,12 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react-swc' +import { tanstackRouter } from '@tanstack/router-plugin/vite' // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()], + plugins: [ + // Must come before the React plugin so it can transform route files. + tanstackRouter({ target: 'react', autoCodeSplitting: true }), + react(), + ], }) From 1f69388c8b6de7366067a034bf3f4f5a84b3f862 Mon Sep 17 00:00:00 2001 From: jermbo Date: Wed, 8 Jul 2026 22:23:27 -0400 Subject: [PATCH 07/26] refactor: migrate styles from SCSS to CSS and clean up unused files - Converted styles from SCSS to CSS, creating a more streamlined and maintainable structure. - Removed obsolete SCSS files and functions, reducing complexity and improving performance. - Updated component imports to reference new CSS files instead of SCSS. - Introduced design tokens for consistent styling across the application. - Enhanced the organization of styles by separating concerns into distinct CSS files for better readability. --- client/package.json | 3 +- client/src/components/APICard/APICard.scss | 0 .../APICategories/APICategories.scss | 0 .../src/components/APIFilter/APIFilter.scss | 0 .../src/components/APISearch/APISearch.scss | 0 client/src/components/APISearch/APISearch.tsx | 1 - .../CodepenWrapper/CodepenWrapper.scss | 1 - .../src/components/Endpoints/Endpoints.scss | 0 client/src/components/Header/Header.scss | 0 client/src/components/Nav/Nav.scss | 0 .../PageHeaderActions/PageHeaderActions.scss | 1 - client/src/pages/APIDetails/APIDetails.css | 15 ++ client/src/pages/APIDetails/APIDetails.scss | 17 --- client/src/pages/APIDetails/APIDetails.tsx | 2 +- client/src/pages/APIList/APIList.scss | 0 client/src/pages/About/About.scss | 0 client/src/pages/Docs/Docs.css | 15 ++ client/src/pages/Docs/Docs.scss | 19 --- client/src/pages/Docs/Docs.tsx | 2 +- client/src/pages/Home/Home.css | 12 ++ client/src/pages/Home/Home.scss | 10 -- client/src/pages/Home/Home.tsx | 2 +- client/src/pages/NotFound/NotFound.scss | 0 client/src/pages/StyleGuide/StyleGuide.scss | 2 - client/src/routes/__root.tsx | 2 +- client/src/styles/_api-categories.scss | 30 ---- client/src/styles/_api-endpoints.scss | 41 ------ client/src/styles/_base.scss | 94 ------------- client/src/styles/_buttons.scss | 22 --- client/src/styles/_custom-properties.scss | 25 ---- client/src/styles/_header.scss | 56 -------- client/src/styles/_nav.scss | 131 ------------------ client/src/styles/_page.scss | 49 ------- client/src/styles/_typography.scss | 105 -------------- .../styles/{_api-card.scss => api-card.css} | 94 +++++++------ client/src/styles/api-categories.css | 29 ++++ client/src/styles/api-endpoints.css | 37 +++++ .../{_api-filter.scss => api-filter.css} | 15 +- .../{_api-search.scss => api-search.css} | 19 ++- client/src/styles/base.css | 91 ++++++++++++ client/src/styles/buttons.css | 19 +++ .../{_code-display.scss => code-display.css} | 8 +- client/src/styles/functions/_colors.scss | 61 -------- client/src/styles/functions/_fonts.scss | 35 ----- client/src/styles/functions/_index.scss | 2 - client/src/styles/functions/_screens.scss | 49 ------- client/src/styles/header.css | 39 ++++++ client/src/styles/mixins/_colors.scss | 14 -- client/src/styles/nav.css | 130 +++++++++++++++++ .../styles/{_not-found.scss => not-found.css} | 7 +- client/src/styles/page.css | 46 ++++++ client/src/styles/styles.css | 16 +++ client/src/styles/styles.scss | 14 -- client/src/styles/tokens.css | 76 ++++++++++ client/src/styles/typography.css | 42 ++++++ client/src/styles/vars/_colors.scss | 52 ------- client/src/styles/vars/_fonts.scss | 58 -------- client/src/styles/vars/_index.scss | 2 - client/src/styles/vars/_screens.scss | 17 --- 59 files changed, 640 insertions(+), 989 deletions(-) delete mode 100644 client/src/components/APICard/APICard.scss delete mode 100644 client/src/components/APICategories/APICategories.scss delete mode 100644 client/src/components/APIFilter/APIFilter.scss delete mode 100644 client/src/components/APISearch/APISearch.scss delete mode 100644 client/src/components/CodepenWrapper/CodepenWrapper.scss delete mode 100644 client/src/components/Endpoints/Endpoints.scss delete mode 100644 client/src/components/Header/Header.scss delete mode 100644 client/src/components/Nav/Nav.scss delete mode 100644 client/src/components/PageHeaderActions/PageHeaderActions.scss create mode 100644 client/src/pages/APIDetails/APIDetails.css delete mode 100644 client/src/pages/APIDetails/APIDetails.scss delete mode 100644 client/src/pages/APIList/APIList.scss delete mode 100644 client/src/pages/About/About.scss create mode 100644 client/src/pages/Docs/Docs.css delete mode 100644 client/src/pages/Docs/Docs.scss create mode 100644 client/src/pages/Home/Home.css delete mode 100644 client/src/pages/Home/Home.scss delete mode 100644 client/src/pages/NotFound/NotFound.scss delete mode 100644 client/src/pages/StyleGuide/StyleGuide.scss delete mode 100644 client/src/styles/_api-categories.scss delete mode 100644 client/src/styles/_api-endpoints.scss delete mode 100644 client/src/styles/_base.scss delete mode 100644 client/src/styles/_buttons.scss delete mode 100644 client/src/styles/_custom-properties.scss delete mode 100644 client/src/styles/_header.scss delete mode 100644 client/src/styles/_nav.scss delete mode 100644 client/src/styles/_page.scss delete mode 100644 client/src/styles/_typography.scss rename client/src/styles/{_api-card.scss => api-card.css} (52%) create mode 100644 client/src/styles/api-categories.css create mode 100644 client/src/styles/api-endpoints.css rename client/src/styles/{_api-filter.scss => api-filter.css} (63%) rename client/src/styles/{_api-search.scss => api-search.css} (65%) create mode 100644 client/src/styles/base.css create mode 100644 client/src/styles/buttons.css rename client/src/styles/{_code-display.scss => code-display.css} (81%) delete mode 100644 client/src/styles/functions/_colors.scss delete mode 100644 client/src/styles/functions/_fonts.scss delete mode 100644 client/src/styles/functions/_index.scss delete mode 100644 client/src/styles/functions/_screens.scss create mode 100644 client/src/styles/header.css delete mode 100644 client/src/styles/mixins/_colors.scss create mode 100644 client/src/styles/nav.css rename client/src/styles/{_not-found.scss => not-found.css} (82%) create mode 100644 client/src/styles/page.css create mode 100644 client/src/styles/styles.css delete mode 100644 client/src/styles/styles.scss create mode 100644 client/src/styles/tokens.css create mode 100644 client/src/styles/typography.css delete mode 100644 client/src/styles/vars/_colors.scss delete mode 100644 client/src/styles/vars/_fonts.scss delete mode 100644 client/src/styles/vars/_index.scss delete mode 100644 client/src/styles/vars/_screens.scss diff --git a/client/package.json b/client/package.json index 4ca67cb..b45e65f 100644 --- a/client/package.json +++ b/client/package.json @@ -22,8 +22,7 @@ "@tanstack/react-router": "1.170.17", "@tanstack/react-router-devtools": "1.167.0", "react": "19.2.7", - "react-dom": "19.2.7", - "sass": "1.77.2" + "react-dom": "19.2.7" }, "devDependencies": { "@tanstack/router-plugin": "^1.168.19", diff --git a/client/src/components/APICard/APICard.scss b/client/src/components/APICard/APICard.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/components/APICategories/APICategories.scss b/client/src/components/APICategories/APICategories.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/components/APIFilter/APIFilter.scss b/client/src/components/APIFilter/APIFilter.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/components/APISearch/APISearch.scss b/client/src/components/APISearch/APISearch.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/components/APISearch/APISearch.tsx b/client/src/components/APISearch/APISearch.tsx index 22ddd96..3513a76 100644 --- a/client/src/components/APISearch/APISearch.tsx +++ b/client/src/components/APISearch/APISearch.tsx @@ -1,5 +1,4 @@ import React, { ChangeEvent } from "react"; -import "./APISearch.scss"; import { faSearch } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; diff --git a/client/src/components/CodepenWrapper/CodepenWrapper.scss b/client/src/components/CodepenWrapper/CodepenWrapper.scss deleted file mode 100644 index e1d73d1..0000000 --- a/client/src/components/CodepenWrapper/CodepenWrapper.scss +++ /dev/null @@ -1 +0,0 @@ -.CodepenWrapper {} \ No newline at end of file diff --git a/client/src/components/Endpoints/Endpoints.scss b/client/src/components/Endpoints/Endpoints.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/components/Header/Header.scss b/client/src/components/Header/Header.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/components/Nav/Nav.scss b/client/src/components/Nav/Nav.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/components/PageHeaderActions/PageHeaderActions.scss b/client/src/components/PageHeaderActions/PageHeaderActions.scss deleted file mode 100644 index 0941f2f..0000000 --- a/client/src/components/PageHeaderActions/PageHeaderActions.scss +++ /dev/null @@ -1 +0,0 @@ -.HeaderActions {} \ No newline at end of file diff --git a/client/src/pages/APIDetails/APIDetails.css b/client/src/pages/APIDetails/APIDetails.css new file mode 100644 index 0000000..68cdd5b --- /dev/null +++ b/client/src/pages/APIDetails/APIDetails.css @@ -0,0 +1,15 @@ +.link { + color: var(--color-text-light); + + &:focus, + &:active, + &:hover { + outline: none; + color: var(--color-primary-base); + } + + & span { + display: inline-block; + padding: 0 5px; + } +} diff --git a/client/src/pages/APIDetails/APIDetails.scss b/client/src/pages/APIDetails/APIDetails.scss deleted file mode 100644 index 9412457..0000000 --- a/client/src/pages/APIDetails/APIDetails.scss +++ /dev/null @@ -1,17 +0,0 @@ -@use '../../styles/functions/colors'; - -.link { - color: colors.use-var(text, light); - - &:focus, - &:active, - &:hover { - outline: none; - color: colors.use-var(primary); - } - - span { - display: inline-block; - padding: 0 5px; - } -} diff --git a/client/src/pages/APIDetails/APIDetails.tsx b/client/src/pages/APIDetails/APIDetails.tsx index d3be0e4..879d184 100644 --- a/client/src/pages/APIDetails/APIDetails.tsx +++ b/client/src/pages/APIDetails/APIDetails.tsx @@ -7,7 +7,7 @@ import { APIData, Example } from "../../utils/Interfaces"; import { URLS } from "../../utils/Config"; import { faLink } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import "./APIDetails.scss"; +import "./APIDetails.css"; import { Sandpack } from "@codesandbox/sandpack-react"; import { nightOwl } from "@codesandbox/sandpack-themes"; diff --git a/client/src/pages/APIList/APIList.scss b/client/src/pages/APIList/APIList.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/pages/About/About.scss b/client/src/pages/About/About.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/pages/Docs/Docs.css b/client/src/pages/Docs/Docs.css new file mode 100644 index 0000000..c2f4f10 --- /dev/null +++ b/client/src/pages/Docs/Docs.css @@ -0,0 +1,15 @@ +.section { + margin-top: 50px; +} + +pre { + background-color: #f4f4f4; + padding: 10px; + border-radius: 5px; + overflow-x: auto; + color: black; +} + +a { + color: #007bff; +} diff --git a/client/src/pages/Docs/Docs.scss b/client/src/pages/Docs/Docs.scss deleted file mode 100644 index c042648..0000000 --- a/client/src/pages/Docs/Docs.scss +++ /dev/null @@ -1,19 +0,0 @@ -.Docs {} - - -.section { - margin-top: 50px; -} - -pre { - background-color: #f4f4f4; - padding: 10px; - border-radius: 5px; - overflow-x: auto; - color: black; -} - -a { - color: #007bff; -} - diff --git a/client/src/pages/Docs/Docs.tsx b/client/src/pages/Docs/Docs.tsx index b201dc9..5fd31cf 100644 --- a/client/src/pages/Docs/Docs.tsx +++ b/client/src/pages/Docs/Docs.tsx @@ -1,6 +1,6 @@ import React from "react"; import PageHeaderActions from "../../components/PageHeaderActions/PageHeaderActions"; -import "./Docs.scss"; +import "./Docs.css"; interface Props { } diff --git a/client/src/pages/Home/Home.css b/client/src/pages/Home/Home.css new file mode 100644 index 0000000..98482b2 --- /dev/null +++ b/client/src/pages/Home/Home.css @@ -0,0 +1,12 @@ +.section { + margin-top: 50px; +} + +pre { + overflow-x: auto; + font-size: 0.9rem; +} + +a { + color: #007bff; +} diff --git a/client/src/pages/Home/Home.scss b/client/src/pages/Home/Home.scss deleted file mode 100644 index 7cdf5ed..0000000 --- a/client/src/pages/Home/Home.scss +++ /dev/null @@ -1,10 +0,0 @@ -.section { - margin-top: 50px; -} -pre { - overflow-x: auto; - font-size: 0.9rem; -} -a { - color: #007bff; -} diff --git a/client/src/pages/Home/Home.tsx b/client/src/pages/Home/Home.tsx index b44d4b8..c539d68 100644 --- a/client/src/pages/Home/Home.tsx +++ b/client/src/pages/Home/Home.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from "react"; -import "./Home.scss"; +import "./Home.css"; import APICard from "../../components/APICard/APICard"; import { useApiList } from "../../hooks/useApiList"; diff --git a/client/src/pages/NotFound/NotFound.scss b/client/src/pages/NotFound/NotFound.scss deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/pages/StyleGuide/StyleGuide.scss b/client/src/pages/StyleGuide/StyleGuide.scss deleted file mode 100644 index df2404f..0000000 --- a/client/src/pages/StyleGuide/StyleGuide.scss +++ /dev/null @@ -1,2 +0,0 @@ -.StyleGuide { -} diff --git a/client/src/routes/__root.tsx b/client/src/routes/__root.tsx index 75e32f5..5539071 100644 --- a/client/src/routes/__root.tsx +++ b/client/src/routes/__root.tsx @@ -1,7 +1,7 @@ import { createRootRoute, Outlet } from "@tanstack/react-router"; import Header from "../components/Header/Header"; import NotFound from "../pages/NotFound/NotFound"; -import "../styles/styles.scss"; +import "../styles/styles.css"; export const Route = createRootRoute({ component: RootLayout, diff --git a/client/src/styles/_api-categories.scss b/client/src/styles/_api-categories.scss deleted file mode 100644 index aed9626..0000000 --- a/client/src/styles/_api-categories.scss +++ /dev/null @@ -1,30 +0,0 @@ -@use './functions/colors'; -@use './vars/colors' as *; - -.api-categories { - margin: 0; - padding: 0 1rem 0 0; -} - -.api-category { - font-size: 0.85rem; - list-style: none; - display: inline-block; - padding: 0.25rem 0.5rem; - margin-bottom: 0.5rem; - letter-spacing: 1px; - border-radius: 10px; - border-color: var(--cat-color); - background: var(--cat-color); - color: colors.use-var(text, dark); - - &:not(:last-child) { - margin-right: 0.5rem; - } - - @for $i from 1 through length($colors) { - &:nth-child(#{length($colors)}n + #{$i}) { - --cat-color: #{nth($colors, $i)}; - } - } -} diff --git a/client/src/styles/_api-endpoints.scss b/client/src/styles/_api-endpoints.scss deleted file mode 100644 index 9f9587a..0000000 --- a/client/src/styles/_api-endpoints.scss +++ /dev/null @@ -1,41 +0,0 @@ -@use './functions/colors'; -@use './functions/fonts'; -@use './vars/colors' as *; - -.api-endpoints { - margin: 0; - padding: 0; - display: flex; - flex-wrap: wrap; - gap: .75rem; -} - -.api-endpoint { - list-style: none; - display: block; - - @for $i from 1 through length($colors) { - &:nth-child(#{length($colors)}n + #{$i}) { - .btn { - $color: nth($colors, $i); - --color: #{$color}; - --hover-text: #{darken($color, 50%)}; - border-color: var(--color); - color: var(--color); - - &:focus, - &:hover { - outline: none; - color: var(--hover-text); - background: var(--color); - } - } - } - } - - a { - // color: colors.use-var(text, light); - display: inline-block; - text-transform: capitalize; - } -} diff --git a/client/src/styles/_base.scss b/client/src/styles/_base.scss deleted file mode 100644 index b0b403b..0000000 --- a/client/src/styles/_base.scss +++ /dev/null @@ -1,94 +0,0 @@ -@use './functions/screens'; -@use './functions/colors'; -@use './functions/fonts'; - -@use './vars/colors' as *; - -*, -*:before, -*:after { - box-sizing: border-box; -} - -html, -body { - margin: 0; - font-family: fonts.family(text); - font-weight: fonts.weight(base); - color: colors.use-var(text, light); - background: colors.use-var(bg, darkest); - - &.-nav-visible { - height: 100vh; - overflow: hidden; - } -} - -#root{ - display: grid; - grid-template-columns: minmax(25px, 150px) minmax(50%, 90%) minmax(25px, 150px); - grid-template-areas: "left center right"; - margin-bottom: 5rem; -} - -.content { - grid-area: center; -} - -p { - margin: 0; - font-size: fonts.size(text, 2); - max-width: 80ch; - - + P { - margin-top: 1rem; - } -} - -a { - text-decoration: none; - transition: all 0.25s ease; -} - -abbr { - transition: all 0.25s ease; - cursor: help; - position: relative; - - @for $i from 1 through length($colors) { - &:nth-of-type(#{length($colors)}n + #{$i}) { - $color: nth($colors, $i); - --color: #{$color}; - --hover-text: #{darken($color, 50%)}; - border-color: var(--color); - color: var(--color); - - &:focus, - &:hover { - outline: none; - color: var(--hover-text); - background: var(--color); - z-index: 100; - - &::after { - content: attr(title); - background: var(--color); - box-shadow: 0 0 10px black; - position: absolute; - display: block; - bottom: 100%; - left: 0; - padding: 0.25rem 0.5rem; - font-size: fonts.size(text, 3); - white-space: nowrap; - } - } - } - } -} - -.featured-icon { - position: absolute; - top: 1rem; - right: 1rem; -} diff --git a/client/src/styles/_buttons.scss b/client/src/styles/_buttons.scss deleted file mode 100644 index addad6e..0000000 --- a/client/src/styles/_buttons.scss +++ /dev/null @@ -1,22 +0,0 @@ -@use './functions/colors'; -@use './functions/fonts'; - -// TODO: Update all padding to use CSS Var - -.btn { - font-size: fonts.size(text, 4); - color: colors.use-var(text, light); - border: 1px solid colors.use-var(text, light); - padding: 0.5rem; - text-decoration: none; - background: transparent; - - span + svg { - display: inline-block; - margin-left: 0.5rem; - } - - &:not(:last-child) { - margin-right: 1rem; - } -} diff --git a/client/src/styles/_custom-properties.scss b/client/src/styles/_custom-properties.scss deleted file mode 100644 index 7b10d28..0000000 --- a/client/src/styles/_custom-properties.scss +++ /dev/null @@ -1,25 +0,0 @@ -@use './vars/colors'; -@use './vars/fonts'; - -:root { - @each $group, $colors in colors.$colors-map { - /*** Color - #{capitalize($group)} ***/ - @each $variant, $color in $colors { - --color-#{$group}-#{$variant}: #{$color}; - } - } - - @each $group, $sizes in fonts.$sizes { - /*** Font Sizes - #{capitalize($group)} ***/ - @each $variant, $size in $sizes { - --font-size-#{$group}-#{$variant}: #{$size}; - } - } - - @each $group, $options in fonts.$details { - /*** Font Details - #{capitalize($group)} ***/ - @each $variant, $option in $options { - --font-#{$group}-#{$variant}: #{$option}; - } - } -} diff --git a/client/src/styles/_header.scss b/client/src/styles/_header.scss deleted file mode 100644 index b1c2b56..0000000 --- a/client/src/styles/_header.scss +++ /dev/null @@ -1,56 +0,0 @@ -@use './functions/colors'; -@use './vars/colors' as *; - -@function cosmic_gradient($clrs) { - $colorLength: length($clrs); - $gradient: ""; - - @for $i from 1 through $colorLength { - @if $i < $colorLength { - $gradient: $gradient + nth($clrs, $i) + ", "; - } @else { - $gradient: $gradient + nth($clrs, $i); - } - } - @return $gradient; -} - -.main-header { - display: flex; - justify-content: space-between; - align-items: center; - position: fixed; - z-index: 100; - top: 0; - left: 0; - width: 100vw; - padding: 1rem 2rem; - - &:before { - content: ""; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: linear-gradient(to right, #{cosmic_gradient($colors)}); - opacity: 0.75; - z-index: -1; - } -} - -.logo { - margin: 0; - font-size: 1rem; - - a { - color: colors.use-var(text, light); - text-decoration: none; - - &:focus, - &:hover { - outline: none; - color: colors.use-var(text, dark); - } - } -} diff --git a/client/src/styles/_nav.scss b/client/src/styles/_nav.scss deleted file mode 100644 index fff1e4c..0000000 --- a/client/src/styles/_nav.scss +++ /dev/null @@ -1,131 +0,0 @@ -@use './functions/fonts'; -@use './functions/colors'; -@use './vars/colors' as *; - -.burger-nav { - background: transparent; - border: none; - color: colors.use-var(text, light); - font-weight: bold; - z-index: 9999; - cursor: pointer; - transition: all 0.25s ease; - display: flex; - padding: 0; - height: 30px; - transform: rotate(-90deg); - - span { - display: block; - transition: all 0.25s ease; - width: 3px; - height: 100%; - background: white; - - &:nth-child(2) { - margin: 0 10px; - } - } - - &:focus { - outline: none; - span { - background: colors.use-var(text, dark); - .-nav-visible & { - background: colors.use-var(primary); - } - } - } - - .-nav-visible & { - span { - opacity: 0; - &:first-of-type { - transform: rotate(-45deg) translate(-50%, 10%); - transform-origin: top right; - opacity: 1; - } - &:last-of-type { - transform: rotate(45deg) translate(50%, 20%); - transform-origin: top right; - opacity: 1; - } - } - } -} - -.full-screen-nav { - position: fixed; - z-index: 9998; - width: 100%; - height: 100vh; - background: colors.use-var(bg, darkest); - visibility: hidden; - transition: all 0.25s ease; - opacity: 0; - top: 0; - left: 0; - display: flex; - justify-content: center; - align-items: center; - - ul { - margin: 0; - padding: 0; - text-align: center; - vertical-align: middle; - width: 100%; - - li { - list-style: none; - - @for $i from 1 through length($colors) { - &:nth-child(#{length($colors)}n + #{$i}) { - a { - $color: nth($colors, $i); - --color: #{$color}; - --hover-text: #{darken($color, 50%)}; - border-color: var(--color); - color: var(--color); - - &:focus, - &:hover { - outline: none; - color: var(--hover-text); - background: var(--color); - } - } - } - } - } - - a { - display: block; - font-size: fonts.size(text, 1); - color: colors.use-var(text, light); - text-decoration: none; - padding: 6rem; - transition: all 0.25s ease; - } - } - - .-nav-visible & { - opacity: 1 !important; - visibility: visible !important; - - a { - opacity: 1 !important; - padding: 2rem; - } - } -} - -.fadeIn { - opacity: 1 !important; - visibility: visible !important; -} - -.fadeUp { - opacity: 1 !important; - margin-top: 0 !important; -} diff --git a/client/src/styles/_page.scss b/client/src/styles/_page.scss deleted file mode 100644 index be6b88d..0000000 --- a/client/src/styles/_page.scss +++ /dev/null @@ -1,49 +0,0 @@ -@use './functions/colors'; -@use './functions/fonts'; -@use './vars/colors' as *; - -.page { - position: relative; -} - -.page-header { - padding: 20rem 0 2rem; - max-width: 100ch; -} - -.page-header__title { - font-family: fonts.family(display); - font-size: fonts.size(display, 1); -} - -.page-header__desc { - font-size: fonts.size(heading, 1); -} - -.page-header-actions { - padding: 1rem 0 0; - - @for $i from 1 through length($colors) { - .btn:nth-child(#{length($colors)}n + #{$i}) { - $color: nth($colors, $i); - --color: #{$color}; - --hover-text: #{darken($color, 50%)}; - border-color: var(--color); - color: var(--color); - - &:focus, - &:hover { - outline: none; - color: var(--hover-text); - filter: hue-rotate(15deg); - background: var(--color); - } - } - } -} - -.section { - p { - line-height: fonts.height(comfortable); - } -} diff --git a/client/src/styles/_typography.scss b/client/src/styles/_typography.scss deleted file mode 100644 index 67f6450..0000000 --- a/client/src/styles/_typography.scss +++ /dev/null @@ -1,105 +0,0 @@ -@use './functions/fonts'; -@use './functions/colors'; - -h1, -.h1, -h2, -.h2, -h3, -.h3, -h4, -.h4, -h5, -.h5, -h6, -.h6 { - font-family: fonts.family(text); - margin: 0; - line-height: 1.25em; -} - -h1, -.h1 { - font-size: fonts.size(heading, 1); -} - -h2, -.h2 { - font-size: fonts.size(heading, 2); -} - -h3, -.h3 { - font-size: fonts.size(heading, 3); -} - -h4, -.h4 { - font-size: fonts.size(heading, 4); -} - -h5, -.h5 { - font-size: fonts.size(heading, 5); -} - -h6, -.h6 { - font-size: fonts.size(heading, 6); -} - -.display-1, -.display-2, -.display-3, -.display-4, -.display-5, -.display-6 { - font-family: fonts.family(display); - font-weight: fonts.weight(thick); - margin: 0; - line-height: 1.25em; -} - -.display-1 { - font-size: fonts.size(display, 1); -} - -.display-2 { - font-size: fonts.size(display, 2); -} - -.display-3 { - font-size: fonts.size(display, 3); -} - -.display-4 { - font-size: fonts.size(display, 4); -} - -.display-5 { - font-size: fonts.size(display, 5); -} - -.display-6 { - font-size: fonts.size(display, 6); -} - -.text-1 { - font-size: fonts.size(text, 1); -} - -.text-2 { - font-size: fonts.size(text, 2); -} - -.text-3 { - font-size: fonts.size(text, 3); -} - -.text-4 { - font-size: fonts.size(text, 4); -} - -.text-5 { - font-size: fonts.size(text, 5); -} diff --git a/client/src/styles/_api-card.scss b/client/src/styles/api-card.css similarity index 52% rename from client/src/styles/_api-card.scss rename to client/src/styles/api-card.css index 1d0c106..4cd06f5 100644 --- a/client/src/styles/_api-card.scss +++ b/client/src/styles/api-card.css @@ -1,17 +1,14 @@ -@use './functions/colors'; -@use './vars/colors' as *; - .section-header { margin-bottom: 1rem; padding-bottom: 1rem; - border-bottom: 1px solid colors.use-var(text, light); + border-bottom: 1px solid var(--color-text-light); display: flex; justify-content: space-between; align-items: flex-end; flex-wrap: wrap; - gap: .5rem; + gap: 0.5rem; - .actions { + & .actions { display: flex; } } @@ -24,7 +21,7 @@ } .api-card { - border: 1px solid colors.use-var(text, light); + border: 1px solid var(--color-text-light); position: relative; &:before { @@ -38,34 +35,38 @@ z-index: 0; transition: all 0.25s ease; } +} - @for $i from 1 through length($colors) { - &:nth-child(#{length($colors)}n + #{$i}) { - --card-color: #{nth($colors, $i)}; - color: var(--card-color); - border-color: var(--card-color); - &:before { - background: repeating-linear-gradient( - -45deg, - var(--card-color) 0, - var(--card-color) 4px, - transparent 0, - transparent 8px - ); - } +/* Accent color cycled across cards */ +.api-card:nth-child(6n + 1) { --card-color: #00d6e9; } +.api-card:nth-child(6n + 2) { --card-color: #15e3d9; } +.api-card:nth-child(6n + 3) { --card-color: #56edbf; } +.api-card:nth-child(6n + 4) { --card-color: #8cf5a2; } +.api-card:nth-child(6n + 5) { --card-color: #c2f985; } +.api-card:nth-child(6n + 6) { --card-color: #f9f871; } - &:focus-within, - &:hover { - &:before { - transform: translate(-1rem, 1rem); - } - } - } +.api-card { + color: var(--card-color); + border-color: var(--card-color); + + &:before { + background: repeating-linear-gradient( + -45deg, + var(--card-color) 0, + var(--card-color) 4px, + transparent 0, + transparent 8px + ); + } + + &:focus-within:before, + &:hover:before { + transform: translate(-1rem, 1rem); } } .api-card__inner { - background: colors.use-var(bg, darkest); + background: var(--color-bg-darkest); padding: 1rem; width: 100%; height: 100%; @@ -79,7 +80,7 @@ display: flex; align-items: center; - .btn { + & .btn { color: var(--card-color); margin-left: 0.25rem; border: none; @@ -88,24 +89,22 @@ outline: 2px solid var(--card-color); } } - - .noleftmargin { + + & .noleftmargin { margin-left: 0; padding-left: 0; } } -.api-card__desc { - p { - margin: 0; - } +.api-card__desc p { + margin: 0; } .api-card__endpoints { margin-top: 0.5rem; position: relative; - summary { + & summary { padding: 0.5rem; position: relative; @@ -126,25 +125,30 @@ } } - ul { + & ul { margin: 0; background: var(--card-color); - color: colors.use-var(text, dark); + color: var(--color-text-dark); padding: 0.5rem; position: relative; - li { + & li { list-style: none; position: relative; margin: 0; padding: 0.5rem; transition: all 0.25s ease; - @for $i from 1 through 10 { - &:nth-child(#{$i}) { - transition-delay: #{$i * 0.05}s; - } - } + &:nth-child(1) { transition-delay: 0.05s; } + &:nth-child(2) { transition-delay: 0.1s; } + &:nth-child(3) { transition-delay: 0.15s; } + &:nth-child(4) { transition-delay: 0.2s; } + &:nth-child(5) { transition-delay: 0.25s; } + &:nth-child(6) { transition-delay: 0.3s; } + &:nth-child(7) { transition-delay: 0.35s; } + &:nth-child(8) { transition-delay: 0.4s; } + &:nth-child(9) { transition-delay: 0.45s; } + &:nth-child(10) { transition-delay: 0.5s; } } } } diff --git a/client/src/styles/api-categories.css b/client/src/styles/api-categories.css new file mode 100644 index 0000000..347786e --- /dev/null +++ b/client/src/styles/api-categories.css @@ -0,0 +1,29 @@ +.api-categories { + margin: 0; + padding: 0 1rem 0 0; +} + +.api-category { + font-size: 0.85rem; + list-style: none; + display: inline-block; + padding: 0.25rem 0.5rem; + margin-bottom: 0.5rem; + letter-spacing: 1px; + border-radius: 10px; + border-color: var(--cat-color); + background: var(--cat-color); + color: var(--color-text-dark); + + &:not(:last-child) { + margin-right: 0.5rem; + } +} + +/* Accent color cycled across category tags */ +.api-category:nth-child(6n + 1) { --cat-color: #00d6e9; } +.api-category:nth-child(6n + 2) { --cat-color: #15e3d9; } +.api-category:nth-child(6n + 3) { --cat-color: #56edbf; } +.api-category:nth-child(6n + 4) { --cat-color: #8cf5a2; } +.api-category:nth-child(6n + 5) { --cat-color: #c2f985; } +.api-category:nth-child(6n + 6) { --cat-color: #f9f871; } diff --git a/client/src/styles/api-endpoints.css b/client/src/styles/api-endpoints.css new file mode 100644 index 0000000..cbdef1d --- /dev/null +++ b/client/src/styles/api-endpoints.css @@ -0,0 +1,37 @@ +.api-endpoints { + margin: 0; + padding: 0; + display: flex; + flex-wrap: wrap; + gap: 0.75rem; +} + +.api-endpoint { + list-style: none; + display: block; + + & a { + display: inline-block; + text-transform: capitalize; + } +} + +/* Accent color cycled across endpoint buttons */ +.api-endpoint:nth-child(6n + 1) .btn { --color: #00d6e9; --hover-text: black; } +.api-endpoint:nth-child(6n + 2) .btn { --color: #15e3d9; --hover-text: black; } +.api-endpoint:nth-child(6n + 3) .btn { --color: #56edbf; --hover-text: #073d2d; } +.api-endpoint:nth-child(6n + 4) .btn { --color: #8cf5a2; --hover-text: #0a7821; } +.api-endpoint:nth-child(6n + 5) .btn { --color: #c2f985; --hover-text: #427906; } +.api-endpoint:nth-child(6n + 6) .btn { --color: #f9f871; --hover-text: #676604; } + +.api-endpoint .btn { + border-color: var(--color); + color: var(--color); + + &:focus, + &:hover { + outline: none; + color: var(--hover-text); + background: var(--color); + } +} diff --git a/client/src/styles/_api-filter.scss b/client/src/styles/api-filter.css similarity index 63% rename from client/src/styles/_api-filter.scss rename to client/src/styles/api-filter.css index 94e1306..6903a39 100644 --- a/client/src/styles/_api-filter.scss +++ b/client/src/styles/api-filter.css @@ -1,6 +1,3 @@ -@use './functions/colors'; -@use './functions/fonts'; - .api-filter { position: relative; display: flex; @@ -11,7 +8,7 @@ content: ""; position: absolute; display: block; - border-top: 6px solid colors.use-var(text, light); + border-top: 6px solid var(--color-text-light); border-left: 6px solid transparent; border-right: 6px solid transparent; top: 50%; @@ -19,19 +16,19 @@ transform: translate(-50%, -50%); } - select { + & select { border: 1px solid transparent; - border-bottom: 1px solid colors.use-var(text, light); + border-bottom: 1px solid var(--color-text-light); padding: 0.5rem; background-color: transparent; - color: colors.use-var(text, light); + color: var(--color-text-light); appearance: none; - font-size: fonts.size(text, 2); + font-size: var(--font-size-text-2); transition: all 0.25s ease; &:focus, &:hover { - border: 1px solid colors.use-var(text, light); + border: 1px solid var(--color-text-light); outline: none; } } diff --git a/client/src/styles/_api-search.scss b/client/src/styles/api-search.css similarity index 65% rename from client/src/styles/_api-search.scss rename to client/src/styles/api-search.css index b370150..27429f3 100644 --- a/client/src/styles/_api-search.scss +++ b/client/src/styles/api-search.css @@ -1,6 +1,3 @@ -@use './functions/colors'; -@use './functions/fonts'; - .api-search { display: flex; align-items: center; @@ -9,11 +6,11 @@ } .api-search__inner { - color: colors.use-var(text, light); - font-size: fonts.size(text, 1); + color: var(--color-text-light); + font-size: var(--font-size-text-1); - svg { - font-size: fonts.size(text, 1); + & svg { + font-size: var(--font-size-text-1); cursor: pointer; transition: all 0.25s ease-out; transform: scale(1); @@ -23,15 +20,15 @@ } } - input { - font-size: fonts.size(text, 1); + & input { + font-size: var(--font-size-text-1); height: 30px; width: 0; padding: 1rem; background: transparent; - color: colors.use-var(text, light); + color: var(--color-text-light); border: solid 0 transparent; - border-bottom: solid 1px colors.use-var(text, light); + border-bottom: solid 1px var(--color-text-light); outline: 0; text-align: right; transition: all 0.25s ease-out; diff --git a/client/src/styles/base.css b/client/src/styles/base.css new file mode 100644 index 0000000..0e02ce8 --- /dev/null +++ b/client/src/styles/base.css @@ -0,0 +1,91 @@ +*, +*:before, +*:after { + box-sizing: border-box; +} + +html, +body { + margin: 0; + font-family: var(--font-family-text); + font-weight: var(--font-weight-base); + color: var(--color-text-light); + background: var(--color-bg-darkest); + + &.-nav-visible { + height: 100vh; + overflow: hidden; + } +} + +#root { + display: grid; + grid-template-columns: minmax(25px, 150px) minmax(50%, 90%) minmax(25px, 150px); + grid-template-areas: "left center right"; + margin-bottom: 5rem; +} + +.content { + grid-area: center; +} + +p { + margin: 0; + font-size: var(--font-size-text-2); + max-width: 80ch; + + & + p { + margin-top: 1rem; + } +} + +a { + text-decoration: none; + transition: all 0.25s ease; +} + +abbr { + transition: all 0.25s ease; + cursor: help; + position: relative; +} + +/* Accent color cycled across abbreviations */ +abbr:nth-of-type(6n + 1) { --color: #00d6e9; --hover-text: black; } +abbr:nth-of-type(6n + 2) { --color: #15e3d9; --hover-text: black; } +abbr:nth-of-type(6n + 3) { --color: #56edbf; --hover-text: #073d2d; } +abbr:nth-of-type(6n + 4) { --color: #8cf5a2; --hover-text: #0a7821; } +abbr:nth-of-type(6n + 5) { --color: #c2f985; --hover-text: #427906; } +abbr:nth-of-type(6n + 6) { --color: #f9f871; --hover-text: #676604; } + +abbr { + border-color: var(--color); + color: var(--color); + + &:focus, + &:hover { + outline: none; + color: var(--hover-text); + background: var(--color); + z-index: 100; + + &::after { + content: attr(title); + background: var(--color); + box-shadow: 0 0 10px black; + position: absolute; + display: block; + bottom: 100%; + left: 0; + padding: 0.25rem 0.5rem; + font-size: var(--font-size-text-3); + white-space: nowrap; + } + } +} + +.featured-icon { + position: absolute; + top: 1rem; + right: 1rem; +} diff --git a/client/src/styles/buttons.css b/client/src/styles/buttons.css new file mode 100644 index 0000000..cb05eb0 --- /dev/null +++ b/client/src/styles/buttons.css @@ -0,0 +1,19 @@ +/* TODO: Update all padding to use CSS Var */ + +.btn { + font-size: var(--font-size-text-4); + color: var(--color-text-light); + border: 1px solid var(--color-text-light); + padding: 0.5rem; + text-decoration: none; + background: transparent; + + & span + svg { + display: inline-block; + margin-left: 0.5rem; + } + + &:not(:last-child) { + margin-right: 1rem; + } +} diff --git a/client/src/styles/_code-display.scss b/client/src/styles/code-display.css similarity index 81% rename from client/src/styles/_code-display.scss rename to client/src/styles/code-display.css index 4174649..79ba046 100644 --- a/client/src/styles/_code-display.scss +++ b/client/src/styles/code-display.css @@ -1,5 +1,3 @@ -@use './functions/colors'; - .top-pane { background-color: hsl(225, 6%, 25%); } @@ -33,15 +31,15 @@ .expand-collapse-btn { background: none; border: none; - color: colors.use-var(text, light); + color: var(--color-text-light); cursor: pointer; } .editor-title { display: flex; justify-content: space-between; - background-color: colors.use-var(bg, darkest); - color: colors.use-var(text, light); + background-color: var(--color-bg-darkest); + color: var(--color-text-light); padding: 0.5rem; } diff --git a/client/src/styles/functions/_colors.scss b/client/src/styles/functions/_colors.scss deleted file mode 100644 index 0017049..0000000 --- a/client/src/styles/functions/_colors.scss +++ /dev/null @@ -1,61 +0,0 @@ -@use '../vars/colors'; - -// ---------------------------------------------------- -// Creates CSS Custom Property syntax for colors -// @param {string} $group -// @param {string} $variant -// -// 1. Validates the $group param. -// 2. Validates the $variant param -// 3. Returns proper CSS Custom Property syntax -// 4. Throws error for invalid $variant param -// 5. Throws error for invalid $group param -// -@function use-var($group, $variant: base) { - $map: colors.$colors-map; - - // [1] - @if map-has-key($map, $group) { - // [2] - @if map-has-key(map-get($map, $group), $variant) { - // [3] - @return var(--color-#{$group}-#{$variant}); - } @else { - // [4] - @error "`#{$variant}` is not a valid key in `$colors-map.#{$group}`."; - } - } @else { - // [5] - @error "`#{$group}` is not a valid key in `$colors-map`."; - } -} - -// ---------------------------------------------------- -// Creates HEX syntax for colors -// @param {string} $group -// @param {string} $variant -// -// 1. Validates the $group param. -// 2. Validates the $variant param -// 3. Returns proper CSS Custom Property syntax -// 4. Throws error for invalid $variant param -// 5. Throws error for invalid $group param -// -@function use-hex($group, $variant: base) { - $map: colors.$colors-map; - - // [1] - @if map-has-key($map, $group) { - // [2] - @if map-has-key(map-get($map, $group), $variant) { - // [3] - @return map-get(map-get($map, $group), $variant); - } @else { - // [4] - @error "`#{$variant}` is not a valid key in `#{$group}` color map."; - } - } @else { - // [5] - @error "`#{$group}` is not a valid key in `$colors-map`."; - } -} diff --git a/client/src/styles/functions/_fonts.scss b/client/src/styles/functions/_fonts.scss deleted file mode 100644 index 05cebd0..0000000 --- a/client/src/styles/functions/_fonts.scss +++ /dev/null @@ -1,35 +0,0 @@ -@use '../vars/fonts'; - -@function size($group, $size) { - @return var(--font-size-#{$group}-#{$size}); -} - -@function family($group) { - $map: map-get(fonts.$details, family); - - @if map-has-key($map, $group) { - @return var(--font-family-#{$group}); - } @else { - @error "`#{$group}` is not a valid key in `$details.family`."; - } -} - -@function weight($weight) { - $map: map-get(fonts.$details, weight); - - @if map-has-key($map, $weight) { - @return var(--font-weight-#{$weight}); - } @else { - @error "`#{$weight}` is not a valid key in `$details.weight`."; - } -} - -@function height($height) { - $map: map-get(fonts.$details, height); - - @if map-has-key($map, $height) { - @return var(--font-height-#{$height}); - } @else { - @error "`#{$height}` is not a valid key in `$details.height`."; - } -} diff --git a/client/src/styles/functions/_index.scss b/client/src/styles/functions/_index.scss deleted file mode 100644 index 13ca873..0000000 --- a/client/src/styles/functions/_index.scss +++ /dev/null @@ -1,2 +0,0 @@ -@use 'colors'; -@use 'screens'; diff --git a/client/src/styles/functions/_screens.scss b/client/src/styles/functions/_screens.scss deleted file mode 100644 index 60d6ffb..0000000 --- a/client/src/styles/functions/_screens.scss +++ /dev/null @@ -1,49 +0,0 @@ -@use '../vars/screens'; - -// ----------------------------------------------------------= -// Creates media min query based on predefined breakpoint sizes -// @param {string} $group -// @param {string} $variant -// -// 1. Validates the $size param. -// 2. Returns proper Media Query syntax -// 3. Throws error for invalid $size param -// -@mixin min($size) { - $map: screens.$breakpoints; - - // [1] - @if map-has-key($map, $size) { - // [2] - @media (min-width: map-get(screens.$breakpoints, $size)) { - @content; - } - } @else { - // [3] - @error "`#{$size}` is not a valid key in `$breakpoints`."; - } -} - -// ----------------------------------------------------------= -// Creates media max query based on predefined breakpoint sizes -// @param {string} $group -// @param {string} $variant -// -// 1. Validates the $size param. -// 2. Returns proper Media Query syntax -// 3. Throws error for invalid $size param -// -@mixin max($size) { - $map: screens.$breakpoints; - - // [1] - @if map-has-key($map, $size) { - // [2] - @media (max-width: map-get(screens.$breakpoints, $size)) { - @content; - } - } @else { - // [3] - @error "`#{$size}` is not a valid key in `$breakpoints`."; - } -} diff --git a/client/src/styles/header.css b/client/src/styles/header.css new file mode 100644 index 0000000..493a9e7 --- /dev/null +++ b/client/src/styles/header.css @@ -0,0 +1,39 @@ +.main-header { + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + z-index: 100; + top: 0; + left: 0; + width: 100vw; + padding: 1rem 2rem; + + &:before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient(to right, #00d6e9, #15e3d9, #56edbf, #8cf5a2, #c2f985, #f9f871); + opacity: 0.75; + z-index: -1; + } +} + +.logo { + margin: 0; + font-size: 1rem; + + & a { + color: var(--color-text-light); + text-decoration: none; + + &:focus, + &:hover { + outline: none; + color: var(--color-text-dark); + } + } +} diff --git a/client/src/styles/mixins/_colors.scss b/client/src/styles/mixins/_colors.scss deleted file mode 100644 index 0ea0edf..0000000 --- a/client/src/styles/mixins/_colors.scss +++ /dev/null @@ -1,14 +0,0 @@ -@use '../vars/colors' as *; - -// This might be making things to abstract and complicated -// Might delete later -@mixin color-cycle($element) { - @for $i from 1 through length($colors) { - .#{$element}:nth-child(#{length($colors)}n + #{$i}) { - $color: nth($colors, $i); - --color: #{$color}; - --hover-text: #{darken($color, 50%)}; - @content; - } - } -} diff --git a/client/src/styles/nav.css b/client/src/styles/nav.css new file mode 100644 index 0000000..8b4ea59 --- /dev/null +++ b/client/src/styles/nav.css @@ -0,0 +1,130 @@ +.burger-nav { + background: transparent; + border: none; + color: var(--color-text-light); + font-weight: bold; + z-index: 9999; + cursor: pointer; + transition: all 0.25s ease; + display: flex; + padding: 0; + height: 30px; + transform: rotate(-90deg); + + & span { + display: block; + transition: all 0.25s ease; + width: 3px; + height: 100%; + background: white; + + &:nth-child(2) { + margin: 0 10px; + } + } + + &:focus { + outline: none; + + & span { + background: var(--color-text-dark); + + .-nav-visible & { + background: var(--color-primary-base); + } + } + } + + .-nav-visible & span { + opacity: 0; + + &:first-of-type { + transform: rotate(-45deg) translate(-50%, 10%); + transform-origin: top right; + opacity: 1; + } + + &:last-of-type { + transform: rotate(45deg) translate(50%, 20%); + transform-origin: top right; + opacity: 1; + } + } +} + +.full-screen-nav { + position: fixed; + z-index: 9998; + width: 100%; + height: 100vh; + background: var(--color-bg-darkest); + visibility: hidden; + transition: all 0.25s ease; + opacity: 0; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; + + & ul { + margin: 0; + padding: 0; + text-align: center; + vertical-align: middle; + width: 100%; + + & li { + list-style: none; + } + + & a { + display: block; + font-size: var(--font-size-text-1); + color: var(--color-text-light); + text-decoration: none; + padding: 6rem; + transition: all 0.25s ease; + } + } + + .-nav-visible & { + opacity: 1 !important; + visibility: visible !important; + + & a { + opacity: 1 !important; + padding: 2rem; + } + } +} + +/* Accent color cycled across the full-screen nav links */ +.full-screen-nav ul li:nth-child(6n + 1) a { --color: #00d6e9; --hover-text: black; } +.full-screen-nav ul li:nth-child(6n + 2) a { --color: #15e3d9; --hover-text: black; } +.full-screen-nav ul li:nth-child(6n + 3) a { --color: #56edbf; --hover-text: #073d2d; } +.full-screen-nav ul li:nth-child(6n + 4) a { --color: #8cf5a2; --hover-text: #0a7821; } +.full-screen-nav ul li:nth-child(6n + 5) a { --color: #c2f985; --hover-text: #427906; } +.full-screen-nav ul li:nth-child(6n + 6) a { --color: #f9f871; --hover-text: #676604; } + +.full-screen-nav ul li a { + border-color: var(--color); + color: var(--color); + + &:focus, + &:hover { + outline: none; + color: var(--hover-text); + background: var(--color); + } +} + +.fadeIn { + opacity: 1 !important; + visibility: visible !important; +} + +.fadeUp { + opacity: 1 !important; + margin-top: 0 !important; +} diff --git a/client/src/styles/_not-found.scss b/client/src/styles/not-found.css similarity index 82% rename from client/src/styles/_not-found.scss rename to client/src/styles/not-found.css index ad2e226..02a8aa0 100644 --- a/client/src/styles/_not-found.scss +++ b/client/src/styles/not-found.css @@ -1,7 +1,4 @@ -@use './functions/colors'; - .-not-found { - display: block; background: linear-gradient(180deg, rgba(2, 214, 233, 1) 0%, rgba(249, 248, 113, 1) 100%); width: 100vw; height: 100vh; @@ -13,7 +10,7 @@ justify-content: center; align-items: center; - code { + & code { font-size: 3rem; white-space: pre-wrap; padding: 0; @@ -22,6 +19,6 @@ background: none; box-shadow: none; font-weight: bold; - color: colors.use-var(text, dark); + color: var(--color-text-dark); } } diff --git a/client/src/styles/page.css b/client/src/styles/page.css new file mode 100644 index 0000000..c2a4a2c --- /dev/null +++ b/client/src/styles/page.css @@ -0,0 +1,46 @@ +.page { + position: relative; +} + +.page-header { + padding: 20rem 0 2rem; + max-width: 100ch; +} + +.page-header__title { + font-family: var(--font-family-display); + font-size: var(--font-size-display-1); +} + +.page-header__desc { + font-size: var(--font-size-heading-1); +} + +.page-header-actions { + padding: 1rem 0 0; +} + +/* Accent color cycled across page-header action buttons */ +.page-header-actions .btn:nth-child(6n + 1) { --color: #00d6e9; --hover-text: black; } +.page-header-actions .btn:nth-child(6n + 2) { --color: #15e3d9; --hover-text: black; } +.page-header-actions .btn:nth-child(6n + 3) { --color: #56edbf; --hover-text: #073d2d; } +.page-header-actions .btn:nth-child(6n + 4) { --color: #8cf5a2; --hover-text: #0a7821; } +.page-header-actions .btn:nth-child(6n + 5) { --color: #c2f985; --hover-text: #427906; } +.page-header-actions .btn:nth-child(6n + 6) { --color: #f9f871; --hover-text: #676604; } + +.page-header-actions .btn { + border-color: var(--color); + color: var(--color); + + &:focus, + &:hover { + outline: none; + color: var(--hover-text); + filter: hue-rotate(15deg); + background: var(--color); + } +} + +.section p { + line-height: var(--font-height-comfortable); +} diff --git a/client/src/styles/styles.css b/client/src/styles/styles.css new file mode 100644 index 0000000..f669ba0 --- /dev/null +++ b/client/src/styles/styles.css @@ -0,0 +1,16 @@ +@import url("https://fonts.googleapis.com/css2?family=Montserrat+Alternates:wght@200;400;600&family=Roboto:wght@200;400;600&display=swap"); + +@import "./tokens.css"; +@import "./base.css"; +@import "./typography.css"; +@import "./buttons.css"; +@import "./header.css"; +@import "./nav.css"; +@import "./page.css"; +@import "./api-card.css"; +@import "./api-categories.css"; +@import "./api-search.css"; +@import "./api-filter.css"; +@import "./api-endpoints.css"; +@import "./code-display.css"; +@import "./not-found.css"; diff --git a/client/src/styles/styles.scss b/client/src/styles/styles.scss deleted file mode 100644 index 2feb1c4..0000000 --- a/client/src/styles/styles.scss +++ /dev/null @@ -1,14 +0,0 @@ -@use 'custom-properties'; -@use 'base'; -@use 'typography'; -@use 'buttons'; -@use 'header'; -@use 'nav'; -@use 'page'; -@use 'api-card'; -@use 'api-categories'; -@use 'api-search'; -@use 'api-filter'; -@use 'api-endpoints'; -@use 'code-display'; -@use 'not-found'; diff --git a/client/src/styles/tokens.css b/client/src/styles/tokens.css new file mode 100644 index 0000000..9ee986a --- /dev/null +++ b/client/src/styles/tokens.css @@ -0,0 +1,76 @@ +/* Design tokens — hand-authored custom properties. + Replaces the former Sass maps in vars/ that only existed to emit these. */ + +:root { + /* Color — primary */ + --color-primary-base: #00d6e9; + --color-primary-light: #04eaff; + --color-primary-dark: #00bfd0; + + /* Color — buttons */ + --color-buttons-base: #00d6e9; + --color-buttons-light: #04eaff; + --color-buttons-dark: #00bfd0; + + /* Color — secondary */ + --color-secondary-base: #f9f871; + --color-secondary-light: #faf989; + --color-secondary-dark: #f8f759; + + /* Color — text */ + --color-text-light: #fafafa; + --color-text-base: #bdbdbd; + --color-text-dark: #363636; + + /* Color — background */ + --color-bg-lightest: #ffffff; + --color-bg-light: #efefef; + --color-bg-base: #bdbdbd; + --color-bg-dark: #505050; + --color-bg-darkest: #181818; + + /* Palette — the six accent colors cycled across cards, tags, endpoints */ + --palette-1: #00d6e9; + --palette-2: #15e3d9; + --palette-3: #56edbf; + --palette-4: #8cf5a2; + --palette-5: #c2f985; + --palette-6: #f9f871; + + /* Font sizes — text */ + --font-size-text-1: 1.55rem; + --font-size-text-2: 1.25rem; + --font-size-text-3: 1rem; + --font-size-text-4: 0.875rem; + --font-size-text-5: 0.675rem; + + /* Font sizes — heading */ + --font-size-heading-1: 2.5rem; + --font-size-heading-2: 2rem; + --font-size-heading-3: 1.75rem; + --font-size-heading-4: 1.5rem; + --font-size-heading-5: 1.25rem; + --font-size-heading-6: 1rem; + + /* Font sizes — display */ + --font-size-display-1: 5rem; + --font-size-display-2: 4.5rem; + --font-size-display-3: 4rem; + --font-size-display-4: 3.5rem; + --font-size-display-5: 3rem; + --font-size-display-6: 2.5rem; + + /* Font families */ + --font-family-display: "Montserrat Alternates"; + --font-family-text: "Roboto"; + + /* Font weights */ + --font-weight-thin: 200; + --font-weight-base: 400; + --font-weight-thick: 600; + + /* Line heights */ + --font-height-compact: 1em; + --font-height-normal: 1.25em; + --font-height-comfortable: 1.75em; +} diff --git a/client/src/styles/typography.css b/client/src/styles/typography.css new file mode 100644 index 0000000..374750c --- /dev/null +++ b/client/src/styles/typography.css @@ -0,0 +1,42 @@ +h1, .h1, +h2, .h2, +h3, .h3, +h4, .h4, +h5, .h5, +h6, .h6 { + font-family: var(--font-family-text); + margin: 0; + line-height: 1.25em; +} + +h1, .h1 { font-size: var(--font-size-heading-1); } +h2, .h2 { font-size: var(--font-size-heading-2); } +h3, .h3 { font-size: var(--font-size-heading-3); } +h4, .h4 { font-size: var(--font-size-heading-4); } +h5, .h5 { font-size: var(--font-size-heading-5); } +h6, .h6 { font-size: var(--font-size-heading-6); } + +.display-1, +.display-2, +.display-3, +.display-4, +.display-5, +.display-6 { + font-family: var(--font-family-display); + font-weight: var(--font-weight-thick); + margin: 0; + line-height: 1.25em; +} + +.display-1 { font-size: var(--font-size-display-1); } +.display-2 { font-size: var(--font-size-display-2); } +.display-3 { font-size: var(--font-size-display-3); } +.display-4 { font-size: var(--font-size-display-4); } +.display-5 { font-size: var(--font-size-display-5); } +.display-6 { font-size: var(--font-size-display-6); } + +.text-1 { font-size: var(--font-size-text-1); } +.text-2 { font-size: var(--font-size-text-2); } +.text-3 { font-size: var(--font-size-text-3); } +.text-4 { font-size: var(--font-size-text-4); } +.text-5 { font-size: var(--font-size-text-5); } diff --git a/client/src/styles/vars/_colors.scss b/client/src/styles/vars/_colors.scss deleted file mode 100644 index 4f65ee8..0000000 --- a/client/src/styles/vars/_colors.scss +++ /dev/null @@ -1,52 +0,0 @@ -// Greys -$white: #ffffff; -$grey-1: #fafafa; -$grey-2: #efefef; -$grey-3: #eeeeee; -$grey-4: #e0e0e0; -$grey-5: #bdbdbd; -$grey-6: #9e9e9e; -$grey-7: #757575; -$grey-8: #505050; -$grey-9: #363636; -$black: #181818; - -$bright-turquoise: #00d6e9; -$piston-blue: #15e3d9; -$turquoise-blue: #56edbf; -$mint-green: #8cf5a2; -$mineral: #c2f985; -$festival: #f9f871; - -// This is used for color effects in the site. -$colors: ($bright-turquoise, $piston-blue, $turquoise-blue, $mint-green, $mineral, $festival); - -$colors-map: ( - primary: ( - base: $bright-turquoise, - light: lighten($bright-turquoise, 5%), - dark: darken($bright-turquoise, 5%), - ), - buttons: ( - base: $bright-turquoise, - light: lighten($bright-turquoise, 5%), - dark: darken($bright-turquoise, 5%), - ), - secondary: ( - base: $festival, - light: lighten($festival, 5%), - dark: darken($festival, 5%), - ), - text: ( - light: $grey-1, - base: $grey-5, - dark: $grey-9, - ), - bg: ( - lightest: $white, - light: $grey-2, - base: $grey-5, - dark: $grey-8, - darkest: $black, - ), -); diff --git a/client/src/styles/vars/_fonts.scss b/client/src/styles/vars/_fonts.scss deleted file mode 100644 index eab29c1..0000000 --- a/client/src/styles/vars/_fonts.scss +++ /dev/null @@ -1,58 +0,0 @@ -@import url("https://fonts.googleapis.com/css2?family=Montserrat+Alternates:wght@200;400;600&family=Roboto:wght@200;400;600&display=swap"); - -$font-size-base: 1rem !default; - -$font-families: ( - display: "Montserrat Alternates", - text: "Roboto", -); - -$font-weights: ( - thin: 200, - base: 400, - thick: 600, -); - -$line-heights: ( - compact: 1em, - normal: 1.25em, - comfortable: 1.75em, -); - -$details: ( - family: $font-families, - weight: $font-weights, - height: $line-heights, -); - -$text-sizes: ( - 1: $font-size-base * 1.55, - 2: $font-size-base * 1.25, - 3: $font-size-base, - 4: $font-size-base * 0.875, - 5: $font-size-base * 0.675, -); - -$heading-sizes: ( - 1: $font-size-base * 2.5, - 2: $font-size-base * 2, - 3: $font-size-base * 1.75, - 4: $font-size-base * 1.5, - 5: $font-size-base * 1.25, - 6: $font-size-base, -); - -$display-sizes: ( - 1: 5rem, - 2: 4.5rem, - 3: 4rem, - 4: 3.5rem, - 5: 3rem, - 6: 2.5rem, -); - -$sizes: ( - text: $text-sizes, - heading: $heading-sizes, - display: $display-sizes, -); diff --git a/client/src/styles/vars/_index.scss b/client/src/styles/vars/_index.scss deleted file mode 100644 index b843dd5..0000000 --- a/client/src/styles/vars/_index.scss +++ /dev/null @@ -1,2 +0,0 @@ -@use 'colors'; -@use 'containers'; diff --git a/client/src/styles/vars/_screens.scss b/client/src/styles/vars/_screens.scss deleted file mode 100644 index 0e34987..0000000 --- a/client/src/styles/vars/_screens.scss +++ /dev/null @@ -1,17 +0,0 @@ -$container-max-widths: ( - xs: 90%, - sm: 400px, - md: 688px, - lg: 944px, - xl: 1194px, - xxl: 1468px, -); - -$breakpoints: ( - xs: 0, - sm: 480px, - md: 768px, - lg: 1024px, - xl: 1274px, - xxl: 1548px, -); From e16818a124769a46b093812f327c50d8c6be8cfb Mon Sep 17 00:00:00 2001 From: jermbo Date: Wed, 8 Jul 2026 22:25:37 -0400 Subject: [PATCH 08/26] feat: add self-hosted fonts for improved performance - Introduced @fontsource packages for Montserrat Alternates and Roboto to eliminate render-blocking requests. - Updated styles.css to import self-hosted font files, enhancing loading speed and layout stability. --- client/package.json | 2 ++ client/src/styles/styles.css | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/client/package.json b/client/package.json index b45e65f..6621bb4 100644 --- a/client/package.json +++ b/client/package.json @@ -14,6 +14,8 @@ "dependencies": { "@codesandbox/sandpack-react": "2.20.0", "@codesandbox/sandpack-themes": "2.0.21", + "@fontsource/montserrat-alternates": "5.2.8", + "@fontsource/roboto": "5.2.10", "@fortawesome/fontawesome-svg-core": "6.5.2", "@fortawesome/free-solid-svg-icons": "6.5.2", "@fortawesome/react-fontawesome": "0.2.2", diff --git a/client/src/styles/styles.css b/client/src/styles/styles.css index f669ba0..290db25 100644 --- a/client/src/styles/styles.css +++ b/client/src/styles/styles.css @@ -1,4 +1,11 @@ -@import url("https://fonts.googleapis.com/css2?family=Montserrat+Alternates:wght@200;400;600&family=Roboto:wght@200;400;600&display=swap"); +/* Self-hosted fonts (Fontsource) — bundled and served same-origin so there is + no render-blocking third-party request or font-swap layout shift. */ +@import "@fontsource/roboto/latin-200.css"; +@import "@fontsource/roboto/latin-400.css"; +@import "@fontsource/roboto/latin-600.css"; +@import "@fontsource/montserrat-alternates/latin-200.css"; +@import "@fontsource/montserrat-alternates/latin-400.css"; +@import "@fontsource/montserrat-alternates/latin-600.css"; @import "./tokens.css"; @import "./base.css"; From d42452a772d5469d4686d26933b7f0cd555c7d7b Mon Sep 17 00:00:00 2001 From: jermbo Date: Thu, 9 Jul 2026 07:32:00 -0400 Subject: [PATCH 09/26] refactor: enhance component structure and improve accessibility - Updated main.tsx to enable smooth cross-page animations using the View Transitions API. - Refactored APISearch, Nav, APIList, About, Docs, Home, StyleGuide components to use semantic HTML elements (e.g., , ); }; diff --git a/client/src/main.tsx b/client/src/main.tsx index 900b3ba..ac4ab4c 100644 --- a/client/src/main.tsx +++ b/client/src/main.tsx @@ -19,7 +19,12 @@ const queryClient = new QueryClient({ }, }); -const router = createRouter({ routeTree }); +const router = createRouter({ + routeTree, + // Wrap navigations in document.startViewTransition() where supported, + // for smooth cross-page animations (see styles/transitions.css). + defaultViewTransition: true, +}); // Register the router instance for type-safety across the app. declare module "@tanstack/react-router" { diff --git a/client/src/pages/APIList/APIList.tsx b/client/src/pages/APIList/APIList.tsx index 97a78ec..b4afbfb 100644 --- a/client/src/pages/APIList/APIList.tsx +++ b/client/src/pages/APIList/APIList.tsx @@ -35,7 +35,7 @@ const APIList: React.FC = () => { }; return ( -
+

API List

@@ -62,7 +62,7 @@ const APIList: React.FC = () => { ))}

-
+ ); }; diff --git a/client/src/pages/About/About.tsx b/client/src/pages/About/About.tsx index 7ea751c..cc9dd72 100644 --- a/client/src/pages/About/About.tsx +++ b/client/src/pages/About/About.tsx @@ -5,7 +5,7 @@ interface Props {} const About: React.FC = () => { return ( -
+

About Sample APIs

@@ -35,7 +35,7 @@ const About: React.FC = () => { JSONP.

-
+ ); }; diff --git a/client/src/pages/Docs/Docs.tsx b/client/src/pages/Docs/Docs.tsx index 5fd31cf..3c15d4d 100644 --- a/client/src/pages/Docs/Docs.tsx +++ b/client/src/pages/Docs/Docs.tsx @@ -2,80 +2,93 @@ import React from "react"; import PageHeaderActions from "../../components/PageHeaderActions/PageHeaderActions"; import "./Docs.css"; - -interface Props { } +interface Props {} const Docs: React.FC = () => { return ( -
+

Documentation

-

-

A simple, no fuss, no mess, no auth playground for learning to play with APIs and call them without thinking of Authentication or permissions.

-
-
-

Purpose

-

Understanding RESTful APIs is hard enough, even without including an authentication mechanism. The sole purpose of this repository is to play with RESTful endpoints and learn. We have a few endpoints that you can start playing around with right away! If you are not finding anything you are interested in, create your own endpoints and/or submit a pull request. Take a look at the CONTRIBUTING for more information on how to get involved.

-
-
-

How to use the service

-

Choose an endpoint, say "futurama", then choose what information you'd like, say "characters": -

-                fetch("https://api.sampleapis.com/futurama/characters") 
- .then(resp => resp.json())
- .then(data => console.log(data));
-
- Want to Search? for all chatacters with the name "Bender"? -
-                fetch(`https://api.sampleapis.com/futurama/characters?name.first=Bender`) 
- .then(resp => resp.json())
- .then(data => console.log(data));
-
-

- - Want to learn more? Try watching this video that will explain how to use this api and showcase the results - without any front end coding: https://www.youtube.com/watch?v=lCs9EriXnY8 - -

-

-
-
-

- You also have full CRUD, so you can add information or correct existing ones. -

- Note: Just know that we reset all datapoints weekly and each time we have a new endpoint added. -

-
-
-

Disclaimers

-

-

    -
  • The data on this site is for educational purposes only and is not owned by SampleAPIs.com
  • -
  • Data will be reset back to its original state on a regular basis. If you are updating or adding data to the endpoints and want to have them persist as part of the collection, please contribute to the repo by submitting a pull request.
  • -
  • By using SampleAPIs.com you agree to the following terms: This service is provided under an "as is" condition. It might change or will be discontinued without prior notice. The maker of this service can't be held liable in any way for any reason.
  • -
-

-
- - - - - - - - - - - - - + A simple, no fuss, no mess, no auth playground for learning to play with APIs and call + them without thinking of Authentication or permissions. +

+ +
+
+

Purpose

+

+ Understanding RESTful APIs is hard enough, even without including an authentication + mechanism. The sole purpose of this repository is to play with RESTful endpoints and + learn. We have a few endpoints that you can start playing around with right away! If you + are not finding anything you are interested in, create your own endpoints and/or submit a + pull request. Take a look at the{" "} + + CONTRIBUTING + {" "} + for more information on how to get involved.

+
-
-
+
+

How to use the service

+

+ Choose an endpoint, say "futurama", then choose what information you'd like, say + "characters": +

+
+          {`fetch("https://api.sampleapis.com/futurama/characters")
+  .then(resp => resp.json())
+  .then(data => console.log(data));`}
+        
+

Want to Search for all characters with the name "Bender"?

+
+          {`fetch("https://api.sampleapis.com/futurama/characters?name.first=Bender")
+  .then(resp => resp.json())
+  .then(data => console.log(data));`}
+        
+

+ Want to learn more? Try watching this video that will explain how to use this api and + showcase the results without any front end coding:{" "} + + Hackathon Secrets - presenting without an API + +

+
+
+

You also have full CRUD, so you can add information or correct existing ones.

+

+ Note: Just know that we reset all datapoints weekly and each time we have a new endpoint + added. +

+
+ +
+

Disclaimers

+
    +
  • + The data on this site is for educational purposes only and is not owned by + SampleAPIs.com +
  • +
  • + Data will be reset back to its original state on a regular basis. If you are updating or + adding data to the endpoints and want to have them persist as part of the collection, + please contribute to the repo by submitting a pull request. +
  • +
  • + By using SampleAPIs.com you agree to the following terms: This service is provided under + an "as is" condition. It might change or will be discontinued without prior notice. The + maker of this service can't be held liable in any way for any reason. +
  • +
+
+ ); }; diff --git a/client/src/pages/Home/Home.tsx b/client/src/pages/Home/Home.tsx index c539d68..d118993 100644 --- a/client/src/pages/Home/Home.tsx +++ b/client/src/pages/Home/Home.tsx @@ -6,21 +6,17 @@ import { useApiList } from "../../hooks/useApiList"; import { APIData } from "../../utils/Interfaces"; import PageHeaderActions from "../../components/PageHeaderActions/PageHeaderActions"; -interface Props { } +interface Props {} const Home: React.FC = () => { const { data: apiList = [] } = useApiList(); const [featuredAPIs, setFeatureAPIs] = useState([] as APIData[]); - useEffect(() => { const featured = apiList .filter((api) => api.metaData.featured) .sort(() => (Math.random() > 0.5 ? 1 : -1)); setFeatureAPIs(featured); - - - }, [apiList]); return ( @@ -35,19 +31,20 @@ const Home: React.FC = () => {

-
+

Example

- Understanding RESTful APIs is hard enough, even without including an - authentication mechanism. The sole purpose of this repository is to - play with RESTful endpoints and learn. We have a few endpoints that - you can start playing around with right away! + Understanding RESTful APIs is hard enough, even without including an authentication + mechanism. The sole purpose of this repository is to play with RESTful endpoints and + learn. We have a few endpoints that you can start playing around with right away!

-

Here's an example where I've pulled from: - and chosen the "hot" endpoint: https://api.sampleapis.com/coffee/hot
+

+ Here's an example where I've pulled from: and chosen the "hot" endpoint: + https://api.sampleapis.com/coffee/hot +
then we ran the following code:

@@ -55,21 +52,23 @@ const Home: React.FC = () => {
             .then(resp => resp.json()) 
.then(data => console.log(data[0].title));
+

and randomly selected a coffee and we get the following json back:

+
"Black Coffee"
+

Don't believe me? Try it yourself....

- and randomly selected a coffee and we get the following json back: -

-
-             "Black Coffee"
-          
-

- Don't believe me? Try it yourself.... -

-

or....Want to learn more? Try watching this video that will explain how to use this api and showcase the results - without any front end coding: https://www.youtube.com/watch?v=7MZ6yTzesgg + or....Want to learn more? Try watching this video that will explain how to use this api + and showcase the results without any front end coding:{" "} + + Hackathon Secrets - Presenting without a front end +

-
-
+ +

Featured APIs @@ -82,7 +81,7 @@ const Home: React.FC = () => { ))}

-
+ ); }; diff --git a/client/src/pages/StyleGuide/StyleGuide.tsx b/client/src/pages/StyleGuide/StyleGuide.tsx index 2a152a8..cbf4f59 100644 --- a/client/src/pages/StyleGuide/StyleGuide.tsx +++ b/client/src/pages/StyleGuide/StyleGuide.tsx @@ -4,7 +4,7 @@ interface Props {} const StyleGuide: React.FC = () => { return ( -
+

Home Page

Home Page

@@ -39,7 +39,7 @@ const StyleGuide: React.FC = () => {

Sample APIs

Sample APIs

-
+ ); }; diff --git a/client/src/routes/__root.tsx b/client/src/routes/__root.tsx index 5539071..54c0c5c 100644 --- a/client/src/routes/__root.tsx +++ b/client/src/routes/__root.tsx @@ -10,9 +10,11 @@ export const Route = createRootRoute({ function RootLayout() { return ( -
+ <>
- -
+
+ +
+ ); } diff --git a/client/src/styles/api-card.css b/client/src/styles/api-card.css index 4cd06f5..5e9a1a4 100644 --- a/client/src/styles/api-card.css +++ b/client/src/styles/api-card.css @@ -15,7 +15,8 @@ .cards-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); + /* min() keeps a single card from overflowing containers narrower than 350px */ + grid-template-columns: repeat(auto-fill, minmax(min(100%, 350px), 1fr)); grid-template-rows: repeat(auto-fill, minmax(100px, 1fr)); gap: 2rem; } diff --git a/client/src/styles/base.css b/client/src/styles/base.css index 0e02ce8..a5c6924 100644 --- a/client/src/styles/base.css +++ b/client/src/styles/base.css @@ -18,6 +18,12 @@ body { } } +/* Full-width query container — for elements outside the page column + (site header, full-screen nav, the root grid itself). */ +body { + container: viewport / inline-size; +} + #root { display: grid; grid-template-columns: minmax(25px, 150px) minmax(50%, 90%) minmax(25px, 150px); diff --git a/client/src/styles/responsive.css b/client/src/styles/responsive.css new file mode 100644 index 0000000..c85dd95 --- /dev/null +++ b/client/src/styles/responsive.css @@ -0,0 +1,56 @@ +/* Responsive behavior driven by container queries (not viewport media queries). + Everything here queries the `viewport` container (defined on in + base.css) so the layout changes stay coordinated — the root grid collapse + and the hero spacing change at the same breakpoint, with no dead band. */ + +@container viewport (max-width: 768px) { + /* Drop the decorative side gutters and go single-column. */ + #root { + grid-template-columns: minmax(100%, 1fr); + grid-template-areas: "center"; + padding-inline: 1rem; + } + + /* Shrink the hero in step with the layout change (no longer a huge gap). */ + .page-header { + padding: 8rem 0 1.5rem; + } + + .page-header__title { + font-size: var(--font-size-display-4); + } + + .page-header__desc { + font-size: var(--font-size-heading-3); + } +} + +@container viewport (max-width: 640px) { + .main-header { + padding: 0.75rem 1rem; + } + + .full-screen-nav ul a { + padding: 3rem; + font-size: var(--font-size-text-2); + } +} + +@container viewport (max-width: 480px) { + .page-header { + padding: 6rem 0 1rem; + } + + .page-header__title { + font-size: var(--font-size-display-6); + } + + .page-header__desc { + font-size: var(--font-size-heading-4); + } + + /* Keep the expanding search field from overflowing a narrow toolbar. */ + .api-search__inner input:focus { + width: 140px; + } +} diff --git a/client/src/styles/styles.css b/client/src/styles/styles.css index 290db25..0d36046 100644 --- a/client/src/styles/styles.css +++ b/client/src/styles/styles.css @@ -21,3 +21,5 @@ @import "./api-endpoints.css"; @import "./code-display.css"; @import "./not-found.css"; +@import "./responsive.css"; +@import "./transitions.css"; diff --git a/client/src/styles/transitions.css b/client/src/styles/transitions.css new file mode 100644 index 0000000..f8bfab1 --- /dev/null +++ b/client/src/styles/transitions.css @@ -0,0 +1,44 @@ +/* Smooth page transitions via the View Transitions API. + Enabled by `defaultViewTransition: true` on the router (main.tsx). + Browsers without support simply navigate instantly — graceful fallback. */ + +@keyframes vt-fade-in { + from { + opacity: 0; + } +} + +@keyframes vt-fade-out { + to { + opacity: 0; + } +} + +@keyframes vt-slide-up { + from { + transform: translateY(14px); + } +} + +::view-transition-old(root) { + animation: vt-fade-out 180ms ease both; +} + +::view-transition-new(root) { + animation: + vt-fade-in 260ms ease both, + vt-slide-up 260ms ease both; +} + +/* Keep the fixed site header stable across transitions instead of letting it + fade/slide with the page content. */ +.main-header { + view-transition-name: site-header; +} + +@media (prefers-reduced-motion: reduce) { + ::view-transition-old(root), + ::view-transition-new(root) { + animation: none; + } +} From 579069ec77b9eda3adcf7cdc5563e12c00c3af20 Mon Sep 17 00:00:00 2001 From: jermbo Date: Thu, 9 Jul 2026 08:00:19 -0400 Subject: [PATCH 10/26] feat: modernize server environment and CI configuration - Added .nvmrc to specify Node.js version 26 for consistency across environments. - Updated GitHub Actions workflow to include separate jobs for server and client, both using Node.js 26. - Enhanced CI to install server dependencies and run tests, ensuring compatibility and reliability. - Introduced a Server Modernization Plan document outlining phases for upgrading dependencies and improving architecture. - Updated Dockerfile to use Node.js 26, aligning with the new environment standards. - Added baseline response snapshots for regression testing during future upgrades. --- .github/workflows/node.js.yml | 54 ++++++-- .nvmrc | 1 + docs/server-modernization-plan.md | 122 ++++++++++++++++++ server/Dockerfile | 4 +- server/package-lock.json | 12 +- server/package.json | 4 + server/tests/baseline/README.md | 28 ++++ server/tests/baseline/beers-ale-1.json | 1 + server/tests/baseline/beers-ale.json | 1 + server/tests/baseline/beers-graphql-ales.json | 1 + 10 files changed, 209 insertions(+), 19 deletions(-) create mode 100644 .nvmrc create mode 100644 docs/server-modernization-plan.md create mode 100644 server/tests/baseline/README.md create mode 100644 server/tests/baseline/beers-ale-1.json create mode 100644 server/tests/baseline/beers-ale.json create mode 100644 server/tests/baseline/beers-graphql-ales.json diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 67941de..593f7d3 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -1,30 +1,56 @@ -# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# This workflow installs dependencies, runs the server test suite, and builds the client # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions name: Node.js CI on: push: - branches: [ "main" ] + branches: ["main"] pull_request: - branches: [ "main" ] + branches: ["main"] jobs: - build: - + server: runs-on: ubuntu-latest strategy: matrix: - node-version: [16.x] + node-version: [26.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - run: cd client - - run: npm run build --if-present + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + cache-dependency-path: server/package-lock.json + - name: Install server dependencies + run: npm ci + working-directory: server + - name: Run server tests + run: npm test + working-directory: server + + client: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [26.x] + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + cache-dependency-path: client/package-lock.json + - name: Install client dependencies + run: npm ci + working-directory: client + - name: Build client + run: npm run build --if-present + working-directory: client diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..6f4247a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +26 diff --git a/docs/server-modernization-plan.md b/docs/server-modernization-plan.md new file mode 100644 index 0000000..2c6861c --- /dev/null +++ b/docs/server-modernization-plan.md @@ -0,0 +1,122 @@ +# Server Modernization Plan + +> Scope: **server only** (`server/`). Companion to `frontend-modernization-plan.md`. +> Goal: bring the backend runtime, dependencies, and security current, clear the audit backlog, and remove long-standing architectural smells — **without changing the public API contract** for consumers. + +## Guiding decisions + +- **One Node version everywhere.** Standardize on **Node 26** (current; maintainer is on 26.5.0) and pin it in `engines`, `.nvmrc`, CI, and the Dockerfile (which today drift across 16 / 22 / 24). +- **Preserve the public API surface.** Endpoint paths, response shapes, and the reset behavior stay compatible. Consumers depend on `/{api}` and `/{api}/{resource}` responses. +- **Keep GraphQL, upgrade it.** `json-graphql-server@2.4` is the source of most of the vulnerability chain, so we move to `3.x` rather than dropping the `/graphql` endpoints (see Phase 3). +- **Native over polyfill.** Node 26 ships global `fetch`; drop `node-fetch`. `express.json()` replaces `body-parser`. +- **Each phase lands as its own PR** and stays green on install + `jest` in CI. No phase should change response payloads (verified by a snapshot baseline captured in Phase 0). + +## Current state (baseline) + +| Area | Now | +|---|---| +| Runtime | CI **Node 16**, Dockerfile **Node 22**, local **Node 24** — no `engines` field | +| Framework | Express **4.21** (CommonJS), Pug views, `morgan`, `cors` | +| Data APIs | `json-server@0.17.4`, `json-graphql-server@2.4.0` | +| Data store | 51 flat `api/*.json` files, each with a `*.json.backup` twin for resets | +| Rate limiting | `express-rate-limit@7` + `express-slow-down@2` (present, working) | +| Tests | `jest@29` suite in `server/tests/apis.test.js` — **not run in CI** | +| CI | `.github/workflows/node.js.yml` builds the **client** only; never installs/tests the server | + +### Known issues to fix along the way + +- **`cors` is undeclared.** It's `require`d in `sampleapis.js` but missing from `server/package.json`; it only resolves via a hoisted `node_modules`. A clean install breaks the server. (Phase 1) +- **`process.exit(1)` on the reset success path** (`routes/reset.js`, both `/all` and `/:id`) deliberately kills the process and relies on Docker/PM2 to restart it. Fragile, surprising, and returns a failure exit code for a success. (Phase 4) +- **24 npm audit vulnerabilities** (1 critical, 7 high, 11 moderate, 5 low) — dominated by `json-graphql-server → apollo-test-utils → graphql-tools → uuid`, plus a critical `shell-quote`. (Phases 2–3) +- **Lockfile drift:** `package.json` pins `concurrently ^8.2.2` but `9.1.2` is installed. (Phase 1) +- **Redundant deps:** `body-parser` (superseded by `express.json()`), `node-fetch@3` ESM-only in a CommonJS project (superseded by global `fetch`). (Phase 1) +- **CORS is wide open** (`app.use(cors())` with no options). Acceptable for a public sample API, but should be a deliberate, documented choice. (Phase 4) + +--- + +## Phase 0 — Baseline & safety net (do first) + +Nothing here changes behavior; it makes every later phase verifiable. + +1. **Pin the runtime.** Add `"engines": { "node": ">=26" }` to `server/package.json`, add a repo-root `.nvmrc` (`26`), and bump the Dockerfile from `node:22-alpine` to `node:26-alpine`. +2. **Fix CI** (`.github/workflows/node.js.yml`): add a server job that runs `npm ci` + `npm test` in `server/`, and bump the matrix off Node 16 to `[26.x]` (add `24.x` if you want a lower-bound guard). The client build step stays. +3. **Capture a response baseline.** Boot the server and snapshot representative endpoints (a REST list, a single resource, and a GraphQL query) into `docs/` or a test fixture. This is the regression oracle for Phases 1–3. +4. Confirm `jest` passes locally against the current code before touching anything. + +**Exit criteria:** one Node version across CI/Docker/`.nvmrc`/`engines`; CI runs server tests and is green; a saved response baseline exists. + +## Phase 1 — Dependency hygiene (low-risk, high-value) + +1. **Declare `cors`** in `server/package.json` (this is a latent clean-install break). +2. **Remove `body-parser`** — `express.json()` / `express.urlencoded()` already cover it in `sampleapis.js`. +3. **Remove `node-fetch`** — replace its use in `routes/testApis.js` with the global `fetch` (Node 22 native). Confirm no remaining `require("node-fetch")`. +4. **Apply safe (non-breaking) bumps:** `express 4.21 → 4.22`, `morgan → 1.11`, `express-rate-limit → 7.5.1`, `pug → 3.0.4`, `nodemon` latest. Align `concurrently` to the installed major. +5. **`npm audit fix`** (non-`--force` only) to clear what's fixable without breaking changes. +6. Regenerate and commit a clean `package-lock.json`. Re-run `jest` + baseline check. + +**Exit criteria:** clean install works from scratch; `body-parser`/`node-fetch` gone; lockfile in sync; tests + baseline green; audit count reduced. + +## Phase 2 — Clear the critical vulnerability (isolated breaking change) + +1. **`shell-quote` (critical):** resolve via the appropriate transitive upgrade / `overrides`. Verify nothing in the tree still pins the vulnerable range. +2. **`uuid` / transitive moderates:** bump where reachable without pulling in the GraphQL breaking change (that's Phase 3). +3. Re-run `npm audit`; document any residual advisories that are blocked solely by `json-graphql-server` so Phase 3 owns them. + +**Exit criteria:** zero critical advisories; remaining highs traceable to the GraphQL chain and explicitly deferred to Phase 3. + +## Phase 3 — Upgrade GraphQL to 3.x (clears the bulk of the audit backlog) + +Most remaining high/moderate advisories chain from `json-graphql-server@2.4` → `apollo-test-utils → graphql-tools → uuid`. **We keep the `/graphql` endpoints and upgrade the library** to cut that subtree out. + +1. **Bump `json-graphql-server 2.4 → 3.x`** (breaking — API/config and the `graphql`/apollo internals changed). Review its changelog for the server-setup signature. +2. **Re-wire the registration** in `routes/base-apis.js` — today it calls `jsonGraphqlExpress.default(data)` per API. Confirm the 3.x export/mounting shape and adjust (the default-export/handler contract may differ). +3. **Verify every `/{api}/graphql` endpoint** against the Phase 0 baseline: run the same queries and diff the responses. Pay attention to any schema/type-inference differences between 2.x and 3.x. +4. Re-run `npm audit`; it should be **clean or near-clean** after this bump. + +**Exit criteria:** on `json-graphql-server@3.x`; all `/graphql` endpoints verified against baseline; `npm audit` clean (or only accepted low advisories, documented). + +## Phase 4 — Architecture & robustness + +1. **Replace the `process.exit(1)` reset mechanism** in `routes/reset.js`: restore files in place (copy `*.json.backup → *.json`) and return a normal response **without killing the process**. Guard against invalid `:id`. This removes the dependency on an external supervisor to stay alive. +2. **Add `helmet`** for security headers, and make **CORS explicit** — keep it permissive for a public sample API, but configure it deliberately (documented allowed methods/headers) rather than a bare `cors()`. +3. **Add a real health endpoint** (`/health` or `/healthz`) returning `200` + minimal JSON, and point the docker-compose healthcheck at it instead of `wget --spider /`. +4. **Centralized error handling:** an Express error-handling middleware so route failures return consistent JSON instead of default HTML stacks; remove scattered `console.log(err)` swallowing. +5. **Config via env:** ensure `PORT` and any origins/limits come from env with sane defaults (partially done — audit for hardcoded values). + +**Exit criteria:** reset no longer exits the process; `helmet` + explicit CORS in place; `/health` wired into the compose healthcheck; uniform JSON error responses. + +## Phase 5 — Framework & tooling upgrades (larger, more testing) + +Sequenced last because these are the highest-churn changes and benefit from all prior safety nets. + +1. **`express 4 → 5`** — review breaking changes (routing, `req`/`res` API, middleware signatures). Re-verify all routes against baseline. +2. **`express-slow-down 2 → 3`** and **`express-rate-limit 7 → 8`** — config/API changes; re-verify limiter behavior via `utils/rateLimiterDefaults.js`. +3. **`jest 29 → 30`** — update config/matchers as needed. +4. **`json-server 0.17 → 1.0`** — this is a **full rewrite**, not a bump. Treat as its own spike: confirm the `jsonServer.router(dataPath)` usage in `routes/base-apis.js` still maps cleanly, or adapt. Only proceed if 1.0 preserves the response contract; otherwise stay on 0.17. + +**Exit criteria:** Express 5 + limiters + Jest 30 upgraded and green; `json-server` 1.0 either migrated with verified parity or a documented decision to hold. + +## Phase 6 — Optional: ESM / TypeScript (stretch) + +Higher effort, no user-facing change — do only if the maintenance win is wanted. + +- **ESM migration:** `require` → `import`, `"type": "module"`, update entry/route files. Pairs naturally with having already dropped CommonJS-only `node-fetch`. +- **TypeScript:** incremental adoption starting at `utils/` and route handlers, mirroring the client's TS setup for consistency. + +**Exit criteria:** build/test green under the chosen module system; documented for contributors in `CONTRIBUTING.md`. + +--- + +## Sequencing summary + +| Phase | Theme | Risk | Breaking? | +|---|---|---|---| +| 0 | Runtime pin, CI, baseline | none | no | +| 1 | Dependency hygiene | low | no | +| 2 | Critical vuln (shell-quote/uuid) | low | isolated | +| 3 | GraphQL upgrade to 3.x | medium | yes (isolated) | +| 4 | Architecture & robustness | medium | no (behavior-compatible) | +| 5 | Express 5 / limiters / Jest / json-server | high | yes | +| 6 | ESM / TypeScript (optional) | high | no (internal) | + +**Invariant across all phases:** the public API response contract stays stable, verified against the Phase 0 baseline. Any intentional change to it is called out explicitly in that phase's PR. diff --git a/server/Dockerfile b/server/Dockerfile index 020cacc..0e9c8ea 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,5 +1,5 @@ -# Use Node.js 22 -FROM node:22-alpine +# Use Node.js 26 +FROM node:26-alpine # Set working directory WORKDIR /app diff --git a/server/package-lock.json b/server/package-lock.json index b344a74..04b06df 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "body-parser": "^1.20.2", + "cors": "^2.8.6", "express": "^4.21.1", "express-rate-limit": "^7.2.0", "express-slow-down": "^2.0.3", @@ -2026,15 +2027,20 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", "dependencies": { "object-assign": "^4", "vary": "^1" }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/create-jest": { diff --git a/server/package.json b/server/package.json index af01c5e..da50fdb 100644 --- a/server/package.json +++ b/server/package.json @@ -19,8 +19,12 @@ "test": "jest" }, "homepage": "https://github.com/jermbo/SampleAPIs#readme", + "engines": { + "node": ">=26" + }, "dependencies": { "body-parser": "^1.20.2", + "cors": "^2.8.6", "express": "^4.21.1", "express-rate-limit": "^7.2.0", "express-slow-down": "^2.0.3", diff --git a/server/tests/baseline/README.md b/server/tests/baseline/README.md new file mode 100644 index 0000000..ada7d36 --- /dev/null +++ b/server/tests/baseline/README.md @@ -0,0 +1,28 @@ +# Response baseline (Phase 0) + +Captured snapshots of representative endpoints **before** the Phase 1+ dependency and +framework upgrades, to act as a regression oracle. If a later phase changes any of these +payloads, that change must be intentional and called out in the PR. + +Captured on Node 26 against `json-graphql-server@2.4` / `json-server@0.17`, server on `PORT=5599`: + +| File | Request | +|---|---| +| `beers-ale.json` | `GET /beers/ale` — REST list | +| `beers-ale-1.json` | `GET /beers/ale/1` — REST single resource | +| `beers-graphql-ales.json` | `POST /beers/graphql` body `{"query":"{ allAles(perPage: 2) { id name price } }"}` | + +## How to re-verify after an upgrade + +```sh +cd server +PORT=5599 node ./sampleapis.js & +curl -s http://localhost:5599/beers/ale | diff - tests/baseline/beers-ale.json +curl -s http://localhost:5599/beers/ale/1 | diff - tests/baseline/beers-ale-1.json +curl -s -X POST http://localhost:5599/beers/graphql \ + -H "Content-Type: application/json" \ + -d '{"query":"{ allAles(perPage: 2) { id name price } }"}' \ + | diff - tests/baseline/beers-graphql-ales.json +``` + +No `diff` output = payload unchanged. diff --git a/server/tests/baseline/beers-ale-1.json b/server/tests/baseline/beers-ale-1.json new file mode 100644 index 0000000..e72d5e5 --- /dev/null +++ b/server/tests/baseline/beers-ale-1.json @@ -0,0 +1 @@ +{"price":"$16.99","name":"Founders All Day IPA","rating":{"average":4.411243509154233,"reviews":453},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h00/h94/11891416367134.png","id":1} \ No newline at end of file diff --git a/server/tests/baseline/beers-ale.json b/server/tests/baseline/beers-ale.json new file mode 100644 index 0000000..0417167 --- /dev/null +++ b/server/tests/baseline/beers-ale.json @@ -0,0 +1 @@ +[{"price":"$16.99","name":"Founders All Day IPA","rating":{"average":4.411243509154233,"reviews":453},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h00/h94/11891416367134.png","id":1},{"price":"$13.99","name":"Blue Moon Belgian White Belgian-Style Wheat Ale","rating":{"average":4.775260833383482,"reviews":305},"image":"https://www.totalwine.com/media/sys_master/twmmedia/he8/h67/11931543830558.png","id":2},{"price":"$16.99","name":"Guinness Extra Stout","rating":{"average":3.9785961474594638,"reviews":119},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h50/h90/11996630056990.png","id":3},{"price":"$8.99","name":"Guinness Extra Stout","rating":{"average":3.5135460961961718,"reviews":199},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h35/he7/11996577726494.png","id":4},{"price":"$15.49","name":"Sierra Nevada Pale Ale","rating":{"average":4.266364643483868,"reviews":414},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h19/h43/11735160193054.png","id":5},{"price":"$15.49","name":"Sierra Nevada Pale Ale","rating":{"average":3.141161723541611,"reviews":459},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h0a/h17/11589987434526.png","id":6},{"price":"$15.99","name":"Lagunitas IPA","rating":{"average":1.7610665871324303,"reviews":358},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hd2/hfd/11348869382174.png","id":7},{"price":"$11.99","name":"Dogfish Head 120-Minute IPA","rating":{"average":3.1053162095618543,"reviews":64},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hf7/h2e/8814407614494.png","id":8},{"price":"$15.49","name":"Sierra Nevada Torpedo Extra IPA","rating":{"average":1.1092369711087207,"reviews":345},"image":"https://www.totalwine.com/media/sys_master/twmmedia/ha5/h01/8799883329566.png","id":9},{"price":"$15.99","name":"Sierra Nevada Hazy Little Thing IPA","rating":{"average":3.9890785544340925,"reviews":170},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":10},{"price":"$14.99","name":"New Holland Dragon's Milk","rating":{"average":1.2005615080794012,"reviews":493},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hf1/hef/11388243083294.png","id":11},{"price":"$12.99","name":"New Belgium Oakspire Bourbon Barrel Ale","rating":{"average":2.0996330805016186,"reviews":342},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h8b/h8f/11475320012830.png","id":12},{"price":"$7.49","name":"Guinness Draught","rating":{"average":1.4506545003190645,"reviews":452},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hcc/h64/11996579201054.png","id":13},{"price":"$10.99","name":"Dogfish Head 60-Minute IPA","rating":{"average":1.3770307904176358,"reviews":324},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h17/hc9/10124015599646.png","id":14},{"price":"$7.99","name":"Blue Moon Belgian White Belgian-Style Wheat Ale","rating":{"average":4.041128289991199,"reviews":50},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h5b/hff/11941592694814.png","id":15},{"price":"$16.99","name":"Guinness Draught","rating":{"average":2.9002860700543973,"reviews":401},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h66/h6a/11996634775582.png","id":16},{"price":"$10.99","name":"Weihenstephaner Hefe Weissbier","rating":{"average":2.89292945072894,"reviews":267},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h19/he2/11969419083806.png","id":17},{"price":"$2.29","name":"Cigar City Jai-Alai IPA","rating":{"average":3.779669618771213,"reviews":206},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hdb/h25/11969380712478.png","id":18},{"price":"$21.99","name":"Bell's Two Hearted Ale","rating":{"average":1.768500733899927,"reviews":63},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hfc/h84/11735172120606.png","id":19},{"price":"$12.99","name":"Kentucky Bourbon Barrel Ale","rating":{"average":2.2328898766089313,"reviews":377},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h0f/h40/11931598913566.png","id":20},{"price":"$12.99","name":"Dogfish Head 90-Minute IPA","rating":{"average":3.7771776781196387,"reviews":496},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hd0/h80/11717909905438.png","id":21},{"price":"$9.49","name":"Sierra Nevada Hazy Little Thing IPA","rating":{"average":1.4359814370189987,"reviews":351},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h42/h71/11375171207198.png","id":22},{"price":"$4.99","name":"Bell's Double Two Hearted","rating":{"average":4.268804254746469,"reviews":74},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":23},{"price":"$11.99","name":"Victory Golden Monkey Ale","rating":{"average":3.1676642120290497,"reviews":141},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hab/ha1/11849258827806.png","id":24},{"price":"$18.49","name":"Founders Underground Mountain Brown","rating":{"average":2.1446471059009395,"reviews":319},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":25},{"price":"$10.99","name":"Bell's Two Hearted Ale","rating":{"average":2.857913327526303,"reviews":440},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hd0/h7c/8813760610334.png","id":26},{"price":"$89.99","name":"Blue Moon Belgian White Belgian-Style Wheat Ale","rating":{"average":1.508525625330103,"reviews":381},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hc2/he9/11975816085534.png","id":27},{"price":"$11.49","name":"Elysian Space Dust IPA","rating":{"average":1.56330286120944,"reviews":203},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h0f/hb6/11735169466398.png","id":28},{"price":"$12.49","name":"Duvel Belgian Ale","rating":{"average":2.5572486237237335,"reviews":191},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h0c/h86/8810864082974.png","id":29},{"price":"$9.99","name":"Founders Breakfast Stout","rating":{"average":2.536098631569753,"reviews":105},"image":"https://www.totalwine.com/media/sys_master/twmmedia/ha2/he2/8796687728670.png","id":30},{"price":"$16.79","name":"Founders Centennial IPA","rating":{"average":4.902598150770166,"reviews":407},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h9d/h94/11167126519838.png","id":31},{"price":"$8.99","name":"Lagunitas IPA","rating":{"average":4.599331298776508,"reviews":135},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h2c/h78/8804310777886.png","id":32},{"price":"$14.99","name":"New Belgium Fat Tire","rating":{"average":1.056104104160374,"reviews":492},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hee/hb0/8809351217182.png","id":33},{"price":"$8.49","name":"Boddingtons Pub Ale","rating":{"average":1.3365664144031921,"reviews":364},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hc8/h2c/8806352846878.png","id":34},{"price":"$7.99","name":"Hoegaarden Witbier Blanche","rating":{"average":3.565917975071695,"reviews":189},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h97/h48/11931669102622.png","id":35},{"price":"$9.99","name":"Lagunitas Daytime IPA","rating":{"average":3.7896243815044306,"reviews":477},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hd1/h89/11657040003102.png","id":36},{"price":"$11.49","name":"Stone IPA (India Pale Ale)","rating":{"average":1.878226983778763,"reviews":380},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h26/h91/11770094026782.png","id":37},{"price":"$9.99","name":"Spaten Franziskaner Hefe-Weisse","rating":{"average":1.9830030107855592,"reviews":223},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h25/h97/8798007754782.png","id":38},{"price":"$18.99","name":"Southern Tier Warlock Imperial Pumpkin Stout","rating":{"average":2.043941554653335,"reviews":241},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h80/h0d/10734657470494.png","id":39},{"price":"$19.99","name":"Dogfish Head 60-Minute IPA","rating":{"average":3.48129639229092,"reviews":310},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h5f/h00/10124016648222.png","id":40},{"price":"$16.99","name":"Newcastle Brown Ale","rating":{"average":1.0385809111488369,"reviews":485},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hf5/h03/11969565622302.png","id":41},{"price":"$11.49","name":"New Belgium Voodoo Ranger Imperial IPA","rating":{"average":1.030031658964159,"reviews":412},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h06/h57/10672758161438.png","id":42},{"price":"$9.99","name":"Smithwick's Irish Ale","rating":{"average":3.344299483944976,"reviews":190},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h64/had/11996577431582.png","id":43},{"price":"$19.99","name":"Stone IPA (India Pale Ale)","rating":{"average":3.679742063810279,"reviews":404},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h80/he9/10140961341470.png","id":44},{"price":"$11.49","name":"Left Hand Milk Stout Nitro","rating":{"average":1.5222183530402447,"reviews":457},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h2d/haf/8813239762974.png","id":45},{"price":"$9.99","name":"Founders Porter","rating":{"average":3.7036191902784807,"reviews":247},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h37/h9f/8796760277022.png","id":46},{"price":"$14.99","name":"Shock Top Belgian White Ale","rating":{"average":4.02565627585603,"reviews":418},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hbe/h78/11891420495902.png","id":47},{"price":"$10.99","name":"Dogfish Head Slightly Mighty IPA","rating":{"average":3.518525930659723,"reviews":312},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hcd/ha2/11845581078558.png","id":48},{"price":"$15.99","name":"Founders Backwoods Bastard","rating":{"average":3.0187543429516914,"reviews":226},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h8f/h35/11536035217438.png","id":49},{"price":"$16.99","name":"Goose Island IPA","rating":{"average":1.1082348289013026,"reviews":117},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hb3/h9b/11444657618974.png","id":50},{"price":"$18.49","name":"Stone Farking Wheaton w00tstout","rating":{"average":3.3898938755564823,"reviews":61},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":51},{"price":"$7.99","name":"Kona Big Wave Golden Ale","rating":{"average":4.216231501611103,"reviews":253},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hb9/h8e/8797338894366.png","id":52},{"price":"$10.99","name":"North Coast Old Rasputin Imperial Stout","rating":{"average":1.7226627560750893,"reviews":171},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h25/h63/11770107363358.png","id":53},{"price":"$9.99","name":"Lagunitas A Little Sumpin Sumpin","rating":{"average":3.5321444435967244,"reviews":129},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hdb/h96/10856913207326.png","id":54},{"price":"$21.49","name":"Chimay Grande Reserve Blue","rating":{"average":4.7937905748912435,"reviews":99},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h8a/h92/8798154031134.png","id":55},{"price":"$13.99","name":"Ballast Point Sculpin IPA","rating":{"average":1.0633744801576714,"reviews":323},"image":"https://www.totalwine.com/media/sys_master/twmmedia/he7/hcf/11969504673822.png","id":56},{"price":"$12.99","name":"Stone Fear.Movie.Lions Double IPA","rating":{"average":4.193323291786882,"reviews":319},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h78/hdf/11797725052958.png","id":57},{"price":"$7.99","name":"New Belgium Fat Tire","rating":{"average":4.36964965425013,"reviews":440},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hfa/hc0/11805929209886.png","id":58},{"price":"$87.99","name":"New Belgium Fat Tire","rating":{"average":4.492195528374378,"reviews":83},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h5f/h1f/9781897035806.png","id":59},{"price":"$10.99","name":"New Belgium Trippel Belgian Style Ale","rating":{"average":2.6576216939051998,"reviews":389},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hc7/h44/11464107982878.png","id":60},{"price":"$1.99","name":"Paulaner Hefe Weizen","rating":{"average":2.224460075596946,"reviews":87},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h7f/h64/8820569014302.png","id":61},{"price":"$10.99","name":"Dogfish Head SeaQuenchAle","rating":{"average":2.604050274543601,"reviews":62},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h60/h11/10124017303582.png","id":62},{"price":"$20.99","name":"St Bernardus Abt 12","rating":{"average":1.0089880840508387,"reviews":205},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hcc/h30/10728889778206.png","id":63},{"price":"$36.99","name":"Dogfish Head World Wide Stout","rating":{"average":1.1643783197497646,"reviews":119},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h8c/h4e/10657395245086.png","id":64},{"price":"$9.99","name":"Unibroue - La Fin Du Monde","rating":{"average":2.514476444565455,"reviews":127},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h8c/hcd/8800920829982.png","id":65},{"price":"$9.49","name":"Sierra Nevada Pale Ale","rating":{"average":4.017110604857885,"reviews":393},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h05/h54/11589988024350.png","id":66},{"price":"$8.99","name":"Blue Moon Mango Wheat","rating":{"average":3.7853182263516203,"reviews":58},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hed/h46/11170760327198.png","id":67},{"price":"$12.99","name":"Oskar Blues Death By Coconut","rating":{"average":2.499562698383815,"reviews":130},"image":"https://www.totalwine.com/media/sys_master/twmmedia/ha6/h87/9664767787038.png","id":68},{"price":"$16.49","name":"New Belgium Voodoo Ranger IPA","rating":{"average":1.3981363388800485,"reviews":441},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h5d/h93/10675772489758.png","id":69},{"price":"$14.99","name":"Kona Big Wave Golden Ale","rating":{"average":3.366369397953016,"reviews":370},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h8a/hcc/12027169669150.png","id":70},{"price":"$8.99","name":"Guinness Foreign Extra Stout","rating":{"average":3.955232912250458,"reviews":57},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h64/h42/11996578906142.png","id":71},{"price":"$15.99","name":"Schofferhofer Hefeweizen Grapefruit","rating":{"average":2.887846830566846,"reviews":297},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hb5/hd5/11358023155742.png","id":72},{"price":"$13.99","name":"Ballast Point Sculpin IPA","rating":{"average":1.4983124359520046,"reviews":53},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h54/h09/11969425702942.png","id":73},{"price":"$11.49","name":"Stone Arrogant Bastard Ale","rating":{"average":4.476922876044725,"reviews":410},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h7a/h9c/11770097860638.png","id":74},{"price":"$13.49","name":"Ballast Point Grapefruit Sculpin IPA","rating":{"average":2.2181579436694605,"reviews":130},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h2e/h8e/11969407221790.png","id":75},{"price":"$9.99","name":"Oskar Blues Dale's Pale Ale","rating":{"average":1.0189692403493238,"reviews":280},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h2f/h10/8804817240094.png","id":76},{"price":"$13.99","name":"Chimay Grande Reserve Blue","rating":{"average":3.3233628692606922,"reviews":90},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h43/hf5/8820567834654.png","id":77},{"price":"$17.49","name":"Boulevard Bourbon Barrel Quad","rating":{"average":3.3608031669590206,"reviews":126},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h6b/ha4/10501577375774.png","id":78},{"price":"$9.49","name":"Hofbrau Hefe Weizen","rating":{"average":3.1129695093601795,"reviews":169},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h08/h77/8816818946078.png","id":79},{"price":"$14.99","name":"Boulevard Tank 7 Farmhouse Ale","rating":{"average":2.525521586557562,"reviews":369},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h41/h0f/12021147697182.png","id":80},{"price":"$2.99","name":"Samuel Smith's Organic Chocolate Stout","rating":{"average":4.1555247865397416,"reviews":169},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h37/ha6/8803802054686.png","id":81},{"price":"$2.79","name":"Bell's Special Double Cream Stout","rating":{"average":3.682967725411885,"reviews":56},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h73/h11/8803018965022.png","id":82},{"price":"$9.99","name":"Founders Dirty Bastard Ale","rating":{"average":3.970086617125669,"reviews":72},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h6b/ha2/8806269812766.png","id":83},{"price":"$11.79","name":"Achouffe La Chouffe","rating":{"average":3.800563812674647,"reviews":151},"image":"https://www.totalwine.com/media/sys_master/twmmedia/ha0/h87/10140920315934.png","id":84},{"price":"$17.99","name":"Founders Mosaic Promise","rating":{"average":4.052128197668433,"reviews":378},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h32/hca/10698194583582.png","id":85},{"price":"$22.99","name":"Stone Delicious IPA","rating":{"average":4.437512706307549,"reviews":238},"image":"https://www.totalwine.com/media/sys_master/twmmedia/ha2/h39/12007074758686.png","id":86},{"price":"$10.99","name":"Rogue Batsquatch Hazy IPA","rating":{"average":4.502906484625454,"reviews":483},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hc3/h11/11931839692830.png","id":87},{"price":"$11.49","name":"New Belgium Voodoo Ranger Juicy Haze IPA","rating":{"average":4.800191829796816,"reviews":255},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":88},{"price":"$17.99","name":"Boulevard Whiskey Barrel Stout","rating":{"average":3.7756782589755353,"reviews":180},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h69/h85/11443360235550.png","id":89},{"price":"$9.99","name":"Lagunitas Maximus IPA","rating":{"average":3.641323719494787,"reviews":493},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h45/h8f/9418350657566.png","id":90},{"price":"$12.99","name":"Offshoot Relax (It's Just a Hazy IPA)","rating":{"average":4.169674694322197,"reviews":164},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h90/h58/11311020245022.png","id":91},{"price":"$12.99","name":"Sixpoint Resin","rating":{"average":3.1029248482584535,"reviews":234},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hf5/hfb/10657396424734.png","id":92},{"price":"$99.99","name":"Cigar City Jai-Alai IPA","rating":{"average":1.0601853988027745,"reviews":485},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hdc/h98/9781940322334.png","id":93},{"price":"$12.99","name":"Wicked Weed Pernicious IPA","rating":{"average":1.3267940892543262,"reviews":234},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":94},{"price":"$12.99","name":"Dogfish Head SuperEIGHT","rating":{"average":2.4587302813711283,"reviews":191},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":95},{"price":"$6.99","name":"Rochefort 10 Trappist Ale","rating":{"average":2.6243993844011806,"reviews":303},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hcc/h4a/8803981787166.png","id":96},{"price":"$18.99","name":"Delirium Tremens","rating":{"average":4.2526903890313905,"reviews":463},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h05/ha0/8804687970334.png","id":97},{"price":"$8.99","name":"Lagunitas SuperCluster","rating":{"average":4.969725976340016,"reviews":59},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":98},{"price":"$12.99","name":"New Holland Dragon's Milk White Stout","rating":{"average":2.62207680296948,"reviews":66},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":99},{"price":"$7.99","name":"Goose Island IPA","rating":{"average":4.002017823140871,"reviews":323},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h39/h7f/9985249247262.png","id":100},{"price":"$13.49","name":"Ballast Point Grapefruit Sculpin IPA","rating":{"average":2.924150050325185,"reviews":66},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h14/h10/11969425997854.png","id":101},{"price":"$1.79","name":"Sierra Nevada Torpedo Extra IPA","rating":{"average":4.132209648216585,"reviews":86},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h88/h47/8796708962334.png","id":102},{"price":"$10.99","name":"Duclaw Sweet Baby Jesus!","rating":{"average":4.089769886898315,"reviews":402},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hb1/h21/9351707328542.png","id":103},{"price":"$16.99","name":"Lagunitas Sumpin' Easy","rating":{"average":1.3485746897254929,"reviews":334},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h29/h71/11312566894622.png","id":104},{"price":"$12.99","name":"Lord Hobo Boom Sauce","rating":{"average":4.271835995644435,"reviews":102},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h28/h24/11544524718110.png","id":105},{"price":"$12.99","name":"Weihenstephaner Vitus","rating":{"average":1.3135036691160673,"reviews":469},"image":"https://www.totalwine.com/media/sys_master/twmmedia/he4/hd0/11969417609246.png","id":106},{"price":"$12.79","name":"New Belgium Voodoo Ranger Juicifer IPA","rating":{"average":3.9492021918949725,"reviews":236},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":107},{"price":"$12.99","name":"Lindeman's Framboise","rating":{"average":2.7519071827960273,"reviews":108},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":108},{"price":"$14.99","name":"Dogfish Head Palo Santo Marron","rating":{"average":2.4190073235744673,"reviews":75},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hbe/h3c/10225139908638.png","id":109},{"price":"$15.49","name":"Clown Shoes Space Cake","rating":{"average":4.883356891746129,"reviews":367},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":110},{"price":"$9.99","name":"Bell's Best Brown Ale","rating":{"average":2.6802502419403025,"reviews":406},"image":"https://www.totalwine.com/media/sys_master/twmmedia/heb/h89/8815740649502.png","id":111},{"price":"$11.99","name":"Victory Golden Monkey Ale","rating":{"average":3.223867503577261,"reviews":257},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h2e/h20/11849258532894.png","id":112},{"price":"$8.99","name":"Erdinger Weissbier","rating":{"average":3.9267369526916545,"reviews":78},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h61/hda/8820602109982.png","id":113},{"price":"$10.99","name":"Robinsons Trooper Ale","rating":{"average":3.834032592144709,"reviews":338},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h42/hf3/10675674120222.png","id":114},{"price":"$3.99","name":"Kentucky Coffee Barrel Stout","rating":{"average":1.335718639280703,"reviews":416},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h25/h7f/11931443626014.png","id":115},{"price":"$9.99","name":"21st Amendment Brew Free Or Die Blood Orange IPA","rating":{"average":4.894730680324359,"reviews":230},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h7d/had/11170752692254.png","id":116},{"price":"$9.49","name":"Kronenbourg Blanc","rating":{"average":2.7826152662684214,"reviews":304},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h8c/ha4/9354116857886.png","id":117},{"price":"$10.99","name":"Bell's Official Hazy IPA","rating":{"average":4.4548183643373855,"reviews":480},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":118},{"price":"$8.99","name":"Cigar City Maduro Brown","rating":{"average":2.6831070228729246,"reviews":474},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h8f/heb/11589816057886.png","id":119},{"price":"$20.99","name":"Gulden Draak 9000 Quadrupel","rating":{"average":2.7633099153167375,"reviews":359},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h71/h01/8800490422302.png","id":120},{"price":"$10.99","name":"Bell's Two Hearted Ale","rating":{"average":3.086009671445667,"reviews":499},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":121},{"price":"$9.99","name":"Sierra Nevada Hop Bullet","rating":{"average":4.606551938913049,"reviews":409},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":122},{"price":"$8.99","name":"Sweetwater 420 Strain G-13","rating":{"average":4.176603737571783,"reviews":371},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":123},{"price":"$19.99","name":"Tripel Karmeliet","rating":{"average":3.5888947699078804,"reviews":378},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h7f/h6e/8797892739102.png","id":124},{"price":"$8.49","name":"New Belgium Voodoo Ranger IPA","rating":{"average":4.107273030523367,"reviews":93},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h2c/h7e/10508834045982.png","id":125},{"price":"$92.99","name":"Kona Big Wave Golden Ale","rating":{"average":1.4034451390194747,"reviews":443},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h90/hfb/9687556685854.png","id":126},{"price":"$9.99","name":"Heavy Seas Loose Cannon IPA","rating":{"average":4.2247057118155755,"reviews":189},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hba/h54/11931504771102.png","id":127},{"price":"$9.49","name":"Newcastle Brown Ale","rating":{"average":1.3062165130061514,"reviews":122},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h2e/he3/10072387780638.png","id":128},{"price":"$15.99","name":"Ommegang Three Philosophers","rating":{"average":3.7650339790702576,"reviews":271},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h39/h4a/9382849708062.png","id":129},{"price":"$7.49","name":"Shock Top Belgian White Ale","rating":{"average":3.5245058222634285,"reviews":262},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hf6/h53/11891418136606.png","id":130},{"price":"$19.49","name":"Duchesse De Bourgogne","rating":{"average":3.7854120339206645,"reviews":115},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h1d/h1c/8804202479646.png","id":131},{"price":"$9.49","name":"New Belgium Fat Tire Belgian White","rating":{"average":3.079965625452034,"reviews":160},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hb5/hd4/11698320834590.png","id":132},{"price":"$10.49","name":"Cigar City Guayabera Citra Pale Ale","rating":{"average":4.146664357611568,"reviews":416},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h4a/h12/11401918382110.png","id":133},{"price":"$13.99","name":"Dogfish Head American Beauty","rating":{"average":2.1059576853999387,"reviews":64},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hc1/hc4/11797694316574.png","id":134},{"price":"$11.49","name":"Old Speckled Hen","rating":{"average":2.3637872222112417,"reviews":187},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h18/h7e/8804595925022.png","id":135},{"price":"$10.99","name":"Samuel Smith's Oatmeal Stout","rating":{"average":3.755651312235952,"reviews":231},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hf4/h32/8802976104478.png","id":136},{"price":"$1.99","name":"Foster's Special Bitter","rating":{"average":3.345153453413597,"reviews":456},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hd3/hf0/11941521293342.png","id":137},{"price":"$8.99","name":"Kona Hanalei Island IPA","rating":{"average":3.861066233750919,"reviews":59},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hc4/h25/9947401158686.png","id":138},{"price":"$12.99","name":"Gaffel Kolsch","rating":{"average":3.5860968066070953,"reviews":446},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h4d/h45/8804792565790.png","id":139},{"price":"$9.99","name":"Left Hand Milk Stout Nitro","rating":{"average":4.726783116573011,"reviews":236},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h13/hcc/10950394413086.png","id":140},{"price":"$8.99","name":"Paulaner Hefe Weizen","rating":{"average":2.290946882490756,"reviews":55},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":141},{"price":"$11.49","name":"Stone Tangerine Express IPA","rating":{"average":2.4853029525964736,"reviews":185},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h44/h41/12007072989214.png","id":142},{"price":"$15.99","name":"Samuel Adams Rebel IPA","rating":{"average":2.8238527317268174,"reviews":383},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h4f/h71/8807125319710.png","id":143},{"price":"$8.49","name":"Bass Ale","rating":{"average":4.05017330128582,"reviews":374},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h83/he6/11931937210398.png","id":144},{"price":"$20.49","name":"Chimay Premiere Red","rating":{"average":3.240237215285262,"reviews":79},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h8c/hec/8804559716382.png","id":145},{"price":"$11.99","name":"Duvel Tripel Hop","rating":{"average":1.7576812202358694,"reviews":357},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h47/h64/10126441840670.png","id":146},{"price":"$11.99","name":"Tripel Karmeliet","rating":{"average":2.0935730249494418,"reviews":428},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h92/h87/8820300283934.png","id":147},{"price":"$11.99","name":"Rogue Hazelnut Brown Nectar","rating":{"average":1.9354656518898867,"reviews":259},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h53/hf1/11139791421470.png","id":148},{"price":"$19.99","name":"Chimay Cinq Cents White Triple","rating":{"average":3.750476125324088,"reviews":184},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hb8/h2f/8804746330142.png","id":149},{"price":"$8.99","name":"Cigar City Florida Cracker Belgian-style White Ale","rating":{"average":3.6242276941091225,"reviews":113},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h33/h59/11589816352798.png","id":150},{"price":"$12.99","name":"New Belgium Honey Orange Tripel","rating":{"average":4.180322318620529,"reviews":408},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h03/h93/11375132606494.png","id":151},{"price":"$14.79","name":"Dogfish Head Flesh and Blood IPA","rating":{"average":3.250643535696838,"reviews":385},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hdd/hba/10124016943134.png","id":152},{"price":"$17.99","name":"Bell's Expedition Stout","rating":{"average":3.717992549497703,"reviews":404},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h60/hb2/8800955105310.png","id":153},{"price":"$11.49","name":"Duchesse De Bourgogne","rating":{"average":2.524190913111866,"reviews":262},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h8f/h1d/8801000161310.png","id":154},{"price":"$14.99","name":"Westmalle Tripel Trappist Ale","rating":{"average":2.209130924062644,"reviews":129},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hb1/hd1/8798192369694.png","id":155},{"price":"$3.99","name":"Weihenstephaner HefeWeissbier Dark","rating":{"average":3.434066764526942,"reviews":374},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h43/h4b/10734629224478.png","id":156},{"price":"$8.99","name":"Fuller's London Pride","rating":{"average":4.788464936323404,"reviews":465},"image":"https://www.totalwine.com/media/sys_master/twmmedia/had/h2c/9770875682846.png","id":157},{"price":"$16.49","name":"SweetWater 420 Pale Ale","rating":{"average":1.5438991712581398,"reviews":144},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h38/h5f/11508996374558.png","id":158},{"price":"$16.99","name":"Sweetwater 420 Strain G-13","rating":{"average":4.032524982682152,"reviews":370},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":159},{"price":"$9.99","name":"Lagunitas Hop Stoopid Ale","rating":{"average":2.0824476203303357,"reviews":468},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h59/hc4/11213336576030.png","id":160},{"price":"$114.99","name":"Dogfish Head 60-Minute IPA","rating":{"average":1.630334145085353,"reviews":311},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h52/h71/9789269934110.png","id":161},{"price":"$9.99","name":"Founders All Day IPA","rating":{"average":4.008025403767698,"reviews":441},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h13/hd3/11891418726430.png","id":162},{"price":"$8.49","name":"Unibroue - La Fin Du Monde","rating":{"average":2.8047611369349283,"reviews":470},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h74/h43/8804124753950.png","id":163},{"price":"$15.99","name":"Oskar Blues Ten FIDY","rating":{"average":2.9788154999137637,"reviews":436},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hc1/h8e/11465945481246.png","id":164},{"price":"$10.99","name":"Anderson Valley GOSE Blood Orange","rating":{"average":3.1066752148241683,"reviews":288},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h4a/h43/11635363905566.png","id":165},{"price":"$12.49","name":"Lindeman's Peche","rating":{"average":3.0755646338784075,"reviews":138},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h3a/hf0/8810013884446.png","id":166},{"price":"$12.49","name":"Stone Scorpion Bowl IPA","rating":{"average":2.733436034499219,"reviews":339},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h49/h76/11443412828190.png","id":167},{"price":"$15.99","name":"Dogfish Head Burton Baton","rating":{"average":3.926503869642703,"reviews":86},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hae/haf/10124015304734.png","id":168},{"price":"$14.99","name":"Boulevard The Calling IPA","rating":{"average":1.5012371833611837,"reviews":93},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hec/hc3/11192440225822.png","id":169},{"price":"$4.99","name":"Delirium Red","rating":{"average":3.329751337964476,"reviews":385},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":170},{"price":"$1.99","name":"Karbach Love Street Summer","rating":{"average":4.620266818178933,"reviews":185},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h47/hf1/10777645285406.png","id":171},{"price":"$11.99","name":"Einstok Icelandic White Ale","rating":{"average":4.81471460936719,"reviews":58},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h66/h62/11234593931294.png","id":172},{"price":"$9.99","name":"Dogfish Head 90-Minute IPA","rating":{"average":3.8590704317769315,"reviews":120},"image":"https://www.totalwine.com/media/sys_master/cmsmedia/hff/h0e/8979036078110.png","id":173},{"price":"$10.99","name":"Anderson Valley Briney Melon Gose","rating":{"average":1.6308706827038444,"reviews":215},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h0b/hbe/11635387465758.png","id":174},{"price":"$8.99","name":"Boulevard Space Camper Cosmic IPA","rating":{"average":1.0521580970660143,"reviews":214},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hff/h26/11735207706654.png","id":175},{"price":"$17.99","name":"Piraat Ale","rating":{"average":4.94233495501944,"reviews":185},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h67/he1/9071469920286.png","id":176},{"price":"$6.49","name":"Lindeman's Framboise","rating":{"average":3.749494609725903,"reviews":321},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h6e/h57/10225140629534.png","id":177},{"price":"$13.99","name":"Blue Moon Belgian White Belgian-Style Wheat Ale","rating":{"average":2.323260489551802,"reviews":132},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h54/h53/11931543535646.png","id":178},{"price":"$9.99","name":"Founders All Day IPA","rating":{"average":5,"reviews":462},"image":"https://www.totalwine.com/media/sys_master/twmmedia/hcb/h02/11891413352478.png","id":179},{"price":"$11.99","name":"Chimay Cinq Cents White Triple","rating":{"average":1.997464538301898,"reviews":89},"image":"https://www.totalwine.com/media/sys_master/twmmedia/h67/h22/8801543749662.png","id":180}] \ No newline at end of file diff --git a/server/tests/baseline/beers-graphql-ales.json b/server/tests/baseline/beers-graphql-ales.json new file mode 100644 index 0000000..e12f29f --- /dev/null +++ b/server/tests/baseline/beers-graphql-ales.json @@ -0,0 +1 @@ +{"data":{"allAles":[{"id":"1","name":"Founders All Day IPA","price":"$16.99"},{"id":"2","name":"Blue Moon Belgian White Belgian-Style Wheat Ale","price":"$13.99"},{"id":"3","name":"Guinness Extra Stout","price":"$16.99"},{"id":"4","name":"Guinness Extra Stout","price":"$8.99"},{"id":"5","name":"Sierra Nevada Pale Ale","price":"$15.49"},{"id":"6","name":"Sierra Nevada Pale Ale","price":"$15.49"},{"id":"7","name":"Lagunitas IPA","price":"$15.99"},{"id":"8","name":"Dogfish Head 120-Minute IPA","price":"$11.99"},{"id":"9","name":"Sierra Nevada Torpedo Extra IPA","price":"$15.49"},{"id":"10","name":"Sierra Nevada Hazy Little Thing IPA","price":"$15.99"},{"id":"11","name":"New Holland Dragon's Milk","price":"$14.99"},{"id":"12","name":"New Belgium Oakspire Bourbon Barrel Ale","price":"$12.99"},{"id":"13","name":"Guinness Draught","price":"$7.49"},{"id":"14","name":"Dogfish Head 60-Minute IPA","price":"$10.99"},{"id":"15","name":"Blue Moon Belgian White Belgian-Style Wheat Ale","price":"$7.99"},{"id":"16","name":"Guinness Draught","price":"$16.99"},{"id":"17","name":"Weihenstephaner Hefe Weissbier","price":"$10.99"},{"id":"18","name":"Cigar City Jai-Alai IPA","price":"$2.29"},{"id":"19","name":"Bell's Two Hearted Ale","price":"$21.99"},{"id":"20","name":"Kentucky Bourbon Barrel Ale","price":"$12.99"},{"id":"21","name":"Dogfish Head 90-Minute IPA","price":"$12.99"},{"id":"22","name":"Sierra Nevada Hazy Little Thing IPA","price":"$9.49"},{"id":"23","name":"Bell's Double Two Hearted","price":"$4.99"},{"id":"24","name":"Victory Golden Monkey Ale","price":"$11.99"},{"id":"25","name":"Founders Underground Mountain Brown","price":"$18.49"},{"id":"26","name":"Bell's Two Hearted Ale","price":"$10.99"},{"id":"27","name":"Blue Moon Belgian White Belgian-Style Wheat Ale","price":"$89.99"},{"id":"28","name":"Elysian Space Dust IPA","price":"$11.49"},{"id":"29","name":"Duvel Belgian Ale","price":"$12.49"},{"id":"30","name":"Founders Breakfast Stout","price":"$9.99"},{"id":"31","name":"Founders Centennial IPA","price":"$16.79"},{"id":"32","name":"Lagunitas IPA","price":"$8.99"},{"id":"33","name":"New Belgium Fat Tire","price":"$14.99"},{"id":"34","name":"Boddingtons Pub Ale","price":"$8.49"},{"id":"35","name":"Hoegaarden Witbier Blanche","price":"$7.99"},{"id":"36","name":"Lagunitas Daytime IPA","price":"$9.99"},{"id":"37","name":"Stone IPA (India Pale Ale)","price":"$11.49"},{"id":"38","name":"Spaten Franziskaner Hefe-Weisse","price":"$9.99"},{"id":"39","name":"Southern Tier Warlock Imperial Pumpkin Stout","price":"$18.99"},{"id":"40","name":"Dogfish Head 60-Minute IPA","price":"$19.99"},{"id":"41","name":"Newcastle Brown Ale","price":"$16.99"},{"id":"42","name":"New Belgium Voodoo Ranger Imperial IPA","price":"$11.49"},{"id":"43","name":"Smithwick's Irish Ale","price":"$9.99"},{"id":"44","name":"Stone IPA (India Pale Ale)","price":"$19.99"},{"id":"45","name":"Left Hand Milk Stout Nitro","price":"$11.49"},{"id":"46","name":"Founders Porter","price":"$9.99"},{"id":"47","name":"Shock Top Belgian White Ale","price":"$14.99"},{"id":"48","name":"Dogfish Head Slightly Mighty IPA","price":"$10.99"},{"id":"49","name":"Founders Backwoods Bastard","price":"$15.99"},{"id":"50","name":"Goose Island IPA","price":"$16.99"},{"id":"51","name":"Stone Farking Wheaton w00tstout","price":"$18.49"},{"id":"52","name":"Kona Big Wave Golden Ale","price":"$7.99"},{"id":"53","name":"North Coast Old Rasputin Imperial Stout","price":"$10.99"},{"id":"54","name":"Lagunitas A Little Sumpin Sumpin","price":"$9.99"},{"id":"55","name":"Chimay Grande Reserve Blue","price":"$21.49"},{"id":"56","name":"Ballast Point Sculpin IPA","price":"$13.99"},{"id":"57","name":"Stone Fear.Movie.Lions Double IPA","price":"$12.99"},{"id":"58","name":"New Belgium Fat Tire","price":"$7.99"},{"id":"59","name":"New Belgium Fat Tire","price":"$87.99"},{"id":"60","name":"New Belgium Trippel Belgian Style Ale","price":"$10.99"},{"id":"61","name":"Paulaner Hefe Weizen","price":"$1.99"},{"id":"62","name":"Dogfish Head SeaQuenchAle","price":"$10.99"},{"id":"63","name":"St Bernardus Abt 12","price":"$20.99"},{"id":"64","name":"Dogfish Head World Wide Stout","price":"$36.99"},{"id":"65","name":"Unibroue - La Fin Du Monde","price":"$9.99"},{"id":"66","name":"Sierra Nevada Pale Ale","price":"$9.49"},{"id":"67","name":"Blue Moon Mango Wheat","price":"$8.99"},{"id":"68","name":"Oskar Blues Death By Coconut","price":"$12.99"},{"id":"69","name":"New Belgium Voodoo Ranger IPA","price":"$16.49"},{"id":"70","name":"Kona Big Wave Golden Ale","price":"$14.99"},{"id":"71","name":"Guinness Foreign Extra Stout","price":"$8.99"},{"id":"72","name":"Schofferhofer Hefeweizen Grapefruit","price":"$15.99"},{"id":"73","name":"Ballast Point Sculpin IPA","price":"$13.99"},{"id":"74","name":"Stone Arrogant Bastard Ale","price":"$11.49"},{"id":"75","name":"Ballast Point Grapefruit Sculpin IPA","price":"$13.49"},{"id":"76","name":"Oskar Blues Dale's Pale Ale","price":"$9.99"},{"id":"77","name":"Chimay Grande Reserve Blue","price":"$13.99"},{"id":"78","name":"Boulevard Bourbon Barrel Quad","price":"$17.49"},{"id":"79","name":"Hofbrau Hefe Weizen","price":"$9.49"},{"id":"80","name":"Boulevard Tank 7 Farmhouse Ale","price":"$14.99"},{"id":"81","name":"Samuel Smith's Organic Chocolate Stout","price":"$2.99"},{"id":"82","name":"Bell's Special Double Cream Stout","price":"$2.79"},{"id":"83","name":"Founders Dirty Bastard Ale","price":"$9.99"},{"id":"84","name":"Achouffe La Chouffe","price":"$11.79"},{"id":"85","name":"Founders Mosaic Promise","price":"$17.99"},{"id":"86","name":"Stone Delicious IPA","price":"$22.99"},{"id":"87","name":"Rogue Batsquatch Hazy IPA","price":"$10.99"},{"id":"88","name":"New Belgium Voodoo Ranger Juicy Haze IPA","price":"$11.49"},{"id":"89","name":"Boulevard Whiskey Barrel Stout","price":"$17.99"},{"id":"90","name":"Lagunitas Maximus IPA","price":"$9.99"},{"id":"91","name":"Offshoot Relax (It's Just a Hazy IPA)","price":"$12.99"},{"id":"92","name":"Sixpoint Resin","price":"$12.99"},{"id":"93","name":"Cigar City Jai-Alai IPA","price":"$99.99"},{"id":"94","name":"Wicked Weed Pernicious IPA","price":"$12.99"},{"id":"95","name":"Dogfish Head SuperEIGHT","price":"$12.99"},{"id":"96","name":"Rochefort 10 Trappist Ale","price":"$6.99"},{"id":"97","name":"Delirium Tremens","price":"$18.99"},{"id":"98","name":"Lagunitas SuperCluster","price":"$8.99"},{"id":"99","name":"New Holland Dragon's Milk White Stout","price":"$12.99"},{"id":"100","name":"Goose Island IPA","price":"$7.99"},{"id":"101","name":"Ballast Point Grapefruit Sculpin IPA","price":"$13.49"},{"id":"102","name":"Sierra Nevada Torpedo Extra IPA","price":"$1.79"},{"id":"103","name":"Duclaw Sweet Baby Jesus!","price":"$10.99"},{"id":"104","name":"Lagunitas Sumpin' Easy","price":"$16.99"},{"id":"105","name":"Lord Hobo Boom Sauce","price":"$12.99"},{"id":"106","name":"Weihenstephaner Vitus","price":"$12.99"},{"id":"107","name":"New Belgium Voodoo Ranger Juicifer IPA","price":"$12.79"},{"id":"108","name":"Lindeman's Framboise","price":"$12.99"},{"id":"109","name":"Dogfish Head Palo Santo Marron","price":"$14.99"},{"id":"110","name":"Clown Shoes Space Cake","price":"$15.49"},{"id":"111","name":"Bell's Best Brown Ale","price":"$9.99"},{"id":"112","name":"Victory Golden Monkey Ale","price":"$11.99"},{"id":"113","name":"Erdinger Weissbier","price":"$8.99"},{"id":"114","name":"Robinsons Trooper Ale","price":"$10.99"},{"id":"115","name":"Kentucky Coffee Barrel Stout","price":"$3.99"},{"id":"116","name":"21st Amendment Brew Free Or Die Blood Orange IPA","price":"$9.99"},{"id":"117","name":"Kronenbourg Blanc","price":"$9.49"},{"id":"118","name":"Bell's Official Hazy IPA","price":"$10.99"},{"id":"119","name":"Cigar City Maduro Brown","price":"$8.99"},{"id":"120","name":"Gulden Draak 9000 Quadrupel","price":"$20.99"},{"id":"121","name":"Bell's Two Hearted Ale","price":"$10.99"},{"id":"122","name":"Sierra Nevada Hop Bullet","price":"$9.99"},{"id":"123","name":"Sweetwater 420 Strain G-13","price":"$8.99"},{"id":"124","name":"Tripel Karmeliet","price":"$19.99"},{"id":"125","name":"New Belgium Voodoo Ranger IPA","price":"$8.49"},{"id":"126","name":"Kona Big Wave Golden Ale","price":"$92.99"},{"id":"127","name":"Heavy Seas Loose Cannon IPA","price":"$9.99"},{"id":"128","name":"Newcastle Brown Ale","price":"$9.49"},{"id":"129","name":"Ommegang Three Philosophers","price":"$15.99"},{"id":"130","name":"Shock Top Belgian White Ale","price":"$7.49"},{"id":"131","name":"Duchesse De Bourgogne","price":"$19.49"},{"id":"132","name":"New Belgium Fat Tire Belgian White","price":"$9.49"},{"id":"133","name":"Cigar City Guayabera Citra Pale Ale","price":"$10.49"},{"id":"134","name":"Dogfish Head American Beauty","price":"$13.99"},{"id":"135","name":"Old Speckled Hen","price":"$11.49"},{"id":"136","name":"Samuel Smith's Oatmeal Stout","price":"$10.99"},{"id":"137","name":"Foster's Special Bitter","price":"$1.99"},{"id":"138","name":"Kona Hanalei Island IPA","price":"$8.99"},{"id":"139","name":"Gaffel Kolsch","price":"$12.99"},{"id":"140","name":"Left Hand Milk Stout Nitro","price":"$9.99"},{"id":"141","name":"Paulaner Hefe Weizen","price":"$8.99"},{"id":"142","name":"Stone Tangerine Express IPA","price":"$11.49"},{"id":"143","name":"Samuel Adams Rebel IPA","price":"$15.99"},{"id":"144","name":"Bass Ale","price":"$8.49"},{"id":"145","name":"Chimay Premiere Red","price":"$20.49"},{"id":"146","name":"Duvel Tripel Hop","price":"$11.99"},{"id":"147","name":"Tripel Karmeliet","price":"$11.99"},{"id":"148","name":"Rogue Hazelnut Brown Nectar","price":"$11.99"},{"id":"149","name":"Chimay Cinq Cents White Triple","price":"$19.99"},{"id":"150","name":"Cigar City Florida Cracker Belgian-style White Ale","price":"$8.99"},{"id":"151","name":"New Belgium Honey Orange Tripel","price":"$12.99"},{"id":"152","name":"Dogfish Head Flesh and Blood IPA","price":"$14.79"},{"id":"153","name":"Bell's Expedition Stout","price":"$17.99"},{"id":"154","name":"Duchesse De Bourgogne","price":"$11.49"},{"id":"155","name":"Westmalle Tripel Trappist Ale","price":"$14.99"},{"id":"156","name":"Weihenstephaner HefeWeissbier Dark","price":"$3.99"},{"id":"157","name":"Fuller's London Pride","price":"$8.99"},{"id":"158","name":"SweetWater 420 Pale Ale","price":"$16.49"},{"id":"159","name":"Sweetwater 420 Strain G-13","price":"$16.99"},{"id":"160","name":"Lagunitas Hop Stoopid Ale","price":"$9.99"},{"id":"161","name":"Dogfish Head 60-Minute IPA","price":"$114.99"},{"id":"162","name":"Founders All Day IPA","price":"$9.99"},{"id":"163","name":"Unibroue - La Fin Du Monde","price":"$8.49"},{"id":"164","name":"Oskar Blues Ten FIDY","price":"$15.99"},{"id":"165","name":"Anderson Valley GOSE Blood Orange","price":"$10.99"},{"id":"166","name":"Lindeman's Peche","price":"$12.49"},{"id":"167","name":"Stone Scorpion Bowl IPA","price":"$12.49"},{"id":"168","name":"Dogfish Head Burton Baton","price":"$15.99"},{"id":"169","name":"Boulevard The Calling IPA","price":"$14.99"},{"id":"170","name":"Delirium Red","price":"$4.99"},{"id":"171","name":"Karbach Love Street Summer","price":"$1.99"},{"id":"172","name":"Einstok Icelandic White Ale","price":"$11.99"},{"id":"173","name":"Dogfish Head 90-Minute IPA","price":"$9.99"},{"id":"174","name":"Anderson Valley Briney Melon Gose","price":"$10.99"},{"id":"175","name":"Boulevard Space Camper Cosmic IPA","price":"$8.99"},{"id":"176","name":"Piraat Ale","price":"$17.99"},{"id":"177","name":"Lindeman's Framboise","price":"$6.49"},{"id":"178","name":"Blue Moon Belgian White Belgian-Style Wheat Ale","price":"$13.99"},{"id":"179","name":"Founders All Day IPA","price":"$9.99"},{"id":"180","name":"Chimay Cinq Cents White Triple","price":"$11.99"}]}} \ No newline at end of file From 28467504956d57727f3e6ea992ea729d6deefa5b Mon Sep 17 00:00:00 2001 From: jermbo Date: Thu, 9 Jul 2026 08:39:44 -0400 Subject: [PATCH 11/26] refactor: update server dependencies and improve API routing - Updated dependencies in package.json and package-lock.json to specific versions for better stability and performance. - Replaced json-graphql-server with a custom jsonRouter for enhanced flexibility in API routing. - Simplified API endpoint setup by removing unused code and improving data verification logic. - Introduced a new utility for creating JSON-based routers, allowing for CRUD operations on JSON files. --- server/package-lock.json | 7837 +++++++++++++++++++++--------------- server/package.json | 22 +- server/routes/base-apis.js | 15 +- server/routes/testApis.js | 1 - server/utils/jsonRouter.js | 199 + server/utils/verifyData.js | 15 +- 6 files changed, 4886 insertions(+), 3203 deletions(-) create mode 100644 server/utils/jsonRouter.js diff --git a/server/package-lock.json b/server/package-lock.json index 04b06df..79df8df 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -9,145 +9,64 @@ "version": "2.8.0", "license": "MIT", "dependencies": { - "body-parser": "^1.20.2", - "cors": "^2.8.6", - "express": "^4.21.1", - "express-rate-limit": "^7.2.0", - "express-slow-down": "^2.0.3", - "json-graphql-server": "2.4.0", - "json-server": "^0.17.4", - "morgan": "^1.10.0", - "node-fetch": "^3.3.2", - "pug": "^3.0.3" + "cors": "2.8.6", + "express": "5.2.1", + "express-rate-limit": "8.5.2", + "express-slow-down": "3.1.0", + "morgan": "1.11.0", + "pug": "3.0.4" }, "devDependencies": { - "concurrently": "^8.2.2", - "jest": "^29.7.0", - "nodemon": "^3.1.1" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "concurrently": "10.0.3", + "jest": "30.4.2", + "nodemon": "3.1.14" }, "engines": { - "node": ">=6.0.0" + "node": ">=26" } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", - "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.5", - "@babel/parser": "^7.23.5", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -163,12 +82,13 @@ } }, "node_modules/@babel/core/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -180,35 +100,39 @@ } }, "node_modules/@babel/core/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/@babel/generator": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", - "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.23.5", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -216,63 +140,40 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -282,166 +183,65 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", - "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@babel/types": "^7.29.7" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -454,6 +254,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -466,6 +267,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -478,6 +280,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -485,11 +288,44 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -502,6 +338,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -510,12 +347,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -529,6 +367,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -541,6 +380,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -553,6 +393,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -565,6 +406,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -577,6 +419,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -589,6 +432,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -596,11 +440,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-top-level-await": { + "node_modules/@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -611,13 +456,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -626,60 +472,64 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/runtime": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", - "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", "dev": true, + "license": "MIT", "dependencies": { - "regenerator-runtime": "^0.14.0" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", - "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.5", - "@babel/types": "^7.23.5", - "debug": "^4.1.0", - "globals": "^11.1.0" + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -691,19 +541,20 @@ } }, "node_modules/@babel/traverse/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -713,87 +564,193 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@emnapi/core": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz", + "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==", "dev": true, + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@emnapi/runtime": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", + "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", "dev": true, - "engines": { - "node": ">=8" + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", "dev": true, + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "@jest/types": "^29.6.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.4.1.tgz", + "integrity": "sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.4.1", "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", + "chalk": "^4.1.2", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.4.2.tgz", + "integrity": "sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/console": "30.4.1", + "@jest/pattern": "30.4.0", + "@jest/reporters": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "exit-x": "^0.2.2", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-changed-files": "30.4.1", + "jest-config": "30.4.2", + "jest-haste-map": "30.4.1", + "jest-message-util": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-resolve-dependencies": "30.4.2", + "jest-runner": "30.4.2", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "jest-watcher": "30.4.1", + "pretty-format": "30.4.1", + "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -804,111 +761,196 @@ } } }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/diff-sequences": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", + "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", + "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-mock": "^29.7.0" + "jest-mock": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==", "dev": true, + "license": "MIT", "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" + "expect": "30.4.1", + "jest-snapshot": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", + "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", "dev": true, + "license": "MIT", "dependencies": { - "jest-get-type": "^29.6.3" + "@jest/get-type": "30.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", + "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", + "@jest/types": "30.4.1", + "@sinonjs/fake-timers": "^15.4.0", "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.4.1.tgz", + "integrity": "sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q==", "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/types": "30.4.1", + "jest-mock": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", + "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", + "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" + "@types/node": "*", + "jest-regex-util": "30.4.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.4.1.tgz", + "integrity": "sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA==", "dev": true, + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", + "@jest/console": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", + "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", + "chalk": "^4.1.2", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", + "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", + "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -919,175 +961,440 @@ } } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.27.8" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "node_modules/@jest/schemas": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" + "@sinclair/typebox": "^0.34.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "node_modules/@jest/snapshot-utils": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.4.1.tgz", + "integrity": "sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" + "@jest/types": "30.4.1", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "node_modules/@jest/snapshot-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "node_modules/@jest/snapshot-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "node_modules/@jest/snapshot-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=6.0.0" + "node": ">=8" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "node_modules/@jest/source-map": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", + "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" + }, "engines": { - "node": ">=6.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "node_modules/@jest/test-result": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz", + "integrity": "sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@jest/console": "30.4.1", + "@jest/types": "30.4.1", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "node_modules/@jest/test-sequencer": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.4.1.tgz", + "integrity": "sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw==", "dev": true, + "license": "MIT", "dependencies": { - "type-detect": "4.0.8" + "@jest/test-result": "30.4.1", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "node_modules/@jest/transform": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", + "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/types": "30.4.1", + "@jridgewell/trace-mapping": "^0.3.25", + "babel-plugin-istanbul": "^7.0.1", + "chalk": "^4.1.2", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", + "pirates": "^4.0.7", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", + "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.4.0", + "@jest/schemas": "30.4.1", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz", + "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.50", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.50.tgz", + "integrity": "sha512-ydBWw0G6WFwWHzh9RK4B5c690UkreOG0llq0r+DaI7LgKgxigf8mhHzIPI3S0850g1BPkq/zpuCfrq4QFgUlTQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", + "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "@sinonjs/commons": "^3.0.0" + "tslib": "^2.4.0" } }, "node_modules/@types/babel__core": { @@ -1095,6 +1402,7 @@ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -1104,10 +1412,11 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.7", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", - "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } @@ -1117,47 +1426,35 @@ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__traverse": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", - "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", "dev": true, + "license": "MIT", "dependencies": { - "@types/node": "*" + "@babel/types": "^7.28.2" } }, - "node_modules/@types/graphql": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-0.10.2.tgz", - "integrity": "sha512-Ayw0w+kr8vYd8DToiMXjcHxXv1ljWbqX2mnLwXDxkBgog3vywGriC0JZ+npsuohKs3+E88M8OOtobo4g0X3SIA==", - "optional": true, - "peer": true - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -1167,30 +1464,34 @@ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/node": { - "version": "20.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", - "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "version": "26.1.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz", + "integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~8.3.0" } }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -1199,374 +1500,606 @@ "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, - "node_modules/@types/zen-observable": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.7.tgz", - "integrity": "sha512-LKzNTjj+2j09wAo/vvVjzgw5qckJJzhdGgWHW7j69QIGdq/KnZrMAMIHQiWGl3Ccflh5/CudBAntTPYdprPltA==" + "dev": true, + "license": "MIT" }, - "node_modules/@wry/equality": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.11.tgz", - "integrity": "sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA==", - "dependencies": { - "tslib": "^1.9.3" - } + "node_modules/@ungap/structured-clone": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.2.tgz", + "integrity": "sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA==", + "dev": true, + "license": "ISC" }, - "node_modules/@wry/equality/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] }, - "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==", - "engines": { - "node": ">=8" - } + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", + "cpu": [ + "wasm32" + ], "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { - "node": ">= 8" + "node": ">=14.0.0" } }, - "node_modules/apollo-client": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/apollo-client/-/apollo-client-1.9.3.tgz", - "integrity": "sha512-JABKKbqvcw8DJm3YUkEmyx1SK74i+/DesEtAtyocJi10LLmeMQYQFpg8W3BG1tZsYEQ3owEmPbsdNGTly+VOQg==", - "peer": true, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "apollo-link-core": "^0.5.0", - "graphql": "^0.10.0", - "graphql-anywhere": "^3.0.1", - "graphql-tag": "^2.0.0", - "redux": "^3.4.0", - "symbol-observable": "^1.0.2", - "whatwg-fetch": "^2.0.0" - }, - "optionalDependencies": { - "@types/graphql": "0.10.2" + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" } }, - "node_modules/apollo-client/node_modules/graphql": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.10.5.tgz", - "integrity": "sha512-Q7cx22DiLhwHsEfUnUip1Ww/Vfx7FS0w6+iHItNuN61+XpegHSa3k5U0+6M5BcpavQImBwFiy0z3uYwY7cXMLQ==", - "peer": true, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "iterall": "^1.1.0" + "tslib": "^2.4.0" } }, - "node_modules/apollo-link": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.14.tgz", - "integrity": "sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==", + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "apollo-utilities": "^1.3.0", - "ts-invariant": "^0.4.0", - "tslib": "^1.9.3", - "zen-observable-ts": "^0.8.21" - }, - "peerDependencies": { - "graphql": "^0.11.3 || ^0.12.3 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "tslib": "^2.4.0" } }, - "node_modules/apollo-link-core": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/apollo-link-core/-/apollo-link-core-0.5.4.tgz", - "integrity": "sha512-OxL0Kjizb0eS2ObldDqJEs/tFN9xI9RZuTJcaszgGy+xudoPXhIMCHMr7hGZhy0mK+U+BbBULZJw4YQU4J0ODQ==", - "peer": true, - "dependencies": { - "graphql": "^0.10.3", - "graphql-tag": "^2.4.2", - "zen-observable-ts": "^0.4.4" - } + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/apollo-link-core/node_modules/graphql": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.10.5.tgz", - "integrity": "sha512-Q7cx22DiLhwHsEfUnUip1Ww/Vfx7FS0w6+iHItNuN61+XpegHSa3k5U0+6M5BcpavQImBwFiy0z3uYwY7cXMLQ==", - "peer": true, - "dependencies": { - "iterall": "^1.1.0" - } + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/apollo-link-core/node_modules/zen-observable-ts": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.4.4.tgz", - "integrity": "sha512-SNVY1sWWhoe7FwFmHpD9ERi+7Mhhj3+JdS0BGy2UxLIg7cY+3zQbyZauQCI6DN6YK4uoKNaIm3S7Qkqi1Lr+Fw==", - "peer": true + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/apollo-link/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, - "node_modules/apollo-test-utils": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/apollo-test-utils/-/apollo-test-utils-0.3.2.tgz", - "integrity": "sha512-3PtLQmTgLXzwr0qZq3eb/zNEKJAWwPESwlKTuseDShF4GtgGYkTdFdjRuPIVwwn9FrnCGJChcyI6dn2x/32cBA==", - "dependencies": { - "graphql": "^0.10.0", - "graphql-tag": "^2.0.0", - "graphql-tools": "^1.0.0" + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" }, - "peerDependencies": { - "apollo-client": "^1.0.0" + "engines": { + "node": ">=0.4.0" } }, - "node_modules/apollo-test-utils/node_modules/@types/graphql": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@types/graphql/-/graphql-0.9.4.tgz", - "integrity": "sha512-ob2dps4itT/Le5DbxjssBXtBnloDIRUbkgtAvaB42mJ8pVIWMRuURD9WjnhaEGZ4Ql/EryXMQWeU8Y0EU73QLw==", - "optional": true - }, - "node_modules/apollo-test-utils/node_modules/graphql": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.10.5.tgz", - "integrity": "sha512-Q7cx22DiLhwHsEfUnUip1Ww/Vfx7FS0w6+iHItNuN61+XpegHSa3k5U0+6M5BcpavQImBwFiy0z3uYwY7cXMLQ==", + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", "dependencies": { - "iterall": "^1.1.0" + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/apollo-test-utils/node_modules/graphql-tools": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-1.2.3.tgz", - "integrity": "sha512-3inNK3rmk32G4hGWbqBuVNxusF+Mcuckg+3aD4hHaMxO0LrSgteWoTD8pTD9GUnmoSRG4AbYHZ0jibGD5MTlrQ==", - "deprecated": "This package has been deprecated and now it only exports makeExecutableSchema.\nAnd it will no longer receive updates.\nWe recommend you to migrate to scoped packages such as @graphql-tools/schema, @graphql-tools/utils and etc.\nCheck out https://www.graphql-tools.com to learn what package you should use instead", - "dependencies": { - "deprecated-decorator": "^0.1.6", - "uuid": "^3.0.1" + "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" }, - "optionalDependencies": { - "@types/graphql": "^0.9.0" + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" }, - "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/apollo-utilities": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.4.tgz", - "integrity": "sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig==", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "dependencies": { - "@wry/equality": "^0.1.2", - "fast-json-stable-stringify": "^2.0.0", - "ts-invariant": "^0.4.0", - "tslib": "^1.10.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, - "peerDependencies": { - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "engines": { + "node": ">= 8" } }, - "node_modules/apollo-utilities/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, "node_modules/assert-never": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", - "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz", + "integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==", + "license": "MIT" }, "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", + "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", + "@jest/transform": "30.4.1", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.1", + "babel-preset-jest": "30.4.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "@babel/core": "^7.8.0" + "@babel/core": "^7.11.0 || ^8.0.0-0" } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" + "color-convert": "^2.0.1" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, + "node_modules/babel-plugin-istanbul": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", + "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "dev": true, + "license": "BSD-3-Clause", + "workspaces": [ + "test/babel-8" + ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.4.0.tgz", + "integrity": "sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" + "@types/babel__core": "^7.20.5" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0 || ^8.0.0-0" } }, "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.4.0.tgz", + "integrity": "sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg==", "dev": true, + "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" + "babel-plugin-jest-hoist": "30.4.0", + "babel-preset-current-node-syntax": "^1.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.11.0 || ^8.0.0-beta.1" } }, "node_modules/babel-walk": { "version": "3.0.0-canary-5", "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "license": "MIT", "dependencies": { "@babel/types": "^7.9.6" }, @@ -1578,7 +2111,21 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.42", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.42.tgz", + "integrity": "sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } }, "node_modules/basic-auth": { "version": "2.0.1", @@ -1605,37 +2152,14 @@ "node": ">=8" } }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -1651,9 +2175,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.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.5.tgz", + "integrity": "sha512-Cu2E6QejHWzuDMTkuwgpABFgDfZrXLQq5V13YOACZx4mFAG4IwGTbTfHPMr4WtxlHoXSM8FIuRwYYCz5XiabaQ==", "dev": true, "funding": [ { @@ -1669,11 +2193,13 @@ "url": "https://github.com/sponsors/ai" } ], + "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.10.42", + "caniuse-lite": "^1.0.30001800", + "electron-to-chromium": "^1.5.387", + "node-releases": "^2.0.50", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -1687,6 +2213,7 @@ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } @@ -1695,7 +2222,8 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/bytes": { "version": "3.1.2", @@ -1723,11 +2251,41 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1737,14 +2295,15 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001566", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", - "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", + "version": "1.0.30001803", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001803.tgz", + "integrity": "sha512-g/uHREV2ZpK9qMalCsWaxmA6ol+DX8GYhuf3T40RKoP+oL7vhRJh8LNt73PCjpnR6l14FzfPrB5Yux4PKm2meg==", "dev": true, "funding": [ { @@ -1759,39 +2318,28 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "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": ">=10" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -1832,9 +2380,9 @@ } }, "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, "funding": [ { @@ -1842,27 +2390,87 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", - "dev": true + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "dev": true, + "license": "MIT" }, "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/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/cliui/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/cliui/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/cliui/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": "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/co": { @@ -1870,1324 +2478,2292 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, + "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" } }, "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true, + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "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, + "license": "MIT" + }, + "node_modules/concurrently": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-10.0.3.tgz", + "integrity": "sha512-hc3LH4UaKWd/bbyDK/IGVa4RB6PtQ3CUYwtrkzqHn+wIG3Hr5fhpRlk0L/gCa8ZE1L/Ufj50Zho69cI5w8SQBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "5.6.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.4", + "supports-color": "10.2.2", + "tree-kill": "1.2.2", + "yargs": "18.0.0" + }, + "bin": { + "conc": "dist/bin/index.js", + "concurrently": "dist/bin/index.js" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/content-disposition": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", + "license": "MIT" + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "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/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.389", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz", + "integrity": "sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "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" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "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/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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/execa/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/exit-x": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", + "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.4.1", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz", + "integrity": "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==", + "license": "MIT", + "dependencies": { + "ip-address": "^10.2.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/express-slow-down": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/express-slow-down/-/express-slow-down-3.1.0.tgz", + "integrity": "sha512-0gZ1HHow8H83z1/+81DdWB60RSGHI0mJB0ZM1m5P6/BexORFcA8P1TgU0NKEwOiRmxyCIoktZYqmA+1UCc83+A==", + "license": "MIT", + "dependencies": { + "express-rate-limit": "8" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "express": "4 || 5 || ^5.0.0-beta.1" + } + }, + "node_modules/express/node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/body-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^2.0.0", + "debug": "^4.4.3", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", + "on-finished": "^2.4.1", + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/express/node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/express/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/express/node_modules/type-is": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", + "license": "MIT", + "dependencies": { + "content-type": "^2.0.0", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/type-is/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "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, + "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", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "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", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { - "node": ">=7.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=8.0.0" } }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.4" } }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "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": ">= 0.8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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 - }, - "node_modules/concurrently": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz", - "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==", + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, + "license": "ISC", "dependencies": { - "chalk": "^4.1.2", - "date-fns": "^2.30.0", - "lodash": "^4.17.21", - "rxjs": "^7.8.1", - "shell-quote": "^1.8.1", - "spawn-command": "0.0.2", - "supports-color": "^8.1.1", - "tree-kill": "^1.2.2", - "yargs": "^17.7.2" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" }, "engines": { - "node": "^14.13.0 || >=16.0.0" + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/connect-pause": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/connect-pause/-/connect-pause-0.1.1.tgz", - "integrity": "sha512-a1gSWQBQD73krFXdUEYJom2RTFrWUL3YvXDCRkyv//GVXc79cdW9MngtRuN9ih4FDKBtfJAJId+BbDuX+1rh2w==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/constantinople": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", - "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.1" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" }, - "node_modules/cors": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", - "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { - "object-assign": "^4", - "vary": "^1" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { - "node": ">= 0.10" + "node": ">= 0.8" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "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, - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, + "license": "Apache-2.0", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10.17.0" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, + "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" }, "engines": { - "node": ">= 8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 12" + "node": ">=0.8.19" } }, - "node_modules/date-fns": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { - "@babel/runtime": "^7.21.0" - }, + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ip-address": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", + "license": "MIT", "engines": { - "node": ">=0.11" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" + "node": ">= 12" } }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" } }, - "node_modules/dedent": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true, - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } + "license": "MIT" }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" } }, - "node_modules/deprecated-decorator": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz", - "integrity": "sha512-MHidOOnCHGlZDKsI21+mbIIhf4Fff+hhCTB7gtVg4uoIqjcrTZc5v6M+GS2zVI0sV7PqK415rb8XaOSQsQkHOw==" - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=0.10.0" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "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/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, + "license": "MIT", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/doctypes": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", - "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" - }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/electron-to-chromium": { - "version": "1.4.609", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.609.tgz", - "integrity": "sha512-ihiCP7PJmjoGNuLpl7TjNA8pCQWu09vGyjlPYw1Rqww4gvNuCcmvl+44G+2QyJ6S2K4o+wbTS++Xz0YN8Q9ERw==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "is-extglob": "^2.1.1" }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "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==" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "engines": { - "node": ">= 0.8" + "node": ">=0.10.0" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/errorhandler": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", - "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", - "dependencies": { - "accepts": "~1.3.7", - "escape-html": "~1.0.3" - }, "engines": { - "node": ">= 0.8" + "node": ">=0.12.0" } }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dependencies": { - "get-intrinsic": "^1.2.4" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "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": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/escape-string-regexp": { + "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" }, "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">= 0.6" + "node": ">=10" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "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" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" } }, - "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express-graphql": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/express-graphql/-/express-graphql-0.9.0.tgz", - "integrity": "sha512-wccd9Lb6oeJ8yHpUs/8LcnGjFUUQYmOG9A5BNLybRdCzGw0PeUrtBxsIR8bfiur6uSW4OvPkVDoYH06z6/N9+w==", - "deprecated": "This package is no longer maintained. We recommend using `graphql-http` instead. Please consult the migration document https://github.com/graphql/graphql-http#migrating-express-grpahql.", - "dependencies": { - "accepts": "^1.3.7", - "content-type": "^1.0.4", - "http-errors": "^1.7.3", - "raw-body": "^2.4.1" - }, - "engines": { - "node": ">= 8.x" + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" }, - "peerDependencies": { - "graphql": "^14.4.1" - } - }, - "node_modules/express-graphql/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "engines": { - "node": ">= 0.6" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/express-graphql/node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "node_modules/istanbul-lib-source-maps/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express-graphql/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/express-rate-limit": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.2.0.tgz", - "integrity": "sha512-T7nul1t4TNyfZMJ7pKRKkdeVJWa2CqB8NA1P8BwYaoDI5QSBZARv5oMS43J7b7I5P+4asjVXjb7ONuwDKucahg==", - "engines": { - "node": ">= 16" + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" }, "funding": { - "url": "https://github.com/sponsors/express-rate-limit" + "url": "https://github.com/sponsors/isaacs" }, - "peerDependencies": { - "express": "4 || 5 || ^5.0.0-beta.1" + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/express-slow-down": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/express-slow-down/-/express-slow-down-2.0.3.tgz", - "integrity": "sha512-vATCiFd8uQHtTeK5/Q0nLUukhZh+RV5zkcHxLQr0X5dEFVEYqzVXEe48nW23Z49fwtR+ApD9zn9sZRisTCR99w==", + "node_modules/jest": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.4.2.tgz", + "integrity": "sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ==", + "dev": true, + "license": "MIT", "dependencies": { - "express-rate-limit": "7" + "@jest/core": "30.4.2", + "@jest/types": "30.4.1", + "import-local": "^3.2.0", + "jest-cli": "30.4.2" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">= 16" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "express": "4 || 5 || ^5.0.0-beta.1" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/express-urlrewrite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/express-urlrewrite/-/express-urlrewrite-1.4.0.tgz", - "integrity": "sha512-PI5h8JuzoweS26vFizwQl6UTF25CAHSggNv0J25Dn/IKZscJHWZzPrI5z2Y2jgOzIaw2qh8l6+/jUcig23Z2SA==", + "node_modules/jest-changed-files": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.4.1.tgz", + "integrity": "sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg==", + "dev": true, + "license": "MIT", "dependencies": { - "debug": "*", - "path-to-regexp": "^1.0.3" + "execa": "^5.1.1", + "jest-util": "30.4.1", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/express-urlrewrite/node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "node_modules/jest-circus": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.4.2.tgz", + "integrity": "sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ==", + "dev": true, + "license": "MIT", "dependencies": { - "isarray": "0.0.1" + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", + "@types/node": "*", + "chalk": "^4.1.2", + "co": "^4.6.0", + "dedent": "^1.6.0", + "is-generator-fn": "^2.1.0", + "jest-each": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", + "p-limit": "^3.1.0", + "pretty-format": "30.4.1", + "pure-rand": "^7.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "bser": "2.1.1" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^12.20 || >= 14.13" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "to-regex-range": "^5.0.1" + "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "node_modules/jest-cli": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.4.2.tgz", + "integrity": "sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q==", + "dev": true, + "license": "MIT", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "@jest/core": "30.4.2", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", + "chalk": "^4.1.2", + "exit-x": "^0.2.2", + "import-local": "^3.2.0", + "jest-config": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "yargs": "^17.7.2" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">= 0.8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/jest-cli/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, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", "dependencies": { - "fetch-blob": "^3.1.2" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=12.20.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "node_modules/jest-cli/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=12" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "node_modules/jest-cli/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/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/jest-cli/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, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=8" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/jest-cli/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/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=6.9.0" + "node": ">=8" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/jest-cli/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "node_modules/jest-cli/node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "dev": true, + "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "node_modules/jest-cli/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { - "node": ">=8.0.0" + "node": ">=12" } }, - "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==", + "node_modules/jest-config": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.4.2.tgz", + "integrity": "sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", + "@jest/pattern": "30.4.0", + "@jest/test-sequencer": "30.4.1", + "@jest/types": "30.4.1", + "babel-jest": "30.4.1", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "deepmerge": "^4.3.1", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "jest-circus": "30.4.2", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-runner": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "parse-json": "^5.2.0", + "pretty-format": "30.4.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": ">=10" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@types/node": "*", + "esbuild-register": ">=3.4.0", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "esbuild-register": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "node_modules/jest-diff": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", + "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", + "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.3" + "@jest/diff-sequences": "30.4.0", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.4.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/graphql": { - "version": "14.7.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.7.0.tgz", - "integrity": "sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA==", + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", "dependencies": { - "iterall": "^1.2.2" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 6.x" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/graphql-anywhere": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/graphql-anywhere/-/graphql-anywhere-3.1.0.tgz", - "integrity": "sha512-7+pskZqmSounBJTH5hjzR54BYRAVmKLpntpbUOiq0hp9VKE7Peig6+6UwXjfmK6iVlsqr6OT3TL3980CKQJs6A==", - "peer": true - }, - "node_modules/graphql-tag": { - "version": "2.12.6", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", - "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.1.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, - "peerDependencies": { - "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/graphql-tools": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.8.tgz", - "integrity": "sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg==", - "deprecated": "This package has been deprecated and now it only exports makeExecutableSchema.\nAnd it will no longer receive updates.\nWe recommend you to migrate to scoped packages such as @graphql-tools/schema, @graphql-tools/utils and etc.\nCheck out https://www.graphql-tools.com to learn what package you should use instead", + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", "dependencies": { - "apollo-link": "^1.2.14", - "apollo-utilities": "^1.0.1", - "deprecated-decorator": "^0.1.6", - "iterall": "^1.1.3", - "uuid": "^3.1.0" + "has-flag": "^4.0.0" }, - "peerDependencies": { - "graphql": "^0.13.0 || ^14.0.0 || ^15.0.0" - } - }, - "node_modules/graphql-type-json": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz", - "integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==", - "peerDependencies": { - "graphql": ">=0.8.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "node_modules/jest-docblock": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.4.0.tgz", + "integrity": "sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA==", + "dev": true, + "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0" + "detect-newline": "^3.1.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" + "node_modules/jest-each": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.4.1.tgz", + "integrity": "sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.4.1", + "chalk": "^4.1.2", + "jest-util": "30.4.1", + "pretty-format": "30.4.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", "dependencies": { - "function-bind": "^1.1.2" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/jest-environment-node": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.4.1.tgz", + "integrity": "sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==", + "dev": true, + "license": "MIT", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", + "@types/node": "*", + "jest-mock": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1" }, "engines": { - "node": ">= 0.8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "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==", + "node_modules/jest-haste-map": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", + "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "@jest/types": "30.4.1", + "@types/node": "*", + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", + "picomatch": "^4.0.3", + "walker": "^1.0.8" }, "engines": { - "node": ">=0.10.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.3" } }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "node_modules/jest-haste-map/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/jest-leak-detector": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz", + "integrity": "sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "pretty-format": "30.4.1" + }, "engines": { - "node": ">=0.8.19" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/inflection": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", - "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==", - "engines": [ - "node >= 0.4.0" - ] - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "node_modules/jest-matcher-utils": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", + "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", "dev": true, + "license": "MIT", "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.4.1", + "pretty-format": "30.4.1" + }, "engines": { - "node": ">= 0.10" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "binary-extensions": "^2.0.0" + "color-convert": "^2.0.1" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/is-expression": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", - "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", "dependencies": { - "acorn": "^7.1.1", - "object-assign": "^4.1.1" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/jest-message-util": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", + "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.4.1", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-util": "30.4.1", + "picomatch": "^4.0.3", + "pretty-format": "30.4.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, "engines": { - "node": ">=0.10.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "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==", + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/jest-message-util/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=0.12.0" + "node": ">=8" } }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "node_modules/jest-mock": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", + "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", + "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "@jest/types": "30.4.1", + "@types/node": "*", + "jest-util": "30.4.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "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==", + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=6" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } } }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "node_modules/jest-regex-util": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", + "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", - "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "node_modules/jest-resolve": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.4.1.tgz", + "integrity": "sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.4.1", + "jest-pnp-resolver": "^1.2.3", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "slash": "^3.0.0", + "unrs-resolver": "^1.7.11" }, "engines": { - "node": ">=10" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/istanbul-lib-instrument/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/jest-resolve-dependencies": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.4.2.tgz", + "integrity": "sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ==", "dev": true, + "license": "MIT", "dependencies": { - "yallist": "^4.0.0" + "jest-regex-util": "30.4.0", + "jest-snapshot": "30.4.1" }, "engines": { - "node": ">=10" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/istanbul-lib-instrument/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", + "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { + "node_modules/jest-resolve/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -3195,654 +4771,530 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/jest-runner": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.4.2.tgz", + "integrity": "sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "@jest/console": "30.4.1", + "@jest/environment": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", + "@types/node": "*", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-haste-map": "30.4.1", + "jest-leak-detector": "30.4.1", + "jest-message-util": "30.4.1", + "jest-resolve": "30.4.1", + "jest-runtime": "30.4.2", + "jest-util": "30.4.1", + "jest-watcher": "30.4.1", + "jest-worker": "30.4.1", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/istanbul-lib-source-maps/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" + "color-convert": "^2.0.1" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" - }, - "node_modules/jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - }, - "bin": { - "jest": "bin/jest.js" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "node": ">=10" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" + "has-flag": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "node_modules/jest-runtime": { + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.4.2.tgz", + "integrity": "sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/globals": "30.4.1", + "@jest/source-map": "30.0.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", + "chalk": "^4.1.2", + "cjs-module-lexer": "^2.1.0", + "collect-v8-coverage": "^1.0.2", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "strip-bom": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", - "dev": true, - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "node": ">=8" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" + "node": ">=10" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "has-flag": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "node_modules/jest-snapshot": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", + "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", "dev": true, + "license": "MIT", "dependencies": { - "detect-newline": "^3.0.0" + "@babel/core": "^7.27.4", + "@babel/generator": "^7.27.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/types": "^7.27.3", + "@jest/expect-utils": "30.4.1", + "@jest/get-type": "30.1.0", + "@jest/snapshot-utils": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", + "babel-preset-current-node-syntax": "^1.2.0", + "chalk": "^4.1.2", + "expect": "30.4.1", + "graceful-fs": "^4.2.11", + "jest-diff": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "pretty-format": "30.4.1", + "semver": "^7.7.2", + "synckit": "^0.11.8" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" } }, - "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" + "has-flag": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" + "node": ">=8" } }, - "node_modules/jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "node_modules/jest-util": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", + "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", "dev": true, + "license": "MIT", "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "@jest/types": "30.4.1", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.3" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "node": ">=8" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" + "node": ">=10" }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "node_modules/jest-util/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, + "license": "MIT", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" + "node": ">=12" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" + "has-flag": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "node_modules/jest-validate": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz", + "integrity": "sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" + "@jest/get-type": "30.1.0", + "@jest/types": "30.4.1", + "camelcase": "^6.3.0", + "chalk": "^4.1.2", + "leven": "^3.1.0", + "pretty-format": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-snapshot/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { - "yallist": "^4.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/jest-snapshot/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "node_modules/jest-watcher": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.4.1.tgz", + "integrity": "sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "jest-util": "30.4.1", + "string-length": "^4.0.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" + "has-flag": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", + "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", - "jest-util": "^29.7.0", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.4.1", "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "supports-color": "^8.1.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jju": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", - "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==" + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } }, "node_modules/js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", - "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", + "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" }, "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.15.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.0.tgz", + "integrity": "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -3852,120 +5304,24 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" - } - }, - "node_modules/json-graphql-server": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/json-graphql-server/-/json-graphql-server-2.4.0.tgz", - "integrity": "sha512-gAkzNpzE6sn/8oV1hzRK9lwMGkAq2GvyqOrAHV/h3J8maiKs59Vag9jaievqR1wme543PHOe3XjDBgRnOCATfA==", - "dependencies": { - "apollo-client": "^2.6.4", - "apollo-test-utils": "^0.3.2", - "cors": "^2.8.4", - "express": "^4.19.2", - "express-graphql": "^0.9.0", - "graphql": "^14.5.8", - "graphql-tag": "^2.10.1", - "graphql-tools": "^4.0.5", - "graphql-type-json": "^0.3.0", - "inflection": "^1.12.0", - "lodash.merge": "^4.6.2", - "reify": "^0.20.12", - "xhr-mock": "^2.5.0" - }, - "bin": { - "json-graphql-server": "bin/json-graphql-server.js" - } - }, - "node_modules/json-graphql-server/node_modules/apollo-client": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/apollo-client/-/apollo-client-2.6.10.tgz", - "integrity": "sha512-jiPlMTN6/5CjZpJOkGeUV0mb4zxx33uXWdj/xQCfAMkuNAC3HN7CvYDyMHHEzmcQ5GV12LszWoQ/VlxET24CtA==", - "dependencies": { - "@types/zen-observable": "^0.8.0", - "apollo-cache": "1.3.5", - "apollo-link": "^1.0.0", - "apollo-utilities": "1.3.4", - "symbol-observable": "^1.0.2", - "ts-invariant": "^0.4.0", - "tslib": "^1.10.0", - "zen-observable": "^0.8.0" - }, - "peerDependencies": { - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" - } - }, - "node_modules/json-graphql-server/node_modules/apollo-client/node_modules/apollo-cache": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/apollo-cache/-/apollo-cache-1.3.5.tgz", - "integrity": "sha512-1XoDy8kJnyWY/i/+gLTEbYLnoiVtS8y7ikBr/IfmML4Qb+CM7dEEbIUOjnY716WqmZ/UpXIxTfJsY7rMcqiCXA==", - "dependencies": { - "apollo-utilities": "^1.3.4", - "tslib": "^1.10.0" - }, - "peerDependencies": { - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + "node": ">=6" } }, - "node_modules/json-graphql-server/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-parse-helpfulerror": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", - "integrity": "sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==", - "dependencies": { - "jju": "^1.1.0" - } - }, - "node_modules/json-server": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/json-server/-/json-server-0.17.4.tgz", - "integrity": "sha512-bGBb0WtFuAKbgI7JV3A864irWnMZSvBYRJbohaOuatHwKSRFUfqtQlrYMrB6WbalXy/cJabyjlb7JkHli6dYjQ==", - "dependencies": { - "body-parser": "^1.19.0", - "chalk": "^4.1.2", - "compression": "^1.7.4", - "connect-pause": "^0.1.1", - "cors": "^2.8.5", - "errorhandler": "^1.5.1", - "express": "^4.17.1", - "express-urlrewrite": "^1.4.0", - "json-parse-helpfulerror": "^1.0.3", - "lodash": "^4.17.21", - "lodash-id": "^0.14.1", - "lowdb": "^1.0.0", - "method-override": "^3.0.0", - "morgan": "^1.10.0", - "nanoid": "^3.1.23", - "please-upgrade-node": "^3.2.0", - "pluralize": "^8.0.0", - "server-destroy": "^1.0.1", - "yargs": "^17.0.1" - }, - "bin": { - "json-server": "lib/cli/bin.js" - }, - "engines": { - "node": ">=12" - } + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", @@ -3988,20 +5344,12 @@ "promise": "^7.0.1" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4010,13 +5358,15 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -4024,279 +5374,137 @@ "node": ">=8" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "peer": true - }, - "node_modules/lodash-id": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/lodash-id/-/lodash-id-0.14.1.tgz", - "integrity": "sha512-ikQPBTiq/d5m6dfKQlFdIXFzvThPi2Be9/AHxktOnDSfSxE1j9ICbBT5Elk1ke7HSTgM38LHTpmJovo9/klnLg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "peer": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lowdb": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", - "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==", - "dependencies": { - "graceful-fs": "^4.1.3", - "is-promise": "^2.1.0", - "lodash": "4", - "pify": "^3.0.0", - "steno": "^0.4.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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 - }, - "node_modules/method-override": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", - "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", - "dependencies": { - "debug": "3.1.0", - "methods": "~1.1.2", - "parseurl": "~1.3.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/method-override/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" + "yallist": "^3.0.2" } }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "semver": "^7.5.3" }, "engines": { - "node": ">=8.6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "node_modules/make-dir/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", "bin": { - "mime": "cli.js" + "semver": "bin/semver.js" }, "engines": { - "node": ">=4" + "node": ">=10" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.4" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, + "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/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": "MIT", "engines": { "node": ">=6" } }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dependencies": { - "dom-walk": "^0.1.0" - } - }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.2" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" } }, "node_modules/morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.11.0.tgz", + "integrity": "sha512-zSkVu3t18r39pw4ixfBKvfZi3y2UOqr7d4WYwcj3m8nXpEQK4rPO6GLzs/CExoRgmX3y9EjmmcXqv6jq0SK46g==", + "license": "MIT", "dependencies": { "basic-auth": "~2.0.1", "debug": "2.6.9", "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" + "on-finished": "~2.4.1", + "on-headers": "~1.1.0" }, "engines": { "node": ">= 0.8.0" - } - }, - "node_modules/morgan/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dependencies": { - "ee-first": "1.1.1" }, - "engines": { - "node": ">= 0.8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/ms": { @@ -4304,94 +5512,57 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", "bin": { - "nanoid": "bin/nanoid.cjs" + "napi-postinstall": "lib/cli.js" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" } }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } + "dev": true, + "license": "MIT" }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "dev": true, + "license": "MIT" }, "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.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/nodemon": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.1.tgz", - "integrity": "sha512-k43xGaDtaDIcufn0Fc6fTtsdKSkV/hQzoQFigNH//GaKta28yoKVYXCnV+KXRqfT/YzsFaQU9VdeEG+HEyxr6A==", + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.14.tgz", + "integrity": "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==", "dev": true, + "license": "MIT", "dependencies": { "chokidar": "^3.5.2", "debug": "^4", "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", + "minimatch": "^10.2.1", "pstree.remy": "^1.1.8", "semver": "^7.5.3", "simple-update-notifier": "^2.0.0", @@ -4410,6 +5581,29 @@ "url": "https://opencollective.com/nodemon" } }, + "node_modules/nodemon/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/nodemon/node_modules/brace-expansion": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/nodemon/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -4436,6 +5630,22 @@ "node": ">=4" } }, + "node_modules/nodemon/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/nodemon/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4495,6 +5705,7 @@ "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" }, @@ -4511,9 +5722,10 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4533,9 +5745,10 @@ } }, "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -4544,7 +5757,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -4554,6 +5766,7 @@ "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" }, @@ -4569,6 +5782,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -4584,6 +5798,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -4596,6 +5811,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -4611,15 +5827,24 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -4646,6 +5871,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4655,6 +5881,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4664,6 +5891,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4673,22 +5901,53 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -4696,19 +5955,12 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "engines": { - "node": ">=4" - } - }, "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -4718,6 +5970,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -4725,54 +5978,20 @@ "node": ">=8" } }, - "node_modules/please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dependencies": { - "semver-compare": "^1.0.0" - } - }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "engines": { - "node": ">=4" - } - }, "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "engines": { - "node": ">= 0.6.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/promise": { @@ -4783,19 +6002,6 @@ "asap": "~2.0.3" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -4815,11 +6021,12 @@ "dev": true }, "node_modules/pug": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.3.tgz", - "integrity": "sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.4.tgz", + "integrity": "sha512-kFfq5mMzrS7+wrl5pLJzZEzemx34OQ0w4SARfhy/3yxTlhbstsudDwJzhf1hP02yHzbjoVMSXUj/Sz6RNfMyXg==", + "license": "MIT", "dependencies": { - "pug-code-gen": "^3.0.3", + "pug-code-gen": "^3.0.4", "pug-filters": "^4.0.0", "pug-lexer": "^5.0.1", "pug-linker": "^4.0.0", @@ -4833,6 +6040,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "license": "MIT", "dependencies": { "constantinople": "^4.0.1", "js-stringify": "^1.0.2", @@ -4840,9 +6048,10 @@ } }, "node_modules/pug-code-gen": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.3.tgz", - "integrity": "sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.4.tgz", + "integrity": "sha512-6okWYIKdasTyXICyEtvobmTZAVX57JkzgzIi4iRJlin8kmhG+Xry2dsus+Mun/nGCn6F2U49haHI5mkELXB14g==", + "license": "MIT", "dependencies": { "constantinople": "^4.0.1", "doctypes": "^1.1.0", @@ -4911,7 +6120,8 @@ "node_modules/pug-runtime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", - "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "license": "MIT" }, "node_modules/pug-strip-comments": { "version": "2.0.0", @@ -4926,15 +6136,10 @@ "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - }, "node_modules/pure-rand": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", - "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", + "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", "dev": true, "funding": [ { @@ -4945,14 +6150,17 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ] + ], + "license": "MIT" }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.6" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -4962,109 +6170,52 @@ } }, "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", + "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", + "license": "MIT", "engines": { "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" }, - "engines": { - "node": ">=8.10.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/redux": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", - "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", - "peer": true, - "dependencies": { - "lodash": "^4.2.1", - "lodash-es": "^4.2.1", - "loose-envify": "^1.1.0", - "symbol-observable": "^1.0.3" - } + "node_modules/react-is-18": { + "name": "react-is", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, - "node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", - "dev": true + "node_modules/react-is-19": { + "name": "react-is", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz", + "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==", + "dev": true, + "license": "MIT" }, - "node_modules/reify": { - "version": "0.20.12", - "resolved": "https://registry.npmjs.org/reify/-/reify-0.20.12.tgz", - "integrity": "sha512-4BzKwDWyJJbukwI6xIJRh+BDTitoGzxdgYPiQQ1zbcTZW6I8xgHPw1DnVuEs/mEZQlYm1e09DcFSApb4UaR5bQ==", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, "dependencies": { - "acorn": "^6.1.1", - "acorn-dynamic-import": "^4.0.0", - "magic-string": "^0.25.3", - "semver": "^5.4.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/reify/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "bin": { - "acorn": "bin/acorn" + "picomatch": "^2.2.1" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/reify/node_modules/acorn-dynamic-import": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", - "deprecated": "This is probably built in to whatever tool you're using. If you still need it... idk", - "peerDependencies": { - "acorn": "^6.0.0" - } - }, - "node_modules/reify/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" + "node": ">=8.10.0" } }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5090,6 +6241,7 @@ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -5102,47 +6254,66 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, "engines": { - "node": ">=10" + "node": ">= 18" + } + }, + "node_modules/router/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, + "node_modules/router/node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/router/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, - "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==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -5153,70 +6324,104 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" - }, "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "node_modules/send/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, "engines": { - "node": ">= 0.8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/send/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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==" - }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -5243,6 +6448,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -5255,28 +6461,88 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.4.tgz", + "integrity": "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -5286,10 +6552,17 @@ } }, "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 + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/simple-update-notifier": { "version": "2.0.0", @@ -5315,17 +6588,12 @@ "node": ">=10" } }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5335,6 +6603,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -5344,34 +6613,25 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead" - }, - "node_modules/spawn-command": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", - "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", - "dev": true - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "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" }, @@ -5380,51 +6640,138 @@ } }, "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/steno": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz", - "integrity": "sha512-EEHMVYHNXFHfGtgjNITnka0aHhiAlo93F7z2/Pwd+g0teG9CnM3JIINM7hVVB5/rhw9voufD7Wukwgtw2uqh6w==", - "dependencies": { - "graceful-fs": "^4.1.3" - } - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length/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/string-length/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/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/string-width-cjs": { + "name": "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/string-width-cjs/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/string-width-cjs/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/string-width-cjs/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": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "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==", + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/strip-ansi": { + "node_modules/strip-ansi-cjs": { + "name": "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" }, @@ -5432,11 +6779,22 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs/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/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5446,6 +6804,7 @@ "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" } @@ -5455,6 +6814,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -5463,15 +6823,13 @@ } }, "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" @@ -5488,12 +6846,20 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "node_modules/synckit": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.13.tgz", + "integrity": "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.3.6" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" } }, "node_modules/test-exclude": { @@ -5501,6 +6867,7 @@ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -5510,19 +6877,58 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -5570,29 +6976,19 @@ "tree-kill": "cli.js" } }, - "node_modules/ts-invariant": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz", - "integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==", - "dependencies": { - "tslib": "^1.9.3" - } - }, - "node_modules/ts-invariant/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -5602,6 +6998,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -5609,18 +7006,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", @@ -5628,10 +7013,11 @@ "dev": true }, "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": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "dev": true, + "license": "MIT" }, "node_modules/unpipe": { "version": "1.0.0", @@ -5641,10 +7027,48 @@ "node": ">= 0.8" } }, + "node_modules/unrs-resolver": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.4" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" + } + }, "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": [ { @@ -5660,9 +7084,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" @@ -5671,37 +7096,12 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.2" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, + "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", @@ -5723,6 +7123,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5732,29 +7133,17 @@ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } }, - "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/whatwg-fetch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", - "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", - "peer": true - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5769,6 +7158,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "license": "MIT", "dependencies": { "@babel/parser": "^7.9.6", "@babel/types": "^7.9.6", @@ -5780,9 +7170,30 @@ } }, "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/wrap-ansi-cjs": { + "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -5795,38 +7206,105 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/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/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/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" + "signal-exit": "^4.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/xhr-mock": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/xhr-mock/-/xhr-mock-2.5.1.tgz", - "integrity": "sha512-UKOjItqjFgPUwQGPmRAzNBn8eTfIhcGjBVGvKYAWxUQPQsXNGD6KEckGTiHwyaAUp9C9igQlnN1Mp79KWCg7CQ==", - "dependencies": { - "global": "^4.3.0", - "url": "^0.11.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -5835,31 +7313,60 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", "dependencies": { - "cliui": "^8.0.1", + "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^7.2.0", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^22.0.0" }, "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/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/yargs/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/yocto-queue": { @@ -5867,31 +7374,13 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zen-observable": { - "version": "0.8.15", - "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", - "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==" - }, - "node_modules/zen-observable-ts": { - "version": "0.8.21", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz", - "integrity": "sha512-Yj3yXweRc8LdRMrCC8nIc4kkjWecPAUVh0TI0OUrWXx6aX790vLcDlWca6I4vsyCGH3LpWxq0dJRcMOFoVqmeg==", - "dependencies": { - "tslib": "^1.9.3", - "zen-observable": "^0.8.0" - } - }, - "node_modules/zen-observable-ts/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" } } } diff --git a/server/package.json b/server/package.json index da50fdb..7c5d090 100644 --- a/server/package.json +++ b/server/package.json @@ -23,20 +23,16 @@ "node": ">=26" }, "dependencies": { - "body-parser": "^1.20.2", - "cors": "^2.8.6", - "express": "^4.21.1", - "express-rate-limit": "^7.2.0", - "express-slow-down": "^2.0.3", - "json-graphql-server": "2.4.0", - "json-server": "^0.17.4", - "morgan": "^1.10.0", - "node-fetch": "^3.3.2", - "pug": "^3.0.3" + "cors": "2.8.6", + "express": "5.2.1", + "express-rate-limit": "8.5.2", + "express-slow-down": "3.1.0", + "morgan": "1.11.0", + "pug": "3.0.4" }, "devDependencies": { - "concurrently": "^8.2.2", - "jest": "^29.7.0", - "nodemon": "^3.1.1" + "concurrently": "10.0.3", + "jest": "30.4.2", + "nodemon": "3.1.14" } } diff --git a/server/routes/base-apis.js b/server/routes/base-apis.js index 311bf67..c8c56c8 100644 --- a/server/routes/base-apis.js +++ b/server/routes/base-apis.js @@ -1,11 +1,9 @@ const express = require("express"); const router = express.Router(); const path = require("path"); -const jsonServer = require("json-server"); -const jsonGraphqlExpress = require("json-graphql-server"); const { apiLimits } = require("../utils/rateLimiterDefaults"); -const { getFromFile } = require("../utils/utils"); +const { createJsonRouter } = require("../utils/jsonRouter"); const { verifyData } = require("../utils/verifyData"); const GeneratedAPIList = require("../GeneratedAPIList"); @@ -13,16 +11,7 @@ const GeneratedAPIList = require("../GeneratedAPIList"); const init = async () => { GeneratedAPIList.forEach(({ link }) => { const dataPath = path.join(__dirname, `../api/${link}.json`); - const data = getFromFile(dataPath); - - try { - router.use(`/${link}/graphql`, apiLimits, jsonGraphqlExpress.default(data)); - } catch (err) { - console.log(`Unable to set up /${link}/graphql`); - console.error(err); - } - - router.use(`/${link}`, verifyData, apiLimits, jsonServer.router(dataPath)); + router.use(`/${link}`, verifyData, apiLimits, createJsonRouter(dataPath)); }); }; diff --git a/server/routes/testApis.js b/server/routes/testApis.js index 998a784..1a940e7 100644 --- a/server/routes/testApis.js +++ b/server/routes/testApis.js @@ -1,6 +1,5 @@ const express = require("express"); const ApiList = require("../apiList"); -//const fetch = require("node-fetch"); const router = express.Router(); /// Main EndPoint Route diff --git a/server/utils/jsonRouter.js b/server/utils/jsonRouter.js new file mode 100644 index 0000000..d378d9a --- /dev/null +++ b/server/utils/jsonRouter.js @@ -0,0 +1,199 @@ +const express = require("express"); +const fs = require("fs"); + +/** + * A small json-server-compatible router factory. + * + * Serves every top-level key of a JSON file as a REST resource with full CRUD. + * Array values are collections (`/:resource`, `/:resource/:id`); object values + * are singular resources (`/:resource`). Mutations are persisted back to disk so + * students can manipulate the data, and the reset routes restore from the + * `.json.backup` twins. + * + * Response shapes mirror json-server 0.17 so existing tutorials keep working. + */ +function createJsonRouter(dataPath) { + const router = express.Router(); + + // In-memory db, loaded once and written through on every mutation. + let db = JSON.parse(fs.readFileSync(dataPath, "utf-8")); + const persist = () => fs.writeFileSync(dataPath, JSON.stringify(db, null, 2)); + + const isCollection = (name) => Array.isArray(db[name]); + const exists = (name) => Object.prototype.hasOwnProperty.call(db, name); + + // GET /:resource — collection query or singular object + router.get("/:resource", (req, res) => { + const { resource } = req.params; + if (!exists(resource)) return res.status(404).json({}); + if (!isCollection(resource)) return res.json(db[resource]); + + let items = [...db[resource]]; + items = applyFilters(items, req.query); + items = applySort(items, req.query); + + const total = items.length; + items = applySlice(items, req.query, res, total, req); + + res.setHeader("X-Total-Count", total); + res.json(items); + }); + + // GET /:resource/:id + router.get("/:resource/:id", (req, res) => { + const { resource, id } = req.params; + if (!isCollection(resource)) return res.status(404).json({}); + const item = db[resource].find((r) => String(r.id) === String(id)); + if (!item) return res.status(404).json({}); + res.json(item); + }); + + // POST /:resource + router.post("/:resource", (req, res) => { + const { resource } = req.params; + if (!isCollection(resource)) return res.status(404).json({}); + const item = { ...req.body, id: req.body.id ?? nextId(db[resource]) }; + db[resource].push(item); + persist(); + res.status(201).location(`${req.originalUrl}/${item.id}`).json(item); + }); + + // PUT /:resource/:id — full replace + router.put("/:resource/:id", (req, res) => { + const { resource, id } = req.params; + if (!isCollection(resource)) return res.status(404).json({}); + const idx = db[resource].findIndex((r) => String(r.id) === String(id)); + if (idx === -1) return res.status(404).json({}); + const item = { ...req.body, id: db[resource][idx].id }; + db[resource][idx] = item; + persist(); + res.json(item); + }); + + // PATCH /:resource/:id — partial update + router.patch("/:resource/:id", (req, res) => { + const { resource, id } = req.params; + if (!isCollection(resource)) return res.status(404).json({}); + const idx = db[resource].findIndex((r) => String(r.id) === String(id)); + if (idx === -1) return res.status(404).json({}); + const item = { ...db[resource][idx], ...req.body, id: db[resource][idx].id }; + db[resource][idx] = item; + persist(); + res.json(item); + }); + + // DELETE /:resource/:id + router.delete("/:resource/:id", (req, res) => { + const { resource, id } = req.params; + if (!isCollection(resource)) return res.status(404).json({}); + const idx = db[resource].findIndex((r) => String(r.id) === String(id)); + if (idx === -1) return res.status(404).json({}); + db[resource].splice(idx, 1); + persist(); + res.json({}); + }); + + return router; +} + +// --- query helpers (json-server 0.17 subset) --- + +const CONTROL_KEYS = new Set(["_sort", "_order", "_page", "_limit", "_start", "_end", "q"]); + +function getPath(obj, path) { + return path.split(".").reduce((acc, key) => (acc == null ? acc : acc[key]), obj); +} + +function applyFilters(items, query) { + // Full-text search across the whole record + if (query.q) { + const needle = String(query.q).toLowerCase(); + items = items.filter((r) => JSON.stringify(r).toLowerCase().includes(needle)); + } + + for (const [key, value] of Object.entries(query)) { + if (CONTROL_KEYS.has(key)) continue; + + // operator suffixes: field_gte, field_lte, field_ne, field_like + const opMatch = key.match(/^(.*)_(gte|lte|ne|like)$/); + if (opMatch) { + const [, field, op] = opMatch; + items = items.filter((r) => { + const v = getPath(r, field); + if (op === "gte") return v >= value; + if (op === "lte") return v <= value; + if (op === "ne") return String(v) !== String(value); + if (op === "like") return new RegExp(value, "i").test(String(v)); + }); + continue; + } + + // equality (supports repeated params → OR match) + const wanted = [].concat(value).map(String); + items = items.filter((r) => wanted.includes(String(getPath(r, key)))); + } + + return items; +} + +function applySort(items, query) { + if (!query._sort) return items; + const fields = String(query._sort).split(","); + const orders = String(query._order || "").split(","); + return [...items].sort((a, b) => { + for (let i = 0; i < fields.length; i++) { + const dir = (orders[i] || "asc").toLowerCase() === "desc" ? -1 : 1; + const av = getPath(a, fields[i]); + const bv = getPath(b, fields[i]); + if (av < bv) return -1 * dir; + if (av > bv) return 1 * dir; + } + return 0; + }); +} + +function applySlice(items, query, res, total, req) { + // Pagination: _page (+ _limit, default 10) + if (query._page) { + const page = Math.max(1, parseInt(query._page, 10) || 1); + const limit = parseInt(query._limit, 10) || 10; + const start = (page - 1) * limit; + setLinkHeader(res, req, page, limit, total); + return items.slice(start, start + limit); + } + // Range: _start / _end / _limit + if (query._start !== undefined) { + const start = parseInt(query._start, 10) || 0; + const end = + query._end !== undefined + ? parseInt(query._end, 10) + : start + (parseInt(query._limit, 10) || items.length); + return items.slice(start, end); + } + if (query._limit !== undefined) { + return items.slice(0, parseInt(query._limit, 10) || items.length); + } + return items; +} + +function setLinkHeader(res, req, page, limit, total) { + const last = Math.max(1, Math.ceil(total / limit)); + const base = `${req.protocol}://${req.get("host")}${req.baseUrl}${req.path}`; + const link = (p) => { + const params = new URLSearchParams({ ...req.query, _page: p, _limit: limit }); + return `<${base}?${params}>`; + }; + const parts = []; + if (page > 1) parts.push(`${link(1)}; rel="first"`, `${link(page - 1)}; rel="prev"`); + if (page < last) parts.push(`${link(page + 1)}; rel="next"`, `${link(last)}; rel="last"`); + if (parts.length) res.setHeader("Link", parts.join(", ")); +} + +function nextId(collection) { + const numericIds = collection + .map((r) => Number(r.id)) + .filter((n) => Number.isFinite(n)); + return numericIds.length ? Math.max(...numericIds) + 1 : 1; +} + +module.exports = { createJsonRouter }; diff --git a/server/utils/verifyData.js b/server/utils/verifyData.js index 521f027..c7ed5fa 100644 --- a/server/utils/verifyData.js +++ b/server/utils/verifyData.js @@ -2,9 +2,20 @@ const { getFromFile } = require("./utils"); const verifyData = (req, res, next) => { - const { method, originalUrl, body } = req; + const { method, originalUrl } = req; + // Reads don't carry a body to validate. Bail out before touching req.body or + // parsing the path — under Express 5 req.body is undefined on bodyless + // requests, which the shape checks below would otherwise choke on. + if (method === "GET" || method === "DELETE") { + return next(); + } + const body = req.body || {}; try { - const [baseParent, endPoint] = originalUrl.split("/").filter((d) => d); + // Strip any query string so the resource name resolves cleanly. + const [baseParent, endPoint] = originalUrl + .split("?")[0] + .split("/") + .filter((d) => d); const dataPath = path.join(__dirname, `../api/${baseParent}.json`); const data = getFromFile(dataPath)[endPoint][0]; From 922d3ec00dfbaed9b4ed4d775a6cb722b531b932 Mon Sep 17 00:00:00 2001 From: jermbo Date: Thu, 9 Jul 2026 08:53:42 -0400 Subject: [PATCH 12/26] refactor: remove deprecated APIs and clean up JSON files - Deleted unused API entries for Bitcoin and Rick and Morty from apiList.js and GeneratedAPIList.js. - Removed bitcoin.json and its backup, streamlining the API structure. - Updated checkdiff.sh to eliminate checks for removed JSON files. - Enhanced coffee.json with improved descriptions and ingredient translations for better clarity. - Corrected historical inaccuracies in presidents.json, including name and term adjustments for several presidents. --- checkdiff.sh | 10 - server/GeneratedAPIList.js | 25 -- server/api/bitcoin.json | 12 - server/api/coffee.json | 142 ++++----- server/api/coffee.json.backup | 142 ++++----- server/api/movies.json | 133 +++++++- server/api/movies.json.backup | 133 +++++++- server/api/presidents.json | 24 +- server/api/presidents.json.backup | 26 +- server/api/rickandmorty.json | 477 ---------------------------- server/api/rickandmorty.json.backup | 477 ---------------------------- server/api/thestates.json | 110 +++---- server/api/thestates.json.backup | 110 +++---- server/apiList.js | 19 -- 14 files changed, 543 insertions(+), 1297 deletions(-) delete mode 100644 server/api/bitcoin.json delete mode 100644 server/api/rickandmorty.json delete mode 100644 server/api/rickandmorty.json.backup diff --git a/checkdiff.sh b/checkdiff.sh index f12077c..d3d55f7 100755 --- a/checkdiff.sh +++ b/checkdiff.sh @@ -15,11 +15,6 @@ if [ "$DIFF" != "" ] then echo "beers modified" fi -DIFF=$(diff bitcoin.json bitcoin.json.backup) -if [ "$DIFF" != "" ] -then - echo "bitcoin modified" -fi DIFF=$(diff cartoons.json cartoons.json.backup) if [ "$DIFF" != "" ] then @@ -95,11 +90,6 @@ if [ "$DIFF" != "" ] then echo "recipes modified" fi -DIFF=$(diff rickandmorty.json rickandmorty.json.backup) -if [ "$DIFF" != "" ] -then - echo "rickandmorty modified" -fi DIFF=$(diff simpsons.json simpsons.json.backup) if [ "$DIFF" != "" ] then diff --git a/server/GeneratedAPIList.js b/server/GeneratedAPIList.js index 2ebe902..330d937 100644 --- a/server/GeneratedAPIList.js +++ b/server/GeneratedAPIList.js @@ -241,19 +241,6 @@ module.exports = [ }, endpoints: ["recipes"], }, - { - name: "rickandmorty", - link: "rickandmorty", - metaData: { - title: "Rick And Morty", - longDesc: - "Get all the Rick-iest Episodes, Locations and Characters from a copy of the https://rickandmortyapi.com data. That's the way Rick would have done it!", - desc: "API for all current Rick & Morty episodes, locations and characters", - featured: false, - categories: ["cartoon", "tv", "entertainment"], - }, - endpoints: ["characters", "episodes", "locations"], - }, { name: "simpsons", link: "simpsons", @@ -338,17 +325,5 @@ module.exports = [ categories: ["funny"], }, endpoints: ["goodJokes"], - }, - { - name: "bitcoin", - link: "bitcoin", - metaData: { - title: "Bitcoin (historical data)", - longDesc: "You've wanted it and now we got it. Going back from January 2022 to August 2010", - desc: "Bitcoin Historical Data from August 2010 to January 2022", - featured: false, - categories: ["crypto","prices"], - }, - endpoints: ["historical_prices"], }, ]; diff --git a/server/api/bitcoin.json b/server/api/bitcoin.json deleted file mode 100644 index cb3aa34..0000000 --- a/server/api/bitcoin.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "metaData": [ - { - "title": "Bitcoin", - "longDesc": "Bitcoin Facts (historically. nothing is live)", - "desc": "Bitcoin is a wonder, and it's interesting to look back and certain facts", - "featured": false, - "categories": ["crypto", "prices"] - } - ], - "historical_prices": [{"Date":"01/01/2022","Price":41321,"Open":46217.5,"High":47944.9,"ChangePercentFromLastMonth":-10.6,"Volume":"517.02K"},{"Date":"12/01/2021","Price":46219.5,"Open":56891.7,"High":59064.3,"ChangePercentFromLastMonth":-18.75,"Volume":"1.90M"},{"Date":"11/01/2021","Price":56882.9,"Open":61310.1,"High":68990.6,"ChangePercentFromLastMonth":-7.22,"Volume":"1.85M"},{"Date":"10/01/2021","Price":61309.6,"Open":43824.4,"High":66967.1,"ChangePercentFromLastMonth":39.9,"Volume":"2.18M"},{"Date":"09/01/2021","Price":43823.3,"Open":47129.2,"High":52885.3,"ChangePercentFromLastMonth":-7.02,"Volume":"2.21M"},{"Date":"08/01/2021","Price":47130.4,"Open":41510,"High":50498.8,"ChangePercentFromLastMonth":13.42,"Volume":"2.14M"},{"Date":"07/01/2021","Price":41553.7,"Open":35030.7,"High":42285.3,"ChangePercentFromLastMonth":18.63,"Volume":"2.44M"},{"Date":"06/01/2021","Price":35026.9,"Open":37294.3,"High":41318,"ChangePercentFromLastMonth":-6.09,"Volume":"4.14M"},{"Date":"05/01/2021","Price":37298.6,"Open":57719.1,"High":59523.9,"ChangePercentFromLastMonth":-35.38,"Volume":"5.33M"},{"Date":"03/01/2021","Price":57720.3,"Open":58763.2,"High":64778,"ChangePercentFromLastMonth":-1.78,"Volume":"2.97M"},{"Date":"03/01/2021","Price":58763.7,"Open":45160.5,"High":61795.8,"ChangePercentFromLastMonth":30.11,"Volume":"3.01M"},{"Date":"02/01/2021","Price":45164,"Open":33106.8,"High":58335.1,"ChangePercentFromLastMonth":36.41,"Volume":"4.01M"},{"Date":"01/01/2021","Price":33108.1,"Open":28951.7,"High":41921.7,"ChangePercentFromLastMonth":14.37,"Volume":"5.50M"},{"Date":"12/01/2020","Price":28949.4,"Open":19697.8,"High":29298.8,"ChangePercentFromLastMonth":46.97,"Volume":"3.85M"},{"Date":"11/01/2020","Price":19698.1,"Open":18394.6,"High":19831.2,"ChangePercentFromLastMonth":42.77,"Volume":"4.05M"},{"Date":"10/01/2020","Price":13797.3,"Open":10776.6,"High":14065.4,"ChangePercentFromLastMonth":28.04,"Volume":"2.41M"},{"Date":"09/01/2020","Price":10776.1,"Open":11644.2,"High":12045.9,"ChangePercentFromLastMonth":-7.46,"Volume":"83.88M"},{"Date":"08/01/2020","Price":11644.2,"Open":11333.2,"High":12444.1,"ChangePercentFromLastMonth":2.74,"Volume":"15.39M"},{"Date":"07/01/2020","Price":11333.4,"Open":10961.1,"High":11434.8,"ChangePercentFromLastMonth":24.06,"Volume":"13.21M"},{"Date":"06/01/2020","Price":9135.4,"Open":9454.5,"High":10301.8,"ChangePercentFromLastMonth":-3.38,"Volume":"15.35M"},{"Date":"05/01/2020","Price":9454.8,"Open":8628.6,"High":10033,"ChangePercentFromLastMonth":9.57,"Volume":"38.48M"},{"Date":"03/01/2020","Price":8629,"Open":6412.4,"High":9437.5,"ChangePercentFromLastMonth":34.56,"Volume":"39.41M"},{"Date":"03/01/2020","Price":6412.5,"Open":8543.8,"High":9180.8,"ChangePercentFromLastMonth":-24.94,"Volume":"48.24M"},{"Date":"02/01/2020","Price":8543.7,"Open":9349.3,"High":10482.6,"ChangePercentFromLastMonth":-8.62,"Volume":"23.76M"},{"Date":"01/01/2020","Price":9349.1,"Open":7196.4,"High":9569,"ChangePercentFromLastMonth":29.91,"Volume":"23.56M"},{"Date":"12/01/2019","Price":7196.4,"Open":7546.5,"High":7702.2,"ChangePercentFromLastMonth":-4.64,"Volume":"21.03M"},{"Date":"11/01/2019","Price":7546.6,"Open":9153.1,"High":9500.4,"ChangePercentFromLastMonth":-17.55,"Volume":"21.33M"},{"Date":"10/01/2019","Price":9152.6,"Open":8285,"High":10540,"ChangePercentFromLastMonth":10.48,"Volume":"19.93M"},{"Date":"09/01/2019","Price":8284.3,"Open":9594.7,"High":10896.2,"ChangePercentFromLastMonth":-13.65,"Volume":"13.58M"},{"Date":"08/01/2019","Price":9594.4,"Open":10081.9,"High":12291.9,"ChangePercentFromLastMonth":-4.84,"Volume":"17.53M"},{"Date":"07/01/2019","Price":10082,"Open":10821.4,"High":13134.4,"ChangePercentFromLastMonth":-6.81,"Volume":"23.61M"},{"Date":"06/01/2019","Price":10818.6,"Open":8556.9,"High":13929.8,"ChangePercentFromLastMonth":26.41,"Volume":"22.96M"},{"Date":"05/01/2019","Price":8558.3,"Open":5321.1,"High":9045.9,"ChangePercentFromLastMonth":60.85,"Volume":"44.06M"},{"Date":"03/01/2019","Price":5320.8,"Open":4102.3,"High":5594.4,"ChangePercentFromLastMonth":29.7,"Volume":"54.03M"},{"Date":"03/01/2019","Price":4102.3,"Open":3816.7,"High":4138.1,"ChangePercentFromLastMonth":7.49,"Volume":"81.62M"},{"Date":"02/01/2019","Price":3816.6,"Open":3437.7,"High":4194.2,"ChangePercentFromLastMonth":11.04,"Volume":"23.13M"},{"Date":"01/01/2019","Price":3437.2,"Open":3709.5,"High":4070.5,"ChangePercentFromLastMonth":-7.34,"Volume":"15.72M"},{"Date":"12/01/2018","Price":3709.4,"Open":4038.7,"High":4316.1,"ChangePercentFromLastMonth":-8.18,"Volume":"15.70M"},{"Date":"11/01/2018","Price":4039.7,"Open":6365.9,"High":6594.3,"ChangePercentFromLastMonth":-36.54,"Volume":"8.71M"},{"Date":"10/01/2018","Price":6365.9,"Open":6635.2,"High":7358.4,"ChangePercentFromLastMonth":-4.06,"Volume":"58.80M"},{"Date":"09/01/2018","Price":6635.2,"Open":7032.4,"High":7409.9,"ChangePercentFromLastMonth":-5.67,"Volume":"154.15M"},{"Date":"08/01/2018","Price":7033.8,"Open":7728.5,"High":7753.2,"ChangePercentFromLastMonth":-9,"Volume":"63.25M"},{"Date":"07/01/2018","Price":7729.4,"Open":6398.5,"High":8484.6,"ChangePercentFromLastMonth":20.79,"Volume":"7.06M"},{"Date":"06/01/2018","Price":6398.9,"Open":7502.5,"High":7775,"ChangePercentFromLastMonth":-14.71,"Volume":"4.78M"},{"Date":"05/01/2018","Price":7502.6,"Open":9245.1,"High":9992.8,"ChangePercentFromLastMonth":-18.85,"Volume":"5.04M"},{"Date":"03/01/2018","Price":9245.1,"Open":6939.1,"High":9753.1,"ChangePercentFromLastMonth":33.25,"Volume":"6.22M"},{"Date":"03/01/2018","Price":6938.2,"Open":10335.1,"High":11506.9,"ChangePercentFromLastMonth":-32.86,"Volume":"7.61M"},{"Date":"02/01/2018","Price":10333.9,"Open":10266.2,"High":11791.5,"ChangePercentFromLastMonth":0.67,"Volume":"8.54M"},{"Date":"01/01/2018","Price":10265.4,"Open":13850.5,"High":17252.8,"ChangePercentFromLastMonth":-25.88,"Volume":"4.84M"},{"Date":"12/01/2017","Price":13850.4,"Open":9947.1,"High":19870.6,"ChangePercentFromLastMonth":39.25,"Volume":"5.12M"},{"Date":"11/01/2017","Price":9946.8,"Open":6449.1,"High":11417.8,"ChangePercentFromLastMonth":54.18,"Volume":"3.96M"},{"Date":"10/01/2017","Price":6451.2,"Open":4360.6,"High":6467.2,"ChangePercentFromLastMonth":47.94,"Volume":"2.98M"},{"Date":"09/01/2017","Price":4360.6,"Open":4735.1,"High":4976.5,"ChangePercentFromLastMonth":-7.91,"Volume":"3.93M"},{"Date":"08/01/2017","Price":4735.1,"Open":2883.3,"High":4765.1,"ChangePercentFromLastMonth":64.23,"Volume":"3.13M"},{"Date":"07/01/2017","Price":2883.3,"Open":2480.6,"High":2932.8,"ChangePercentFromLastMonth":16.23,"Volume":"3.75M"},{"Date":"06/01/2017","Price":2480.6,"Open":2303.3,"High":2985.1,"ChangePercentFromLastMonth":7.7,"Volume":"3.35M"},{"Date":"05/01/2017","Price":2303.3,"Open":1351.9,"High":2781.8,"ChangePercentFromLastMonth":70.38,"Volume":"3.45M"},{"Date":"03/01/2017","Price":1351.9,"Open":1079.1,"High":1358.9,"ChangePercentFromLastMonth":25.28,"Volume":"1.56M"},{"Date":"03/01/2017","Price":1079.1,"Open":1189.3,"High":1330.4,"ChangePercentFromLastMonth":-9.26,"Volume":"2.68M"},{"Date":"02/01/2017","Price":1189.3,"Open":965.5,"High":1211.7,"ChangePercentFromLastMonth":23.18,"Volume":"1.31M"},{"Date":"01/01/2017","Price":965.5,"Open":963.4,"High":1150.6,"ChangePercentFromLastMonth":0.22,"Volume":"2.21M"},{"Date":"12/01/2016","Price":963.4,"Open":742.5,"High":982.6,"ChangePercentFromLastMonth":29.75,"Volume":"1.27M"},{"Date":"11/01/2016","Price":742.5,"Open":698.7,"High":755.3,"ChangePercentFromLastMonth":6.27,"Volume":"1.23M"},{"Date":"10/01/2016","Price":698.7,"Open":608.1,"High":720.2,"ChangePercentFromLastMonth":14.89,"Volume":"905.66K"},{"Date":"09/01/2016","Price":608.1,"Open":573.9,"High":705,"ChangePercentFromLastMonth":5.97,"Volume":"748.55K"},{"Date":"08/01/2016","Price":573.9,"Open":621.9,"High":627.9,"ChangePercentFromLastMonth":-7.72,"Volume":"1.08M"},{"Date":"07/01/2016","Price":621.9,"Open":670,"High":701.5,"ChangePercentFromLastMonth":-7.19,"Volume":"1.63M"},{"Date":"06/01/2016","Price":670,"Open":528.9,"High":776,"ChangePercentFromLastMonth":26.68,"Volume":"3.55M"},{"Date":"05/01/2016","Price":528.9,"Open":448.5,"High":548,"ChangePercentFromLastMonth":17.92,"Volume":"1.66M"},{"Date":"03/01/2016","Price":448.5,"Open":415.7,"High":468.9,"ChangePercentFromLastMonth":7.91,"Volume":"1.39M"},{"Date":"03/01/2016","Price":415.7,"Open":436.2,"High":439,"ChangePercentFromLastMonth":-4.71,"Volume":"1.66M"},{"Date":"02/01/2016","Price":436.2,"Open":369.8,"High":447.6,"ChangePercentFromLastMonth":17.95,"Volume":"1.99M"},{"Date":"01/01/2016","Price":369.8,"Open":430,"High":462.9,"ChangePercentFromLastMonth":-13.98,"Volume":"2.49M"},{"Date":"12/01/2015","Price":430,"Open":378,"High":467.7,"ChangePercentFromLastMonth":13.75,"Volume":"3.20M"},{"Date":"11/01/2015","Price":378,"Open":311.2,"High":492.8,"ChangePercentFromLastMonth":21.44,"Volume":"4.29M"},{"Date":"10/01/2015","Price":311.2,"Open":235.9,"High":334.9,"ChangePercentFromLastMonth":31.92,"Volume":"2.28M"},{"Date":"09/01/2015","Price":235.9,"Open":229.5,"High":246.4,"ChangePercentFromLastMonth":2.82,"Volume":"1.65M"},{"Date":"08/01/2015","Price":229.5,"Open":283.7,"High":285.7,"ChangePercentFromLastMonth":-19.12,"Volume":"2.22M"},{"Date":"07/01/2015","Price":283.7,"Open":264.1,"High":315.9,"ChangePercentFromLastMonth":7.42,"Volume":"1.86M"},{"Date":"06/01/2015","Price":264.1,"Open":229.8,"High":268.7,"ChangePercentFromLastMonth":14.91,"Volume":"1.75M"},{"Date":"05/01/2015","Price":229.8,"Open":235.8,"High":247.9,"ChangePercentFromLastMonth":-2.52,"Volume":"1.64M"},{"Date":"03/01/2015","Price":235.8,"Open":244.1,"High":261.5,"ChangePercentFromLastMonth":-3.43,"Volume":"2.07M"},{"Date":"03/01/2015","Price":244.1,"Open":254.1,"High":301,"ChangePercentFromLastMonth":-3.9,"Volume":"2.97M"},{"Date":"02/01/2015","Price":254.1,"Open":218.5,"High":264.6,"ChangePercentFromLastMonth":16.27,"Volume":"2.09M"},{"Date":"01/01/2015","Price":218.5,"Open":318.2,"High":321.4,"ChangePercentFromLastMonth":-31.34,"Volume":"1.56M"},{"Date":"12/01/2014","Price":318.2,"Open":374.9,"High":384.9,"ChangePercentFromLastMonth":-15.12,"Volume":"847.29K"},{"Date":"11/01/2014","Price":374.9,"Open":337.9,"High":480.5,"ChangePercentFromLastMonth":10.97,"Volume":"711.11K"},{"Date":"10/01/2014","Price":337.9,"Open":388.2,"High":407.7,"ChangePercentFromLastMonth":-12.96,"Volume":"569.00K"},{"Date":"09/01/2014","Price":388.2,"Open":481.8,"High":498.5,"ChangePercentFromLastMonth":-19.43,"Volume":"295.62K"},{"Date":"08/01/2014","Price":481.8,"Open":589.5,"High":608.2,"ChangePercentFromLastMonth":-18.28,"Volume":"126.17K"},{"Date":"07/01/2014","Price":589.5,"Open":635.1,"High":652.5,"ChangePercentFromLastMonth":-7.18,"Volume":"107.22K"},{"Date":"06/01/2014","Price":635.1,"Open":627.9,"High":676.5,"ChangePercentFromLastMonth":1.15,"Volume":"111.81K"},{"Date":"05/01/2014","Price":627.9,"Open":445.6,"High":629,"ChangePercentFromLastMonth":40.9,"Volume":"85.75K"},{"Date":"03/01/2014","Price":445.6,"Open":444.7,"High":549,"ChangePercentFromLastMonth":0.22,"Volume":"161.16K"},{"Date":"03/01/2014","Price":444.7,"Open":573.9,"High":695.4,"ChangePercentFromLastMonth":-22.53,"Volume":"94.27K"},{"Date":"02/01/2014","Price":573.9,"Open":938.8,"High":969.2,"ChangePercentFromLastMonth":-38.87,"Volume":"996.35K"},{"Date":"01/01/2014","Price":938.8,"Open":805.9,"High":1093.4,"ChangePercentFromLastMonth":16.49,"Volume":"306.25K"},{"Date":"12/01/2013","Price":805.9,"Open":1205.7,"High":1239.9,"ChangePercentFromLastMonth":-33.15,"Volume":"920.80K"},{"Date":"11/01/2013","Price":1205.7,"Open":211.2,"High":1241.9,"ChangePercentFromLastMonth":470.94,"Volume":"1.13M"},{"Date":"10/01/2013","Price":211.2,"Open":141.9,"High":233.4,"ChangePercentFromLastMonth":48.82,"Volume":"753.58K"},{"Date":"09/01/2013","Price":141.9,"Open":141,"High":148.9,"ChangePercentFromLastMonth":0.64,"Volume":"451.29K"},{"Date":"08/01/2013","Price":141,"Open":106.2,"High":148.7,"ChangePercentFromLastMonth":32.76,"Volume":"604.91K"},{"Date":"07/01/2013","Price":106.2,"Open":97.5,"High":111.7,"ChangePercentFromLastMonth":8.92,"Volume":"1.14M"},{"Date":"06/01/2013","Price":97.5,"Open":128.8,"High":130.1,"ChangePercentFromLastMonth":-24.31,"Volume":"1.05M"},{"Date":"05/01/2013","Price":128.8,"Open":139.2,"High":140.1,"ChangePercentFromLastMonth":-7.48,"Volume":"2.07M"},{"Date":"03/01/2013","Price":139.2,"Open":93,"High":266,"ChangePercentFromLastMonth":49.66,"Volume":"4.73M"},{"Date":"03/01/2013","Price":93,"Open":33.4,"High":95.7,"ChangePercentFromLastMonth":178.7,"Volume":"2.12M"},{"Date":"02/01/2013","Price":33.4,"Open":20.4,"High":34.5,"ChangePercentFromLastMonth":63.55,"Volume":"1.58M"},{"Date":"01/01/2013","Price":20.4,"Open":13.5,"High":21.4,"ChangePercentFromLastMonth":51.07,"Volume":"1.46M"},{"Date":"12/01/2012","Price":13.5,"Open":12.6,"High":13.9,"ChangePercentFromLastMonth":7.48,"Volume":"876.92K"},{"Date":"11/01/2012","Price":12.6,"Open":11.2,"High":12.6,"ChangePercentFromLastMonth":12.23,"Volume":"804.19K"},{"Date":"10/01/2012","Price":11.2,"Open":12.4,"High":13.1,"ChangePercentFromLastMonth":-9.68,"Volume":"1.15M"},{"Date":"09/01/2012","Price":12.4,"Open":10.2,"High":12.7,"ChangePercentFromLastMonth":22.05,"Volume":"959.78K"},{"Date":"08/01/2012","Price":10.2,"Open":9.4,"High":15.4,"ChangePercentFromLastMonth":8.66,"Volume":"2.45M"},{"Date":"07/01/2012","Price":9.4,"Open":6.7,"High":9.7,"ChangePercentFromLastMonth":39.76,"Volume":"1.90M"},{"Date":"06/01/2012","Price":6.7,"Open":5.2,"High":6.8,"ChangePercentFromLastMonth":29.15,"Volume":"1.38M"},{"Date":"05/01/2012","Price":5.2,"Open":4.9,"High":5.2,"ChangePercentFromLastMonth":4.65,"Volume":"1.24M"},{"Date":"03/01/2012","Price":4.9,"Open":4.9,"High":5.5,"ChangePercentFromLastMonth":0,"Volume":"1.66M"},{"Date":"03/01/2012","Price":4.9,"Open":4.9,"High":5.4,"ChangePercentFromLastMonth":0,"Volume":"1.76M"},{"Date":"02/01/2012","Price":4.9,"Open":5.5,"High":6.2,"ChangePercentFromLastMonth":-11.31,"Volume":"2.84M"},{"Date":"01/01/2012","Price":5.5,"Open":4.7,"High":7.2,"ChangePercentFromLastMonth":16.1,"Volume":"3.21M"},{"Date":"12/01/2011","Price":4.7,"Open":3,"High":5,"ChangePercentFromLastMonth":58.92,"Volume":"1.90M"},{"Date":"11/01/2011","Price":3,"Open":3.3,"High":3.4,"ChangePercentFromLastMonth":-8.62,"Volume":"1.97M"},{"Date":"10/01/2011","Price":3.3,"Open":5.1,"High":5.3,"ChangePercentFromLastMonth":-36.77,"Volume":"1.73M"},{"Date":"09/01/2011","Price":5.1,"Open":8.2,"High":8.7,"ChangePercentFromLastMonth":-37.32,"Volume":"1.49M"},{"Date":"08/01/2011","Price":8.2,"Open":13.4,"High":13.6,"ChangePercentFromLastMonth":-38.58,"Volume":"1.22M"},{"Date":"07/01/2011","Price":13.4,"Open":16.1,"High":16.7,"ChangePercentFromLastMonth":-17.08,"Volume":"1.05M"},{"Date":"06/01/2011","Price":16.1,"Open":8.7,"High":31.9,"ChangePercentFromLastMonth":84.21,"Volume":"1.36M"},{"Date":"05/01/2011","Price":8.7,"Open":3.5,"High":9.5,"ChangePercentFromLastMonth":149.71,"Volume":"949.02K"},{"Date":"03/01/2011","Price":3.5,"Open":0.8,"High":4.2,"ChangePercentFromLastMonth":346.09,"Volume":"868.76K"},{"Date":"03/01/2011","Price":0.8,"Open":0.9,"High":1,"ChangePercentFromLastMonth":-8.77,"Volume":"243.30K"},{"Date":"02/01/2011","Price":0.9,"Open":0.5,"High":1.1,"ChangePercentFromLastMonth":65.38,"Volume":"367.30K"},{"Date":"01/01/2011","Price":0.5,"Open":0.3,"High":0.9,"ChangePercentFromLastMonth":73.33,"Volume":"377.75K"},{"Date":"12/01/2010","Price":0.3,"Open":0.2,"High":0.3,"ChangePercentFromLastMonth":44.09,"Volume":"263.65K"},{"Date":"11/01/2010","Price":0.2,"Open":0.2,"High":0.5,"ChangePercentFromLastMonth":0,"Volume":"826.25K"},{"Date":"10/01/2010","Price":0.2,"Open":0.1,"High":0.2,"ChangePercentFromLastMonth":210.99,"Volume":"1.11M"},{"Date":"09/01/2010","Price":0.1,"Open":0.1,"High":0.2,"ChangePercentFromLastMonth":0,"Volume":"216.81K"},{"Date":"08/01/2010","Price":0.1,"Open":0.1,"High":0.1,"ChangePercentFromLastMonth":0,"Volume":"221.74K"}] -} \ No newline at end of file diff --git a/server/api/coffee.json b/server/api/coffee.json index 0b383ff..4f989f4 100644 --- a/server/api/coffee.json +++ b/server/api/coffee.json @@ -14,7 +14,7 @@ "hot": [ { "title": "Black Coffee", - "description": "Svart kaffe är så enkelt som det kan bli med malda kaffebönor dränkta i hett vatten, serverat varmt. Och om du vill låta fancy kan du kalla svart kaffe med sitt rätta namn: café noir.", + "description": "Black coffee is as simple as it gets with ground coffee beans steeped in hot water, served warm. And if you want to sound fancy, you can call black coffee by its proper name: cafe noir.", "ingredients": [ "Coffee" ], @@ -23,31 +23,31 @@ }, { "title": "Latte", - "description": "Som den mest populära kaffedrycken där ute består latte av en skvätt espresso och ångad mjölk med bara en gnutta skum. Den kan beställas utan smak eller med smak av allt från vanilj till pumpa kryddor.", + "description": "As the most popular coffee drink out there, the latte is made with a shot of espresso and steamed milk, with just a touch of foam. It can be ordered plain or flavored with everything from vanilla to pumpkin spice.", "ingredients": [ "Espresso", - "Ångad mjölk" + "Steamed milk" ], "image": "https://images.unsplash.com/photo-1561882468-9110e03e0f78?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTl8fGxhdHRlfGVufDB8fDB8fHww", "id": 2 }, { "title": "Caramel Latte", - "description": "Om du gillar latte med en speciell smak kan karamell latte vara det bästa alternativet för att ge dig en upplevelse av den naturliga sötman och krämigheten hos ångad mjölk och karamell.", + "description": "If you like flavored lattes, a caramel latte is a great choice, combining espresso, steamed milk, and caramel for a naturally sweet and creamy drink.", "ingredients": [ "Espresso", - "Ångad mjölk", - "Karamellsirap" + "Steamed milk", + "Caramel syrup" ], "image": "https://images.unsplash.com/photo-1599398054066-846f28917f38?auto=format&fit=crop&q=80&w=1887&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "id": 3 }, { "title": "Cappuccino", - "description": "Cappuccino är en latte som är gjord med mer skum än ångad mjölk, ofta med ett strö av kakaopulver eller kanel på toppen. Ibland kan du hitta variationer som använder grädde istället för mjölk eller sådana som tillsätter smakämnen också.", + "description": "A cappuccino is an espresso drink with steamed milk and a thick layer of foam, often topped with cocoa powder or cinnamon. Some variations use cream instead of milk or add flavored syrups.", "ingredients": [ "Espresso", - "Ångad mjölk", + "Steamed milk", "Foam" ], "image": "https://images.unsplash.com/photo-1557006021-b85faa2bc5e2?auto=format&fit=crop&q=80&w=1887&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", @@ -55,17 +55,17 @@ }, { "title": "Americano", - "description": "Med en liknande smak som svart kaffe består americano av en espresso skott utspätt med hett vatten.", + "description": "With a flavor similar to black coffee, an americano is made by diluting a shot of espresso with hot water.", "ingredients": [ "Espresso", - "Hett vatten" + "Hot water" ], "image": "https://images.unsplash.com/photo-1532004491497-ba35c367d634?auto=format&fit=crop&q=80&w=1887&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "id": 5 }, { "title": "Espresso", - "description": "Ett espressoskott kan serveras ensamt eller användas som grund för de flesta kaffedrycker, som latte och macchiato.", + "description": "A shot of espresso can be served on its own or used as the base for most coffee drinks, like lattes and macchiatos.", "ingredients": [ "Espresso" ], @@ -74,7 +74,7 @@ }, { "title": "Macchiato", - "description": "Macchiaton är en annan espresso-baserad dryck som har en liten mängd skum på toppen. Det är det glada mellanrummet mellan en cappuccino och en doppio.", + "description": "An espresso macchiato is a shot of espresso marked with a small dollop of foam. It is stronger and smaller than a cappuccino or latte.", "ingredients": [ "Espresso", "Foam" @@ -84,146 +84,146 @@ }, { "title": "Mocha", - "description": "För alla chokladälskare där ute kommer ni att bli förälskade i en mocha. Mocha är en choklad-espressodryck med ångad mjölk och skum.", + "description": "For all the chocolate lovers out there, a mocha is an easy favorite. It is a chocolate espresso drink made with steamed milk and foam.", "ingredients": [ "Espresso", - "Ångad mjölk", - "Choklad" + "Steamed milk", + "Chocolate" ], "image": "https://images.unsplash.com/photo-1607260550778-aa9d29444ce1?auto=format&fit=crop&q=80&w=1887&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "id": 8 }, { "title": "Hot Chocolate", - "description": "Under kalla vinterdagar får en kopp varm choklad dig att känna dig bekväm och lycklig. Den får dig också att må bra eftersom den innehåller energigivande koffein.", + "description": "A classic warm drink made with chocolate and steamed milk. Rich, cozy, and especially good on cold days.", "ingredients": [ - "Choklad", - "Mjölk" + "Chocolate", + "Milk" ], "image": "https://images.unsplash.com/photo-1542990253-0d0f5be5f0ed?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NDh8fGhvdCUyMGNob2NvbGF0ZXxlbnwwfHwwfHx8MA%3D%3D", "id": 9 }, { "title": "Chai Latte", - "description": "Om du letar efter en smakfull varm dryck mitt i vintern, välj chai latte. Kombinationen av kardemumma och kanel ger en underbar smak.", + "description": "A spiced tea latte made with black tea, steamed milk, and warming spices such as ginger, cardamom, and cinnamon.", "ingredients": [ - "Te", - "Mjölk", - "Ingefära", - "Kardemumma", - "Kanel" + "Tea", + "Milk", + "Ginger", + "Cardamom", + "Cinnamon" ], "image": "https://images.unsplash.com/photo-1578899952107-9c390f1af1b7?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTJ8fGNoYWklMjBsYXR0ZXxlbnwwfHwwfHx8MA%3D%3D", "id": 10 }, { "title": "Matcha Latte", - "description": "Matcha latte är en grön, hälsosam kaffedryck med finkrossad matcha-te och mjölk, erbjuder mild sötma, en unik smak och en mild koffeinkick.", + "description": "A matcha latte is a green tea drink made with finely ground matcha and milk, offering mild sweetness, a distinctive flavor, and a gentle caffeine boost.", "ingredients": [ - "Matcha-pulver", - "Mjölk", - "Socker*" + "Matcha powder", + "Milk", + "Sugar*" ], "image": "https://images.unsplash.com/photo-1536256263959-770b48d82b0a?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8M3x8bWF0Y2hhJTIwbGF0dGV8ZW58MHx8MHx8fDA%3D", "id": 11 }, { "title": "Seasonal Brew", - "description": "Säsongs kaffe med olika smaktoner som karamell, frukt och choklad", + "description": "A seasonal coffee with flavor notes that can include caramel, fruit, and chocolate.", "ingredients": [ - "Kaffe" + "Coffee" ], "image": "https://images.unsplash.com/photo-1611162458324-aae1eb4129a4?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTg1fHxibGFjayUyMGNvZmZlZXxlbnwwfHwwfHx8MA%3D%3D", "id": 12 }, { - "title": "Svart Te", - "description": "Svart te föddes i Kina. Det är tillverkat av blad från en växt som kallas Camellia och kan smaksättas olika med frukter till exempel. En trevlig, varm, smakfull och aromatisk dryck som passar till vardagen.", + "title": "Black Tea", + "description": "Black tea is made from the leaves of the Camellia sinensis plant. It can be enjoyed plain or flavored with fruit, spices, or other additions.", "ingredients": [ - "Te" + "Tea" ], "image": "https://images.unsplash.com/photo-1576092768241-dec231879fc3?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MjB8fHRlYXxlbnwwfHwwfHx8MA%3D%3D", "id": 13 }, { - "title": "Islatte", - "description": "Iced latte är en kyld kaffedryck som görs genom att blanda espresso och kyld mjölk. Den serveras med isbitar och är även känd som cafè latte iced eller latte on the rocks.", + "title": "Iced Latte", + "description": "An iced latte is espresso poured over ice and cold milk. Sweet syrup is optional, and it is also known as an iced cafe latte.", "ingredients": [ "Espresso", - "Mjölk", - "Is", - "Sirap" + "Milk", + "Ice", + "Syrup" ], "image": "https://images.unsplash.com/photo-1517701550927-30cf4ba1dba5?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NHx8aWNlZCUyMGxhdHRlfGVufDB8fDB8fHww", "id": 14 }, { - "title": "Islatte Mocha", - "description": "Iced latte Mocha är en kombination av latte och mocha, som i sig är en kombination av choklad och kaffe. Den ger kalla dryckälskare en läcker upplevelse av choklad och kaffe.", + "title": "Iced Mocha Latte", + "description": "An iced mocha latte combines a latte with mocha flavors, bringing together chocolate and coffee in a rich and refreshing drink.", "ingredients": [ "Espresso", - "Is", - "Mjölk", - "Choklad " + "Ice", + "Milk", + "Chocolate" ], "image": "https://images.unsplash.com/photo-1642647391072-6a2416f048e5?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mzh8fGljZWQlMjBtb2NoYSUyMGxhdHRlfGVufDB8fDB8fHww", "id": 15 }, { - "title": "Frapino Caramel", - "description": "Det är en blandad eller bättre sagt skakad kaffe med vispad grädde på toppen. Ett måste för varma sommardagar.", + "title": "Blended Caramel Coffee", + "description": "A blended iced coffee with caramel syrup, milk, and ice, topped with whipped cream and caramel sauce.", "ingredients": [ - "coffee", - "Is", - "Mjölk", - "Karamellsirap", - "Vispgrädde*", - "Karamellsås" + "Coffee", + "Ice", + "Milk", + "Caramel syrup", + "Whipped cream*", + "Caramel sauce" ], "image": "https://images.unsplash.com/photo-1662047102608-a6f2e492411f?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NHx8ZnJhcGlubyUyMGNhcmFtZWx8ZW58MHx8MHx8fDA%3D", "id": 16 }, { - "title": "Frapino Mocka", - "description": "Ännu en berömd och utsökt kall dryck för dem som föredrar choklad. Tänk dig smaken av en shake med choklad och vispad grädde på toppen.", + "title": "Blended Mocha Coffee", + "description": "A blended iced mocha with coffee, milk, cocoa, and ice, finished with whipped cream for a chocolate shake-like treat.", "ingredients": [ "Coffee", - "Is", - "Mjölk", + "Ice", + "Milk", "Cocoa", - "Vispgrädde*" + "Whipped cream*" ], "image": "https://images.unsplash.com/photo-1530373239216-42518e6b4063?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NHx8ZnJhcGlubyUyMG1vY2hhfGVufDB8fDB8fHww", "id": 17 }, { - "title": "Apelsinjuice", - "description": "Vi har inget att säga om vår nypressade apelsinjuice. Du måste prova den själv.", + "title": "Orange Juice", + "description": "Freshly squeezed orange juice served cold over ice.", "ingredients": [ - "Färska Apelsiner", - "Is" + "Fresh oranges", + "Ice" ], "image": "https://images.unsplash.com/photo-1600271886742-f049cd451bba?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NzF8fG9yYW5nZSUyMGp1aWNlfGVufDB8fDB8fHww", "id": 18 }, { "title": "Frozen Lemonade", - "description": "Frozen lemonade är en uppfriskande sommardryck som kombinerar färskpressad citronsaft, is och sötning till en svalkande, syrlig och sötsyrlig smaksensation.", + "description": "Frozen lemonade is a refreshing summer drink that combines freshly squeezed lemon juice, ice, and sweetener into a cool, tangy treat.", "ingredients": [ - "Citronsaft", - "Is", - "Socker*" + "Lemon juice", + "Ice", + "Sugar*" ], "image": "https://images.unsplash.com/photo-1523371054106-bbf80586c38c?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTZ8fGxlbW9uYWRlJTIwd2l0aCUyMGljZXxlbnwwfHwwfHx8MA%3D%3D", "id": 19 }, { - "title": "Lemonad", - "description": "Var känd i Paris först och blev sedan mycket populär i hela Europa. Denna söta, färglösa, kolsyrade dryck görs genom att blanda citronsaft och kolsyrat vatten.", + "title": "Lemonade", + "description": "A sweet-tart sparkling lemonade made with lemon juice, carbonated water, and honey.", "ingredients": [ - "Citronsaft", - "Kolsyrat vatten", - "Honung" + "Lemon juice", + "Sparkling water", + "Honey" ], "image": "https://images.unsplash.com/photo-1621263764928-df1444c5e859?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Nnx8bGVtb25hZGV8ZW58MHx8MHx8fDA%3D", "id": 20 @@ -244,7 +244,7 @@ }, { "title": "Iced Espresso", - "description": "Like an iced coffee, iced espresso can be served straight or with a dash of milk, cream or sweetener. You can also ice speciality espresso-based drinks like americanos, mochas, macchiatos, lattes and flat whites.", + "description": "Like iced coffee, iced espresso can be served straight or with a dash of milk, cream, or sweetener. You can also ice specialty espresso-based drinks like americanos, mochas, macchiatos, lattes, and flat whites.", "ingredients": [ "Espresso", "Ice", @@ -266,7 +266,7 @@ }, { "title": "Frappuccino", - "description": "Made famous by Starbucks, the Frappuccino is a blended iced coffee drink that’s topped with whipped cream and syrup. ", + "description": "Made famous by Starbucks, the Frappuccino is a blended iced coffee drink topped with whipped cream and syrup.", "ingredients": [ "Espresso", "Blended ice", diff --git a/server/api/coffee.json.backup b/server/api/coffee.json.backup index 0b383ff..4f989f4 100644 --- a/server/api/coffee.json.backup +++ b/server/api/coffee.json.backup @@ -14,7 +14,7 @@ "hot": [ { "title": "Black Coffee", - "description": "Svart kaffe är så enkelt som det kan bli med malda kaffebönor dränkta i hett vatten, serverat varmt. Och om du vill låta fancy kan du kalla svart kaffe med sitt rätta namn: café noir.", + "description": "Black coffee is as simple as it gets with ground coffee beans steeped in hot water, served warm. And if you want to sound fancy, you can call black coffee by its proper name: cafe noir.", "ingredients": [ "Coffee" ], @@ -23,31 +23,31 @@ }, { "title": "Latte", - "description": "Som den mest populära kaffedrycken där ute består latte av en skvätt espresso och ångad mjölk med bara en gnutta skum. Den kan beställas utan smak eller med smak av allt från vanilj till pumpa kryddor.", + "description": "As the most popular coffee drink out there, the latte is made with a shot of espresso and steamed milk, with just a touch of foam. It can be ordered plain or flavored with everything from vanilla to pumpkin spice.", "ingredients": [ "Espresso", - "Ångad mjölk" + "Steamed milk" ], "image": "https://images.unsplash.com/photo-1561882468-9110e03e0f78?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTl8fGxhdHRlfGVufDB8fDB8fHww", "id": 2 }, { "title": "Caramel Latte", - "description": "Om du gillar latte med en speciell smak kan karamell latte vara det bästa alternativet för att ge dig en upplevelse av den naturliga sötman och krämigheten hos ångad mjölk och karamell.", + "description": "If you like flavored lattes, a caramel latte is a great choice, combining espresso, steamed milk, and caramel for a naturally sweet and creamy drink.", "ingredients": [ "Espresso", - "Ångad mjölk", - "Karamellsirap" + "Steamed milk", + "Caramel syrup" ], "image": "https://images.unsplash.com/photo-1599398054066-846f28917f38?auto=format&fit=crop&q=80&w=1887&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "id": 3 }, { "title": "Cappuccino", - "description": "Cappuccino är en latte som är gjord med mer skum än ångad mjölk, ofta med ett strö av kakaopulver eller kanel på toppen. Ibland kan du hitta variationer som använder grädde istället för mjölk eller sådana som tillsätter smakämnen också.", + "description": "A cappuccino is an espresso drink with steamed milk and a thick layer of foam, often topped with cocoa powder or cinnamon. Some variations use cream instead of milk or add flavored syrups.", "ingredients": [ "Espresso", - "Ångad mjölk", + "Steamed milk", "Foam" ], "image": "https://images.unsplash.com/photo-1557006021-b85faa2bc5e2?auto=format&fit=crop&q=80&w=1887&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", @@ -55,17 +55,17 @@ }, { "title": "Americano", - "description": "Med en liknande smak som svart kaffe består americano av en espresso skott utspätt med hett vatten.", + "description": "With a flavor similar to black coffee, an americano is made by diluting a shot of espresso with hot water.", "ingredients": [ "Espresso", - "Hett vatten" + "Hot water" ], "image": "https://images.unsplash.com/photo-1532004491497-ba35c367d634?auto=format&fit=crop&q=80&w=1887&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "id": 5 }, { "title": "Espresso", - "description": "Ett espressoskott kan serveras ensamt eller användas som grund för de flesta kaffedrycker, som latte och macchiato.", + "description": "A shot of espresso can be served on its own or used as the base for most coffee drinks, like lattes and macchiatos.", "ingredients": [ "Espresso" ], @@ -74,7 +74,7 @@ }, { "title": "Macchiato", - "description": "Macchiaton är en annan espresso-baserad dryck som har en liten mängd skum på toppen. Det är det glada mellanrummet mellan en cappuccino och en doppio.", + "description": "An espresso macchiato is a shot of espresso marked with a small dollop of foam. It is stronger and smaller than a cappuccino or latte.", "ingredients": [ "Espresso", "Foam" @@ -84,146 +84,146 @@ }, { "title": "Mocha", - "description": "För alla chokladälskare där ute kommer ni att bli förälskade i en mocha. Mocha är en choklad-espressodryck med ångad mjölk och skum.", + "description": "For all the chocolate lovers out there, a mocha is an easy favorite. It is a chocolate espresso drink made with steamed milk and foam.", "ingredients": [ "Espresso", - "Ångad mjölk", - "Choklad" + "Steamed milk", + "Chocolate" ], "image": "https://images.unsplash.com/photo-1607260550778-aa9d29444ce1?auto=format&fit=crop&q=80&w=1887&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", "id": 8 }, { "title": "Hot Chocolate", - "description": "Under kalla vinterdagar får en kopp varm choklad dig att känna dig bekväm och lycklig. Den får dig också att må bra eftersom den innehåller energigivande koffein.", + "description": "A classic warm drink made with chocolate and steamed milk. Rich, cozy, and especially good on cold days.", "ingredients": [ - "Choklad", - "Mjölk" + "Chocolate", + "Milk" ], "image": "https://images.unsplash.com/photo-1542990253-0d0f5be5f0ed?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NDh8fGhvdCUyMGNob2NvbGF0ZXxlbnwwfHwwfHx8MA%3D%3D", "id": 9 }, { "title": "Chai Latte", - "description": "Om du letar efter en smakfull varm dryck mitt i vintern, välj chai latte. Kombinationen av kardemumma och kanel ger en underbar smak.", + "description": "A spiced tea latte made with black tea, steamed milk, and warming spices such as ginger, cardamom, and cinnamon.", "ingredients": [ - "Te", - "Mjölk", - "Ingefära", - "Kardemumma", - "Kanel" + "Tea", + "Milk", + "Ginger", + "Cardamom", + "Cinnamon" ], "image": "https://images.unsplash.com/photo-1578899952107-9c390f1af1b7?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTJ8fGNoYWklMjBsYXR0ZXxlbnwwfHwwfHx8MA%3D%3D", "id": 10 }, { "title": "Matcha Latte", - "description": "Matcha latte är en grön, hälsosam kaffedryck med finkrossad matcha-te och mjölk, erbjuder mild sötma, en unik smak och en mild koffeinkick.", + "description": "A matcha latte is a green tea drink made with finely ground matcha and milk, offering mild sweetness, a distinctive flavor, and a gentle caffeine boost.", "ingredients": [ - "Matcha-pulver", - "Mjölk", - "Socker*" + "Matcha powder", + "Milk", + "Sugar*" ], "image": "https://images.unsplash.com/photo-1536256263959-770b48d82b0a?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8M3x8bWF0Y2hhJTIwbGF0dGV8ZW58MHx8MHx8fDA%3D", "id": 11 }, { "title": "Seasonal Brew", - "description": "Säsongs kaffe med olika smaktoner som karamell, frukt och choklad", + "description": "A seasonal coffee with flavor notes that can include caramel, fruit, and chocolate.", "ingredients": [ - "Kaffe" + "Coffee" ], "image": "https://images.unsplash.com/photo-1611162458324-aae1eb4129a4?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTg1fHxibGFjayUyMGNvZmZlZXxlbnwwfHwwfHx8MA%3D%3D", "id": 12 }, { - "title": "Svart Te", - "description": "Svart te föddes i Kina. Det är tillverkat av blad från en växt som kallas Camellia och kan smaksättas olika med frukter till exempel. En trevlig, varm, smakfull och aromatisk dryck som passar till vardagen.", + "title": "Black Tea", + "description": "Black tea is made from the leaves of the Camellia sinensis plant. It can be enjoyed plain or flavored with fruit, spices, or other additions.", "ingredients": [ - "Te" + "Tea" ], "image": "https://images.unsplash.com/photo-1576092768241-dec231879fc3?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MjB8fHRlYXxlbnwwfHwwfHx8MA%3D%3D", "id": 13 }, { - "title": "Islatte", - "description": "Iced latte är en kyld kaffedryck som görs genom att blanda espresso och kyld mjölk. Den serveras med isbitar och är även känd som cafè latte iced eller latte on the rocks.", + "title": "Iced Latte", + "description": "An iced latte is espresso poured over ice and cold milk. Sweet syrup is optional, and it is also known as an iced cafe latte.", "ingredients": [ "Espresso", - "Mjölk", - "Is", - "Sirap" + "Milk", + "Ice", + "Syrup" ], "image": "https://images.unsplash.com/photo-1517701550927-30cf4ba1dba5?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NHx8aWNlZCUyMGxhdHRlfGVufDB8fDB8fHww", "id": 14 }, { - "title": "Islatte Mocha", - "description": "Iced latte Mocha är en kombination av latte och mocha, som i sig är en kombination av choklad och kaffe. Den ger kalla dryckälskare en läcker upplevelse av choklad och kaffe.", + "title": "Iced Mocha Latte", + "description": "An iced mocha latte combines a latte with mocha flavors, bringing together chocolate and coffee in a rich and refreshing drink.", "ingredients": [ "Espresso", - "Is", - "Mjölk", - "Choklad " + "Ice", + "Milk", + "Chocolate" ], "image": "https://images.unsplash.com/photo-1642647391072-6a2416f048e5?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mzh8fGljZWQlMjBtb2NoYSUyMGxhdHRlfGVufDB8fDB8fHww", "id": 15 }, { - "title": "Frapino Caramel", - "description": "Det är en blandad eller bättre sagt skakad kaffe med vispad grädde på toppen. Ett måste för varma sommardagar.", + "title": "Blended Caramel Coffee", + "description": "A blended iced coffee with caramel syrup, milk, and ice, topped with whipped cream and caramel sauce.", "ingredients": [ - "coffee", - "Is", - "Mjölk", - "Karamellsirap", - "Vispgrädde*", - "Karamellsås" + "Coffee", + "Ice", + "Milk", + "Caramel syrup", + "Whipped cream*", + "Caramel sauce" ], "image": "https://images.unsplash.com/photo-1662047102608-a6f2e492411f?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NHx8ZnJhcGlubyUyMGNhcmFtZWx8ZW58MHx8MHx8fDA%3D", "id": 16 }, { - "title": "Frapino Mocka", - "description": "Ännu en berömd och utsökt kall dryck för dem som föredrar choklad. Tänk dig smaken av en shake med choklad och vispad grädde på toppen.", + "title": "Blended Mocha Coffee", + "description": "A blended iced mocha with coffee, milk, cocoa, and ice, finished with whipped cream for a chocolate shake-like treat.", "ingredients": [ "Coffee", - "Is", - "Mjölk", + "Ice", + "Milk", "Cocoa", - "Vispgrädde*" + "Whipped cream*" ], "image": "https://images.unsplash.com/photo-1530373239216-42518e6b4063?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NHx8ZnJhcGlubyUyMG1vY2hhfGVufDB8fDB8fHww", "id": 17 }, { - "title": "Apelsinjuice", - "description": "Vi har inget att säga om vår nypressade apelsinjuice. Du måste prova den själv.", + "title": "Orange Juice", + "description": "Freshly squeezed orange juice served cold over ice.", "ingredients": [ - "Färska Apelsiner", - "Is" + "Fresh oranges", + "Ice" ], "image": "https://images.unsplash.com/photo-1600271886742-f049cd451bba?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NzF8fG9yYW5nZSUyMGp1aWNlfGVufDB8fDB8fHww", "id": 18 }, { "title": "Frozen Lemonade", - "description": "Frozen lemonade är en uppfriskande sommardryck som kombinerar färskpressad citronsaft, is och sötning till en svalkande, syrlig och sötsyrlig smaksensation.", + "description": "Frozen lemonade is a refreshing summer drink that combines freshly squeezed lemon juice, ice, and sweetener into a cool, tangy treat.", "ingredients": [ - "Citronsaft", - "Is", - "Socker*" + "Lemon juice", + "Ice", + "Sugar*" ], "image": "https://images.unsplash.com/photo-1523371054106-bbf80586c38c?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTZ8fGxlbW9uYWRlJTIwd2l0aCUyMGljZXxlbnwwfHwwfHx8MA%3D%3D", "id": 19 }, { - "title": "Lemonad", - "description": "Var känd i Paris först och blev sedan mycket populär i hela Europa. Denna söta, färglösa, kolsyrade dryck görs genom att blanda citronsaft och kolsyrat vatten.", + "title": "Lemonade", + "description": "A sweet-tart sparkling lemonade made with lemon juice, carbonated water, and honey.", "ingredients": [ - "Citronsaft", - "Kolsyrat vatten", - "Honung" + "Lemon juice", + "Sparkling water", + "Honey" ], "image": "https://images.unsplash.com/photo-1621263764928-df1444c5e859?auto=format&fit=crop&q=60&w=800&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Nnx8bGVtb25hZGV8ZW58MHx8MHx8fDA%3D", "id": 20 @@ -244,7 +244,7 @@ }, { "title": "Iced Espresso", - "description": "Like an iced coffee, iced espresso can be served straight or with a dash of milk, cream or sweetener. You can also ice speciality espresso-based drinks like americanos, mochas, macchiatos, lattes and flat whites.", + "description": "Like iced coffee, iced espresso can be served straight or with a dash of milk, cream, or sweetener. You can also ice specialty espresso-based drinks like americanos, mochas, macchiatos, lattes, and flat whites.", "ingredients": [ "Espresso", "Ice", @@ -266,7 +266,7 @@ }, { "title": "Frappuccino", - "description": "Made famous by Starbucks, the Frappuccino is a blended iced coffee drink that’s topped with whipped cream and syrup. ", + "description": "Made famous by Starbucks, the Frappuccino is a blended iced coffee drink topped with whipped cream and syrup.", "ingredients": [ "Espresso", "Blended ice", diff --git a/server/api/movies.json b/server/api/movies.json index 6806e11..d4d7d19 100644 --- a/server/api/movies.json +++ b/server/api/movies.json @@ -2,10 +2,13 @@ "metaData": [ { "title": "Movies", - "longDesc": "Movies", - "desc": "Movies", + "longDesc": "Curated movie lists by genre, including classic and contemporary titles with IMDb IDs and poster URLs.", + "desc": "Curated movie lists by genre.", "featured": false, - "categories": ["list", "entertainment"] + "categories": [ + "list", + "entertainment" + ] } ], "action-adventure": [ @@ -536,6 +539,18 @@ "title": "The Bourne Ultimatum", "posterURL": "https://m.media-amazon.com/images/M/MV5BNGNiNmU2YTMtZmU4OS00MjM0LTlmYWUtMjVlYjAzYjE2N2RjXkEyXkFqcGdeQXVyNDk3NzU2MTQ@._V1_SX300.jpg", "imdbId": "tt0440963" + }, + { + "id": 89, + "title": "Top Gun: Maverick", + "imdbId": "tt1745960", + "posterURL": "https://m.media-amazon.com/images/M/MV5BZWYzOGExMjYtZDc4MS00YzY1LWEydC0yMzY2YjIzYmUyZmM3XkEyXkFqcGdeQXVyMTM4NDIzNTE@._V1_SX300.jpg" + }, + { + "id": 90, + "title": "Dune: Part Two", + "imdbId": "tt15239678", + "posterURL": "https://m.media-amazon.com/images/M/MV5BN2MyOTk1OTU2NV5BMl5BanBnXkFtZTgwNjE0NjkyMTE@._V1_SX300.jpg" } ], "animation": [ @@ -1000,6 +1015,18 @@ "title": "The Princess and the Frog", "posterURL": "https://m.media-amazon.com/images/M/MV5BMjEyOTQ5NzAzNl5BMl5BanBnXkFtZTcwMTcyNTU1Mg@@._V1_SX300.jpg", "imdbId": "tt0780521" + }, + { + "id": 78, + "title": "Spider-Man: Across the Spider-Verse", + "imdbId": "tt9362722", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" + }, + { + "id": 79, + "title": "Inside Out 2", + "imdbId": "tt22022452", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "classic": [ @@ -1506,6 +1533,18 @@ "title": "Dr. No", "posterURL": "https://m.media-amazon.com/images/M/MV5BMTk4YzdjOTgtNjM4NS00YjljLThhM2QtYTI3OTQ0OGVhNTMxXkEyXkFqcGdeQXVyNjc1NTYyMjg@._V1_SX300.jpg", "imdbId": "tt0055928" + }, + { + "id": 85, + "title": "Parasite", + "imdbId": "tt6751668", + "posterURL": "https://m.media-amazon.com/images/M/MV5BZWYzOGExMjYtZDc4MS00YzY1LWEydC0yMzY2YjIzYmUyZmM3XkEyXkFqcGdeQXVyMTM4NDIzNTE@._V1_SX300.jpg" + }, + { + "id": 86, + "title": "Everything Everywhere All at Once", + "imdbId": "tt6710474", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "comedy": [ @@ -2030,6 +2069,18 @@ "title": "Blindspotting", "posterURL": "https://m.media-amazon.com/images/M/MV5BNjgwYTQ4YmEtOTcwYy00NjBlLWI0ZjYtNDM0YmI1OGM0MWY0XkEyXkFqcGdeQXVyMjMxOTE0ODA@._V1_SX300.jpg", "imdbId": "tt7242142" + }, + { + "id": 88, + "title": "Barbie", + "imdbId": "tt1517268", + "posterURL": "https://m.media-amazon.com/images/M/MV5BNjU0N2Y0NzYtYzM0Yy00YzM0LWE0YjAtYzM0Yy00YzM0Yy00YzM0YkEyXkFqcGc@._V1_SX300.jpg" + }, + { + "id": 89, + "title": "The Holdovers", + "imdbId": "tt14849194", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "drama": [ @@ -2536,6 +2587,18 @@ "title": "The Artist", "posterURL": "https://m.media-amazon.com/images/M/MV5BMDUyZWU5N2UtOWFlMy00MTI0LTk0ZDYtMzFhNjljODBhZDA5XkEyXkFqcGdeQXVyNzA4ODc3ODU@._V1_SX300.jpg", "imdbId": "tt1655442" + }, + { + "id": 85, + "title": "Oppenheimer", + "imdbId": "tt1285016", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMDBmYTZkNjYtNTEgLTjlhZi0tMjQxZjRiN2I0NzQ5XkEyXkFqcGc@._V1_SX300.jpg" + }, + { + "id": 86, + "title": "Killers of the Flower Moon", + "imdbId": "tt5537002", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "horror": [ @@ -3006,6 +3069,18 @@ "title": "The Autopsy of Jane Doe", "posterURL": "https://m.media-amazon.com/images/M/MV5BMjA2MTEzMzkzM15BMl5BanBnXkFtZTgwMjM2MTM5MDI@._V1_SX300.jpg", "imdbId": "tt3289956" + }, + { + "id": 79, + "title": "Talk to Me", + "imdbId": "tt10633456", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" + }, + { + "id": 80, + "title": "A Quiet Place: Day One", + "imdbId": "tt13433802", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "family": [ @@ -3512,6 +3587,18 @@ "title": "Harry Potter and the Half-Blood Prince", "posterURL": "https://m.media-amazon.com/images/M/MV5BNzU3NDg4NTAyNV5BMl5BanBnXkFtZTcwOTg2ODg1Mg@@._V1_SX300.jpg", "imdbId": "tt0417741" + }, + { + "id": 85, + "title": "Elemental", + "imdbId": "tt15789038", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" + }, + { + "id": 86, + "title": "Wonka", + "imdbId": "tt6166392", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "mystery": [ @@ -4030,6 +4117,18 @@ "title": "It", "posterURL": "https://m.media-amazon.com/images/M/MV5BZDVkZmI0YzAtNzdjYi00ZjhhLWE1ODEtMWMzMWMzNDA0NmQ4XkEyXkFqcGdeQXVyNzYzODM3Mzg@._V1_SX300.jpg", "imdbId": "tt1396484" + }, + { + "id": 87, + "title": "Glass Onion", + "imdbId": "tt11564570", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" + }, + { + "id": 88, + "title": "Knives Out", + "imdbId": "tt8946378", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "scifi-fantasy": [ @@ -4251,7 +4350,7 @@ }, { "id": 37, - "title": "WALL·E", + "title": "WALL\u00b7E", "posterURL": "https://m.media-amazon.com/images/M/MV5BMjExMTg5OTU0NF5BMl5BanBnXkFtZTcwMjMxMzMzMw@@._V1_SX300.jpg", "imdbId": "tt0910970" }, @@ -4275,7 +4374,7 @@ }, { "id": 41, - "title": "Snowpiercer: Transperceneige, From the Blank Page to the Black Screen: A Documentary by Jésus Castro-", + "title": "Snowpiercer: Transperceneige, From the Blank Page to the Black Screen: A Documentary by J\u00e9sus Castro-", "posterURL": "https://m.media-amazon.com/images/M/MV5BMjNiY2NjZDUtMGYxNS00YTU0LTkyNDEtZTBmZjdlYTA1ZmY0XkEyXkFqcGdeQXVyMjgzNDIyNjE@._V1_SX300.jpg", "imdbId": "tt4481854" }, @@ -4530,6 +4629,18 @@ "title": "The Hunger Games: Catching Fire", "posterURL": "https://m.media-amazon.com/images/M/MV5BMTAyMjQ3OTAxMzNeQTJeQWpwZ15BbWU4MDU0NzA1MzAx._V1_SX300.jpg", "imdbId": "tt1951264" + }, + { + "id": 84, + "title": "Avatar: The Way of Water", + "imdbId": "tt1630029", + "posterURL": "https://m.media-amazon.com/images/M/MV5BN2MyOTk1OTU2NV5BMl5BanBnXkFtZTgwNjE0NjkyMTE@._V1_SX300.jpg" + }, + { + "id": 85, + "title": "The Batman", + "imdbId": "tt1877830", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "western": [ @@ -4928,6 +5039,18 @@ "title": "Texas Rangers", "posterURL": "https://m.media-amazon.com/images/M/MV5BMTIwOTM3ODk4NV5BMl5BanBnXkFtZTcwNjI3NjYxMQ@@._V1_SX300.jpg", "imdbId": "tt0193560" + }, + { + "id": 67, + "title": "Horizon: An American Saga - Chapter 1", + "imdbId": "tt1856080", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" + }, + { + "id": 68, + "title": "The Power of the Dog", + "imdbId": "tt10293406", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ] } diff --git a/server/api/movies.json.backup b/server/api/movies.json.backup index 6806e11..d4d7d19 100644 --- a/server/api/movies.json.backup +++ b/server/api/movies.json.backup @@ -2,10 +2,13 @@ "metaData": [ { "title": "Movies", - "longDesc": "Movies", - "desc": "Movies", + "longDesc": "Curated movie lists by genre, including classic and contemporary titles with IMDb IDs and poster URLs.", + "desc": "Curated movie lists by genre.", "featured": false, - "categories": ["list", "entertainment"] + "categories": [ + "list", + "entertainment" + ] } ], "action-adventure": [ @@ -536,6 +539,18 @@ "title": "The Bourne Ultimatum", "posterURL": "https://m.media-amazon.com/images/M/MV5BNGNiNmU2YTMtZmU4OS00MjM0LTlmYWUtMjVlYjAzYjE2N2RjXkEyXkFqcGdeQXVyNDk3NzU2MTQ@._V1_SX300.jpg", "imdbId": "tt0440963" + }, + { + "id": 89, + "title": "Top Gun: Maverick", + "imdbId": "tt1745960", + "posterURL": "https://m.media-amazon.com/images/M/MV5BZWYzOGExMjYtZDc4MS00YzY1LWEydC0yMzY2YjIzYmUyZmM3XkEyXkFqcGdeQXVyMTM4NDIzNTE@._V1_SX300.jpg" + }, + { + "id": 90, + "title": "Dune: Part Two", + "imdbId": "tt15239678", + "posterURL": "https://m.media-amazon.com/images/M/MV5BN2MyOTk1OTU2NV5BMl5BanBnXkFtZTgwNjE0NjkyMTE@._V1_SX300.jpg" } ], "animation": [ @@ -1000,6 +1015,18 @@ "title": "The Princess and the Frog", "posterURL": "https://m.media-amazon.com/images/M/MV5BMjEyOTQ5NzAzNl5BMl5BanBnXkFtZTcwMTcyNTU1Mg@@._V1_SX300.jpg", "imdbId": "tt0780521" + }, + { + "id": 78, + "title": "Spider-Man: Across the Spider-Verse", + "imdbId": "tt9362722", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" + }, + { + "id": 79, + "title": "Inside Out 2", + "imdbId": "tt22022452", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "classic": [ @@ -1506,6 +1533,18 @@ "title": "Dr. No", "posterURL": "https://m.media-amazon.com/images/M/MV5BMTk4YzdjOTgtNjM4NS00YjljLThhM2QtYTI3OTQ0OGVhNTMxXkEyXkFqcGdeQXVyNjc1NTYyMjg@._V1_SX300.jpg", "imdbId": "tt0055928" + }, + { + "id": 85, + "title": "Parasite", + "imdbId": "tt6751668", + "posterURL": "https://m.media-amazon.com/images/M/MV5BZWYzOGExMjYtZDc4MS00YzY1LWEydC0yMzY2YjIzYmUyZmM3XkEyXkFqcGdeQXVyMTM4NDIzNTE@._V1_SX300.jpg" + }, + { + "id": 86, + "title": "Everything Everywhere All at Once", + "imdbId": "tt6710474", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "comedy": [ @@ -2030,6 +2069,18 @@ "title": "Blindspotting", "posterURL": "https://m.media-amazon.com/images/M/MV5BNjgwYTQ4YmEtOTcwYy00NjBlLWI0ZjYtNDM0YmI1OGM0MWY0XkEyXkFqcGdeQXVyMjMxOTE0ODA@._V1_SX300.jpg", "imdbId": "tt7242142" + }, + { + "id": 88, + "title": "Barbie", + "imdbId": "tt1517268", + "posterURL": "https://m.media-amazon.com/images/M/MV5BNjU0N2Y0NzYtYzM0Yy00YzM0LWE0YjAtYzM0Yy00YzM0Yy00YzM0YkEyXkFqcGc@._V1_SX300.jpg" + }, + { + "id": 89, + "title": "The Holdovers", + "imdbId": "tt14849194", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "drama": [ @@ -2536,6 +2587,18 @@ "title": "The Artist", "posterURL": "https://m.media-amazon.com/images/M/MV5BMDUyZWU5N2UtOWFlMy00MTI0LTk0ZDYtMzFhNjljODBhZDA5XkEyXkFqcGdeQXVyNzA4ODc3ODU@._V1_SX300.jpg", "imdbId": "tt1655442" + }, + { + "id": 85, + "title": "Oppenheimer", + "imdbId": "tt1285016", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMDBmYTZkNjYtNTEgLTjlhZi0tMjQxZjRiN2I0NzQ5XkEyXkFqcGc@._V1_SX300.jpg" + }, + { + "id": 86, + "title": "Killers of the Flower Moon", + "imdbId": "tt5537002", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "horror": [ @@ -3006,6 +3069,18 @@ "title": "The Autopsy of Jane Doe", "posterURL": "https://m.media-amazon.com/images/M/MV5BMjA2MTEzMzkzM15BMl5BanBnXkFtZTgwMjM2MTM5MDI@._V1_SX300.jpg", "imdbId": "tt3289956" + }, + { + "id": 79, + "title": "Talk to Me", + "imdbId": "tt10633456", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" + }, + { + "id": 80, + "title": "A Quiet Place: Day One", + "imdbId": "tt13433802", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "family": [ @@ -3512,6 +3587,18 @@ "title": "Harry Potter and the Half-Blood Prince", "posterURL": "https://m.media-amazon.com/images/M/MV5BNzU3NDg4NTAyNV5BMl5BanBnXkFtZTcwOTg2ODg1Mg@@._V1_SX300.jpg", "imdbId": "tt0417741" + }, + { + "id": 85, + "title": "Elemental", + "imdbId": "tt15789038", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" + }, + { + "id": 86, + "title": "Wonka", + "imdbId": "tt6166392", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "mystery": [ @@ -4030,6 +4117,18 @@ "title": "It", "posterURL": "https://m.media-amazon.com/images/M/MV5BZDVkZmI0YzAtNzdjYi00ZjhhLWE1ODEtMWMzMWMzNDA0NmQ4XkEyXkFqcGdeQXVyNzYzODM3Mzg@._V1_SX300.jpg", "imdbId": "tt1396484" + }, + { + "id": 87, + "title": "Glass Onion", + "imdbId": "tt11564570", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" + }, + { + "id": 88, + "title": "Knives Out", + "imdbId": "tt8946378", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "scifi-fantasy": [ @@ -4251,7 +4350,7 @@ }, { "id": 37, - "title": "WALL·E", + "title": "WALL\u00b7E", "posterURL": "https://m.media-amazon.com/images/M/MV5BMjExMTg5OTU0NF5BMl5BanBnXkFtZTcwMjMxMzMzMw@@._V1_SX300.jpg", "imdbId": "tt0910970" }, @@ -4275,7 +4374,7 @@ }, { "id": 41, - "title": "Snowpiercer: Transperceneige, From the Blank Page to the Black Screen: A Documentary by Jésus Castro-", + "title": "Snowpiercer: Transperceneige, From the Blank Page to the Black Screen: A Documentary by J\u00e9sus Castro-", "posterURL": "https://m.media-amazon.com/images/M/MV5BMjNiY2NjZDUtMGYxNS00YTU0LTkyNDEtZTBmZjdlYTA1ZmY0XkEyXkFqcGdeQXVyMjgzNDIyNjE@._V1_SX300.jpg", "imdbId": "tt4481854" }, @@ -4530,6 +4629,18 @@ "title": "The Hunger Games: Catching Fire", "posterURL": "https://m.media-amazon.com/images/M/MV5BMTAyMjQ3OTAxMzNeQTJeQWpwZ15BbWU4MDU0NzA1MzAx._V1_SX300.jpg", "imdbId": "tt1951264" + }, + { + "id": 84, + "title": "Avatar: The Way of Water", + "imdbId": "tt1630029", + "posterURL": "https://m.media-amazon.com/images/M/MV5BN2MyOTk1OTU2NV5BMl5BanBnXkFtZTgwNjE0NjkyMTE@._V1_SX300.jpg" + }, + { + "id": 85, + "title": "The Batman", + "imdbId": "tt1877830", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ], "western": [ @@ -4928,6 +5039,18 @@ "title": "Texas Rangers", "posterURL": "https://m.media-amazon.com/images/M/MV5BMTIwOTM3ODk4NV5BMl5BanBnXkFtZTcwNjI3NjYxMQ@@._V1_SX300.jpg", "imdbId": "tt0193560" + }, + { + "id": 67, + "title": "Horizon: An American Saga - Chapter 1", + "imdbId": "tt1856080", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" + }, + { + "id": 68, + "title": "The Power of the Dog", + "imdbId": "tt10293406", + "posterURL": "https://m.media-amazon.com/images/M/MV5BMzQ1NTYzODAyMV5BMl5BanBnXkFtZTcwNTE1MTM4Nw@@._V1_SX300.jpg" } ] } diff --git a/server/api/presidents.json b/server/api/presidents.json index 1e06817..d9c1244 100644 --- a/server/api/presidents.json +++ b/server/api/presidents.json @@ -100,7 +100,7 @@ { "id": 12, "ordinal": 12, - "name": "Zacary Taylor", + "name": "Zachary Taylor", "yearsInOffice": "1849-1850", "vicePresidents": ["Millard Fillmore"], "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Zachary_Taylor_restored_and_cropped.jpg/220px-Zachary_Taylor_restored_and_cropped.jpg" @@ -134,7 +134,7 @@ "ordinal": 16, "name": "Abraham Lincoln", "yearsInOffice": "1861-1865", - "vicePresidents": ["Hannibal Hamlin", "Andrew John"], + "vicePresidents": ["Hannibal Hamlin", "Andrew Johnson"], "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/Abraham_Lincoln_O-77_matte_collodion_print.jpg/220px-Abraham_Lincoln_O-77_matte_collodion_print.jpg" }, { @@ -181,7 +181,7 @@ "id": 22, "ordinal": 22, "name": "Grover Cleveland", - "yearsInOffice": "1893-1897", + "yearsInOffice": "1885-1889", "vicePresidents": ["Adlai Stevenson I"], "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Grover_Cleveland_-_NARA_-_518139_%28cropped%29.jpg/220px-Grover_Cleveland_-_NARA_-_518139_%28cropped%29.jpg" }, @@ -245,7 +245,7 @@ "id": 30, "ordinal": 30, "name": "Calvin Coolidge", - "yearsInOffice": "1923-1925", + "yearsInOffice": "1923-1929", "vicePresidents": ["Charles G. Dawes"], "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/37/Calvin_Coolidge%2C_bw_head_and_shoulders_photo_portrait_seated%2C_1919.jpg/220px-Calvin_Coolidge%2C_bw_head_and_shoulders_photo_portrait_seated%2C_1919.jpg" }, @@ -365,17 +365,25 @@ "id": 45, "ordinal": 45, "name": "Donald Trump", - "yearsInOffice": "2017-2020", + "yearsInOffice": "2017-2021", "vicePresidents": ["Mike Pence"], "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Donald_Trump_official_portrait.jpg/220px-Donald_Trump_official_portrait.jpg" }, { "id": 46, "ordinal": 46, - "name": "Joseph Biden", - "yearsInOffice": "2020-present", + "name": "Joe Biden", + "yearsInOffice": "2021-2025", "vicePresidents": ["Kamala Harris"], - "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Joe_Biden_presidential_portrait.jpg/440px-Joe_Biden_presidential_portrait.jpg" + "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Joe_Biden_presidential_portrait.jpg/220px-Joe_Biden_presidential_portrait.jpg" + }, + { + "id": 47, + "ordinal": 47, + "name": "Donald Trump", + "yearsInOffice": "2025-present", + "vicePresidents": ["JD Vance"], + "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Official_Presidential_Portrait_of_President_Donald_J._Trump_%282025%29.jpg/220px-Official_Presidential_Portrait_of_President_Donald_J._Trump_%282025%29.jpg" } ] } diff --git a/server/api/presidents.json.backup b/server/api/presidents.json.backup index 1e06817..8a0fb64 100644 --- a/server/api/presidents.json.backup +++ b/server/api/presidents.json.backup @@ -2,7 +2,7 @@ "metaData": [ { "title": "Presidents", - "longDesc": "Millions of peaches! No...not those Presidents. You're practicing API calls, why not learn a little bit about United States history in the process? Here we have a collection of all the US Presidents. Updated every 4-8 years.", + "longDesc": "Millions of peaches! No...not those Presidents. You're practicing API calls, why not learn a little bit about United States history in the process? Here we have a collection of all the US Presidents through the current term.", "desc": "Millions of peaches! No...not those Presidents...", "featured": false, "categories": ["list"] @@ -100,7 +100,7 @@ { "id": 12, "ordinal": 12, - "name": "Zacary Taylor", + "name": "Zachary Taylor", "yearsInOffice": "1849-1850", "vicePresidents": ["Millard Fillmore"], "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Zachary_Taylor_restored_and_cropped.jpg/220px-Zachary_Taylor_restored_and_cropped.jpg" @@ -134,7 +134,7 @@ "ordinal": 16, "name": "Abraham Lincoln", "yearsInOffice": "1861-1865", - "vicePresidents": ["Hannibal Hamlin", "Andrew John"], + "vicePresidents": ["Hannibal Hamlin", "Andrew Johnson"], "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/Abraham_Lincoln_O-77_matte_collodion_print.jpg/220px-Abraham_Lincoln_O-77_matte_collodion_print.jpg" }, { @@ -181,7 +181,7 @@ "id": 22, "ordinal": 22, "name": "Grover Cleveland", - "yearsInOffice": "1893-1897", + "yearsInOffice": "1885-1889", "vicePresidents": ["Adlai Stevenson I"], "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Grover_Cleveland_-_NARA_-_518139_%28cropped%29.jpg/220px-Grover_Cleveland_-_NARA_-_518139_%28cropped%29.jpg" }, @@ -245,7 +245,7 @@ "id": 30, "ordinal": 30, "name": "Calvin Coolidge", - "yearsInOffice": "1923-1925", + "yearsInOffice": "1923-1929", "vicePresidents": ["Charles G. Dawes"], "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/37/Calvin_Coolidge%2C_bw_head_and_shoulders_photo_portrait_seated%2C_1919.jpg/220px-Calvin_Coolidge%2C_bw_head_and_shoulders_photo_portrait_seated%2C_1919.jpg" }, @@ -365,17 +365,25 @@ "id": 45, "ordinal": 45, "name": "Donald Trump", - "yearsInOffice": "2017-2020", + "yearsInOffice": "2017-2021", "vicePresidents": ["Mike Pence"], "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Donald_Trump_official_portrait.jpg/220px-Donald_Trump_official_portrait.jpg" }, { "id": 46, "ordinal": 46, - "name": "Joseph Biden", - "yearsInOffice": "2020-present", + "name": "Joe Biden", + "yearsInOffice": "2021-2025", "vicePresidents": ["Kamala Harris"], - "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Joe_Biden_presidential_portrait.jpg/440px-Joe_Biden_presidential_portrait.jpg" + "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Joe_Biden_presidential_portrait.jpg/220px-Joe_Biden_presidential_portrait.jpg" + }, + { + "id": 47, + "ordinal": 47, + "name": "Donald Trump", + "yearsInOffice": "2025-present", + "vicePresidents": ["JD Vance"], + "photo": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Official_Presidential_Portrait_of_President_Donald_J._Trump_%282025%29.jpg/220px-Official_Presidential_Portrait_of_President_Donald_J._Trump_%282025%29.jpg" } ] } diff --git a/server/api/rickandmorty.json b/server/api/rickandmorty.json deleted file mode 100644 index 76c6a64..0000000 --- a/server/api/rickandmorty.json +++ /dev/null @@ -1,477 +0,0 @@ -{ - "metaData": [ - { - "title": "Rick And Morty", - "longDesc": "Get all the Rick-iest Episodes, Locations and Characters from a copy of the https://rickandmortyapi.com data. That's the way Rick would have done it!", - "desc": "API for all current Rick & Morty episodes, locations and characters", - "featured": false, - "categories": ["cartoon", "tv", "entertainment"] - } - ], - "characters": [ - { - "id": 1, - "name": "Rick Sanchez", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (C-137)", - "image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg" - }, - { - "id": 2, - "name": "Morty Smith", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (C-137)", - "image": "https://rickandmortyapi.com/api/character/avatar/2.jpeg" - }, - { - "id": 3, - "name": "Summer Smith", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Female", - "origin": "Earth (Replacement Dimension)", - "image": "https://rickandmortyapi.com/api/character/avatar/3.jpeg" - }, - { - "id": 4, - "name": "Beth Smith", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Female", - "origin": "Earth (Replacement Dimension)", - "image": "https://rickandmortyapi.com/api/character/avatar/4.jpeg" - }, - { - "id": 5, - "name": "Jerry Smith", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (Replacement Dimension)", - "image": "https://rickandmortyapi.com/api/character/avatar/5.jpeg" - }, - { - "id": 6, - "name": "Abadango Cluster Princess", - "status": "Alive", - "species": "Alien", - "type": "Alien", - "gender": "Female", - "origin": "Abadango", - "image": "https://rickandmortyapi.com/api/character/avatar/6.jpeg" - }, - { - "id": 7, - "name": "Abradolf Lincler", - "status": "unknown", - "species": "Human", - "type": "Genetic experiment", - "gender": "Male", - "origin": "Earth (Replacement Dimension)", - "image": "https://rickandmortyapi.com/api/character/avatar/7.jpeg" - }, - { - "id": 8, - "name": "Adjudicator Rick", - "status": "Dead", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/8.jpeg" - }, - { - "id": 9, - "name": "Agency Director", - "status": "Dead", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (Replacement Dimension)", - "image": "https://rickandmortyapi.com/api/character/avatar/9.jpeg" - }, - { - "id": 10, - "name": "Alan Rails", - "status": "Dead", - "species": "Human", - "type": "Superhuman (Ghost trains summoner)", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/10.jpeg" - }, - { - "id": 11, - "name": "Albert Einstein", - "status": "Dead", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (C-137)", - "image": "https://rickandmortyapi.com/api/character/avatar/11.jpeg" - }, - { - "id": 12, - "name": "Alexander", - "status": "Dead", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (C-137)", - "image": "https://rickandmortyapi.com/api/character/avatar/12.jpeg" - }, - { - "id": 13, - "name": "Alien Googah", - "status": "unknown", - "species": "Alien", - "type": "Alien", - "gender": "unknown", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/13.jpeg" - }, - { - "id": 14, - "name": "Alien Morty", - "status": "unknown", - "species": "Alien", - "type": "Alien", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/14.jpeg" - }, - { - "id": 15, - "name": "Alien Rick", - "status": "unknown", - "species": "Alien", - "type": "Alien", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/15.jpeg" - }, - { - "id": 16, - "name": "Amish Cyborg", - "status": "Dead", - "species": "Alien", - "type": "Parasite", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/16.jpeg" - }, - { - "id": 17, - "name": "Annie", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Female", - "origin": "Earth (C-137)", - "image": "https://rickandmortyapi.com/api/character/avatar/17.jpeg" - }, - { - "id": 18, - "name": "Antenna Morty", - "status": "Alive", - "species": "Human", - "type": "Human with antennae", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/18.jpeg" - }, - { - "id": 19, - "name": "Antenna Rick", - "status": "unknown", - "species": "Human", - "type": "Human with antennae", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/19.jpeg" - }, - { - "id": 20, - "name": "Ants in my Eyes Johnson", - "status": "unknown", - "species": "Human", - "type": "Human with ants in his eyes", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/20.jpeg" - } - ], - "episodes": [ - { - "id": 1, - "name": "Pilot", - "air_date": "December 2, 2013", - "episode": 1, - "season": 1 - }, - { - "id": 2, - "name": "Lawnmower Dog", - "air_date": "December 9, 2013", - "episode": 2, - "season": 1 - }, - { - "id": 3, - "name": "Anatomy Park", - "air_date": "December 16, 2013", - "episode": 3, - "season": 1 - }, - { - "id": 4, - "name": "M. Night Shaym-Aliens!", - "air_date": "January 13, 2014", - "episode": 4, - "season": 1 - }, - { - "id": 5, - "name": "Meeseeks and Destroy", - "air_date": "January 20, 2014", - "episode": 5, - "season": 1 - }, - { - "id": 6, - "name": "Rick Potion #9", - "air_date": "January 27, 2014", - "episode": 6, - "season": 1 - }, - { - "id": 7, - "name": "Raising Gazorpazorp", - "air_date": "March 10, 2014", - "episode": 7, - "season": 1 - }, - { - "id": 8, - "name": "Rixty Minutes", - "air_date": "March 17, 2014", - "episode": 8, - "season": 1 - }, - { - "id": 9, - "name": "Something Ricked This Way Comes", - "air_date": "March 24, 2014", - "episode": 9, - "season": 1 - }, - { - "id": 10, - "name": "Close Rick-counters of the Rick Kind", - "air_date": "April 7, 2014", - "episode": 10, - "season": 1 - }, - { - "id": 11, - "name": "Ricksy Business", - "air_date": "April 14, 2014", - "episode": 11, - "season": 1 - }, - { - "id": 12, - "name": "A Rickle in Time", - "air_date": "July 26, 2015", - "episode": 1, - "season": 2 - }, - { - "id": 13, - "name": "Mortynight Run", - "air_date": "August 2, 2015", - "episode": 2, - "season": 2 - }, - { - "id": 14, - "name": "Auto Erotic Assimilation", - "air_date": "August 9, 2015", - "episode": 3, - "season": 2 - }, - { - "id": 15, - "name": "Total Rickall", - "air_date": "August 16, 2015", - "episode": 4, - "season": 2 - }, - { - "id": 16, - "name": "Get Schwifty", - "air_date": "August 23, 2015", - "episode": 5, - "season": 2 - }, - { - "id": 17, - "name": "The Ricks Must Be Crazy", - "air_date": "August 30, 2015", - "episode": 6, - "season": 2 - }, - { - "id": 18, - "name": "Big Trouble in Little Sanchez", - "air_date": "September 13, 2015", - "episode": 7, - "season": 2 - }, - { - "id": 19, - "name": "Interdimensional Cable 2: Tempting Fate", - "air_date": "September 20, 2015", - "episode": 8, - "season": 2 - }, - { - "id": 20, - "name": "Look Who's Purging Now", - "air_date": "September 27, 2015", - "episode": 9, - "season": 2 - } - ], - "locations": [ - { - "id": 1, - "name": "Earth (C-137)", - "type": "Planet", - "dimension": "Dimension C-137" - }, - { - "id": 2, - "name": "Abadango", - "type": "Cluster", - "dimension": "unknown" - }, - { - "id": 3, - "name": "Citadel of Ricks", - "type": "Space station", - "dimension": "unknown" - }, - { - "id": 4, - "name": "Worldender's lair", - "type": "Planet", - "dimension": "unknown" - }, - { - "id": 5, - "name": "Anatomy Park", - "type": "Microverse", - "dimension": "Dimension C-137" - }, - { - "id": 6, - "name": "Interdimensional Cable", - "type": "TV", - "dimension": "unknown" - }, - { - "id": 7, - "name": "Immortality Field Resort", - "type": "Resort", - "dimension": "unknown" - }, - { - "id": 8, - "name": "Post-Apocalyptic Earth", - "type": "Planet", - "dimension": "Post-Apocalyptic Dimension" - }, - { - "id": 9, - "name": "Purge Planet", - "type": "Planet", - "dimension": "Replacement Dimension" - }, - { - "id": 10, - "name": "Venzenulon 7", - "type": "Planet", - "dimension": "unknown" - }, - { - "id": 11, - "name": "Bepis 9", - "type": "Planet", - "dimension": "unknown" - }, - { - "id": 12, - "name": "Cronenberg Earth", - "type": "Planet", - "dimension": "Cronenberg Dimension" - }, - { - "id": 13, - "name": "Nuptia 4", - "type": "Planet", - "dimension": "unknown" - }, - { - "id": 14, - "name": "Giant's Town", - "type": "Fantasy town", - "dimension": "Fantasy Dimension" - }, - { - "id": 15, - "name": "Bird World", - "type": "Planet", - "dimension": "unknown" - }, - { - "id": 16, - "name": "St. Gloopy Noops Hospital", - "type": "Space station", - "dimension": "unknown" - }, - { - "id": 17, - "name": "Earth (5-126)", - "type": "Planet", - "dimension": "Dimension 5-126" - }, - { - "id": 18, - "name": "Mr. Goldenfold's dream", - "type": "Dream", - "dimension": "Dimension C-137" - }, - { - "id": 19, - "name": "Gromflom Prime", - "type": "Planet", - "dimension": "Replacement Dimension" - }, - { - "id": 20, - "name": "Earth (Replacement Dimension)", - "type": "Planet", - "dimension": "Replacement Dimension" - } - ] -} diff --git a/server/api/rickandmorty.json.backup b/server/api/rickandmorty.json.backup deleted file mode 100644 index 76c6a64..0000000 --- a/server/api/rickandmorty.json.backup +++ /dev/null @@ -1,477 +0,0 @@ -{ - "metaData": [ - { - "title": "Rick And Morty", - "longDesc": "Get all the Rick-iest Episodes, Locations and Characters from a copy of the https://rickandmortyapi.com data. That's the way Rick would have done it!", - "desc": "API for all current Rick & Morty episodes, locations and characters", - "featured": false, - "categories": ["cartoon", "tv", "entertainment"] - } - ], - "characters": [ - { - "id": 1, - "name": "Rick Sanchez", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (C-137)", - "image": "https://rickandmortyapi.com/api/character/avatar/1.jpeg" - }, - { - "id": 2, - "name": "Morty Smith", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (C-137)", - "image": "https://rickandmortyapi.com/api/character/avatar/2.jpeg" - }, - { - "id": 3, - "name": "Summer Smith", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Female", - "origin": "Earth (Replacement Dimension)", - "image": "https://rickandmortyapi.com/api/character/avatar/3.jpeg" - }, - { - "id": 4, - "name": "Beth Smith", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Female", - "origin": "Earth (Replacement Dimension)", - "image": "https://rickandmortyapi.com/api/character/avatar/4.jpeg" - }, - { - "id": 5, - "name": "Jerry Smith", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (Replacement Dimension)", - "image": "https://rickandmortyapi.com/api/character/avatar/5.jpeg" - }, - { - "id": 6, - "name": "Abadango Cluster Princess", - "status": "Alive", - "species": "Alien", - "type": "Alien", - "gender": "Female", - "origin": "Abadango", - "image": "https://rickandmortyapi.com/api/character/avatar/6.jpeg" - }, - { - "id": 7, - "name": "Abradolf Lincler", - "status": "unknown", - "species": "Human", - "type": "Genetic experiment", - "gender": "Male", - "origin": "Earth (Replacement Dimension)", - "image": "https://rickandmortyapi.com/api/character/avatar/7.jpeg" - }, - { - "id": 8, - "name": "Adjudicator Rick", - "status": "Dead", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/8.jpeg" - }, - { - "id": 9, - "name": "Agency Director", - "status": "Dead", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (Replacement Dimension)", - "image": "https://rickandmortyapi.com/api/character/avatar/9.jpeg" - }, - { - "id": 10, - "name": "Alan Rails", - "status": "Dead", - "species": "Human", - "type": "Superhuman (Ghost trains summoner)", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/10.jpeg" - }, - { - "id": 11, - "name": "Albert Einstein", - "status": "Dead", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (C-137)", - "image": "https://rickandmortyapi.com/api/character/avatar/11.jpeg" - }, - { - "id": 12, - "name": "Alexander", - "status": "Dead", - "species": "Human", - "type": "Human", - "gender": "Male", - "origin": "Earth (C-137)", - "image": "https://rickandmortyapi.com/api/character/avatar/12.jpeg" - }, - { - "id": 13, - "name": "Alien Googah", - "status": "unknown", - "species": "Alien", - "type": "Alien", - "gender": "unknown", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/13.jpeg" - }, - { - "id": 14, - "name": "Alien Morty", - "status": "unknown", - "species": "Alien", - "type": "Alien", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/14.jpeg" - }, - { - "id": 15, - "name": "Alien Rick", - "status": "unknown", - "species": "Alien", - "type": "Alien", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/15.jpeg" - }, - { - "id": 16, - "name": "Amish Cyborg", - "status": "Dead", - "species": "Alien", - "type": "Parasite", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/16.jpeg" - }, - { - "id": 17, - "name": "Annie", - "status": "Alive", - "species": "Human", - "type": "Human", - "gender": "Female", - "origin": "Earth (C-137)", - "image": "https://rickandmortyapi.com/api/character/avatar/17.jpeg" - }, - { - "id": 18, - "name": "Antenna Morty", - "status": "Alive", - "species": "Human", - "type": "Human with antennae", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/18.jpeg" - }, - { - "id": 19, - "name": "Antenna Rick", - "status": "unknown", - "species": "Human", - "type": "Human with antennae", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/19.jpeg" - }, - { - "id": 20, - "name": "Ants in my Eyes Johnson", - "status": "unknown", - "species": "Human", - "type": "Human with ants in his eyes", - "gender": "Male", - "origin": "unknown", - "image": "https://rickandmortyapi.com/api/character/avatar/20.jpeg" - } - ], - "episodes": [ - { - "id": 1, - "name": "Pilot", - "air_date": "December 2, 2013", - "episode": 1, - "season": 1 - }, - { - "id": 2, - "name": "Lawnmower Dog", - "air_date": "December 9, 2013", - "episode": 2, - "season": 1 - }, - { - "id": 3, - "name": "Anatomy Park", - "air_date": "December 16, 2013", - "episode": 3, - "season": 1 - }, - { - "id": 4, - "name": "M. Night Shaym-Aliens!", - "air_date": "January 13, 2014", - "episode": 4, - "season": 1 - }, - { - "id": 5, - "name": "Meeseeks and Destroy", - "air_date": "January 20, 2014", - "episode": 5, - "season": 1 - }, - { - "id": 6, - "name": "Rick Potion #9", - "air_date": "January 27, 2014", - "episode": 6, - "season": 1 - }, - { - "id": 7, - "name": "Raising Gazorpazorp", - "air_date": "March 10, 2014", - "episode": 7, - "season": 1 - }, - { - "id": 8, - "name": "Rixty Minutes", - "air_date": "March 17, 2014", - "episode": 8, - "season": 1 - }, - { - "id": 9, - "name": "Something Ricked This Way Comes", - "air_date": "March 24, 2014", - "episode": 9, - "season": 1 - }, - { - "id": 10, - "name": "Close Rick-counters of the Rick Kind", - "air_date": "April 7, 2014", - "episode": 10, - "season": 1 - }, - { - "id": 11, - "name": "Ricksy Business", - "air_date": "April 14, 2014", - "episode": 11, - "season": 1 - }, - { - "id": 12, - "name": "A Rickle in Time", - "air_date": "July 26, 2015", - "episode": 1, - "season": 2 - }, - { - "id": 13, - "name": "Mortynight Run", - "air_date": "August 2, 2015", - "episode": 2, - "season": 2 - }, - { - "id": 14, - "name": "Auto Erotic Assimilation", - "air_date": "August 9, 2015", - "episode": 3, - "season": 2 - }, - { - "id": 15, - "name": "Total Rickall", - "air_date": "August 16, 2015", - "episode": 4, - "season": 2 - }, - { - "id": 16, - "name": "Get Schwifty", - "air_date": "August 23, 2015", - "episode": 5, - "season": 2 - }, - { - "id": 17, - "name": "The Ricks Must Be Crazy", - "air_date": "August 30, 2015", - "episode": 6, - "season": 2 - }, - { - "id": 18, - "name": "Big Trouble in Little Sanchez", - "air_date": "September 13, 2015", - "episode": 7, - "season": 2 - }, - { - "id": 19, - "name": "Interdimensional Cable 2: Tempting Fate", - "air_date": "September 20, 2015", - "episode": 8, - "season": 2 - }, - { - "id": 20, - "name": "Look Who's Purging Now", - "air_date": "September 27, 2015", - "episode": 9, - "season": 2 - } - ], - "locations": [ - { - "id": 1, - "name": "Earth (C-137)", - "type": "Planet", - "dimension": "Dimension C-137" - }, - { - "id": 2, - "name": "Abadango", - "type": "Cluster", - "dimension": "unknown" - }, - { - "id": 3, - "name": "Citadel of Ricks", - "type": "Space station", - "dimension": "unknown" - }, - { - "id": 4, - "name": "Worldender's lair", - "type": "Planet", - "dimension": "unknown" - }, - { - "id": 5, - "name": "Anatomy Park", - "type": "Microverse", - "dimension": "Dimension C-137" - }, - { - "id": 6, - "name": "Interdimensional Cable", - "type": "TV", - "dimension": "unknown" - }, - { - "id": 7, - "name": "Immortality Field Resort", - "type": "Resort", - "dimension": "unknown" - }, - { - "id": 8, - "name": "Post-Apocalyptic Earth", - "type": "Planet", - "dimension": "Post-Apocalyptic Dimension" - }, - { - "id": 9, - "name": "Purge Planet", - "type": "Planet", - "dimension": "Replacement Dimension" - }, - { - "id": 10, - "name": "Venzenulon 7", - "type": "Planet", - "dimension": "unknown" - }, - { - "id": 11, - "name": "Bepis 9", - "type": "Planet", - "dimension": "unknown" - }, - { - "id": 12, - "name": "Cronenberg Earth", - "type": "Planet", - "dimension": "Cronenberg Dimension" - }, - { - "id": 13, - "name": "Nuptia 4", - "type": "Planet", - "dimension": "unknown" - }, - { - "id": 14, - "name": "Giant's Town", - "type": "Fantasy town", - "dimension": "Fantasy Dimension" - }, - { - "id": 15, - "name": "Bird World", - "type": "Planet", - "dimension": "unknown" - }, - { - "id": 16, - "name": "St. Gloopy Noops Hospital", - "type": "Space station", - "dimension": "unknown" - }, - { - "id": 17, - "name": "Earth (5-126)", - "type": "Planet", - "dimension": "Dimension 5-126" - }, - { - "id": 18, - "name": "Mr. Goldenfold's dream", - "type": "Dream", - "dimension": "Dimension C-137" - }, - { - "id": 19, - "name": "Gromflom Prime", - "type": "Planet", - "dimension": "Replacement Dimension" - }, - { - "id": 20, - "name": "Earth (Replacement Dimension)", - "type": "Planet", - "dimension": "Replacement Dimension" - } - ] -} diff --git a/server/api/thestates.json b/server/api/thestates.json index a90aa7b..d5d9e3c 100644 --- a/server/api/thestates.json +++ b/server/api/thestates.json @@ -2,10 +2,12 @@ "metaData": [ { "title": "The United States", - "longDesc": "Info about the all the 50 states in the United States. The endpoint includes the name, abbreviation, capital, largest city, date admitted to union, population, and state flag.", - "desc": "Info about the all the 50 states in the United States.", + "longDesc": "Information about all 50 U.S. states, including name, abbreviation, capital, largest city, date admitted to the Union, July 2024 population estimate, and state flag.", + "desc": "Information about all 50 U.S. states.", "featured": false, - "categories": ["list"] + "categories": [ + "list" + ] } ], "the-states": [ @@ -16,7 +18,7 @@ "capital": "Montgomery", "largest_city": "Birmingham", "admitted_to_union": "December 14, 1819", - "population": "4,903,185", + "population": "5,108,468", "flag": "https://upload.wikimedia.org/wikipedia/commons/5/5c/Flag_of_Alabama.svg" }, { @@ -26,7 +28,7 @@ "capital": "Juneau", "largest_city": "Anchorage", "admitted_to_union": "January 3, 1959", - "population": "710,249", + "population": "733,406", "flag": "https://upload.wikimedia.org/wikipedia/commons/e/e6/Flag_of_Alaska.svg" }, { @@ -36,7 +38,7 @@ "capital": "Phoenix", "largest_city": "Phoenix", "admitted_to_union": "February 14, 1912", - "population": "7,278,717", + "population": "7,582,384", "flag": "https://upload.wikimedia.org/wikipedia/commons/9/9d/Flag_of_Arizona.svg" }, { @@ -46,7 +48,7 @@ "capital": "Little Rock", "largest_city": "Little Rock", "admitted_to_union": "June 15, 1836", - "population": "3,017,804", + "population": "3,067,732", "flag": "https://upload.wikimedia.org/wikipedia/commons/9/9d/Flag_of_Arkansas.svg" }, { @@ -56,7 +58,7 @@ "capital": "Sacramento", "largest_city": "Los Angeles", "admitted_to_union": "September 9, 1850", - "population": "39,512,223", + "population": "39,431,263", "flag": "https://upload.wikimedia.org/wikipedia/commons/0/01/Flag_of_California.svg" }, { @@ -66,7 +68,7 @@ "capital": "Denver", "largest_city": "Denver", "admitted_to_union": "August 1, 1876", - "population": "5,758,736", + "population": "5,957,493", "flag": "https://upload.wikimedia.org/wikipedia/commons/2/21/Flag_of_Colorado_designed_by_Andrew_Carlisle_Carson.svg" }, { @@ -76,7 +78,7 @@ "capital": "Hartford", "largest_city": "Bridgeport", "admitted_to_union": "January 9, 1788", - "population": "3,565,287", + "population": "3,629,848", "flag": "https://upload.wikimedia.org/wikipedia/commons/9/96/Flag_of_Connecticut.svg" }, { @@ -86,7 +88,7 @@ "capital": "Dover", "largest_city": "Wilmington", "admitted_to_union": "December 7, 1787", - "population": "973,764", + "population": "1,031,890", "flag": "https://upload.wikimedia.org/wikipedia/commons/c/c6/Flag_of_Delaware.svg" }, { @@ -96,7 +98,7 @@ "capital": "Tallahassee", "largest_city": "Jacksonville", "admitted_to_union": "March 3, 1845", - "population": "21,477,737", + "population": "23,372,215", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f7/Flag_of_Florida.svg" }, { @@ -106,7 +108,7 @@ "capital": "Atlanta", "largest_city": "Atlanta", "admitted_to_union": "January 2, 1788", - "population": "10,617,423", + "population": "11,180,878", "flag": "https://upload.wikimedia.org/wikipedia/commons/5/54/Flag_of_Georgia_%28U.S._state%29.svg" }, { @@ -116,7 +118,7 @@ "capital": "Honolulu", "largest_city": "Honolulu", "admitted_to_union": "August 21, 1959", - "population": "1,415,872", + "population": "1,435,138", "flag": "https://upload.wikimedia.org/wikipedia/commons/e/ef/Flag_of_Hawaii.svg" }, { @@ -126,7 +128,7 @@ "capital": "Boise", "largest_city": "Boise", "admitted_to_union": "July 3, 1890", - "population": "1,787,065", + "population": "2,001,619", "flag": "https://upload.wikimedia.org/wikipedia/commons/a/a4/Flag_of_Idaho.svg" }, { @@ -136,7 +138,7 @@ "capital": "Springfield", "largest_city": "Chicago", "admitted_to_union": "December 3, 1818", - "population": "12,671,821", + "population": "12,549,689", "flag": "https://upload.wikimedia.org/wikipedia/commons/0/01/Flag_of_Illinois.svg" }, { @@ -146,7 +148,7 @@ "capital": "Indianapolis", "largest_city": "Indianapolis", "admitted_to_union": "December 11, 1816", - "population": "6,732,219", + "population": "6,862,251", "flag": "https://upload.wikimedia.org/wikipedia/commons/a/ac/Flag_of_Indiana.svg" }, { @@ -156,7 +158,7 @@ "capital": "Des Moines", "largest_city": "Des Moines", "admitted_to_union": "December 27, 1846", - "population": "3,155,070", + "population": "3,207,004", "flag": "https://upload.wikimedia.org/wikipedia/commons/a/aa/Flag_of_Iowa.svg" }, { @@ -166,7 +168,7 @@ "capital": "Topeka", "largest_city": "Wichita", "admitted_to_union": "January 29, 1861", - "population": "2,913,314", + "population": "2,940,546", "flag": "https://upload.wikimedia.org/wikipedia/commons/d/da/Flag_of_Kansas.svg" }, { @@ -176,7 +178,7 @@ "capital": "Frankfort", "largest_city": "Louisville", "admitted_to_union": "June 1, 1792", - "population": "4,467,673", + "population": "4,588,372", "flag": "https://upload.wikimedia.org/wikipedia/commons/8/8d/Flag_of_Kentucky.svg" }, { @@ -186,7 +188,7 @@ "capital": "Baton Rouge", "largest_city": "New Orleans", "admitted_to_union": "April 30, 1812", - "population": "4,648,794", + "population": "4,573,749", "flag": "https://upload.wikimedia.org/wikipedia/commons/e/e0/Flag_of_Louisiana.svg" }, { @@ -196,7 +198,7 @@ "capital": "Augusta", "largest_city": "Portland", "admitted_to_union": "March 15, 1820", - "population": "1,344,212", + "population": "1,405,012", "flag": "https://upload.wikimedia.org/wikipedia/commons/3/35/Flag_of_Maine.svg" }, { @@ -206,7 +208,7 @@ "capital": "Annapolis", "largest_city": "Baltimore", "admitted_to_union": "April 28, 1788", - "population": "6,045,680", + "population": "6,278,516", "flag": "https://upload.wikimedia.org/wikipedia/commons/a/a0/Flag_of_Maryland.svg" }, { @@ -216,7 +218,7 @@ "capital": "Boston", "largest_city": "Boston", "admitted_to_union": "February 6, 1788", - "population": "6,939,373", + "population": "7,136,171", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f2/Flag_of_Massachusetts.svg" }, { @@ -226,7 +228,7 @@ "capital": "Lansing", "largest_city": "Detroit", "admitted_to_union": "January 26, 1837", - "population": "9,883,635", + "population": "10,140,459", "flag": "https://upload.wikimedia.org/wikipedia/commons/b/b5/Flag_of_Michigan.svg" }, { @@ -236,7 +238,7 @@ "capital": "Saint Paul", "largest_city": "Minneapolis", "admitted_to_union": "May 11, 1858", - "population": "5,639,632", + "population": "5,757,832", "flag": "https://upload.wikimedia.org/wikipedia/commons/b/b9/Flag_of_Minnesota.svg" }, { @@ -246,7 +248,7 @@ "capital": "Jackson", "largest_city": "Jackson", "admitted_to_union": "December 10, 1817", - "population": "2,976,149", + "population": "2,943,740", "flag": "https://upload.wikimedia.org/wikipedia/commons/4/42/Flag_of_Mississippi.svg" }, { @@ -256,7 +258,7 @@ "capital": "Jefferson City", "largest_city": "Kansas City", "admitted_to_union": "August 10, 1821 ", - "population": "6,137,428", + "population": "6,196,156", "flag": "https://upload.wikimedia.org/wikipedia/commons/5/5a/Flag_of_Missouri.svg" }, { @@ -266,7 +268,7 @@ "capital": "Helena", "largest_city": "Billings", "admitted_to_union": "November 8, 1889", - "population": "1,068,778", + "population": "1,132,812", "flag": "https://upload.wikimedia.org/wikipedia/commons/c/cb/Flag_of_Montana.svg" }, { @@ -276,7 +278,7 @@ "capital": "Lincoln", "largest_city": "Omaha", "admitted_to_union": "March 1, 1867 ", - "population": "1,934,408", + "population": "1,981,432", "flag": "https://upload.wikimedia.org/wikipedia/commons/4/4d/Flag_of_Nebraska.svg" }, { @@ -286,7 +288,7 @@ "capital": "Carson City", "largest_city": "Las Vegas", "admitted_to_union": "October 1, 1864", - "population": "3,080,156", + "population": "3,194,176", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f1/Flag_of_Nevada.svg" }, { @@ -296,7 +298,7 @@ "capital": "Concord", "largest_city": "Manchester", "admitted_to_union": "June 21, 1788", - "population": "1,359,711", + "population": "1,402,054", "flag": "https://upload.wikimedia.org/wikipedia/commons/2/28/Flag_of_New_Hampshire.svg" }, { @@ -306,7 +308,7 @@ "capital": "Trenton", "largest_city": "Newark", "admitted_to_union": "December 18, 1787", - "population": "8,882,190", + "population": "9,500,851", "flag": "https://upload.wikimedia.org/wikipedia/commons/9/92/Flag_of_New_Jersey.svg" }, { @@ -316,7 +318,7 @@ "capital": "Santa Fe", "largest_city": "Albuquerque", "admitted_to_union": "January 6, 1912", - "population": "2,096,829", + "population": "2,114,371", "flag": "https://upload.wikimedia.org/wikipedia/commons/c/c3/Flag_of_New_Mexico.svg" }, { @@ -326,7 +328,7 @@ "capital": "Albany", "largest_city": "New York", "admitted_to_union": "July 26, 1788", - "population": "19,453,561", + "population": "19,867,248", "flag": "https://upload.wikimedia.org/wikipedia/commons/1/1a/Flag_of_New_York.svg" }, { @@ -336,7 +338,7 @@ "capital": "Raleigh", "largest_city": "Charlotte", "admitted_to_union": "November 21, 1789", - "population": "10,488,084", + "population": "10,835,491", "flag": "https://upload.wikimedia.org/wikipedia/commons/b/bb/Flag_of_North_Carolina.svg" }, { @@ -346,7 +348,7 @@ "capital": "Bismark", "largest_city": "Fargo", "admitted_to_union": "November 2, 1889", - "population": "762,062", + "population": "783,926", "flag": "https://upload.wikimedia.org/wikipedia/commons/e/ee/Flag_of_North_Dakota.svg" }, { @@ -356,7 +358,7 @@ "capital": "Columbus", "largest_city": "Columbus", "admitted_to_union": "March 1, 1803", - "population": "11,689,100", + "population": "11,785,935", "flag": "https://upload.wikimedia.org/wikipedia/commons/4/4c/Flag_of_Ohio.svg" }, { @@ -366,7 +368,7 @@ "capital": "Oklahoma City", "largest_city": "Oklahoma City", "admitted_to_union": "November 16, 1907", - "population": "3,956,971", + "population": "4,053,824", "flag": "https://upload.wikimedia.org/wikipedia/commons/6/6e/Flag_of_Oklahoma.svg" }, { @@ -376,7 +378,7 @@ "capital": "Salem", "largest_city": "Portland", "admitted_to_union": "February 14, 1859", - "population": "4,217,737", + "population": "4,272,371", "flag": "https://upload.wikimedia.org/wikipedia/commons/b/b9/Flag_of_Oregon.svg" }, { @@ -386,7 +388,7 @@ "capital": "Harrisburg", "largest_city": "Philadelphia", "admitted_to_union": "December 12, 1787", - "population": "12,801,989", + "population": "12,986,518", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f7/Flag_of_Pennsylvania.svg" }, { @@ -396,7 +398,7 @@ "capital": "Providence", "largest_city": "Providence", "admitted_to_union": "May 29, 1790", - "population": "1,059,361", + "population": "1,109,978", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f3/Flag_of_Rhode_Island.svg" }, { @@ -406,7 +408,7 @@ "capital": "Columbia", "largest_city": "Charleston", "admitted_to_union": "May 23, 1788", - "population": "5,148,714", + "population": "5,478,831", "flag": "https://upload.wikimedia.org/wikipedia/commons/6/69/Flag_of_South_Carolina.svg" }, { @@ -416,7 +418,7 @@ "capital": "Pierre", "largest_city": "Sioux Falls", "admitted_to_union": "November 2, 1889", - "population": "884,659", + "population": "919,318", "flag": "https://upload.wikimedia.org/wikipedia/commons/1/1a/Flag_of_South_Dakota.svg" }, { @@ -426,7 +428,7 @@ "capital": "Nashville", "largest_city": "Nashville", "admitted_to_union": "June 1, 1796", - "population": "6,833,793", + "population": "7,126,489", "flag": "https://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Tennessee.svg" }, { @@ -436,7 +438,7 @@ "capital": "Austin", "largest_city": "Houston", "admitted_to_union": "December 29, 1845", - "population": "28,995,881", + "population": "31,290,831", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f7/Flag_of_Texas.svg" }, { @@ -446,17 +448,17 @@ "capital": "Salt Lake City", "largest_city": "Salt Lake City", "admitted_to_union": "January 4, 1896", - "population": "3,205,958", + "population": "3,503,613", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f6/Flag_of_Utah.svg" }, { "id": 45, "name": "Vermont", "abv": "VT", - "capital": "Montpellier", + "capital": "Montpelier", "largest_city": "Burlington", "admitted_to_union": "March 4, 1791", - "population": "623,989", + "population": "647,464", "flag": "https://upload.wikimedia.org/wikipedia/commons/4/49/Flag_of_Vermont.svg" }, { @@ -466,7 +468,7 @@ "capital": "Richmond", "largest_city": "Virginia Beach", "admitted_to_union": "June 25, 1788", - "population": "8,535,519", + "population": "8,734,685", "flag": "https://upload.wikimedia.org/wikipedia/commons/4/47/Flag_of_Virginia.svg" }, { @@ -476,7 +478,7 @@ "capital": "Olympia", "largest_city": "Seattle", "admitted_to_union": "November 11, 1889", - "population": "7,614,893", + "population": "7,958,180", "flag": "https://upload.wikimedia.org/wikipedia/commons/5/54/Flag_of_Washington.svg" }, { @@ -486,7 +488,7 @@ "capital": "Charleston", "largest_city": "Charleston", "admitted_to_union": "June 20, 1863", - "population": "1,792,147", + "population": "1,769,979", "flag": "https://upload.wikimedia.org/wikipedia/commons/2/22/Flag_of_West_Virginia.svg" }, { @@ -496,7 +498,7 @@ "capital": "Madison", "largest_city": "Milwaukee", "admitted_to_union": "May 29, 1848", - "population": "5,822,434", + "population": "5,960,975", "flag": "https://upload.wikimedia.org/wikipedia/commons/2/22/Flag_of_Wisconsin.svg" }, { @@ -506,7 +508,7 @@ "capital": "Cheyenne", "largest_city": "Cheyenne", "admitted_to_union": "July 10, 1890", - "population": "578,759", + "population": "587,618", "flag": "https://upload.wikimedia.org/wikipedia/commons/b/bc/Flag_of_Wyoming.svg" } ] diff --git a/server/api/thestates.json.backup b/server/api/thestates.json.backup index a90aa7b..d5d9e3c 100644 --- a/server/api/thestates.json.backup +++ b/server/api/thestates.json.backup @@ -2,10 +2,12 @@ "metaData": [ { "title": "The United States", - "longDesc": "Info about the all the 50 states in the United States. The endpoint includes the name, abbreviation, capital, largest city, date admitted to union, population, and state flag.", - "desc": "Info about the all the 50 states in the United States.", + "longDesc": "Information about all 50 U.S. states, including name, abbreviation, capital, largest city, date admitted to the Union, July 2024 population estimate, and state flag.", + "desc": "Information about all 50 U.S. states.", "featured": false, - "categories": ["list"] + "categories": [ + "list" + ] } ], "the-states": [ @@ -16,7 +18,7 @@ "capital": "Montgomery", "largest_city": "Birmingham", "admitted_to_union": "December 14, 1819", - "population": "4,903,185", + "population": "5,108,468", "flag": "https://upload.wikimedia.org/wikipedia/commons/5/5c/Flag_of_Alabama.svg" }, { @@ -26,7 +28,7 @@ "capital": "Juneau", "largest_city": "Anchorage", "admitted_to_union": "January 3, 1959", - "population": "710,249", + "population": "733,406", "flag": "https://upload.wikimedia.org/wikipedia/commons/e/e6/Flag_of_Alaska.svg" }, { @@ -36,7 +38,7 @@ "capital": "Phoenix", "largest_city": "Phoenix", "admitted_to_union": "February 14, 1912", - "population": "7,278,717", + "population": "7,582,384", "flag": "https://upload.wikimedia.org/wikipedia/commons/9/9d/Flag_of_Arizona.svg" }, { @@ -46,7 +48,7 @@ "capital": "Little Rock", "largest_city": "Little Rock", "admitted_to_union": "June 15, 1836", - "population": "3,017,804", + "population": "3,067,732", "flag": "https://upload.wikimedia.org/wikipedia/commons/9/9d/Flag_of_Arkansas.svg" }, { @@ -56,7 +58,7 @@ "capital": "Sacramento", "largest_city": "Los Angeles", "admitted_to_union": "September 9, 1850", - "population": "39,512,223", + "population": "39,431,263", "flag": "https://upload.wikimedia.org/wikipedia/commons/0/01/Flag_of_California.svg" }, { @@ -66,7 +68,7 @@ "capital": "Denver", "largest_city": "Denver", "admitted_to_union": "August 1, 1876", - "population": "5,758,736", + "population": "5,957,493", "flag": "https://upload.wikimedia.org/wikipedia/commons/2/21/Flag_of_Colorado_designed_by_Andrew_Carlisle_Carson.svg" }, { @@ -76,7 +78,7 @@ "capital": "Hartford", "largest_city": "Bridgeport", "admitted_to_union": "January 9, 1788", - "population": "3,565,287", + "population": "3,629,848", "flag": "https://upload.wikimedia.org/wikipedia/commons/9/96/Flag_of_Connecticut.svg" }, { @@ -86,7 +88,7 @@ "capital": "Dover", "largest_city": "Wilmington", "admitted_to_union": "December 7, 1787", - "population": "973,764", + "population": "1,031,890", "flag": "https://upload.wikimedia.org/wikipedia/commons/c/c6/Flag_of_Delaware.svg" }, { @@ -96,7 +98,7 @@ "capital": "Tallahassee", "largest_city": "Jacksonville", "admitted_to_union": "March 3, 1845", - "population": "21,477,737", + "population": "23,372,215", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f7/Flag_of_Florida.svg" }, { @@ -106,7 +108,7 @@ "capital": "Atlanta", "largest_city": "Atlanta", "admitted_to_union": "January 2, 1788", - "population": "10,617,423", + "population": "11,180,878", "flag": "https://upload.wikimedia.org/wikipedia/commons/5/54/Flag_of_Georgia_%28U.S._state%29.svg" }, { @@ -116,7 +118,7 @@ "capital": "Honolulu", "largest_city": "Honolulu", "admitted_to_union": "August 21, 1959", - "population": "1,415,872", + "population": "1,435,138", "flag": "https://upload.wikimedia.org/wikipedia/commons/e/ef/Flag_of_Hawaii.svg" }, { @@ -126,7 +128,7 @@ "capital": "Boise", "largest_city": "Boise", "admitted_to_union": "July 3, 1890", - "population": "1,787,065", + "population": "2,001,619", "flag": "https://upload.wikimedia.org/wikipedia/commons/a/a4/Flag_of_Idaho.svg" }, { @@ -136,7 +138,7 @@ "capital": "Springfield", "largest_city": "Chicago", "admitted_to_union": "December 3, 1818", - "population": "12,671,821", + "population": "12,549,689", "flag": "https://upload.wikimedia.org/wikipedia/commons/0/01/Flag_of_Illinois.svg" }, { @@ -146,7 +148,7 @@ "capital": "Indianapolis", "largest_city": "Indianapolis", "admitted_to_union": "December 11, 1816", - "population": "6,732,219", + "population": "6,862,251", "flag": "https://upload.wikimedia.org/wikipedia/commons/a/ac/Flag_of_Indiana.svg" }, { @@ -156,7 +158,7 @@ "capital": "Des Moines", "largest_city": "Des Moines", "admitted_to_union": "December 27, 1846", - "population": "3,155,070", + "population": "3,207,004", "flag": "https://upload.wikimedia.org/wikipedia/commons/a/aa/Flag_of_Iowa.svg" }, { @@ -166,7 +168,7 @@ "capital": "Topeka", "largest_city": "Wichita", "admitted_to_union": "January 29, 1861", - "population": "2,913,314", + "population": "2,940,546", "flag": "https://upload.wikimedia.org/wikipedia/commons/d/da/Flag_of_Kansas.svg" }, { @@ -176,7 +178,7 @@ "capital": "Frankfort", "largest_city": "Louisville", "admitted_to_union": "June 1, 1792", - "population": "4,467,673", + "population": "4,588,372", "flag": "https://upload.wikimedia.org/wikipedia/commons/8/8d/Flag_of_Kentucky.svg" }, { @@ -186,7 +188,7 @@ "capital": "Baton Rouge", "largest_city": "New Orleans", "admitted_to_union": "April 30, 1812", - "population": "4,648,794", + "population": "4,573,749", "flag": "https://upload.wikimedia.org/wikipedia/commons/e/e0/Flag_of_Louisiana.svg" }, { @@ -196,7 +198,7 @@ "capital": "Augusta", "largest_city": "Portland", "admitted_to_union": "March 15, 1820", - "population": "1,344,212", + "population": "1,405,012", "flag": "https://upload.wikimedia.org/wikipedia/commons/3/35/Flag_of_Maine.svg" }, { @@ -206,7 +208,7 @@ "capital": "Annapolis", "largest_city": "Baltimore", "admitted_to_union": "April 28, 1788", - "population": "6,045,680", + "population": "6,278,516", "flag": "https://upload.wikimedia.org/wikipedia/commons/a/a0/Flag_of_Maryland.svg" }, { @@ -216,7 +218,7 @@ "capital": "Boston", "largest_city": "Boston", "admitted_to_union": "February 6, 1788", - "population": "6,939,373", + "population": "7,136,171", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f2/Flag_of_Massachusetts.svg" }, { @@ -226,7 +228,7 @@ "capital": "Lansing", "largest_city": "Detroit", "admitted_to_union": "January 26, 1837", - "population": "9,883,635", + "population": "10,140,459", "flag": "https://upload.wikimedia.org/wikipedia/commons/b/b5/Flag_of_Michigan.svg" }, { @@ -236,7 +238,7 @@ "capital": "Saint Paul", "largest_city": "Minneapolis", "admitted_to_union": "May 11, 1858", - "population": "5,639,632", + "population": "5,757,832", "flag": "https://upload.wikimedia.org/wikipedia/commons/b/b9/Flag_of_Minnesota.svg" }, { @@ -246,7 +248,7 @@ "capital": "Jackson", "largest_city": "Jackson", "admitted_to_union": "December 10, 1817", - "population": "2,976,149", + "population": "2,943,740", "flag": "https://upload.wikimedia.org/wikipedia/commons/4/42/Flag_of_Mississippi.svg" }, { @@ -256,7 +258,7 @@ "capital": "Jefferson City", "largest_city": "Kansas City", "admitted_to_union": "August 10, 1821 ", - "population": "6,137,428", + "population": "6,196,156", "flag": "https://upload.wikimedia.org/wikipedia/commons/5/5a/Flag_of_Missouri.svg" }, { @@ -266,7 +268,7 @@ "capital": "Helena", "largest_city": "Billings", "admitted_to_union": "November 8, 1889", - "population": "1,068,778", + "population": "1,132,812", "flag": "https://upload.wikimedia.org/wikipedia/commons/c/cb/Flag_of_Montana.svg" }, { @@ -276,7 +278,7 @@ "capital": "Lincoln", "largest_city": "Omaha", "admitted_to_union": "March 1, 1867 ", - "population": "1,934,408", + "population": "1,981,432", "flag": "https://upload.wikimedia.org/wikipedia/commons/4/4d/Flag_of_Nebraska.svg" }, { @@ -286,7 +288,7 @@ "capital": "Carson City", "largest_city": "Las Vegas", "admitted_to_union": "October 1, 1864", - "population": "3,080,156", + "population": "3,194,176", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f1/Flag_of_Nevada.svg" }, { @@ -296,7 +298,7 @@ "capital": "Concord", "largest_city": "Manchester", "admitted_to_union": "June 21, 1788", - "population": "1,359,711", + "population": "1,402,054", "flag": "https://upload.wikimedia.org/wikipedia/commons/2/28/Flag_of_New_Hampshire.svg" }, { @@ -306,7 +308,7 @@ "capital": "Trenton", "largest_city": "Newark", "admitted_to_union": "December 18, 1787", - "population": "8,882,190", + "population": "9,500,851", "flag": "https://upload.wikimedia.org/wikipedia/commons/9/92/Flag_of_New_Jersey.svg" }, { @@ -316,7 +318,7 @@ "capital": "Santa Fe", "largest_city": "Albuquerque", "admitted_to_union": "January 6, 1912", - "population": "2,096,829", + "population": "2,114,371", "flag": "https://upload.wikimedia.org/wikipedia/commons/c/c3/Flag_of_New_Mexico.svg" }, { @@ -326,7 +328,7 @@ "capital": "Albany", "largest_city": "New York", "admitted_to_union": "July 26, 1788", - "population": "19,453,561", + "population": "19,867,248", "flag": "https://upload.wikimedia.org/wikipedia/commons/1/1a/Flag_of_New_York.svg" }, { @@ -336,7 +338,7 @@ "capital": "Raleigh", "largest_city": "Charlotte", "admitted_to_union": "November 21, 1789", - "population": "10,488,084", + "population": "10,835,491", "flag": "https://upload.wikimedia.org/wikipedia/commons/b/bb/Flag_of_North_Carolina.svg" }, { @@ -346,7 +348,7 @@ "capital": "Bismark", "largest_city": "Fargo", "admitted_to_union": "November 2, 1889", - "population": "762,062", + "population": "783,926", "flag": "https://upload.wikimedia.org/wikipedia/commons/e/ee/Flag_of_North_Dakota.svg" }, { @@ -356,7 +358,7 @@ "capital": "Columbus", "largest_city": "Columbus", "admitted_to_union": "March 1, 1803", - "population": "11,689,100", + "population": "11,785,935", "flag": "https://upload.wikimedia.org/wikipedia/commons/4/4c/Flag_of_Ohio.svg" }, { @@ -366,7 +368,7 @@ "capital": "Oklahoma City", "largest_city": "Oklahoma City", "admitted_to_union": "November 16, 1907", - "population": "3,956,971", + "population": "4,053,824", "flag": "https://upload.wikimedia.org/wikipedia/commons/6/6e/Flag_of_Oklahoma.svg" }, { @@ -376,7 +378,7 @@ "capital": "Salem", "largest_city": "Portland", "admitted_to_union": "February 14, 1859", - "population": "4,217,737", + "population": "4,272,371", "flag": "https://upload.wikimedia.org/wikipedia/commons/b/b9/Flag_of_Oregon.svg" }, { @@ -386,7 +388,7 @@ "capital": "Harrisburg", "largest_city": "Philadelphia", "admitted_to_union": "December 12, 1787", - "population": "12,801,989", + "population": "12,986,518", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f7/Flag_of_Pennsylvania.svg" }, { @@ -396,7 +398,7 @@ "capital": "Providence", "largest_city": "Providence", "admitted_to_union": "May 29, 1790", - "population": "1,059,361", + "population": "1,109,978", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f3/Flag_of_Rhode_Island.svg" }, { @@ -406,7 +408,7 @@ "capital": "Columbia", "largest_city": "Charleston", "admitted_to_union": "May 23, 1788", - "population": "5,148,714", + "population": "5,478,831", "flag": "https://upload.wikimedia.org/wikipedia/commons/6/69/Flag_of_South_Carolina.svg" }, { @@ -416,7 +418,7 @@ "capital": "Pierre", "largest_city": "Sioux Falls", "admitted_to_union": "November 2, 1889", - "population": "884,659", + "population": "919,318", "flag": "https://upload.wikimedia.org/wikipedia/commons/1/1a/Flag_of_South_Dakota.svg" }, { @@ -426,7 +428,7 @@ "capital": "Nashville", "largest_city": "Nashville", "admitted_to_union": "June 1, 1796", - "population": "6,833,793", + "population": "7,126,489", "flag": "https://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Tennessee.svg" }, { @@ -436,7 +438,7 @@ "capital": "Austin", "largest_city": "Houston", "admitted_to_union": "December 29, 1845", - "population": "28,995,881", + "population": "31,290,831", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f7/Flag_of_Texas.svg" }, { @@ -446,17 +448,17 @@ "capital": "Salt Lake City", "largest_city": "Salt Lake City", "admitted_to_union": "January 4, 1896", - "population": "3,205,958", + "population": "3,503,613", "flag": "https://upload.wikimedia.org/wikipedia/commons/f/f6/Flag_of_Utah.svg" }, { "id": 45, "name": "Vermont", "abv": "VT", - "capital": "Montpellier", + "capital": "Montpelier", "largest_city": "Burlington", "admitted_to_union": "March 4, 1791", - "population": "623,989", + "population": "647,464", "flag": "https://upload.wikimedia.org/wikipedia/commons/4/49/Flag_of_Vermont.svg" }, { @@ -466,7 +468,7 @@ "capital": "Richmond", "largest_city": "Virginia Beach", "admitted_to_union": "June 25, 1788", - "population": "8,535,519", + "population": "8,734,685", "flag": "https://upload.wikimedia.org/wikipedia/commons/4/47/Flag_of_Virginia.svg" }, { @@ -476,7 +478,7 @@ "capital": "Olympia", "largest_city": "Seattle", "admitted_to_union": "November 11, 1889", - "population": "7,614,893", + "population": "7,958,180", "flag": "https://upload.wikimedia.org/wikipedia/commons/5/54/Flag_of_Washington.svg" }, { @@ -486,7 +488,7 @@ "capital": "Charleston", "largest_city": "Charleston", "admitted_to_union": "June 20, 1863", - "population": "1,792,147", + "population": "1,769,979", "flag": "https://upload.wikimedia.org/wikipedia/commons/2/22/Flag_of_West_Virginia.svg" }, { @@ -496,7 +498,7 @@ "capital": "Madison", "largest_city": "Milwaukee", "admitted_to_union": "May 29, 1848", - "population": "5,822,434", + "population": "5,960,975", "flag": "https://upload.wikimedia.org/wikipedia/commons/2/22/Flag_of_Wisconsin.svg" }, { @@ -506,7 +508,7 @@ "capital": "Cheyenne", "largest_city": "Cheyenne", "admitted_to_union": "July 10, 1890", - "population": "578,759", + "population": "587,618", "flag": "https://upload.wikimedia.org/wikipedia/commons/b/bc/Flag_of_Wyoming.svg" } ] diff --git a/server/apiList.js b/server/apiList.js index 07a4c0c..4db8049 100644 --- a/server/apiList.js +++ b/server/apiList.js @@ -224,16 +224,6 @@ module.exports = [ }, { id: 22, - title: "Rick And Morty", - longDesc: - "Get all the Rick-iest Episodes, Locations and Characters from a copy of the https://rickandmortyapi.com data. That's the way Rick would have done it!", - desc: "API for all current Rick & Morty episodes, locations and characters", - link: "rickandmorty", - graphLink: "rickandmorty/graphql", - endPoints: ["characters", "episodes", "locations"], - }, - { - id: 23, title: "Coffee", longDesc: "Basic list of descriptions and ingredients used for the most popular coffee drinks", desc: "API for popular coffee drinks", @@ -259,13 +249,4 @@ module.exports = [ graphLink: "jokes/graphql", endPoints: ["goodJokes"], }, - { - id: 25, - title: "Bitcoin (historical data)", - longDesc: "You've wanted it and now we got it. Going back from January 2022 to August 2010", - desc: "Bitcoin Historical Data from August 2010 to January 2022", - link: "bitcoin", - graphLink: "bitcoin/graphql", - endPoints: ["historical_prices"], - }, ]; From fd2cf278e25e86f0cfdb799ed6abfaa7b0084c70 Mon Sep 17 00:00:00 2001 From: jermbo Date: Thu, 9 Jul 2026 09:09:46 -0400 Subject: [PATCH 13/26] fix: update health check endpoint and remove GraphQL references - Changed health check command in docker-compose.yml to point to the /health endpoint. - Deleted GraphQL references from various files, including API descriptions and component props, to streamline the API focus on RESTful endpoints. - Removed unused GraphQL links from apiList.js and related files, enhancing clarity and reducing confusion for users. --- GraphQL_Basics.md | 140 ------------------ client/index.html | 6 +- client/src/components/Endpoints/Endpoints.tsx | 14 +- client/src/pages/APIDetails/APIDetails.tsx | 1 - client/src/pages/About/About.tsx | 6 +- client/src/pages/Home/Home.tsx | 3 +- docker-compose.yml | 2 +- server/apiList.js | 24 --- server/package-lock.json | 13 ++ server/package.json | 1 + server/routes/custom-apis.js | 81 ---------- server/routes/reset.js | 54 +++---- server/sampleapis.js | 38 ++++- server/tests/apis.test.js | 4 - server/tests/baseline/beers-graphql-ales.json | 1 - server/utils/jsonRouter.js | 40 +++-- server/views/custom.pug | 33 ----- server/views/index.pug | 1 - 18 files changed, 101 insertions(+), 361 deletions(-) delete mode 100644 GraphQL_Basics.md delete mode 100644 server/routes/custom-apis.js delete mode 100644 server/tests/baseline/beers-graphql-ales.json delete mode 100644 server/views/custom.pug diff --git a/GraphQL_Basics.md b/GraphQL_Basics.md deleted file mode 100644 index 7da654a..0000000 --- a/GraphQL_Basics.md +++ /dev/null @@ -1,140 +0,0 @@ -

- -

GraphQL

-

- -### About : - -This documentation will cover the basics of GraphQL API's. It will include why and when to use GraphQL API's. In this documentation we will cover GraphQL examples with Node.js and Express. - -## What is GraphQL ? -GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. It has many advantages over REST API's while used with large scale applications. It allows the developer to get exactly the data they want without overfetching or underfetching. - -## GraphQL vs REST Structure -Below you can see the difference between REST and GraphQL API Structures. It's important to understand how REST works to see the benefits of GraphQL. As it is seen GraphQL can only perform POST requests and to update data it uses mutations. - -GraphQL: - - -REST: - -## GraphQL Elements -GraphQL has some different keywords then REST. These are: - - Schema - - TypeDefs - - Queries - - Muations - -### Sample JSON Data -This JSON file is going to be act as a database. -```jsx -[ -{"id":1,"pizza_name":"Cheese Pizza", "price": "10$", "ingredients":["Mushrooms","Olives","Extra Cheese"]}, -{"id":2,"pizza_name":"Pepperoni Pizza", "price": "12$", "ingredients":["Pepperoni","Mushrooms","Olives"]}, -{"id":3,"pizza_name":"Veggie Pizza", "price": "15$", "ingredients":["Mushrooms","Olives","Green Peppers","Onions","Extra Cheese"]}, -{"id":4,"pizza_name":"Meat Pizza", "price": "20$", "ingredients":["Pepperoni","Mushrooms","Olives","Sausage","Black Olives","Green Peppers","Onions","Extra Cheese"]}, -{"id":5,"pizza_name":"Margherita Pizza", "price": "10$", "ingredients":["Olives","Sausage","Black Olives"]}, -{"id":6,"pizza_name":"BBQ Chicken Pizza", "price": "18$", "ingredients":["Chicken","Mushrooms","Olives","Sausage","Black Olives","Green Peppers","Onions","Extra Cheese"]}, -{"id":7,"pizza_name":"Hawaiian Pizza", "price": "16$", "ingredients":["Mushrooms","Olives","Sausage","Black Olives","Green Peppers","Onions","Extra Cheese"]} -] -``` -### Schema -Schema is the place where the queries and mutations are stored. Both the front-end and back-end team can look at the schema and understand the API. - -You can see an example schema down below with express and GraphQL. -```jsx -const Query = new GraphQLObjectType({...}); -const Mutation = new GraphQLObjectType({...}); - -//Schema -const schema = new GraphQLSchema({ - query: Query, - mutation: Mutation, -}); - -app.use('/graphql', graphqlHTTP({ - schema, - graphiql: true -})); -``` -The graphiql boolean allows us to open a in browser API testing app. - -### Type Defs -Every graph uses a **schema** to define the types of data it includes. You can think of them just like type definitions from Java like **int**, **string**, **float** etc. -```jsx -const PizzaType = new GraphQLObjectType({ - name: 'Pizza', - fields: { - id: {type: GraphQLInt}, - pizza_name: {type: GraphQLString}, - price: {type: GraphQLString}, - ingredients: {type: GraphQLList(GraphQLString)}, - } -}); -``` - -### Queries -Queries allows us to get data from our API. -```jsx -const Query = new GraphQLObjectType({ - name: 'Query', - fields: { - getAll: { - type: new GraphQLList(PizzaType), - resolve(parent, args) { - return pizzaDB; - } - } - } -}); -``` - -The great thing about queries is that it allows us to get any data we want. If we want all the data but not the **id** we can do that with just one request in GraphQL and there won't be any unused data so it's going to prevent overfetching. -```jsx -query { - getAll { - pizza_name - price - ingredients - } -} -``` -### Mutations -Mutations allows us to mutate our data. We can use mutations to update, delete and etc. inside our API. In the below example we create a mutation to add a new pizza to our pizza JSON database. -```jsx -const Mutation = new GraphQLObjectType({ - name: 'Mutation', - fields: { - createNewPizza: { - type: PizzaType, - args: { - pizza_name: {type: GraphQLString}, - price: {type: GraphQLString}, - ingredients: {type: GraphQLList(GraphQLString)} - }, - resolve(parent, args) { - pizzaDB.push({ - id: pizzaDB.length + 1, - pizza_name: args.pizza_name, - price: args.price, - ingredients: args.ingredients - }); - - return args; - } - } - } -}); -``` - -At below we execute our mutation like this. We don't need to specify the ID since it automatically increases its id to the size of the JSON data. This prevents human error factor. The fallowing query inside of the **createNewPizza** will display the new items that got added. -```jsx -mutation { - createNewPizza(pizza_name: "New Pizza", price: "0$", ingredients: ["tomato", "pepper", "cheese"]) { - id - pizza_name - price - infredients - } -} -``` diff --git a/client/index.html b/client/index.html index 5d9b319..74d4399 100644 --- a/client/index.html +++ b/client/index.html @@ -13,15 +13,15 @@ - + - + diff --git a/client/src/components/Endpoints/Endpoints.tsx b/client/src/components/Endpoints/Endpoints.tsx index 200dad3..6735b86 100644 --- a/client/src/components/Endpoints/Endpoints.tsx +++ b/client/src/components/Endpoints/Endpoints.tsx @@ -1,13 +1,11 @@ import React, { Dispatch, SetStateAction, useState } from "react"; -import { URLS } from "../../utils/Config"; interface Props { - urlBase: string; endpoints: string[]; onEndpointSelect: Dispatch>; } -const APIEndpoints: React.FC = ({ urlBase, endpoints, onEndpointSelect }) => { +const APIEndpoints: React.FC = ({ endpoints, onEndpointSelect }) => { const [selected, setSelected] = useState("initialState"); const showCode = (endpoint: string) => { @@ -22,16 +20,6 @@ const APIEndpoints: React.FC = ({ urlBase, endpoints, onEndpointSelect }) return (
    -
  • - - GraphQL - -
  • {endpoints.map((endpoint) => (