diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 5444d05..0000000
--- a/.dockerignore
+++ /dev/null
@@ -1,75 +0,0 @@
-# Dependencies
-node_modules
-npm-debug.log*
-
-# Build output
-dist
-
-# Environment files
-.env
-.env.local
-.env.development.local
-.env.test.local
-.env.production.local
-
-# Git
-.git
-.gitignore
-
-# IDE
-.vscode
-.idea
-*.swp
-*.swo
-
-# OS
-.DS_Store
-Thumbs.db
-
-# Logs
-logs
-*.log
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Coverage directory used by tools like istanbul
-coverage
-
-# nyc test coverage
-.nyc_output
-
-# Dependency directories
-jspm_packages/
-
-# Optional npm cache directory
-.npm
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# Docker
-Dockerfile
-.dockerignore
-
-# Documentation
-README.md
-*.md
-
-# Test files
-test
-tests
-__tests__
-*.test.js
-*.test.ts
-*.spec.js
-*.spec.ts
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..fe56b7a
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,13 @@
+# MongoDB Configuration
+MONGODB_URI=mongodb://localhost:27017
+NP_DB_NAME=nanda_points
+
+# Server Configuration
+PORT=3000
+HOST=localhost
+
+# x402 Facilitator Configuration
+FACILITATOR_URL=http://localhost:3000/facilitator
+
+# Payment Configuration (for x402 servers)
+ADDRESS=system # Agent name to receive payments
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index c37d36d..1ec6b0d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,89 @@
-node_modules
+# Dependencies
+node_modules/
+packages/*/node_modules/
+
+# Build outputs
+dist/
+build/
+packages/*/dist/
+packages/*/build/
+*.tsbuildinfo
+
+# Environment variables
.env
-dist
-.DS_Store
+.env.local
+.env.*.local
-# Cursor IDE configuration (contains personal/temporary URLs)
+# IDE configuration files
.cursor/
-.vscode/
\ No newline at end of file
+.vscode/
+.idea/
+*.swp
+*.swo
+
+# OS generated files
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
+
+# Logs
+logs/
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# Runtime data
+pids/
+*.pid
+*.seed
+*.pid.lock
+
+# Coverage directory used by tools like istanbul
+coverage/
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Personal development notes
+CLAUDE.md
+*.notes.md
+_test.md
+
+# Temporary files
+*.tmp
+*.temp
+.cache/
+
+# Package manager lock files (allow package-lock.json for reproducible builds)
+# yarn.lock
+
+# Python cache files
+__pycache__/
+*.py[cod]
+*$py.class
+*.so
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
\ No newline at end of file
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..ae3e78a
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,12 @@
+{
+ "semi": true,
+ "trailingComma": "es5",
+ "singleQuote": false,
+ "printWidth": 100,
+ "tabWidth": 2,
+ "useTabs": false,
+ "endOfLine": "lf",
+ "arrowParens": "always",
+ "bracketSpacing": true,
+ "quoteProps": "as-needed"
+}
\ No newline at end of file
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..fa9aa9e
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,208 @@
+# Claude Instructions for NANDA Points Server SDK
+
+## Current Context
+
+You are working on the completed NANDA Points Server SDK (`feature/mcp-server-sdk`) that provides server-side utilities for MCP developers who want to monetize their tools using NANDA Points.
+
+## Project Overview
+
+This SDK provides language-native server libraries for integrating NANDA Points payments into MCP servers and Express.js applications. The focus is on server-side tool monetization, not client-side payment utilities.
+
+**Goal**: The "only way" developers integrate NANDA Points payments into MCP servers: `npm install @nanda/payments-sdk`
+
+## Key Documents
+
+- **PRD.md**: Updated product requirements focused on server-side MCP tool monetization
+- **PLAN.md**: Implementation plan with Phase 1 completed, Phase 2 (documentation) in progress
+- **sdks/payments-sdk/**: Complete TypeScript server SDK implementation
+
+## Current Status ✅ PHASE 1 COMPLETED
+
+- ✅ Feature branch: `feature/mcp-server-sdk` with all SDK commits
+- ✅ TypeScript Server SDK: Complete and ready for npm publication
+- ✅ MCP-specific payment utilities: requirePayment(), createPaidTool(), quickSetup()
+- ✅ Express middleware: paymentMiddleware() for route-level payment protection
+- ✅ Working examples: Complete MCP server showing free vs paid tools
+- ✅ Type safety: Zero TypeScript compilation errors
+- 📝 Phase 2: Documentation and examples in progress
+
+## Implementation Architecture ✅ COMPLETED
+
+### Core Components
+1. **MCP Payment Utilities** (`src/server/index.ts`)
+ - `requirePayment()`: Decorator to wrap free tools with payment requirements
+ - `createPaidTool()`: Create new payment-protected MCP tools
+ - `quickSetup()`: Rapid configuration for MCP servers
+ - `paymentMiddleware()`: Express middleware for route-level protection
+
+2. **Facilitator Integration** (`src/facilitator/index.ts`)
+ - Type-safe wrapper for facilitator endpoints (/verify, /settle, /supported)
+ - Extracted from working `packages/shared` implementation
+ - Automatic retry logic and error handling
+
+3. **Type System** (`src/shared/types.ts`)
+ - Complete x402 protocol type definitions
+ - NANDA Points specific interfaces
+ - Payment requirement and configuration types
+ - Comprehensive error hierarchy
+
+4. **Examples** (`src/examples/`)
+ - Complete MCP server demonstrating paid tool integration
+ - Free vs paid tool comparison
+ - Real-world usage patterns
+
+## Package Structure ✅ IMPLEMENTED
+
+```
+sdks/payments-sdk/ # @nanda/payments-sdk
+├── src/
+│ ├── shared/ # Core x402 and NANDA Points types
+│ ├── facilitator/ # Facilitator API wrapper
+│ ├── server/ # MCP server utilities
+│ ├── examples/ # Working MCP server examples
+│ └── index.ts # Main entry with quickSetup()
+├── dist/ # Compiled TypeScript output
+├── package.json # npm package ready for publication
+└── tsconfig.json # TypeScript configuration
+```
+
+## API Usage Patterns ✅ IMPLEMENTED
+
+### Quick Setup for MCP Servers
+```typescript
+import { quickSetup } from '@nanda/payments-sdk';
+
+const payments = await quickSetup({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'my-mcp-server'
+});
+
+// Convert free tool to paid tool
+const paidTool = payments.requirePayment({
+ amount: 50,
+ description: 'Premium tool access'
+})(originalFreeTool);
+```
+
+### Express Middleware Integration
+```typescript
+import { paymentMiddleware, createPaymentConfig } from '@nanda/payments-sdk';
+
+const config = createPaymentConfig({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'api-server'
+});
+
+app.use(paymentMiddleware({
+ '/api/premium': { amount: 25, description: 'Premium API access' }
+}, config));
+```
+
+### MCP Tool Creation
+```typescript
+import { createPaidTool } from '@nanda/payments-sdk';
+
+const weatherTool = createPaidTool(
+ 'premium_weather',
+ { amount: 100, description: 'Premium weather analysis' },
+ config,
+ async (args) => getPremiumWeatherData(args.location)
+);
+```
+
+## Quality Standards ✅ ACHIEVED
+
+- ✅ Zero TypeScript compilation errors
+- ✅ Complete type safety with IntelliSense support
+- ✅ Extracted from working packages/shared implementation
+- ✅ x402 protocol compliance following Coinbase patterns
+- ✅ npm package configuration ready for publication
+- ✅ Working examples demonstrating all features
+
+## Implementation Decisions
+
+### Server-Side Focus
+- **Primary Use Case**: MCP server developers monetizing tools
+- **Secondary Use Case**: Express.js developers adding payment protection
+- **Future Expansion**: Client-side utilities for A2A/A2P scenarios
+
+### Technical Choices
+- Extracted working middleware from `packages/shared` (no reinvention)
+- TypeScript-first with comprehensive type definitions
+- Modular design allowing future client-side expansion
+- Zero external dependencies beyond essential HTTP/Express libraries
+
+## Current Phase: Documentation 📝
+
+### Completed Documentation Updates
+- ✅ PLAN.md: Updated with Phase 1 completion status
+- ✅ PRD.md: Refocused on server-side MCP tool monetization
+- 📝 CLAUDE.md: Updated with current implementation status
+
+### Remaining Documentation Tasks
+- [ ] Create comprehensive README.md for the SDK package
+- [ ] Document developer journey from free to paid tools
+- [ ] Add API reference documentation
+- [ ] Create troubleshooting guide
+- [ ] Build additional MCP server examples
+
+## Commands to Remember
+
+- `npm run build` - Build the SDK package (TypeScript compilation)
+- `npm run lint` - Check code quality (must pass before commits)
+- `npm run test` - Run test suites (when implemented)
+- `npm run dev` - Start development servers for testing
+
+## Integration Notes
+
+- **Facilitator**: Uses existing facilitator endpoints without modification
+- **x402 Protocol**: Follows Coinbase reference implementation patterns
+- **NANDA Points**: Compatible with existing NANDA Points transaction system
+- **MongoDB**: Works with existing transaction schema and patterns
+
+## Success Metrics ✅ ACHIEVED
+
+- **Package Ready**: npm package configured and buildable
+- **Zero Errors**: Complete TypeScript compilation without errors
+- **Type Safety**: Full IntelliSense support for all APIs
+- **Working Examples**: Complete MCP server demonstrating monetization
+- **Developer Experience**: Three-line setup with quickSetup()
+
+## Future Expansion Plans
+
+### Client-Side SDK (Future)
+- Payment creation utilities for requesting agents
+- Agent balance management and transaction history
+- A2A (Agent-to-Agent) payment flows
+- A2P (Agent-to-Person) payment scenarios
+
+### Additional Languages (Future)
+- Python SDK for server-side tool monetization
+- Same API patterns adapted to Python conventions
+- FastAPI/Django middleware integration
+
+### Enhanced Developer Experience (Future)
+- Mock facilitator utilities for testing
+- CLI tools for payment debugging
+- Comprehensive logging and monitoring
+- Performance optimization features
+
+## Important Notes
+
+- **"Only Way" Philosophy**: This SDK is designed to be the standard way to add payments to MCP tools
+- **No Migration Needed**: We are the first/only users, so no existing integrations to migrate
+- **Extraction Strategy**: Leveraged existing working implementation rather than rebuilding
+- **x402 Compliance**: Follows established patterns from Coinbase reference implementation
+
+## Definition of Done ✅ COMPLETED
+
+An MCP developer can:
+1. ✅ `npm install @nanda/payments-sdk`
+2. ✅ Setup payments with quickSetup() in 3 lines of code
+3. ✅ Wrap free tools with requirePayment() to monetize them
+4. ✅ Create new paid tools with createPaidTool()
+5. ✅ Access full TypeScript IntelliSense and type safety
+6. ✅ Use Express middleware for route-level payment protection
+7. ✅ See working examples in a complete MCP server
+
+The TypeScript Server SDK is complete and ready for developer use. Phase 2 focuses on comprehensive documentation to support adoption.
\ No newline at end of file
diff --git a/DOCKER.md b/DOCKER.md
deleted file mode 100644
index b8664dc..0000000
--- a/DOCKER.md
+++ /dev/null
@@ -1,201 +0,0 @@
-# Docker Setup for NANDA Points Combined Server
-
-This document explains how to run the NANDA Points Combined Server (MCP + API) using Docker with NANDA's actual database.
-
-## Services
-
-The combined server runs both services on separate ports:
-
-- **MCP Server**: `http://localhost:3000` - Model Context Protocol server for AI agents
-- **API Server**: `http://localhost:8080` - REST API for UI teams to access data
-
-## Prerequisites
-
-- Docker and Docker Compose installed
-- Access to NANDA's MongoDB database
-- Environment variables configured (see below)
-
-## Quick Start
-
-### Using Docker Compose (Recommended)
-
-1. **Set up environment variables:**
-
- ```bash
- # Create .env file with NANDA's database credentials
- echo "MONGODB_URI=mongo_url" > .env
- echo "NP_DB_NAME=nanda_points" >> .env
- ```
-
-2. **Start the server:**
-
- ```bash
- docker-compose up -d
- ```
-
-3. **Seed the database (if needed):**
-
- ```bash
- docker-compose exec nanda-points-server node seed.js
- ```
-
-4. **Check health:**
-
- ```bash
- # MCP Server health
- curl http://localhost:3000/health
-
- # API Server health
- curl http://localhost:8080/api/health
- ```
-
-5. **Test API endpoints:**
-
- ```bash
- # Get all wallets
- curl http://localhost:8080/api/wallets
-
- # Get all transactions
- curl http://localhost:8080/api/transactions
-
- # Get all receipts
- curl http://localhost:8080/api/receipts
- ```
-
-6. **Stop services:**
- ```bash
- docker-compose down
- ```
-
-### Using Docker directly
-
-1. **Build the image:**
-
- ```bash
- docker build -t nanda-points-mcp .
- ```
-
-2. **Run with NANDA's database:**
- ```bash
- docker run -p 3000:3000 \
- -e MONGODB_URI="mongo_url" \
- -e NP_DB_NAME="nanda_points" \
- nanda-points-mcp
- ```
-
-## Environment Variables
-
-| Variable | Default | Description |
-| ------------- | -------------- | ------------------------- |
-| `NODE_ENV` | `production` | Node.js environment |
-| `PORT` | `3000` | Server port |
-| `HOST` | `0.0.0.0` | Server host |
-| `MONGODB_URI` | Required | MongoDB connection string |
-| `NP_DB_NAME` | `nanda_points` | Database name |
-
-## Services
-
-### NANDA Points MCP Server
-
-- **Port:** 3000
-- **Health Check:** `GET /health`
-- **MCP Endpoint:** `POST /mcp`
-- **SSE Stream:** `GET /mcp`
-- **Database:** Connects to NANDA's MongoDB cluster
-
-## Development
-
-### Local Development with Docker
-
-```bash
-# Set up environment variables
-export MONGODB_URI="link-to-your-registry"
-export NP_DB_NAME="nanda_points"
-
-# Run the server locally
-npm run dev
-```
-
-### Debugging
-
-```bash
-# View logs
-docker-compose logs -f nanda-points-server
-
-# Access container shell
-docker-compose exec nanda-points-server sh
-
-# View MongoDB logs
-docker-compose logs -f mongodb
-```
-
-## Production Deployment
-
-### Environment Variables for Production
-
-```bash
-# .env file
-NODE_ENV=production
-PORT=3000
-HOST=0.0.0.0
-MONGODB_URI=mongo_url
-NP_DB_NAME=nanda_points
-```
-
-### Docker Compose Override
-
-Create `docker-compose.prod.yml`:
-
-```yaml
-version: "3.8"
-services:
- nanda-points-server:
- environment:
- MONGODB_URI: ${MONGODB_URI}
- restart: always
-```
-
-Run with:
-
-```bash
-docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
-```
-
-## Troubleshooting
-
-### Common Issues
-
-1. **MongoDB Connection Failed**
-
- - Verify NANDA's database connection string in environment variables
- - Check if you have access to NANDA's MongoDB cluster
- - Verify network connectivity to the database
-
-2. **Port Already in Use**
-
- - Change port in docker-compose.yml
- - Kill existing process: `lsof -ti:3000 | xargs kill -9`
-
-3. **Permission Denied**
- - Ensure proper file permissions
- - Check if running as correct user
-
-### Health Checks
-
-```bash
-# Check server health
-curl http://localhost:3000/health
-
-# Check MongoDB connection
-docker-compose exec nanda-points-server node -e "
-const { MongoClient } = require('mongodb');
-const client = new MongoClient(process.env.MONGODB_URI);
-client.connect().then(() => {
- console.log('MongoDB connected successfully');
- process.exit(0);
-}).catch(err => {
- console.error('MongoDB connection failed:', err);
- process.exit(1);
-});
-"
-```
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 458fbc4..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,50 +0,0 @@
-# ---------- Builder ----------
-FROM node:20-alpine AS builder
-
-# Workdir
-WORKDIR /app
-
-# Install ALL deps (including dev) so TypeScript can compile
-COPY package*.json ./
-RUN npm ci
-
-# Copy the rest of the source and build
-COPY . .
-RUN npm run build
-
-# ---------- Runtime ----------
-FROM node:20-alpine AS runner
-
-WORKDIR /app
-
-# Copy only the files needed at runtime
-COPY package*.json ./
-# Install ONLY production deps for a smaller image
-RUN npm ci --omit=dev
-
-# Bring over the compiled JS from the builder stage
-COPY --from=builder /app/dist ./dist
-
-# If you have any non-TS runtime assets (configs/public files), copy them as needed.
-# Example: uncomment if you ship an MCP manifest or static assets at runtime
-# COPY --from=builder /app/mcp.json ./mcp.json
-# COPY --from=builder /app/public ./public
-
-# Use the pre-created non-root `node` user in the official image
-USER node
-
-# Network
-EXPOSE 3000 8080
-
-# Environment
-ENV NODE_ENV=production
-ENV MCP_PORT=3000
-ENV API_PORT=8080
-ENV HOST=0.0.0.0
-
-# Health check (adjust path if your server exposes a different health route)
-HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
- CMD node -e "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"
-
-# Start the app (expects your package.json start script to run the built server, e.g., `node dist/index.js`)
-CMD ["npm", "start"]
\ No newline at end of file
diff --git a/PLAN.md b/PLAN.md
new file mode 100644
index 0000000..1b9d0f2
--- /dev/null
+++ b/PLAN.md
@@ -0,0 +1,259 @@
+# Implementation Plan: NANDA Points Server SDK (TypeScript)
+
+## Overview
+
+Build server-side SDK focused on MCP server developers who want to monetize their tools. The SDK provides language-native interfaces to the x402 protocol and facilitator APIs, enabling developers to add payment requirements to their tools without understanding protocol details.
+
+**Updated Focus**: Server-side SDK for MCP developers (not client SDK)
+
+## Phase 1: TypeScript Server SDK Foundation ✅ COMPLETED
+
+### Goal
+Create the core TypeScript SDK for MCP server developers to easily add payment requirements to their tools.
+
+### Tasks
+- [x] Create `sdks/payments-sdk/` package structure
+- [x] Extract working facilitator client from packages/shared
+- [x] Build MCP-specific payment wrapper utilities (requirePayment, createPaidTool)
+- [x] Implement x402-compliant payment middleware for Express servers
+- [x] Add comprehensive TypeScript definitions for all payment types
+- [x] Create developer-friendly API following x402 patterns
+- [x] Build working MCP server example demonstrating paid tools
+- [x] Package configured for npm publication as @nanda/payments-sdk
+- [x] Fix TypeScript compilation and ensure zero lint errors
+
+### Deliverables ✅ COMPLETED
+- [x] Working `@nanda/payments-sdk` TypeScript package
+- [x] Server-side payment utilities for MCP developers
+- [x] Facilitator API wrapper extracted from working implementation
+- [x] MCP-specific tools: requirePayment(), createPaidTool(), paymentMiddleware()
+- [x] Complete example MCP server showing free vs paid tools
+- [x] npm package ready for publication
+- [x] TypeScript definitions with zero compilation errors
+
+### Actual Time: 1 day (leveraged existing working implementation)
+
+## Phase 2: Documentation & Examples 📝 IN PROGRESS
+
+### Goal
+Complete documentation and create comprehensive examples for the TypeScript SDK.
+
+### Tasks
+- [x] Update PLAN.md with current progress and completion status
+- [ ] Update PRD.md to reflect server-side focus
+- [ ] Create comprehensive README.md for the SDK
+- [ ] Document the developer journey from free to paid tools
+- [ ] Create additional MCP server examples
+- [ ] Add API reference documentation
+- [ ] Create troubleshooting guide
+
+### Deliverables
+- [ ] Complete SDK documentation
+- [ ] Multiple example MCP servers
+- [ ] API reference guide
+- [ ] Migration guide for existing MCP servers
+
+## Phase 3: Documentation & Polish (Week 3)
+
+### Goal
+Complete documentation, examples, and production readiness features.
+
+### Tasks
+- [ ] Create comprehensive API documentation for both SDKs
+- [ ] Build integration tutorials for popular frameworks
+- [ ] Create real-world usage examples and case studies
+- [ ] Add advanced error handling and debugging features
+- [ ] Implement connection pooling and performance optimization
+- [ ] Create migration guides from manual integration
+- [ ] Build CLI tools for testing and debugging
+- [ ] Add webhook support and event handling
+
+### Deliverables
+- [ ] Complete API documentation for both SDKs
+- [ ] Integration tutorials and examples
+- [ ] Performance optimization features
+- [ ] CLI tools for developers
+- [ ] Production deployment guides
+
+### Estimated Time: 5-7 days
+
+## Technical Architecture
+
+### Monorepo Structure
+```
+sdks/
+├── typescript/ # TypeScript SDK (@nanda/payments-sdk)
+│ ├── src/
+│ │ ├── client/ # x402 Payment client
+│ │ ├── facilitator/ # Facilitator API wrapper
+│ │ ├── agent/ # Agent management utilities
+│ │ ├── types/ # TypeScript definitions
+│ │ └── testing/ # Mock servers and test utils
+│ ├── examples/ # Integration examples
+│ ├── docs/ # TypeScript-specific docs
+│ └── package.json
+├── python/ # Python SDK (nanda-payments)
+│ ├── nanda_payments/
+│ │ ├── client.py # Async payment client
+│ │ ├── facilitator.py # Facilitator API wrapper
+│ │ ├── agent.py # Agent management
+│ │ ├── types.py # Type definitions
+│ │ ├── testing/ # Mock servers and pytest fixtures
+│ │ └── integrations/ # Framework integrations
+│ ├── examples/ # Python integration examples
+│ ├── docs/ # Python-specific docs
+│ └── pyproject.toml
+└── shared-docs/ # Cross-language documentation
+```
+
+### TypeScript SDK API Design
+```typescript
+import { NandaPaymentsClient } from '@nanda/payments-sdk';
+
+const client = new NandaPaymentsClient({
+ agentName: 'my-app',
+ facilitatorUrl: 'http://localhost:3001'
+});
+
+// Make x402-compliant requests
+const response = await client.makeRequest('http://api.example.com/premium');
+if (response.paymentRequired) {
+ const payment = await client.createPayment({
+ amount: response.price,
+ recipient: response.payTo
+ });
+ const result = await client.makeRequest('http://api.example.com/premium', payment);
+}
+
+// Agent management
+const balance = await client.getBalance();
+const transactions = await client.getTransactionHistory();
+```
+
+### Python SDK API Design
+```python
+from nanda_payments import NandaPaymentsClient
+
+async with NandaPaymentsClient(
+ agent_name="my-app",
+ facilitator_url="http://localhost:3001"
+) as client:
+ # Make x402-compliant requests
+ response = await client.make_request("http://api.example.com/premium")
+ if response.payment_required:
+ payment = await client.create_payment(
+ amount=response.price,
+ recipient=response.pay_to
+ )
+ result = await client.make_request("http://api.example.com/premium", payment)
+
+ # Agent management
+ balance = await client.get_balance()
+ transactions = await client.get_transaction_history()
+```
+
+### Dependencies Strategy
+- **TypeScript**: Minimal dependencies (axios/fetch, node built-ins)
+- **Python**: aiohttp for async HTTP, pydantic for data validation
+- Reuse protocol knowledge from `packages/shared/` but not code
+- Focus on language-native patterns and conventions
+- Comprehensive testing with minimal external test dependencies
+
+## Integration with Existing Code
+
+### Extract from Current Implementation
+- Payment middleware logic from `packages/shared/src/middleware.ts`
+- Type definitions from `packages/shared/src/types.ts`
+- MongoDB utilities from `packages/shared/src/mongodb.ts`
+- NANDA Points scheme from `packages/shared/src/nanda-points-scheme.ts`
+
+### Simplify and Abstract
+- Hide x402 protocol complexity behind decorators
+- Automatic facilitator URL discovery and configuration
+- Sensible defaults for development and production
+- Clear error messages for common developer mistakes
+
+### Maintain Compatibility
+- Use same facilitator API endpoints
+- Maintain compatibility with existing NANDA Points system
+- Support existing MongoDB schema and transaction patterns
+
+## Testing Strategy
+
+### Unit Tests
+- Decorator functionality and metadata extraction
+- Configuration parsing and validation
+- Error handling scenarios
+
+### Integration Tests
+- End-to-end payment flows
+- HTTP 402 response validation
+- Database transaction verification
+
+### Developer Testing
+- Mock payment client utilities
+- Test payment payload generators
+- Facilitator interaction mocking
+
+## Documentation Strategy
+
+### Getting Started Guide
+- 5-minute quick start tutorial
+- Common use case examples
+- Troubleshooting common issues
+
+### API Reference
+- Complete TypeScript API documentation
+- All decorator options and configurations
+- Error codes and handling
+
+### Integration Examples
+- Express.js integration
+- Next.js API routes
+- Fastify integration
+- Custom framework examples
+
+## Quality Gates
+
+### Phase 1 Requirements
+- [ ] Zero TypeScript compilation errors
+- [ ] All unit tests passing
+- [ ] Basic integration test suite passing
+- [ ] Getting started guide complete
+
+### Phase 2 Requirements
+- [ ] CLI tool functional
+- [ ] All example projects working
+- [ ] Documentation complete and reviewed
+- [ ] Developer feedback incorporated
+
+### Phase 3 Requirements
+- [ ] Production deployment tested
+- [ ] Performance benchmarks established
+- [ ] Advanced feature documentation complete
+- [ ] Security review completed
+
+## Risk Mitigation
+
+### Technical Risks
+- **Decorator complexity**: Start with simple implementation, expand gradually
+- **Framework compatibility**: Begin with Express.js, abstract later
+- **Performance overhead**: Profile and optimize during Phase 3
+
+### Adoption Risks
+- **Learning curve**: Extensive examples and documentation
+- **Migration complexity**: Provide migration tools and guides
+- **Feature gaps**: Regular developer feedback collection
+
+## Success Metrics
+
+- **Time to first payment**: < 10 minutes from npm install
+- **Code reduction**: 80% less boilerplate vs manual implementation
+- **Error rate**: < 5% of developers encounter setup issues
+- **Adoption rate**: Track npm downloads and GitHub usage
+
+## Notes
+
+This SDK will serve as the primary way developers integrate NANDA Points payments into their MCP servers. It should feel as natural as adding any other Express middleware but with the power of the full x402 payment protocol.
+
+Focus on developer experience above all else - if it's not simple enough for a developer to add payments in under 10 minutes, we haven't succeeded.
\ No newline at end of file
diff --git a/PRD.md b/PRD.md
new file mode 100644
index 0000000..e497c44
--- /dev/null
+++ b/PRD.md
@@ -0,0 +1,258 @@
+# Product Requirements Document: NANDA Points Server SDK for MCP Developers
+
+## Problem Statement
+
+MCP (Model Context Protocol) server developers who want to monetize their tools currently need to understand complex x402 protocol details, facilitator APIs, payment verification, and middleware integration. This creates significant barriers to adding payment requirements to MCP tools.
+
+**Current Pain Points:**
+- No standardized server-side libraries for MCP tool monetization
+- Complex x402 protocol implementation requirements
+- Manual payment middleware and verification handling
+- No MCP-specific payment wrapper utilities
+- Duplicated payment integration code across MCP servers
+- Steep learning curve for tool monetization
+
+## Objective
+
+Create a comprehensive server-side SDK focused on MCP developers who want to monetize their tools. The SDK provides language-native interfaces to the x402 protocol and facilitator APIs, enabling developers to add payment requirements to their tools without understanding protocol details.
+
+**Vision**: The "only way" developers integrate NANDA Points payments into MCP servers, with developer-friendly APIs that feel as natural as adding any other middleware.
+
+## Success Criteria
+
+### Must Have - TypeScript Server SDK ✅ COMPLETED
+- [x] npm package installation (`npm install @nanda/payments-sdk`)
+- [x] MCP-specific payment wrapper utilities (requirePayment, createPaidTool)
+- [x] Express middleware for payment verification (paymentMiddleware)
+- [x] x402-compliant payment middleware extracted from working implementation
+- [x] TypeScript definitions and full IntelliSense support
+- [x] Facilitator API wrapper with retry logic
+- [x] Comprehensive error handling with typed exceptions
+- [x] Working MCP server example demonstrating paid tools
+
+### Future Expansion - Client SDK Support
+- [ ] Client-side payment utilities for A2A/A2P scenarios
+- [ ] Agent balance management and transaction history
+- [ ] Payment creation utilities for requesting agents
+- [ ] Python SDK for server-side tool monetization
+
+### Should Have
+- [ ] Built-in payment testing and mocking utilities
+- [ ] Configurable environments (dev, staging, prod)
+- [ ] Automatic facilitator discovery and health checking
+- [ ] Payment webhook handling utilities
+- [ ] Comprehensive logging and debugging support
+- [ ] Integration examples for popular frameworks
+
+### Could Have (Future Work)
+- [ ] Go SDK for high-performance applications
+- [ ] Rust SDK for systems programming
+- [ ] React hooks and components library
+- [ ] Payment analytics and reporting SDKs
+- [ ] GraphQL integration utilities
+
+## Target Users
+
+1. **MCP Server Developers**: Adding payment requirements to existing MCP tools (PRIMARY)
+2. **Express.js Developers**: Creating paid APIs and services with NANDA Points
+3. **Tool Monetization Teams**: Converting free tools to paid services
+4. **AI Service Providers**: Building usage-based billing for AI tools
+5. **Enterprise MCP Teams**: Standardizing payment integration across MCP servers
+
+## User Stories
+
+### Story 1: MCP Server - Quick Setup ✅ IMPLEMENTED
+```typescript
+import { quickSetup } from '@nanda/payments-sdk';
+
+const payments = await quickSetup({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'my-mcp-server'
+});
+
+// Convert free tool to paid tool
+const paidWeatherTool = payments.requirePayment({
+ amount: 50, // 50 NANDA Points
+ description: 'Premium weather data with forecasts'
+})(originalWeatherTool);
+```
+
+### Story 2: MCP Tool Creation ✅ IMPLEMENTED
+```typescript
+import { createPaidTool, createPaymentConfig } from '@nanda/payments-sdk';
+
+const config = createPaymentConfig({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'weather-service'
+});
+
+// Create new paid tool for MCP server
+const premiumWeatherTool = createPaidTool(
+ 'premium_weather',
+ { amount: 100, description: 'Premium weather analysis' },
+ config,
+ async (args) => {
+ // Tool implementation
+ return await getPremiumWeatherData(args.location);
+ }
+);
+```
+
+### Story 3: Express Middleware ✅ IMPLEMENTED
+```typescript
+import express from 'express';
+import { paymentMiddleware, createPaymentConfig } from '@nanda/payments-sdk';
+
+const app = express();
+const config = createPaymentConfig({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'api-server'
+});
+
+// Apply payment requirements to specific routes
+app.use(paymentMiddleware({
+ '/api/premium': { amount: 25, description: 'Premium API access' },
+ '/api/analytics': { amount: 50, description: 'Analytics data' }
+}, config));
+```
+
+## Technical Requirements
+
+### TypeScript Server SDK Core Components ✅ IMPLEMENTED
+
+1. **MCP Payment Utilities**
+ - requirePayment() decorator for tool monetization
+ - createPaidTool() for new payment-protected tools
+ - quickSetup() for rapid MCP server configuration
+ - Type-safe payment requirement definitions
+
+2. **Facilitator API Wrapper**
+ - Type-safe facilitator endpoints (/verify, /settle, /supported)
+ - Extracted from working packages/shared implementation
+ - Automatic retry logic and error handling
+ - NANDA Points scheme compliance
+
+3. **Express Middleware**
+ - paymentMiddleware() for route-level payment protection
+ - Automatic x402 response generation
+ - Payment verification and settlement
+ - Error handling and debugging support
+
+4. **Type System**
+ - Complete TypeScript definitions for x402 protocol
+ - NANDA Points specific type definitions
+ - Tool payment requirement interfaces
+ - Comprehensive error type hierarchy
+
+### Future SDK Expansion
+
+1. **Client-Side Utilities** (Future)
+ - Payment creation for requesting agents
+ - Agent balance management and transaction history
+ - A2A (Agent-to-Agent) payment flows
+ - A2P (Agent-to-Person) payment scenarios
+
+2. **Python Server SDK** (Future)
+ - Python-native MCP tool monetization utilities
+ - FastAPI/Django middleware for payment verification
+ - Async payment handling with aiohttp
+ - Type hints and mypy compatibility
+
+3. **Developer Experience Enhancements** (Future)
+ - Mock facilitator utilities for testing
+ - CLI tools for payment debugging
+ - Comprehensive logging and monitoring
+ - Migration guides and examples
+
+## Implementation Strategy
+
+### Phase 1: TypeScript Server SDK ✅ COMPLETED
+- [x] Extract working payment middleware from packages/shared
+- [x] Build MCP-specific payment wrapper utilities (requirePayment, createPaidTool)
+- [x] Implement x402-compliant payment middleware for Express servers
+- [x] Add comprehensive TypeScript definitions for all payment types
+- [x] Create developer-friendly API following x402 patterns
+- [x] Build working MCP server example demonstrating paid tools
+- [x] Package configured for npm publication as @nanda/payments-sdk
+- [x] Fix TypeScript compilation and ensure zero lint errors
+
+### Phase 2: Documentation & Examples 📝 IN PROGRESS
+- [ ] Update PRD.md to reflect server-side focus
+- [ ] Create comprehensive README.md for the SDK
+- [ ] Document the developer journey from free to paid tools
+- [ ] Create additional MCP server examples
+- [ ] Add API reference documentation
+- [ ] Create troubleshooting guide
+
+### Phase 3: SDK Expansion (Future)
+- [ ] Client-side payment utilities for A2A/A2P scenarios
+- [ ] Python SDK for server-side tool monetization
+- [ ] Advanced testing and mocking utilities
+- [ ] Performance optimization and connection pooling
+- [ ] Community feedback integration and feature requests
+
+## Current SDK Structure ✅ IMPLEMENTED
+
+```
+sdks/
+└── payments-sdk/ # @nanda/payments-sdk
+ ├── src/
+ │ ├── shared/ # Core x402 and NANDA Points types
+ │ ├── facilitator/ # Facilitator API wrapper
+ │ ├── server/ # MCP server utilities (requirePayment, createPaidTool)
+ │ ├── examples/ # MCP server examples
+ │ └── index.ts # Main entry point with quickSetup
+ ├── dist/ # Compiled TypeScript output
+ ├── package.json # npm package configuration
+ └── tsconfig.json # TypeScript configuration
+```
+
+### Future Expansion Structure
+```
+sdks/
+├── payments-sdk/ # Current @nanda/payments-sdk (server-focused)
+└── client-sdk/ # Future client-side utilities (A2A/A2P)
+ ├── src/
+ │ ├── client/ # Payment client for requesting agents
+ │ ├── agent/ # Agent balance management
+ │ └── testing/ # Mock facilitator utilities
+ └── package.json
+```
+
+## Success Metrics
+
+- **TypeScript Server SDK**: ✅ Successful npm package ready for publication
+- **MCP Developer Adoption**: Time to monetize first tool < 10 minutes
+- **API Coverage**: ✅ 100% of facilitator endpoints wrapped with type safety
+- **Error Rate**: ✅ Zero TypeScript compilation errors
+- **Integration Simplicity**: ✅ Three-line setup with quickSetup()
+
+## Non-Goals
+
+- Client-side payment utilities (deferred to future expansion)
+- Supporting non-NANDA payment schemes initially
+- Blockchain or cryptocurrency integrations
+- Payment UI components (pure server-side libraries)
+- Database direct access (only through facilitator APIs)
+- Migration tools (we are the "only way" - no existing integrations to migrate)
+
+## Definition of Done
+
+### TypeScript Server SDK ✅ COMPLETED
+An MCP developer can:
+1. ✅ `npm install @nanda/payments-sdk`
+2. ✅ Setup payments with quickSetup() in 3 lines of code
+3. ✅ Wrap free tools with requirePayment() to monetize them
+4. ✅ Create new paid tools with createPaidTool()
+5. ✅ Access full TypeScript IntelliSense and type safety
+6. ✅ Use Express middleware for route-level payment protection
+7. ✅ See working examples in a complete MCP server
+
+### Future SDK Expansion
+A developer will be able to:
+- Install client-side utilities for A2A/A2P payment scenarios
+- Access agent balance management and transaction history
+- Use Python SDK for server-side tool monetization
+- Leverage comprehensive testing and mocking utilities
+
+The server SDK provides the foundation for MCP tool monetization with a focus on developer experience and x402 protocol compliance.
\ No newline at end of file
diff --git a/README.md b/README.md
index 61196df..6b3756b 100644
--- a/README.md
+++ b/README.md
@@ -1,632 +1,409 @@
-# NANDA Points MCP Server (MongoDB)
+# x402 NANDA Points - Server Infrastructure
-Modular MCP server for NANDA Points using MongoDB with agent-based transactions and **Streamable HTTP Transport**. Features **x402-NP payment protocol** for tool access control.
+**Fork of Coinbase's x402 server examples adapted for NANDA Points settlement instead of blockchain/USDC.**
-## Tools
+## Overview
-### Free Tools
-- `getBalance(agent_name)` - Get NP balance for an agent
-- `initiateTransaction(from, to, amount)` - Transfer NP between agents
-- `getReceipt(txId)` - Get receipt for a transaction ID
-- `getPaymentInfo()` - Get x402-NP payment requirements for paid tools
-- `setServiceCharge(agent_name, serviceChargePoints)` - Set service charge for an agent
-- `attachWallet(agent_name, seedPoints?)` - Attach a wallet to an agent (creates wallet if doesn't exist)
+This monorepo forks Coinbase's working x402 server implementations and adapts them to use NANDA Points + MongoDB instead of blockchain settlement. We maintain full x402 protocol compliance while replacing the payment backend.
-### Paid Tools (x402-NP)
-- `getTimestamp()` - Get current server timestamp (1 NP to system)
+## What This Enables
-**Note:** Paid tools require payment in Nanda Points using the x402-NP protocol. See [x402-NP Documentation](docs/x402-np.md) for details.
+- **x402-compliant servers** that return proper HTTP 402 "Payment Required" responses
+- **NANDA Points settlement** instead of blockchain transactions
+- **Compatibility** with existing x402 clients (x402-axios, x402-mcp, etc.)
+- **MCP integration** with Streamable HTTP transport
## Architecture
-The server uses a modular structure:
-
-- **Models** (`src/models/`) - TypeScript interfaces and centralized points schema
-- **Services** (`src/services/`) - Business logic and database operations
-- **Routes** (`src/routes/`) - API route handlers
-- **MCP Server** (`src/mcp/`) - MCP tool definitions and handlers
-
-## Agent Structure
-
-Agents follow the NANDA agent specification with additional fields:
+```
+┌─────────────────┐ HTTP 402 ┌─────────────────┐
+│ x402 Clients │ ──────────────► │ Our Servers │
+│ (Coinbase MCP, │ Payments │ (This Project) │
+│ x402-axios) │ ◄────────────── │ │
+└─────────────────┘ └─────────────────┘
+ │
+ ▼
+ ┌─────────────────┐
+ │ NANDA Points │
+ │ Facilitator │
+ │ (MongoDB) │
+ └─────────────────┘
+```
-- `agent_name` - Unique identifier
-- `walletId` - Links to associated wallet
-- `serviceCharge` - NP points for service charges
-- Full agent metadata (provider, endpoints, capabilities, etc.)
+## Quick Start
-## Setup
+### Prerequisites
+- Node.js 20+
+- MongoDB running on port 27017
+- NANDA Points database seeded
### 1. Install Dependencies
-
```bash
-npm i
+npm install
```
-### 2. Seed Database
-
+### 2. Set up Environment
```bash
-MONGODB_URI="mongodb://localhost:27017" NP_DB_NAME="nanda_points" npm run seed
+cp .env.example .env
+# Edit .env with your MongoDB settings
```
-This creates 11 sample agents with wallets and 1000 NP each.
-
-### 3. Start Server
-
+### 3. Seed Database
```bash
-MONGODB_URI="mongodb://localhost:27017" NP_DB_NAME="nanda_points" npm run dev
-# or for production
-MONGODB_URI="mongodb://localhost:27017" NP_DB_NAME="nanda_points" npm start
+npm run seed
```
-The server will start on `http://localhost:3000` with the following endpoints:
-
-- **MCP Endpoint**: `http://localhost:3000/mcp` (POST/GET)
-- **Health Check**: `http://localhost:3000/health` (GET)
-
-**Environment Variables:**
-
-- `MONGODB_URI`: MongoDB connection string (default: "mongodb://localhost:27017")
-- `NP_DB_NAME`: Database name for NANDA Points (default: "nanda_points")
-- `PORT`: HTTP server port (default: 3000)
-- `HOST`: HTTP server host (default: localhost)
-
-### 4. Test the Server
-
-Run the included test client to verify functionality:
-
+### 4. Start Express Server
```bash
-npm run test
+npm run dev:express
```
-Custom test options:
+Your x402-compliant server will be running at:
+- **Server**: `http://localhost:3000`
+- **Example endpoints**: `/weather` (requires payment), `/health` (free)
+### 5. Test with x402 Clients
```bash
-# Test with different agents and amount
-npm run test -- --from claude-desktop --to search-agent --amount 100
-
-# Test against different server
-npm run test -- --server http://localhost:3001/mcp
-
-# Skip specific tests
-npm run test -- --no-transaction --no-receipt
+# Test with Coinbase's x402-mcp client
+# Or use any other x402-compatible client
```
-## Proxy HTTP with ngrok
-
-To make your local MCP server accessible from the internet (required for Claude Web), use ngrok:
+## SDK Quick Start (Recommended)
-### 1. Start ngrok tunnel
-
-After your MCP server is running on `http://localhost:3000`, open a new terminal and run:
+For new MCP server development, use the NANDA Payments SDK:
```bash
-ngrok http 3000
+npm install @nanda/payments-sdk
```
-This will output something like:
+```typescript
+import { quickSetup } from '@nanda/payments-sdk';
-```
-Forwarding https://abc123def456.ngrok-free.app -> http://localhost:3000
+// 1. Setup payments for your MCP server
+const payments = await quickSetup({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'my-mcp-server'
+});
+
+// 2. Convert free tool to paid tool
+const freeWeatherTool = (args) => getBasicWeather(args.location);
+const paidWeatherTool = payments.requirePayment({
+ amount: 50, // 50 NANDA Points
+ description: 'Premium weather data'
+})(freeWeatherTool);
+
+// 3. Create new paid tool
+const analyticsTool = payments.createPaidTool(
+ 'analytics',
+ { amount: 100, description: 'Data analytics' },
+ async (args) => getAnalytics(args.dataset)
+);
```
-### 2. Verify ngrok is working
+See the [SDK Documentation](./sdks/payments-sdk/) for complete usage guide.
-Test the public endpoints:
+## Packages
-```bash
-# Check tunnel status
-curl http://localhost:4040/api/tunnels
+### [NANDA Payments SDK](./sdks/payments-sdk/) ⭐ **NEW**
+**TypeScript SDK for MCP tool monetization**
+- `@nanda/payments-sdk` - The primary way to add payments to MCP servers
+- `requirePayment()` decorator for converting free tools to paid tools
+- `quickSetup()` for 3-line MCP server configuration
+- Express middleware for route-level payment protection
+- Full TypeScript support with comprehensive type definitions
-# Test public health endpoint
-curl https://your-ngrok-url.ngrok-free.app/health
-```
+### [Express Server](./packages/express-server/)
+**Production-ready server with middleware**
+- Based on Coinbase's `/examples/typescript/servers/express`
+- Uses `paymentMiddleware` for automatic payment handling
+- Simple configuration, minimal code changes needed
-### 3. Get your public MCP endpoint
+### [Advanced Server](./packages/advanced-server/)
+**Flexible server with manual payment handling**
+- Based on Coinbase's `/examples/typescript/servers/advanced`
+- Manual payment verification and settlement
+- Async settlement patterns, dynamic pricing
-Your MCP server will be available at:
+### [Facilitator](./packages/facilitator/)
+**NANDA Points Facilitator Service**
+- Implements x402 facilitator API (`/verify`, `/settle`, `/supported`)
+- Handles "nanda-points" payment scheme
+- Replaces blockchain calls with MongoDB transactions
-- **Public MCP Endpoint**: `https://your-ngrok-url.ngrok-free.app/mcp`
-- **Public Health Check**: `https://your-ngrok-url.ngrok-free.app/health`
+### [Shared](./packages/shared/)
+**Common utilities and types**
+- x402 protocol types and interfaces
+- NANDA Points transaction utilities
+- Payment validation helpers
-**Note**: ngrok URLs change each time you restart ngrok unless you have a paid account with reserved domains.
+## What We Changed from Coinbase x402
-## Testing with Claude Web
+### Payment Scheme
+- **Before**: EVM blockchain schemes (exact, eip712-usdc-base)
+- **After**: "nanda-points" scheme with MongoDB backend
-### 1. Configure MCP Connector in Claude Web
+### Settlement
+- **Before**: Blockchain RPC calls, smart contract interactions
+- **After**: MongoDB transactions, agent balance updates
-1. Open Claude Web (claude.ai)
-2. Go to your workspace settings
-3. Navigate to "Connectors" or "MCP Servers"
-4. Add a new connector with:
- - **Name**: `NANDA Points`
- - **Type**: `Streamable HTTP`
- - **URL**: `https://your-ngrok-url.ngrok-free.app/mcp`
- - **Description**: `NANDA Points management system for agent transactions`
+### Verification
+- **Before**: Wallet signature verification, on-chain balance checks
+- **After**: Agent authentication, transaction receipt validation
-### 2. Example Prompts for Testing Tools
+### Facilitator
+- **Before**: Ethereum/Solana facilitator endpoints
+- **After**: Custom NP facilitator with `/verify`, `/settle`, `/supported`
-Once connected, you can test each tool with these example prompts:
+## Payment Flow Sequence
-#### **getBalance Tool**
+The following diagram shows the complete x402 payment flow from the Requesting Agent's perspective:
-```
-Check the NP balance for the claude-desktop agent
-```
+```mermaid
+sequenceDiagram
+ participant RA as Requesting Agent
+ participant RS as Resource Server
(Express/MCP)
+ participant FS as Facilitator Service
(Port 3001)
+ participant DB as MongoDB
(NANDA Points)
-```
-What's the current balance for search-agent?
-```
+ Note over RA, DB: 1. Initial Request (No Payment)
+ RA->>RS: GET /weather
+ Note right of RA: No X-PAYMENT header
-```
-Show me the balance for all agents: claude-desktop, search-agent, and summarize-agent
-```
+ RS->>RS: Check payment requirements
+ Note right of RS: Route requires 1 NP
-#### **initiateTransaction Tool**
+ RS-->>RA: HTTP 402 Payment Required
+ Note right of RS: {
"x402Version": 1,
"error": "X-PAYMENT header is required",
"accepts": [{
"scheme": "nanda-points",
"network": "nanda-network",
"maxAmountRequired": "1",
"asset": "NP",
"payTo": "system",
"facilitatorUrl": "http://localhost:3001"
}]
}
-```
-Transfer 100 NP from claude-desktop to search-agent
-```
+ Note over RA, DB: 2. Agent Processes Payment Requirements
+ RA->>RA: Parse payment requirements
+ RA->>RA: Generate unique txId
+ RA->>RA: Create payment payload
+ Note right of RA: {
"scheme": "nanda-points",
"amount": "1",
"from": "requesting-agent",
"to": "system",
"txId": "uuid-123",
"timestamp": 1234567890
}
-```
-Send 50 NANDA Points from search-agent to summarize-agent and show me the receipt
-```
+ Note over RA, DB: 3. Pre-verification (Optional)
+ RA->>FS: POST /verify
+ Note right of RA: Verify payment before committing
-```
-Make a payment of 25 NP from claude-desktop to ocr-agent
-```
+ FS->>DB: Check agent exists
+ DB-->>FS: Agent: {name: "requesting-agent", ...}
-#### **getReceipt Tool**
-
-```
-Get the receipt for transaction ID: [paste-transaction-id-here]
-```
+ FS->>DB: Check wallet balance
+ DB-->>FS: Wallet: {balanceMinor: 150, ...}
-```
-Show me the details of the last transaction receipt
-```
+ FS->>FS: Validate payment
• Amount: 1 ≤ 150 ✓
• Agent exists ✓
• Recipient valid ✓
-#### **getTimestamp Tool**
-```
-What is the current server timestamp?
-```
-```
-Get the current time from the server
-```
+ FS-->>RA: {"isValid": true, "payer": "requesting-agent"}
-#### **setServiceCharge Tool**
+ Note over RA, DB: 4. Make Paid Request
+ RA->>RA: Encode payment as base64
+ RA->>RS: GET /weather
X-PAYMENT:
-```
-Set the service charge for search-agent to 10 NP
-```
+ RS->>RS: Decode X-PAYMENT header
+ RS->>FS: POST /verify (payment + requirements)
-```
-Update the service charge for summarize-agent to 25 NANDA Points
-```
+ FS->>DB: Validate agent & balance
+ DB-->>FS: Validation successful
-```
-Set ocr-agent's service charge to 5 NP
-```
+ FS-->>RS: {"isValid": true, "payer": "requesting-agent"}
-#### **attachWallet Tool**
+ RS->>RS: Execute business logic
+ Note right of RS: Generate weather data
-```
-Attach a wallet to the new-agent (will create wallet if it doesn't exist)
-```
+ RS->>FS: POST /settle (complete payment)
-```
-Attach a wallet to claude-desktop with 2000 NP initial balance
-```
+ Note over FS, DB: 5. Settlement Process
+ FS->>DB: Begin transaction
-```
-Create and attach a wallet to my-custom-agent
-```
+ FS->>DB: Update sender balance
requesting-agent: 150 → 149
+ FS->>DB: Update recipient balance
system: 1000 → 1001
-#### **Complex Multi-Tool Operations**
+ FS->>DB: Create transaction record
+ Note right of DB: {
"txId": "uuid-123",
"from": "requesting-agent",
"to": "system",
"amount": 1,
"status": "completed"
}
-```
-1. Check the balance for claude-desktop
-2. Transfer 75 NP from claude-desktop to vector-agent
-3. Set vector-agent's service charge to 15 NP
-4. Show me the final balances for both agents
-```
+ FS->>DB: Create receipt
+ Note right of DB: {
"txId": "uuid-123",
"timestamp": 1234567890,
"resource": "/weather"
}
-```
-I want to see a complete transaction flow:
-1. Check initial balances for claude-desktop and web-agent
-2. Transfer 200 NP from claude-desktop to web-agent
-3. Get the transaction receipt
-4. Check final balances
-5. Set web-agent's service charge to 20 NP
-```
+ FS->>DB: Commit transaction
-### 3. Expected Responses
+ FS-->>RS: {"success": true, "txId": "uuid-123", ...}
-Each tool returns JSON responses with the following structure:
+ RS->>RS: Create X-PAYMENT-RESPONSE header
+ Note right of RS: base64({
"txId": "uuid-123",
"amount": "1",
"from": "requesting-agent",
"to": "system",
"timestamp": 1234567890
})
-**getBalance**: Returns agent balance information
+ RS-->>RA: HTTP 200 OK
X-PAYMENT-RESPONSE:
+ Note right of RS: {
"report": {
"weather": "sunny",
"temperature": 72
},
"cost": "1 NP",
"message": "Weather data successfully accessed!"
}
-```json
-{
- "agent_name": "claude-desktop",
- "currency": "NP",
- "scale": 0,
- "balanceMinor": 1000,
- "balancePoints": 1000
-}
+ Note over RA, DB: 6. Payment Complete
+ RA->>RA: Process response
+ RA->>RA: Decode X-PAYMENT-RESPONSE
+ RA->>RA: Store receipt for records
```
-**initiateTransaction**: Returns transaction details with receipt
+### Key Flow Points:
-```json
-{
- "txId": "uuid-transaction-id",
- "status": "completed",
- "amountPoints": 100,
- "from": "claude-desktop",
- "to": "search-agent",
- "receipt": { ... }
-}
-```
+1. **Initial Request**: Agent requests resource without payment, receives HTTP 402 with payment requirements
+2. **Payment Preparation**: Agent creates payment payload with unique transaction ID
+3. **Pre-verification**: Optional step to validate payment before committing
+4. **Paid Request**: Agent includes X-PAYMENT header with encoded payment
+5. **Settlement**: Facilitator atomically updates balances and creates transaction records
+6. **Receipt**: Server returns data with X-PAYMENT-RESPONSE header containing settlement proof
-**getReceipt**: Returns receipt details
+### Error Scenarios:
-```json
-{
- "txId": "uuid-transaction-id",
- "fromAgent": "claude-desktop",
- "toAgent": "search-agent",
- "amountMinor": 100,
- "fromBalanceAfter": 900,
- "toBalanceAfter": 1100
-}
-```
+- **Insufficient Balance**: Facilitator returns `{"isValid": false, "invalidReason": "Insufficient balance"}`
+- **Invalid Agent**: Facilitator returns `{"isValid": false, "invalidReason": "Agent not found"}`
+- **Duplicate Transaction**: Facilitator rejects if txId already exists
+- **Settlement Failure**: Server returns HTTP 402 if settlement fails during processing
-**setServiceCharge**: Returns updated service charge
+## Testing
-```json
-{
- "agent_name": "search-agent",
- "serviceCharge": 10
-}
+### Unit Tests
+```bash
+npm test
```
-**attachWallet**: Returns wallet attachment confirmation
-
-```json
-{
- "agent_name": "new-agent",
- "walletId": "uuid-wallet-id",
- "balanceMinor": 1000,
- "balancePoints": 1000,
- "message": "Wallet successfully attached to agent"
-}
+### x402 Protocol Compliance
+```bash
+npm run test:x402
```
-### 4. Troubleshooting Claude Web Connection
-
-If Claude Web can't connect to your MCP server:
-
-1. **Check ngrok tunnel**: Ensure ngrok is running and the URL is correct
-2. **Test health endpoint**: Verify `https://your-ngrok-url.ngrok-free.app/health` returns server info
-3. **Check server logs**: Look for connection attempts in your server console
-4. **Verify MCP endpoint**: Ensure the URL ends with `/mcp`
-5. **Check firewall**: Make sure your local server is accessible
-
-## Testing with Cursor IDE
-
-### 1. Configure MCP Server in Cursor
-
-Cursor supports MCP servers through project-specific configuration. Create a `.cursor/mcp.json` file in your project root:
-
-```json
-{
- "mcpServers": {
- "nanda-points": {
- "url": "https://your-ngrok-url.ngrok-free.app/mcp"
- }
- }
-}
+### Integration with Clients
+```bash
+npm run test:clients
```
-**Alternative Configuration Methods:**
-- **Global Settings**: Open Cursor → Cmd/Ctrl + Shift + P → "Cursor Settings" → "MCP" section
-- **Project-specific**: Place `.cursor/mcp.json` in your project root (recommended for this repo)
-
-### 2. Restart Cursor and Verify Connection
+## Example Testing Prompts
-1. **Restart Cursor** after adding the configuration
-2. **Check MCP Status**: Look for MCP server status in Cursor's status bar or settings
-3. **Verify Tools**: The NANDA Points tools should appear in Cursor's available tools
+### Testing Free Resources
-### 3. Example Prompts for Testing Tools in Cursor
+The following prompts can be used to test free endpoints that don't require payment:
-Once connected, test each tool with these prompts in Cursor's chat:
-
-#### **getBalance Tool**
-```
-@nanda-points Check the NP balance for the claude-desktop agent
+#### Health Check
```
-```
-@nanda-points What's the current balance for search-agent?
-```
-```
-@nanda-points Show me balances for claude-desktop, search-agent, and summarize-agent
+Can you test the health endpoint of our Express server? It should be available at http://localhost:3000/health and return basic server information without requiring payment.
```
-#### **initiateTransaction Tool**
-```
-@nanda-points Transfer 100 NP from claude-desktop to search-agent
-```
+#### Free Weather Data
```
-@nanda-points Send 50 NANDA Points from search-agent to summarize-agent and show the receipt
-```
-```
-@nanda-points Make a payment of 25 NP from claude-desktop to ocr-agent
+Please test our free weather endpoint at http://localhost:3000/weather. This should return weather information without requiring any NANDA Points payment.
```
-#### **getReceipt Tool**
-```
-@nanda-points Get the receipt for transaction ID: [paste-transaction-id-here]
-```
-```
-@nanda-points Show me the details of the last transaction receipt
-```
+### Testing Paid Resources
-#### **getTimestamp Tool**
-```
-@nanda-points What is the current server timestamp?
-```
+These prompts test endpoints that require NANDA Points payments:
+
+#### Premium Content (10 NP)
```
-@nanda-points Get the current time from the server
+Test the premium content endpoint at http://localhost:3000/premium/content. This requires a payment of 10 NANDA Points. You should first try without payment (expect HTTP 402), then make a proper payment using the x402 protocol.
```
-#### **setServiceCharge Tool**
+#### Premium Analysis (10 NP)
```
-@nanda-points Set the service charge for search-agent to 10 NP
+Test the premium analysis endpoint at http://localhost:3000/premium/analysis. This costs 10 NANDA Points and should return market analysis data. Please test both the payment failure and success scenarios.
```
+
+### Testing Payment Flow
+
+#### Complete x402 Flow
```
-@nanda-points Update the service charge for summarize-agent to 25 NANDA Points
+Please test the complete x402 payment flow:
+1. Try accessing /premium/content without payment - should get HTTP 402
+2. Parse the payment requirements from the response
+3. Create a valid NANDA Points payment with txId, amount, from/to agents
+4. Retry the request with the X-PAYMENT header
+5. Verify the response includes X-PAYMENT-RESPONSE header with settlement details
+6. Check that the database balances were updated correctly
```
-#### **Complex Multi-Tool Operations**
+#### Error Scenarios
```
-@nanda-points Complete transaction workflow:
-1. Check balance for claude-desktop
-2. Transfer 75 NP from claude-desktop to vector-agent
-3. Set vector-agent's service charge to 15 NP
-4. Show final balances for both agents
+Test these error scenarios:
+1. Insufficient balance - agent with 0 NP trying to pay 10 NP
+2. Invalid agent - non-existent agent trying to make payment
+3. Duplicate transaction - using the same txId twice
+4. Invalid payment format - malformed X-PAYMENT header
```
-### 4. Troubleshooting Cursor Connection
-
-If Cursor can't connect to your MCP server:
-
-1. **Check .cursor/mcp.json syntax**: Ensure valid JSON format
-2. **Verify ngrok URL**: Test `https://your-ngrok-url.ngrok-free.app/health` returns server info
-3. **Restart Cursor**: MCP configuration changes require restart
-4. **Check Cursor logs**: Look for MCP connection errors in Cursor's developer console
-5. **Test direct connection**: Use the test client to verify server is responding
-6. **Verify project root**: Ensure `.cursor/mcp.json` is in the correct directory
-
-### 5. Cursor vs Claude Web Differences
-
-- **Tool Invocation**: Use `@nanda-points` prefix in Cursor vs direct prompts in Claude Web
-- **Session Management**: Cursor maintains persistent MCP connections vs Claude Web's per-session connections
-- **Configuration**: Cursor uses project files vs Claude Web's workspace settings
-- **Tool Limitations**: Cursor supports up to 40 tools simultaneously
+### Database Verification Prompts
-## Usage
-
-### Example Agent Names
-
-- `claude-desktop` - Payer agent
-- `search-agent` - Search capability agent
-- `summarize-agent` - Summarization agent
-- `extract-agent` - Extraction agent
-- `classify-agent` - Classification agent
-- `translate-agent` - Translation agent
-- `vector-agent` - Vector store agent
-- `ocr-agent` - OCR agent
-- `web-agent` - Web browse agent
-- `sql-agent` - SQL runner agent
-- `image-caption-agent` - Image caption agent
-
-### Error Handling
-
-- `AGENT_NOT_FOUND` - Agent doesn't exist
-- `SENDER_AGENT_NOT_FOUND` - Sender agent doesn't exist
-- `RECEIVER_AGENT_NOT_FOUND` - Receiver agent doesn't exist
-- `INSUFFICIENT_FUNDS` - Not enough NP for transaction
-
-## Client Integration
-
-### MCP Streamable HTTP Transport
-
-This server uses the **Streamable HTTP transport** (MCP specification 2025-03-26) instead of stdio. Clients can connect to:
-
-**Base URL**: `http://localhost:3000/mcp`
-
-**Session Management**: The server automatically assigns session IDs and supports:
-
-- HTTP POST for client-to-server messages
-- HTTP GET for Server-Sent Events (SSE) streaming
-- Session resumability and redelivery
-
-### Claude Desktop Configuration
-
-Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
-
-```json
-{
- "mcpServers": {
- "nanda-points": {
- "type": "streamable-http",
- "url": "http://localhost:3000/mcp"
- }
- }
-}
+#### Balance Tracking
```
-
-**Note**: Ensure the server is running before starting Claude Desktop.
-
-### Legacy stdio Support
-
-For backward compatibility with older MCP clients, you can still run via stdio by modifying the server code to use `StdioServerTransport` instead of `StreamableHTTPServerTransport`.
-
-## Development
-
-### Project Structure
-
+After running payment tests, please check:
+1. The sender's balance decreased by the payment amount
+2. The recipient's balance increased by the payment amount
+3. A transaction record was created in the transactions collection
+4. A receipt was generated in the receipts collection
+5. All records have matching txId values
```
-src/
-├── models/ # TypeScript interfaces
-│ ├── points.ts # Centralized Points class and MinorUnits type
-│ ├── agent.ts # Agent facts and metadata
-│ ├── wallet.ts # Wallet interface
-│ ├── transaction.ts # Transaction interface
-│ ├── receipt.ts # Receipt interface
-│ └── index.ts # Re-exports
-├── services/ # Business logic
-│ ├── database.ts # MongoDB connection
-│ ├── agentService.ts # Agent operations
-│ ├── walletService.ts # Wallet operations
-│ ├── transactionService.ts # Transaction logic
-│ ├── receiptService.ts # Receipt operations
-│ └── index.ts # Re-exports
-├── routes/ # API handlers
-│ ├── agentRoutes.ts # Agent route handlers
-│ ├── walletRoutes.ts # Wallet route handlers
-│ ├── transactionRoutes.ts # Transaction handlers
-│ ├── receiptRoutes.ts # Receipt handlers
-│ └── index.ts # Re-exports
-├── mcp/ # MCP server
-│ └── server.ts # MCP tool definitions
-└── utils/ # Utilities
-└── mongo.ts # MongoDB connection utilities
-
+#### Transaction Logs
```
-
-````
-
-### Build & Test
-
-```bash
-
-npm run build # Compile TypeScript
-npm start # Start MCP server
-npm run seed # Seed database with sample data
-npm run test # Test basic MCP functionality
-npm run test:x402-full # Test x402-NP payment protocol
+Please query the MongoDB database and show:
+1. Recent transactions from the last 10 minutes
+2. Agent wallet balances before and after test payments
+3. Receipt details for successful settlements
+4. Any failed transaction attempts and their error reasons
```
-## x402-NP Payment Protocol
-
-This server implements the x402 payment protocol adapted for Nanda Points (x402-NP), enabling programmatic payments for tool access without cryptocurrency.
-
-### Quick Start
-
-1. **Call a paid tool** without payment → receive payment instructions
-2. **Use `initiateTransaction`** to pay the required amount to the recipient
-3. **Retry the tool** with payment arguments:
- - `_paymentAgent`: Your agent name
- - `_paymentTxId`: Transaction ID from step 2
- - `_paymentAmount`: Amount paid
-
-### Testing the x402-NP Implementation
-
-Run comprehensive tests to verify the payment system:
-
-```bash
-# Test basic MCP functionality
-npm run test
-
-# Test x402-NP payment protocol with full logging
-npm run test:x402-full
+## Development
-# Run updated test with current tool configuration
-npx tsx run-updated-test.ts
+### Project Structure
+```
+packages/
+├── express-server/ # Simple middleware-based server
+├── advanced-server/ # Manual payment handling server
+├── facilitator/ # NP facilitator service
+├── shared/ # Common utilities
+└── examples/ # Usage examples
```
-### Sample Test Prompts
-
-#### Using MCP Client (Recommended)
-
+### Adding a Paid Endpoint (Express Server)
```typescript
-import { Client } from "@modelcontextprotocol/sdk/client/index.js";
-import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
-
-const client = new Client({ name: "test-client", version: "1.0.0" }, { capabilities: {} });
-const transport = new StreamableHTTPClientTransport(new URL("http://localhost:3000/mcp"));
-await client.connect(transport);
-
-// 1. List available tools
-const tools = await client.listTools();
-
-// 2. Test free tool (if available)
-const paymentInfo = await client.callTool({
- name: "getPaymentInfo",
- arguments: {}
-});
-
-// 3. Test free tool (getBalance is now free)
-const balanceResult = await client.callTool({
- name: "getBalance",
- arguments: { agent_name: "claude-desktop" }
-});
-
-// 4. Test paid tool without payment (should require payment)
-const timestampResult = await client.callTool({
- name: "getTimestamp",
- arguments: {}
-});
-
-// 5. Make payment for paid tool
-const payment = await client.callTool({
- name: "initiateTransaction",
- arguments: { from: "claude-desktop", to: "system", amount: 1 }
-});
+// In packages/express-server/index.ts
+app.use(
+ paymentMiddleware(payTo, {
+ "GET /my-endpoint": {
+ price: "$0.001",
+ network: "nanda-points",
+ }
+ }, { facilitatorUrl })
+);
-// 6. Retry paid tool with payment proof
-const paidTimestamp = await client.callTool({
- name: "getTimestamp",
- arguments: {
- _paymentAgent: "claude-desktop",
- _paymentTxId: "transaction-id-from-step-5",
- _paymentAmount: "1"
- }
+app.get("/my-endpoint", (req, res) => {
+ res.json({ data: "This endpoint requires payment" });
});
```
-#### Using Raw HTTP (Advanced)
-
-```bash
-# Health Check
-curl -X GET http://localhost:3000/health
-
-# Note: Direct HTTP calls to /mcp require proper session management
-# Use the MCP client for reliable testing
+### Manual Payment Handling (Advanced Server)
+```typescript
+// In packages/advanced-server/index.ts
+app.get("/my-endpoint", async (req, res) => {
+ const paymentRequirements = [createNandaPaymentRequirements(
+ "10", // 10 NP
+ req.originalUrl,
+ "My paid endpoint"
+ )];
+
+ const isValid = await verifyPayment(req, res, paymentRequirements);
+ if (!isValid) return;
+
+ res.json({ data: "Payment verified!" });
+});
```
-### Current Status
+## Contributing
-**✅ Implementation Status:** The x402-NP payment system is **fully operational**.
+1. Fork the repository
+2. Create a feature branch
+3. Make changes with full test coverage
+4. Ensure zero lint errors: `npm run lint`
+5. Submit a pull request
-**Test Results Summary:**
-- ✅ MCP server running with Streamable HTTP transport
-- ✅ Free tools (getBalance, initiateTransaction, getReceipt) working correctly
-- ✅ Paid tools (getTimestamp) enforcing payment requirements
-- ✅ `getPaymentInfo` tool registered and working
-- ✅ Payment wrapper correctly applied to paid tools
-- ✅ Full payment flow working end-to-end
+## License
-### Complete Test Log
+MIT License - see [LICENSE](LICENSE) for details.
-See `test.log` for detailed interaction logs including:
-- MCP requests/responses
-- Payment flow verification
-- Tool arguments and results
-- Transaction receipts and balances
+## Based on Coinbase x402
-For complete documentation see: [docs/x402-np.md](docs/x402-np.md)
\ No newline at end of file
+This project is based on [Coinbase's x402 protocol](https://github.com/coinbase/x402) server examples. We've adapted the proven implementations to work with NANDA Points while maintaining full x402 protocol compliance.
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index 577a8a8..0000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-version: "3.8"
-
-services:
- # NANDA Points MCP Server
- nanda-points-server:
- build: .
- container_name: nanda-points-server
- restart: unless-stopped
- ports:
- - "3000:3000" # MCP Server
- - "8080:8080" # API Server
- environment:
- NODE_ENV: production
- MCP_PORT: 3000
- API_PORT: 8080
- HOST: 0.0.0.0
- # Connect to NANDA's actual database
- MONGODB_URI: ${MONGODB_URI}
- NP_DB_NAME: ${NP_DB_NAME:-nanda_points}
- healthcheck:
- test:
- [
- "CMD",
- "node",
- "-e",
- "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })",
- ]
- interval: 30s
- timeout: 10s
- retries: 3
- start_period: 40s
diff --git a/docs/examples.md b/docs/examples.md
new file mode 100644
index 0000000..c1a5c16
--- /dev/null
+++ b/docs/examples.md
@@ -0,0 +1,431 @@
+# Examples and Integration Guide
+
+## Quick Start Example
+
+### 1. Start the Services
+
+```bash
+# Terminal 1: Start facilitator
+cd packages/facilitator
+npm run dev
+# Runs on http://localhost:3001
+
+# Terminal 2: Start Express server
+cd packages/express-server
+npm run dev
+# Runs on http://localhost:3000
+```
+
+### 2. Test Free Endpoints
+
+```bash
+# Health check (free)
+curl http://localhost:3000/health
+
+# Weather data (free)
+curl http://localhost:3000/weather
+```
+
+### 3. Test Paid Endpoints (Expect 402)
+
+```bash
+# Premium content (10 NP required)
+curl http://localhost:3000/premium/content
+
+# Premium analysis (10 NP required)
+curl http://localhost:3000/premium/analysis
+```
+
+### 4. Make a Payment
+
+```bash
+# Create payment payload
+PAYMENT='{
+ "x402Version": 1,
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "payTo": "system",
+ "amount": "10",
+ "from": "claude-desktop",
+ "txId": "example-tx-'$(date +%s)'",
+ "timestamp": '$(date +%s)'000'
+}'
+
+# Encode and make request
+ENCODED=$(echo "$PAYMENT" | base64 -w 0)
+curl -H "X-PAYMENT: $ENCODED" http://localhost:3000/premium/content
+```
+
+## Integration Examples
+
+### Express Server with Payments
+
+```typescript
+import express from "express";
+import { npPaymentMiddleware } from "x402-nanda-shared";
+
+const app = express();
+const facilitatorUrl = "http://localhost:3001";
+const recipient = "my-service";
+
+// Configure payment routes
+app.use(
+ npPaymentMiddleware(
+ {
+ // Exact route match
+ "GET /api/premium-analysis": {
+ priceNP: 5,
+ recipient,
+ description: "AI-powered analysis",
+ },
+
+ // Wildcard patterns
+ "/api/premium/*": {
+ priceNP: 10,
+ recipient,
+ description: "Premium API access",
+ },
+
+ // Method-specific
+ "POST /api/generate": {
+ priceNP: 15,
+ recipient,
+ description: "AI content generation",
+ maxTimeoutSeconds: 120,
+ }
+ },
+ facilitatorUrl
+ )
+);
+
+// Free endpoints (no middleware applied)
+app.get("/api/health", (req, res) => {
+ res.json({ status: "healthy", timestamp: Date.now() });
+});
+
+app.get("/api/info", (req, res) => {
+ res.json({
+ service: "AI API",
+ version: "1.0.0",
+ freeEndpoints: ["/api/health", "/api/info"],
+ paidEndpoints: ["/api/premium/*", "/api/generate"]
+ });
+});
+
+// Paid endpoints (automatically protected)
+app.get("/api/premium-analysis", (req, res) => {
+ res.json({
+ analysis: "Detailed AI analysis results...",
+ confidence: 0.95,
+ cost: "5 NP",
+ processingTime: "2.3s"
+ });
+});
+
+app.get("/api/premium/forecast", (req, res) => {
+ res.json({
+ forecast: "Predictive modeling results...",
+ timeframe: "30 days",
+ cost: "10 NP"
+ });
+});
+
+app.post("/api/generate", (req, res) => {
+ const { prompt } = req.body;
+ res.json({
+ generated: `Generated content based on: ${prompt}`,
+ tokens: 150,
+ cost: "15 NP"
+ });
+});
+
+app.listen(3000, () => {
+ console.log("AI API running on http://localhost:3000");
+});
+```
+
+### Tiered Pricing Example
+
+```typescript
+const tieredRoutes = {
+ // Free tier (no payment middleware)
+ // Applied directly to routes
+
+ // Basic tier - 1 NP
+ "GET /basic/*": {
+ priceNP: 1,
+ recipient: "api-service",
+ description: "Basic API access",
+ maxTimeoutSeconds: 30,
+ },
+
+ // Standard tier - 5 NP
+ "GET /standard/*": {
+ priceNP: 5,
+ recipient: "api-service",
+ description: "Standard API access",
+ maxTimeoutSeconds: 60,
+ },
+
+ // Premium tier - 10 NP
+ "GET /premium/*": {
+ priceNP: 10,
+ recipient: "api-service",
+ description: "Premium API access",
+ maxTimeoutSeconds: 120,
+ },
+
+ // Enterprise tier - 25 NP
+ "GET /enterprise/*": {
+ priceNP: 25,
+ recipient: "api-service",
+ description: "Enterprise API access",
+ maxTimeoutSeconds: 300,
+ }
+};
+
+app.use(npPaymentMiddleware(tieredRoutes, facilitatorUrl));
+```
+
+### Dynamic Pricing Example
+
+```typescript
+// Custom middleware for dynamic pricing
+function dynamicPricingMiddleware(basePrice: number, recipient: string) {
+ return npPaymentMiddleware(
+ {
+ "*": {
+ priceNP: basePrice, // Will be overridden
+ recipient,
+ description: "Dynamic pricing endpoint",
+ }
+ },
+ facilitatorUrl
+ );
+}
+
+// Pre-process to set dynamic price
+app.use("/api/dynamic", (req, res, next) => {
+ const complexity = parseInt(req.query.complexity as string) || 1;
+ const basePrice = 5;
+ const dynamicPrice = basePrice * complexity;
+
+ // Store in request for middleware
+ (req as any).dynamicPrice = dynamicPrice;
+ next();
+});
+
+// Apply payment middleware
+app.use("/api/dynamic", dynamicPricingMiddleware(5, "dynamic-service"));
+
+app.get("/api/dynamic/process", (req, res) => {
+ const complexity = req.query.complexity || 1;
+ const price = (req as any).dynamicPrice || 5;
+
+ res.json({
+ result: `Processed with complexity level ${complexity}`,
+ cost: `${price} NP`,
+ formula: "basePrice * complexity"
+ });
+});
+```
+
+## Client Integration
+
+### Node.js Client Example
+
+```typescript
+import fetch from "node-fetch";
+
+class NandaPointsClient {
+ constructor(
+ private baseUrl: string,
+ private agentName: string
+ ) {}
+
+ async makeRequest(endpoint: string, payment?: any) {
+ const headers: any = {
+ 'Content-Type': 'application/json'
+ };
+
+ if (payment) {
+ const encoded = Buffer.from(JSON.stringify(payment)).toString('base64');
+ headers['X-PAYMENT'] = encoded;
+ }
+
+ const response = await fetch(`${this.baseUrl}${endpoint}`, { headers });
+
+ if (response.status === 402) {
+ const paymentInfo = await response.json();
+ return { needsPayment: true, paymentInfo };
+ }
+
+ const data = await response.json();
+ const settlementHeader = response.headers.get('X-PAYMENT-RESPONSE');
+
+ return {
+ data,
+ settlement: settlementHeader ?
+ JSON.parse(Buffer.from(settlementHeader, 'base64').toString()) : null
+ };
+ }
+
+ async accessPremiumContent() {
+ // Try without payment first
+ let result = await this.makeRequest('/premium/content');
+
+ if (result.needsPayment) {
+ console.log('Payment required:', result.paymentInfo);
+
+ // Create payment
+ const payment = {
+ x402Version: 1,
+ scheme: "nanda-points",
+ network: "nanda-network",
+ payTo: result.paymentInfo.accepts[0].payTo,
+ amount: result.paymentInfo.accepts[0].maxAmountRequired,
+ from: this.agentName,
+ txId: `client-${Date.now()}`,
+ timestamp: Date.now()
+ };
+
+ // Retry with payment
+ result = await this.makeRequest('/premium/content', payment);
+ }
+
+ return result;
+ }
+}
+
+// Usage
+const client = new NandaPointsClient('http://localhost:3000', 'my-agent');
+const content = await client.accessPremiumContent();
+console.log('Content:', content.data);
+console.log('Settlement:', content.settlement);
+```
+
+### Error Handling Patterns
+
+```typescript
+async function robustRequest(endpoint: string, agentName: string) {
+ try {
+ const result = await client.makeRequest(endpoint);
+
+ if (result.needsPayment) {
+ const { accepts } = result.paymentInfo;
+ const requirement = accepts[0];
+
+ // Check if we support this payment scheme
+ if (requirement.scheme !== 'nanda-points') {
+ throw new Error(`Unsupported payment scheme: ${requirement.scheme}`);
+ }
+
+ // Create and submit payment
+ const payment = createPayment(agentName, requirement);
+ const paidResult = await client.makeRequest(endpoint, payment);
+
+ if (paidResult.needsPayment) {
+ // Payment failed
+ throw new Error(`Payment failed: ${paidResult.paymentInfo.error}`);
+ }
+
+ return paidResult;
+ }
+
+ return result;
+
+ } catch (error) {
+ console.error(`Request to ${endpoint} failed:`, error);
+ throw error;
+ }
+}
+
+function createPayment(agentName: string, requirement: any) {
+ return {
+ x402Version: 1,
+ scheme: requirement.scheme,
+ network: requirement.network,
+ payTo: requirement.payTo,
+ amount: requirement.maxAmountRequired,
+ from: agentName,
+ txId: `${agentName}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
+ timestamp: Date.now()
+ };
+}
+```
+
+## Testing Scenarios
+
+### Manual Testing with curl
+
+```bash
+# 1. Test all free endpoints
+curl -s http://localhost:3000/health | jq
+curl -s http://localhost:3000/weather | jq
+
+# 2. Test payment required responses
+curl -s http://localhost:3000/premium/content | jq
+curl -s http://localhost:3000/premium/analysis | jq
+
+# 3. Test with valid payment
+PAYMENT='{"x402Version":1,"scheme":"nanda-points","network":"nanda-network","payTo":"system","amount":"10","from":"test-agent","txId":"test-'$(date +%s)'","timestamp":'$(date +%s)'000'}'
+ENCODED=$(echo "$PAYMENT" | base64 -w 0)
+curl -s -H "X-PAYMENT: $ENCODED" http://localhost:3000/premium/content | jq
+
+# 4. Test error scenarios
+INVALID_PAYMENT='{"invalid": "payment"}'
+ENCODED_INVALID=$(echo "$INVALID_PAYMENT" | base64 -w 0)
+curl -s -H "X-PAYMENT: $ENCODED_INVALID" http://localhost:3000/premium/content | jq
+```
+
+### Database State Verification
+
+```bash
+# Check balances before and after payments
+mongosh nanda_points --eval "
+ db.wallets.find({agent_name: {\$in: ['claude-desktop', 'system']}},
+ {agent_name: 1, balanceMinor: 1, _id: 0})
+"
+
+# Check recent transactions
+mongosh nanda_points --eval "
+ db.transactions.find({}, {txId: 1, fromAgent: 1, toAgent: 1, amountMinor: 1, createdAt: 1, _id: 0})
+ .sort({createdAt: -1}).limit(5)
+"
+
+# Check receipts
+mongosh nanda_points --eval "
+ db.receipts.find({}, {txId: 1, fromAgent: 1, toAgent: 1, amountMinor: 1, issuedAt: 1, _id: 0})
+ .sort({issuedAt: -1}).limit(5)
+"
+```
+
+## Production Considerations
+
+### Environment Configuration
+
+```bash
+# .env for production
+MONGODB_URI=mongodb://prod-server:27017
+NP_DB_NAME=nanda_points_prod
+FACILITATOR_BASE_URL=https://facilitator.yourcompany.com
+FACILITATOR_PORT=3001
+PORT=3000
+ADDRESS=production-service
+```
+
+### Security Recommendations
+
+1. **Rate Limiting**: Add rate limiting to prevent abuse
+2. **Authentication**: Consider agent authentication for production
+3. **Monitoring**: Log all payment attempts and failures
+4. **Validation**: Strict input validation on all endpoints
+5. **HTTPS**: Use HTTPS in production environments
+
+### Scaling Considerations
+
+1. **Database Connections**: Use connection pooling
+2. **Facilitator High Availability**: Deploy multiple facilitator instances
+3. **Caching**: Cache agent and balance lookups
+4. **Async Processing**: Consider async payment processing for high volume
+5. **Monitoring**: Set up alerts for failed payments
\ No newline at end of file
diff --git a/docs/facilitator-api.md b/docs/facilitator-api.md
new file mode 100644
index 0000000..4f561a1
--- /dev/null
+++ b/docs/facilitator-api.md
@@ -0,0 +1,180 @@
+# Facilitator API Specification
+
+## Overview
+
+The NANDA Points Facilitator API provides x402-compliant payment verification and settlement services for the "nanda-points" payment scheme.
+
+**Base URL**: `http://localhost:3001`
+
+## Endpoints
+
+### GET /supported
+
+Returns supported payment schemes and capabilities.
+
+**Response**: `200 OK`
+```json
+{
+ "kinds": [{
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "asset": "NP",
+ "extra": {
+ "facilitatorUrl": "http://localhost:3001/facilitator",
+ "description": "NANDA Points payment scheme using MongoDB backend",
+ "scale": 0,
+ "currency": "NP"
+ }
+ }]
+}
+```
+
+### POST /verify
+
+Verifies payment validity without settlement.
+
+**Request Body**:
+```json
+{
+ "payment": {
+ "x402Version": 1,
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "payTo": "system",
+ "amount": "10",
+ "from": "claude-desktop",
+ "txId": "unique-tx-id",
+ "timestamp": 1758628686000
+ },
+ "paymentRequirements": {
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "maxAmountRequired": "10",
+ "resource": "http://localhost:3000/premium/content",
+ "description": "Access to premium content",
+ "payTo": "system",
+ "asset": "NP"
+ }
+}
+```
+
+**Success Response**: `200 OK`
+```json
+{
+ "isValid": true,
+ "payer": "claude-desktop",
+ "amount": "10",
+ "txId": "unique-tx-id"
+}
+```
+
+**Error Response**: `402 Payment Required`
+```json
+{
+ "isValid": false,
+ "invalidReason": "Insufficient balance",
+ "payer": "claude-desktop",
+ "details": {
+ "agent": "claude-desktop",
+ "balance": 5,
+ "required": 10
+ }
+}
+```
+
+### POST /settle
+
+Verifies and settles payment, updating balances.
+
+**Request Body**: Same as `/verify`
+
+**Success Response**: `200 OK`
+```json
+{
+ "success": true,
+ "txId": "unique-tx-id",
+ "amount": "10",
+ "from": "claude-desktop",
+ "to": "system",
+ "timestamp": 1758628686499,
+ "receipt": {
+ "txId": "unique-tx-id",
+ "issuedAt": "2025-09-23T11:58:06.499Z",
+ "fromAgent": "claude-desktop",
+ "toAgent": "system",
+ "amountMinor": 10,
+ "fromBalanceAfter": 1531,
+ "toBalanceAfter": 1021
+ }
+}
+```
+
+**Error Response**: `402 Payment Required`
+```json
+{
+ "success": false,
+ "errorReason": "Agent not found",
+ "txId": "unique-tx-id",
+ "details": {
+ "agent": "non-existent-agent"
+ }
+}
+```
+
+### GET /health
+
+Health check endpoint.
+
+**Response**: `200 OK`
+```json
+{
+ "status": "healthy",
+ "service": "nanda-points-facilitator",
+ "version": "1.0.0",
+ "schemes": ["nanda-points"]
+}
+```
+
+## Error Codes and Messages
+
+| Error | HTTP Status | Message |
+|-------|-------------|---------|
+| Agent not found | 402 | "Agent not found" |
+| Insufficient balance | 402 | "Insufficient balance" |
+| Invalid payment scheme | 402 | "Unsupported payment scheme" |
+| Duplicate transaction | 402 | "Transaction exists but not completed" |
+| Invalid amount | 402 | "Insufficient payment amount" |
+| Recipient mismatch | 402 | "Payment recipient mismatch" |
+
+## Database Operations
+
+The facilitator performs atomic MongoDB operations:
+
+1. **Verification**:
+ - Check sender agent exists
+ - Check recipient agent exists
+ - Validate sender balance
+ - Check for duplicate transactions
+
+2. **Settlement**:
+ - Deduct amount from sender wallet
+ - Add amount to recipient wallet
+ - Create transaction record
+ - Generate receipt
+
+## Authentication
+
+- No authentication required (trust-based system)
+- Agent validation through database lookup
+- Transaction uniqueness prevents double-spending
+
+## Rate Limiting
+
+- No rate limiting implemented
+- Production deployments should add appropriate limits
+
+## Monitoring
+
+- Console logging for all transactions
+- MongoDB operations logged with balances
+- Error conditions logged with details
\ No newline at end of file
diff --git a/docs/mcp-server-sdk.md b/docs/mcp-server-sdk.md
new file mode 100644
index 0000000..483383e
--- /dev/null
+++ b/docs/mcp-server-sdk.md
@@ -0,0 +1,230 @@
+# MCP Server SDK Documentation
+
+## Overview
+
+The MCP Server SDK provides middleware and utilities for adding x402 payment capabilities to MCP (Model Context Protocol) servers using NANDA Points.
+
+## Core Components
+
+### npPaymentMiddleware
+
+Express middleware that adds x402 payment requirements to specified routes.
+
+```typescript
+import { npPaymentMiddleware } from "x402-nanda-shared";
+
+app.use(
+ npPaymentMiddleware(
+ {
+ "GET /premium/content": {
+ priceNP: 10,
+ recipient: "system",
+ description: "Access to premium content",
+ maxTimeoutSeconds: 60,
+ },
+ "/premium/*": {
+ priceNP: 5,
+ recipient: "system",
+ description: "Access to premium features",
+ maxTimeoutSeconds: 30,
+ }
+ },
+ "http://localhost:3001" // facilitator URL
+ )
+);
+```
+
+### Payment Configuration
+
+```typescript
+interface NPPaymentConfig {
+ priceNP: number; // Price in NANDA Points
+ recipient: string; // Recipient agent name
+ description?: string; // Payment description
+ maxTimeoutSeconds?: number; // Payment timeout
+}
+
+interface NPRoutesConfig {
+ [route: string]: NPPaymentConfig;
+}
+```
+
+### Route Patterns
+
+The middleware supports flexible route patterns:
+
+- **Exact match**: `"GET /premium/content"`
+- **Wildcard**: `"/premium/*"` matches `/premium/content`, `/premium/analysis`, etc.
+- **Method-specific**: `"POST /api/action"` only matches POST requests
+- **Method-agnostic**: `"/api/action"` matches any HTTP method
+
+## Middleware Behavior
+
+### Without Payment
+
+When a protected route is accessed without payment:
+
+```http
+GET /premium/content HTTP/1.1
+Host: localhost:3000
+
+HTTP/1.1 402 Payment Required
+Content-Type: application/json
+
+{
+ "x402Version": 1,
+ "error": "X-PAYMENT header is required",
+ "accepts": [{
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "maxAmountRequired": "10",
+ "resource": "http://localhost:3000/premium/content",
+ "description": "Access to premium content",
+ "mimeType": "application/json",
+ "payTo": "system",
+ "maxTimeoutSeconds": 60,
+ "asset": "NP",
+ "extra": {
+ "facilitatorUrl": "http://localhost:3001"
+ }
+ }]
+}
+```
+
+### With Valid Payment
+
+When a valid payment is provided:
+
+```http
+GET /premium/content HTTP/1.1
+Host: localhost:3000
+X-PAYMENT: eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoibmFuZGEtcG9pbnRzIi...
+
+HTTP/1.1 200 OK
+Content-Type: application/json
+X-PAYMENT-RESPONSE: eyJ0eElkIjoidGVzdC0xNzU4NjI4Njg2LTQwMjI3Ii...
+
+{
+ "content": "This is premium content available for 10 NANDA Points",
+ "features": ["Advanced analytics", "Real-time updates"]
+}
+```
+
+## Integration Examples
+
+### Basic MCP Server
+
+```typescript
+import express from "express";
+import { npPaymentMiddleware } from "x402-nanda-shared";
+
+const app = express();
+const facilitatorUrl = "http://localhost:3001";
+const payTo = "my-service";
+
+// Add payment middleware
+app.use(
+ npPaymentMiddleware(
+ {
+ "GET /ai/analyze": {
+ priceNP: 2,
+ recipient: payTo,
+ description: "AI content analysis",
+ },
+ "POST /ai/generate": {
+ priceNP: 5,
+ recipient: payTo,
+ description: "AI content generation",
+ }
+ },
+ facilitatorUrl
+ )
+);
+
+// Free endpoints (no payment required)
+app.get("/health", (req, res) => {
+ res.json({ status: "healthy" });
+});
+
+// Paid endpoints (automatically protected)
+app.get("/ai/analyze", (req, res) => {
+ res.json({
+ analysis: "Content analysis results...",
+ cost: "2 NP"
+ });
+});
+
+app.post("/ai/generate", (req, res) => {
+ res.json({
+ generated: "Generated content...",
+ cost: "5 NP"
+ });
+});
+
+app.listen(3000);
+```
+
+### Advanced Configuration
+
+```typescript
+// Different pricing tiers
+const routes = {
+ "GET /basic/*": {
+ priceNP: 1,
+ recipient: payTo,
+ description: "Basic tier access",
+ maxTimeoutSeconds: 30,
+ },
+ "GET /premium/*": {
+ priceNP: 10,
+ recipient: payTo,
+ description: "Premium tier access",
+ maxTimeoutSeconds: 60,
+ },
+ "GET /enterprise/*": {
+ priceNP: 50,
+ recipient: payTo,
+ description: "Enterprise tier access",
+ maxTimeoutSeconds: 120,
+ }
+};
+```
+
+## Error Handling
+
+The middleware handles various error scenarios:
+
+### Payment Verification Errors
+- Invalid payment format
+- Insufficient balance
+- Agent not found
+- Duplicate transaction
+
+### Network Errors
+- Facilitator unavailable
+- Timeout connecting to facilitator
+- Invalid facilitator response
+
+### Configuration Errors
+- Invalid route patterns
+- Missing facilitator URL
+- Invalid payment configuration
+
+## Best Practices
+
+1. **Route Organization**: Group related endpoints under common prefixes
+2. **Pricing Strategy**: Consider usage patterns and value provided
+3. **Error Handling**: Implement graceful degradation for payment failures
+4. **Monitoring**: Log payment attempts and failures
+5. **Testing**: Test both free and paid endpoints thoroughly
+
+## Streamable HTTP Transport
+
+The SDK is designed for Streamable HTTP transport compatibility:
+
+- Proper HTTP status codes (402 for payment required)
+- Standard HTTP headers (X-PAYMENT, X-PAYMENT-RESPONSE)
+- JSON request/response bodies
+- RESTful API patterns
+
+This ensures compatibility with MCP clients that use HTTP transport rather than stdio.
\ No newline at end of file
diff --git a/docs/nanda-points-scheme.md b/docs/nanda-points-scheme.md
new file mode 100644
index 0000000..b9d73cd
--- /dev/null
+++ b/docs/nanda-points-scheme.md
@@ -0,0 +1,106 @@
+# NANDA Points Payment Scheme Specification
+
+## Overview
+
+The "nanda-points" payment scheme replaces blockchain-based payment schemes (like EVM) with a MongoDB-backed agent transaction system.
+
+## Scheme Identification
+
+- **Scheme**: `"nanda-points"`
+- **Network**: `"nanda-network"`
+- **Asset**: `"NP"`
+
+## Payment Payload Structure
+
+```json
+{
+ "x402Version": 1,
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "payTo": "recipient-agent-name",
+ "amount": "10",
+ "from": "sender-agent-name",
+ "txId": "unique-transaction-id",
+ "timestamp": 1758628686000
+}
+```
+
+### Required Fields
+
+- `scheme`: Must be `"nanda-points"`
+- `network`: Must be `"nanda-network"`
+- `payTo`: Recipient agent name (string)
+- `amount`: Payment amount in NP (string representation of integer)
+- `from`: Sender agent name (string)
+- `txId`: Unique transaction identifier (string)
+- `timestamp`: Unix timestamp in milliseconds (number)
+
+## Payment Requirements Structure
+
+```json
+{
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "maxAmountRequired": "10",
+ "resource": "http://localhost:3000/premium/content",
+ "description": "Access to premium content",
+ "mimeType": "application/json",
+ "payTo": "system",
+ "maxTimeoutSeconds": 60,
+ "asset": "NP",
+ "extra": {
+ "facilitatorUrl": "http://localhost:3001"
+ }
+}
+```
+
+## Differences from Blockchain Schemes
+
+### Authentication
+- **Blockchain**: Wallet signatures (EIP-712)
+- **NANDA Points**: Agent name authentication
+
+### Settlement
+- **Blockchain**: Smart contract calls, gas fees
+- **NANDA Points**: MongoDB balance updates
+
+### Verification
+- **Blockchain**: On-chain balance checks, signature verification
+- **NANDA Points**: Database queries, transaction validation
+
+### Transaction IDs
+- **Blockchain**: On-chain transaction hashes
+- **NANDA Points**: UUID or custom transaction identifiers
+
+## Facilitator Integration
+
+The facilitator provides three endpoints:
+
+### `/verify`
+- Validates payment without settlement
+- Checks agent existence and balance
+- Returns validation status
+
+### `/settle`
+- Performs actual balance transfer
+- Creates transaction and receipt records
+- Returns settlement confirmation
+
+### `/supported`
+- Returns supported payment schemes
+- Includes facilitator URL and capabilities
+
+## Error Scenarios
+
+1. **Agent Not Found**: Sender or recipient doesn't exist
+2. **Insufficient Balance**: Sender lacks required NP amount
+3. **Duplicate Transaction**: txId already exists
+4. **Invalid Amount**: Non-numeric or negative amount
+5. **Schema Validation**: Missing required fields
+
+## Security Considerations
+
+- Transaction IDs must be unique to prevent double-spending
+- Agent validation prevents payments to/from non-existent accounts
+- Balance checks prevent overdrafts
+- Atomic database operations ensure consistency
\ No newline at end of file
diff --git a/docs/x402-np.md b/docs/x402-np.md
deleted file mode 100644
index 640a936..0000000
--- a/docs/x402-np.md
+++ /dev/null
@@ -1,150 +0,0 @@
-# x402-NP: HTTP Payment Protocol for Nanda Points
-
-This implementation brings x402 payment protocol support to the Nanda Points MCP server, enabling agents to pay for tool access using NP instead of cryptocurrency.
-
-## Overview
-
-The x402 protocol uses HTTP 402 "Payment Required" status codes to gate access to paid resources. Our x402-NP implementation adapts this to work with the existing Nanda Points infrastructure.
-
-## How It Works
-
-### 1. Payment Flow
-
-```mermaid
-sequenceDiagram
- participant Client
- participant MCP Server
- participant NP System
-
- Client->>MCP Server: Call paid tool (no payment)
- MCP Server->>Client: 402 Payment Required + payment info
- Client->>NP System: initiateTransaction (pay required amount)
- NP System->>Client: Transaction receipt + txId
- Client->>MCP Server: Retry tool call + payment headers
- MCP Server->>NP System: Verify payment receipt
- NP System->>MCP Server: Payment confirmed
- MCP Server->>Client: Tool result
-```
-
-### 2. Payment Headers
-
-When retrying a paid tool call, include these headers:
-
-- `X-PAYMENT-AGENT`: Your agent name (payer)
-- `X-PAYMENT-TX-ID`: Transaction ID from NP transfer
-- `X-PAYMENT-AMOUNT`: Amount paid in NP points
-
-### 3. Error Responses
-
-The server returns structured error responses:
-
-**402 Payment Required:**
-```json
-{
- "jsonrpc": "2.0",
- "error": {
- "code": -32402,
- "message": "Payment Required",
- "data": {
- "protocol": "x402-np",
- "tool": "getBalance",
- "price": {
- "amount": 1,
- "currency": "NP",
- "scale": 2,
- "recipient": "system"
- },
- "description": "Get agent balance in Nanda Points",
- "instructions": {
- "steps": [
- "Use initiateTransaction tool to transfer 1 NP from your agent to system",
- "Include the returned txId in X-PAYMENT-TX-ID header",
- "Include your agent name in X-PAYMENT-AGENT header",
- "Include the amount in X-PAYMENT-AMOUNT header",
- "Retry the tool call with payment headers"
- ]
- }
- }
- },
- "id": 1
-}
-```
-
-## Configuration
-
-### Paid Tools Configuration
-
-Tools are configured in `src/mcp/server.ts`:
-
-```typescript
-const paidToolsConfig: { [toolName: string]: NPToolConfig } = {
- "getBalance": {
- priceNP: 1,
- recipient: "system",
- description: "Get agent balance in Nanda Points"
- },
- "initiateTransaction": {
- priceNP: 2,
- recipient: "system",
- description: "Transfer NP between agents"
- },
- "getReceipt": {
- priceNP: 1,
- recipient: "system",
- description: "Retrieve transaction receipt"
- }
-};
-```
-
-### Free Tools
-
-These tools remain free to use:
-- `getPaymentInfo` - Get payment requirements for all tools
-- `setServiceCharge` - Set per-call service charges
-
-## Client Implementation
-
-See `examples/x402-client.ts` for a complete client implementation that handles the payment flow automatically.
-
-## Example Usage
-
-```typescript
-import { X402NPClient } from './examples/x402-client';
-
-const client = new X402NPClient('http://localhost:3000', 'alice');
-
-// This will automatically handle payment if required
-const balance = await client.callPaidTool('getBalance', {
- agent_name: 'alice'
-});
-```
-
-## Benefits
-
-1. **No crypto required** - Uses existing NP infrastructure
-2. **Instant settlement** - Payments verified immediately via receipts
-3. **Agent-native** - Natural fit for agent-to-agent payments
-4. **Standard protocol** - Compatible with x402 specification
-5. **Backwards compatible** - Existing tools work unchanged
-
-## Security Features
-
-- Payment verification using cryptographic receipts
-- Amount matching validation
-- Agent existence verification
-- Transaction replay protection via unique txIds
-- Structured error handling
-
-## Monitoring
-
-Payment activities are logged with:
-```
-✅ Payment verified: alice paid 1 NP to system for getBalance
-```
-
-## Future Enhancements
-
-- Rate limiting per agent
-- Payment caching to avoid repeated payments
-- Bulk payment support
-- Payment analytics and reporting
\ No newline at end of file
diff --git a/docs/x402-protocol-analysis.md b/docs/x402-protocol-analysis.md
new file mode 100644
index 0000000..49d4bf9
--- /dev/null
+++ b/docs/x402-protocol-analysis.md
@@ -0,0 +1,74 @@
+# x402 Protocol Analysis
+
+## Client Expectations for Server Behavior
+
+Based on analysis of the x402 protocol and client implementations, servers must provide:
+
+### 1. HTTP 402 Payment Required Response
+
+When payment is required, servers must return:
+- **Status Code**: `402 Payment Required`
+- **Content-Type**: `application/json`
+- **Response Body**: Payment requirements JSON
+
+### 2. Payment Requirements Format
+
+```json
+{
+ "x402Version": 1,
+ "error": "X-PAYMENT header is required",
+ "accepts": [{
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "maxAmountRequired": "10",
+ "resource": "http://localhost:3000/premium/content",
+ "description": "Access to premium content",
+ "mimeType": "application/json",
+ "payTo": "system",
+ "maxTimeoutSeconds": 60,
+ "asset": "NP",
+ "extra": {
+ "facilitatorUrl": "http://localhost:3001"
+ }
+ }]
+}
+```
+
+### 3. X-PAYMENT Header Processing
+
+Servers must:
+- Accept `X-PAYMENT` header with base64-encoded payment payload
+- Decode and validate payment structure
+- Verify payment against requirements
+- Process payment through facilitator
+
+### 4. X-PAYMENT-RESPONSE Header
+
+On successful payment, servers should return:
+- **Status Code**: `200 OK`
+- **X-PAYMENT-RESPONSE Header**: Base64-encoded settlement receipt
+- **Response Body**: Requested resource data
+
+### 5. Error Handling
+
+Servers must handle:
+- Missing X-PAYMENT header → 402 with payment requirements
+- Invalid payment format → 402 with decoding error
+- Insufficient funds → 402 with balance error
+- Invalid agent → 402 with agent not found error
+
+## Client Flow Expectations
+
+1. **Initial Request**: Client requests resource without payment
+2. **Payment Discovery**: Server returns 402 with payment requirements
+3. **Payment Creation**: Client creates payment payload with unique txId
+4. **Payment Submission**: Client retries with X-PAYMENT header
+5. **Settlement**: Server verifies, settles, and returns resource with receipt
+
+## Key Protocol Principles
+
+- **HTTP Native**: Payments complement existing HTTP flows
+- **Chain Agnostic**: Not tied to specific blockchain
+- **Minimal Integration**: Easy to add to existing APIs
+- **Flexible Schemes**: Supports multiple payment methods
+- **Atomic Transactions**: Payment and resource delivery are linked
\ No newline at end of file
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 0000000..a150c65
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,48 @@
+import js from '@eslint/js';
+import tseslint from 'typescript-eslint';
+import prettierPlugin from 'eslint-plugin-prettier';
+
+export default [
+ js.configs.recommended,
+ ...tseslint.configs.recommended,
+ {
+ files: ['**/*.ts'],
+ plugins: {
+ prettier: prettierPlugin,
+ },
+ rules: {
+ // TypeScript rules
+ '@typescript-eslint/no-unused-vars': 'error',
+ '@typescript-eslint/no-explicit-any': 'warn',
+ '@typescript-eslint/explicit-function-return-type': 'off',
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
+ '@typescript-eslint/no-non-null-assertion': 'warn',
+
+ // General rules
+ 'no-console': 'off', // Allow console in server code
+ 'no-unused-vars': 'off', // Use TypeScript version instead
+ 'prefer-const': 'error',
+ 'no-var': 'error',
+
+ // Prettier integration
+ 'prettier/prettier': 'error',
+ },
+ },
+ {
+ files: ['**/*.js'],
+ languageOptions: {
+ ecmaVersion: 2020,
+ sourceType: 'module',
+ },
+ },
+ {
+ ignores: [
+ 'node_modules/**',
+ 'dist/**',
+ 'build/**',
+ '**/dist/**',
+ '**/build/**',
+ '*.d.ts',
+ ],
+ },
+];
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 1b2bcea..7c598b2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,26 +1,47 @@
{
- "name": "nanda-points-mcp-server",
- "version": "0.2.0",
+ "name": "x402-nanda-points",
+ "version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "nanda-points-mcp-server",
- "version": "0.2.0",
+ "name": "x402-nanda-points",
+ "version": "1.0.0",
+ "license": "MIT",
+ "workspaces": [
+ "packages/*"
+ ],
+ "devDependencies": {
+ "@typescript-eslint/eslint-plugin": "^8.29.1",
+ "@typescript-eslint/parser": "^8.29.1",
+ "eslint": "^9.24.0",
+ "eslint-plugin-import": "^2.31.0",
+ "eslint-plugin-jsdoc": "^50.6.9",
+ "eslint-plugin-prettier": "^5.2.6",
+ "prettier": "3.5.2",
+ "tsx": "^4.7.0",
+ "typescript": "^5.3.0",
+ "typescript-eslint": "^8.29.1"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@es-joy/jsdoccomment": {
+ "version": "0.50.2",
+ "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.50.2.tgz",
+ "integrity": "sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "^1.18.0",
- "cors": "^2.8.5",
- "dotenv": "^16.4.5",
- "express": "^4.19.2",
- "mongodb": "^6.8.0",
- "zod": "^3.23.8"
+ "@types/estree": "^1.0.6",
+ "@typescript-eslint/types": "^8.11.0",
+ "comment-parser": "1.4.1",
+ "esquery": "^1.6.0",
+ "jsdoc-type-pratt-parser": "~4.1.0"
},
- "devDependencies": {
- "@types/cors": "^2.8.17",
- "@types/express": "^4.17.21",
- "@types/node": "^24.5.1",
- "tsx": "^4.19.0",
- "typescript": "^5.5.4"
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/@esbuild/aix-ppc64": {
@@ -41,9 +62,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz",
- "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+ "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
"cpu": [
"arm"
],
@@ -54,13 +75,13 @@
"android"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz",
- "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+ "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
"cpu": [
"arm64"
],
@@ -71,13 +92,13 @@
"android"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz",
- "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+ "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
"cpu": [
"x64"
],
@@ -88,13 +109,13 @@
"android"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz",
- "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
+ "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
"cpu": [
"arm64"
],
@@ -105,13 +126,13 @@
"darwin"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz",
- "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+ "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
"cpu": [
"x64"
],
@@ -122,13 +143,13 @@
"darwin"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz",
- "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+ "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
"cpu": [
"arm64"
],
@@ -139,13 +160,13 @@
"freebsd"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz",
- "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+ "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
"cpu": [
"x64"
],
@@ -156,13 +177,13 @@
"freebsd"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz",
- "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+ "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
"cpu": [
"arm"
],
@@ -173,13 +194,13 @@
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz",
- "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+ "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
"cpu": [
"arm64"
],
@@ -190,13 +211,13 @@
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz",
- "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+ "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
"cpu": [
"ia32"
],
@@ -207,13 +228,13 @@
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz",
- "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+ "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
"cpu": [
"loong64"
],
@@ -224,13 +245,13 @@
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz",
- "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+ "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
"cpu": [
"mips64el"
],
@@ -241,13 +262,13 @@
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz",
- "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+ "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
"cpu": [
"ppc64"
],
@@ -258,13 +279,13 @@
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz",
- "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+ "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
"cpu": [
"riscv64"
],
@@ -275,13 +296,13 @@
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz",
- "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+ "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
"cpu": [
"s390x"
],
@@ -292,13 +313,13 @@
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz",
- "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+ "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
"cpu": [
"x64"
],
@@ -309,7 +330,7 @@
"linux"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/netbsd-arm64": {
@@ -330,9 +351,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz",
- "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
"cpu": [
"x64"
],
@@ -343,7 +364,7 @@
"netbsd"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/openbsd-arm64": {
@@ -364,9 +385,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz",
- "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
"cpu": [
"x64"
],
@@ -377,7 +398,7 @@
"openbsd"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/openharmony-arm64": {
@@ -398,9 +419,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz",
- "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+ "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
"cpu": [
"x64"
],
@@ -411,13 +432,13 @@
"sunos"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz",
- "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+ "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
"cpu": [
"arm64"
],
@@ -428,13 +449,13 @@
"win32"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz",
- "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+ "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
"cpu": [
"ia32"
],
@@ -445,13 +466,13 @@
"win32"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz",
- "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==",
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
"cpu": [
"x64"
],
@@ -462,316 +483,383 @@
"win32"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
- "node_modules/@modelcontextprotocol/sdk": {
- "version": "1.18.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.18.0.tgz",
- "integrity": "sha512-JvKyB6YwS3quM+88JPR0axeRgvdDu3Pv6mdZUy+w4qVkCzGgumb9bXG/TmtDRQv+671yaofVfXSQmFLlWU5qPQ==",
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+ "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "ajv": "^6.12.6",
- "content-type": "^1.0.5",
- "cors": "^2.8.5",
- "cross-spawn": "^7.0.5",
- "eventsource": "^3.0.2",
- "eventsource-parser": "^3.0.0",
- "express": "^5.0.1",
- "express-rate-limit": "^7.5.0",
- "pkce-challenge": "^5.0.0",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8",
- "zod-to-json-schema": "^3.24.1"
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
- "node": ">=18"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
}
},
- "node_modules/@modelcontextprotocol/sdk/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==",
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "mime-types": "^3.0.0",
- "negotiator": "^1.0.0"
- },
"engines": {
- "node": ">= 0.6"
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
- "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
- "license": "MIT",
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
+ "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
+ "dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "bytes": "^3.1.2",
- "content-type": "^1.0.5",
- "debug": "^4.4.0",
- "http-errors": "^2.0.0",
- "iconv-lite": "^0.6.3",
- "on-finished": "^2.4.1",
- "qs": "^6.14.0",
- "raw-body": "^3.0.0",
- "type-is": "^2.0.0"
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
},
"engines": {
- "node": ">=18"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
- "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
+ "node_modules/@eslint/config-array/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "safe-buffer": "5.2.1"
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
},
"engines": {
- "node": ">= 0.6"
+ "node": "*"
}
},
- "node_modules/@modelcontextprotocol/sdk/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",
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
+ "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==",
+ "dev": true,
+ "license": "Apache-2.0",
"engines": {
- "node": ">=6.6.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "license": "MIT",
+ "node_modules/@eslint/core": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
+ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
+ "dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "ms": "^2.1.3"
+ "@types/json-schema": "^7.0.15"
},
"engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/express": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
- "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
- "license": "MIT",
- "dependencies": {
- "accepts": "^2.0.0",
- "body-parser": "^2.2.0",
- "content-disposition": "^1.0.0",
- "content-type": "^1.0.5",
- "cookie": "^0.7.1",
- "cookie-signature": "^1.2.1",
- "debug": "^4.4.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"
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
+ "url": "https://opencollective.com/eslint"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
- "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
+ "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
"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": ">= 0.8"
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/fresh": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
- "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "node_modules/@eslint/eslintrc/node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.8"
+ "node": ">= 4"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "license": "MIT",
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
"dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
+ "brace-expansion": "^1.1.7"
},
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/@modelcontextprotocol/sdk/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": "*"
}
},
- "node_modules/@modelcontextprotocol/sdk/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==",
+ "node_modules/@eslint/js": {
+ "version": "9.36.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz",
+ "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">=18"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://eslint.org/donate"
}
},
- "node_modules/@modelcontextprotocol/sdk/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",
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "license": "Apache-2.0",
"engines": {
- "node": ">= 0.6"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
- "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
- "license": "MIT",
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
+ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
+ "dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "mime-db": "^1.54.0"
+ "@eslint/core": "^0.15.2",
+ "levn": "^0.4.1"
},
"engines": {
- "node": ">= 0.6"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@modelcontextprotocol/sdk/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/@modelcontextprotocol/sdk/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",
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
"engines": {
- "node": ">= 0.6"
+ "node": ">=18.18.0"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/qs": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
- "license": "BSD-3-Clause",
+ "node_modules/@humanfs/node": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
+ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+ "dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "side-channel": "^1.1.0"
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.4.0"
},
"engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=18.18.0"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/send": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
- "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.5",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "mime-types": "^3.0.1",
- "ms": "^2.1.3",
- "on-finished": "^2.4.1",
- "range-parser": "^1.2.1",
- "statuses": "^2.0.1"
- },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
"engines": {
- "node": ">= 18"
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
- "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
- "license": "MIT",
- "dependencies": {
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "parseurl": "^1.3.3",
- "send": "^1.2.0"
- },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
"engines": {
- "node": ">= 18"
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
}
},
- "node_modules/@modelcontextprotocol/sdk/node_modules/type-is": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
- "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
- "license": "MIT",
+ "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": {
- "content-type": "^1.0.5",
- "media-typer": "^1.1.0",
- "mime-types": "^3.0.0"
+ "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": ">= 0.6"
+ "node": ">=12"
}
},
- "node_modules/@mongodb-js/saslprep": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.0.tgz",
- "integrity": "sha512-zlayKCsIjYb7/IdfqxorK5+xUMyi4vOKcFy10wKJYc63NSdKI8mNME+uJqfatkPmOSMMUiojrL58IePKBm3gvQ==",
+ "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": {
- "sparse-bitfield": "^3.0.3"
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
}
},
- "node_modules/@types/body-parser": {
+ "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/@mongodb-js/saslprep": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.0.tgz",
+ "integrity": "sha512-zlayKCsIjYb7/IdfqxorK5+xUMyi4vOKcFy10wKJYc63NSdKI8mNME+uJqfatkPmOSMMUiojrL58IePKBm3gvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "sparse-bitfield": "^3.0.3"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "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.2.9",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz",
+ "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/pkgr"
+ }
+ },
+ "node_modules/@rtsao/scc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
+ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/body-parser": {
"version": "1.19.6",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
"integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
@@ -792,33 +880,29 @@
"@types/node": "*"
}
},
- "node_modules/@types/cors": {
- "version": "2.8.19",
- "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz",
- "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==",
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
+ "license": "MIT"
},
"node_modules/@types/express": {
- "version": "4.17.23",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz",
- "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz",
+ "integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/body-parser": "*",
- "@types/express-serve-static-core": "^4.17.33",
- "@types/qs": "*",
+ "@types/express-serve-static-core": "^5.0.0",
"@types/serve-static": "*"
}
},
"node_modules/@types/express-serve-static-core": {
- "version": "4.19.6",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
- "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
+ "version": "5.0.7",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.7.tgz",
+ "integrity": "sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -835,6 +919,20 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/mime": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
@@ -843,9 +941,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "24.5.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.1.tgz",
- "integrity": "sha512-/SQdmUP2xa+1rdx7VwB9yPq8PaKej8TD5cQ+XfKDPWWC+VDJU4rvVVagXqKUzhKjtFoNA8rXDJAkCxQPAe00+Q==",
+ "version": "24.5.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.2.tgz",
+ "integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -904,516 +1002,666 @@
"@types/webidl-conversions": "*"
}
},
- "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==",
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.1.tgz",
+ "integrity": "sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "mime-types": "~2.1.34",
- "negotiator": "0.6.3"
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.44.1",
+ "@typescript-eslint/type-utils": "8.44.1",
+ "@typescript-eslint/utils": "8.44.1",
+ "@typescript-eslint/visitor-keys": "8.44.1",
+ "graphemer": "^1.4.0",
+ "ignore": "^7.0.0",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.1.0"
},
"engines": {
- "node": ">= 0.6"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.44.1",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
}
},
- "node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.1.tgz",
+ "integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
+ "@typescript-eslint/scope-manager": "8.44.1",
+ "@typescript-eslint/types": "8.44.1",
+ "@typescript-eslint/typescript-estree": "8.44.1",
+ "@typescript-eslint/visitor-keys": "8.44.1",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
}
},
- "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==",
- "license": "MIT"
- },
- "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==",
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.1.tgz",
+ "integrity": "sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==",
+ "dev": true,
"license": "MIT",
"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"
+ "@typescript-eslint/tsconfig-utils": "^8.44.1",
+ "@typescript-eslint/types": "^8.44.1",
+ "debug": "^4.3.4"
},
"engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
}
},
- "node_modules/body-parser/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==",
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.1.tgz",
+ "integrity": "sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
+ "@typescript-eslint/types": "8.44.1",
+ "@typescript-eslint/visitor-keys": "8.44.1"
},
"engines": {
- "node": ">= 0.8"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
}
},
- "node_modules/bson": {
- "version": "6.10.4",
- "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz",
- "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==",
- "license": "Apache-2.0",
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.1.tgz",
+ "integrity": "sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=16.20.1"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
}
},
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.1.tgz",
+ "integrity": "sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.44.1",
+ "@typescript-eslint/typescript-estree": "8.44.1",
+ "@typescript-eslint/utils": "8.44.1",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.1.0"
+ },
"engines": {
- "node": ">= 0.8"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
}
},
- "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==",
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.1.tgz",
+ "integrity": "sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
"engines": {
- "node": ">= 0.4"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
}
},
- "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==",
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.1.tgz",
+ "integrity": "sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
+ "@typescript-eslint/project-service": "8.44.1",
+ "@typescript-eslint/tsconfig-utils": "8.44.1",
+ "@typescript-eslint/types": "8.44.1",
+ "@typescript-eslint/visitor-keys": "8.44.1",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.1.0"
},
"engines": {
- "node": ">= 0.4"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
}
},
- "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==",
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.1.tgz",
+ "integrity": "sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "safe-buffer": "5.2.1"
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/scope-manager": "8.44.1",
+ "@typescript-eslint/types": "8.44.1",
+ "@typescript-eslint/typescript-estree": "8.44.1"
},
"engines": {
- "node": ">= 0.6"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
}
},
- "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/@typescript-eslint/visitor-keys": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.1.tgz",
+ "integrity": "sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.44.1",
+ "eslint-visitor-keys": "^4.2.1"
+ },
"engines": {
- "node": ">= 0.6"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
}
},
- "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==",
- "license": "MIT",
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
"engines": {
- "node": ">= 0.6"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
- "node_modules/cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
- "license": "MIT"
- },
- "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==",
+ "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==",
"license": "MIT",
"dependencies": {
- "object-assign": "^4",
- "vary": "^1"
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">= 0.6"
}
},
- "node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
+ "bin": {
+ "acorn": "bin/acorn"
},
"engines": {
- "node": ">= 8"
+ "node": ">=0.4.0"
}
},
- "node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
- "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==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
+ "node_modules/advanced-server-example": {
+ "resolved": "packages/advanced-server",
+ "link": true
},
- "node_modules/destroy": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
- "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
"license": "MIT",
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/dotenv": {
- "version": "16.6.1",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
- "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
- "license": "BSD-2-Clause",
+ "node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
- "url": "https://dotenvx.com"
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
- "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==",
+ "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": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
+ "color-convert": "^2.0.1"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "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/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "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",
+ "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,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
"engines": {
- "node": ">= 0.8"
+ "node": ">= 8"
}
},
- "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==",
+ "node_modules/are-docs-informative": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
+ "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.4"
+ "node": ">=14"
}
},
- "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==",
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
"engines": {
"node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/es-object-atoms": {
+ "node_modules/array-flatten": {
"version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+ "license": "MIT"
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.9",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz",
+ "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "es-errors": "^1.3.0"
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.0",
+ "es-object-atoms": "^1.1.1",
+ "get-intrinsic": "^1.3.0",
+ "is-string": "^1.1.1",
+ "math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/esbuild": {
- "version": "0.25.10",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz",
- "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==",
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
"dev": true,
- "hasInstallScript": true,
"license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/array.prototype.findlastindex": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz",
+ "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-shim-unscopables": "^1.1.0"
},
"engines": {
- "node": ">=18"
+ "node": ">= 0.4"
},
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.25.10",
- "@esbuild/android-arm": "0.25.10",
- "@esbuild/android-arm64": "0.25.10",
- "@esbuild/android-x64": "0.25.10",
- "@esbuild/darwin-arm64": "0.25.10",
- "@esbuild/darwin-x64": "0.25.10",
- "@esbuild/freebsd-arm64": "0.25.10",
- "@esbuild/freebsd-x64": "0.25.10",
- "@esbuild/linux-arm": "0.25.10",
- "@esbuild/linux-arm64": "0.25.10",
- "@esbuild/linux-ia32": "0.25.10",
- "@esbuild/linux-loong64": "0.25.10",
- "@esbuild/linux-mips64el": "0.25.10",
- "@esbuild/linux-ppc64": "0.25.10",
- "@esbuild/linux-riscv64": "0.25.10",
- "@esbuild/linux-s390x": "0.25.10",
- "@esbuild/linux-x64": "0.25.10",
- "@esbuild/netbsd-arm64": "0.25.10",
- "@esbuild/netbsd-x64": "0.25.10",
- "@esbuild/openbsd-arm64": "0.25.10",
- "@esbuild/openbsd-x64": "0.25.10",
- "@esbuild/openharmony-arm64": "0.25.10",
- "@esbuild/sunos-x64": "0.25.10",
- "@esbuild/win32-arm64": "0.25.10",
- "@esbuild/win32-ia32": "0.25.10",
- "@esbuild/win32-x64": "0.25.10"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "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==",
- "license": "MIT"
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
+ "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
- "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/array.prototype.flatmap": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
+ "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
"engines": {
- "node": ">= 0.6"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/eventsource": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
- "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "eventsource-parser": "^3.0.1"
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
},
"engines": {
- "node": ">=18.0.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/eventsource-parser": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz",
- "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==",
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">=18.0.0"
+ "node": ">= 0.4"
}
},
- "node_modules/express": {
- "version": "4.21.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
- "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
"license": "MIT",
"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.12",
- "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"
+ "possible-typed-array-names": "^1.0.0"
},
"engines": {
- "node": ">= 0.10.0"
+ "node": ">= 0.4"
},
"funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/express-rate-limit": {
- "version": "7.5.1",
- "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz",
- "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==",
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">= 16"
+ "node": ">=8"
},
"funding": {
- "url": "https://github.com/sponsors/express-rate-limit"
- },
- "peerDependencies": {
- "express": ">= 4.11"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "license": "MIT"
- },
- "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==",
- "license": "MIT"
- },
- "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/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==",
"license": "MIT",
"dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.5",
"debug": "2.6.9",
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
"on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "statuses": "2.0.1",
- "unpipe": "~1.0.0"
+ "qs": "6.13.0",
+ "raw-body": "2.5.2",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
},
"engines": {
- "node": ">= 0.8"
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
}
},
- "node_modules/forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "node_modules/body-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"license": "MIT",
- "engines": {
- "node": ">= 0.6"
+ "dependencies": {
+ "ms": "2.0.0"
}
},
- "node_modules/fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "node_modules/body-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
"engines": {
- "node": ">= 0.6"
+ "node": ">=8"
}
},
- "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/bson": {
+ "version": "6.10.4",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz",
+ "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.20.1"
+ }
+ },
+ "node_modules/bundle-require": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.2.1.tgz",
+ "integrity": "sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==",
"dev": true,
- "hasInstallScript": true,
"license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
+ "dependencies": {
+ "load-tsconfig": "^0.2.3"
+ },
"engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "esbuild": ">=0.17"
}
},
- "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==",
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": ">= 0.8"
}
},
- "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==",
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "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"
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
},
"engines": {
"node": ">= 0.4"
@@ -1422,37 +1670,28 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "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==",
+ "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": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
- "node_modules/get-tsconfig": {
- "version": "4.10.1",
- "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
- "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
- "dev": true,
+ "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": {
- "resolve-pkg-maps": "^1.0.0"
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
},
- "funding": {
- "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
- }
- },
- "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"
},
@@ -1460,251 +1699,259 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "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==",
+ "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": ">= 0.4"
+ "node": ">=6"
+ }
+ },
+ "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/ljharb"
+ "url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "function-bind": "^1.1.2"
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
}
},
- "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==",
- "license": "MIT",
+ "node_modules/chokidar/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,
+ "license": "ISC",
"dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
+ "is-glob": "^4.0.1"
},
"engines": {
- "node": ">= 0.8"
+ "node": ">= 6"
}
},
- "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==",
+ "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": {
- "safer-buffer": ">= 2.1.2 < 3"
+ "color-name": "~1.1.4"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=7.0.0"
}
},
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
+ "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/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==",
+ "node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.10"
+ "node": ">= 6"
}
},
- "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/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "license": "ISC"
+ "node_modules/comment-parser": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
+ "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12.0.0"
+ }
},
- "node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "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/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "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==",
"license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
"engines": {
- "node": ">= 0.4"
+ "node": ">= 0.6"
}
},
- "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==",
+ "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==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
- "node_modules/memory-pager": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
- "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
- "license": "MIT"
- },
- "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==",
+ "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==",
"license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "engines": {
+ "node": ">= 0.6"
}
},
- "node_modules/methods": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
- "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+ "license": "MIT"
+ },
+ "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": ">= 0.6"
+ "node": ">= 8"
}
},
- "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/data-view-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
+ "dev": true,
"license": "MIT",
- "bin": {
- "mime": "cli.js"
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
},
"engines": {
- "node": ">=4"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "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/data-view-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
"engines": {
- "node": ">= 0.6"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/inspect-js"
}
},
- "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==",
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "mime-db": "1.52.0"
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
},
"engines": {
- "node": ">= 0.6"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/mongodb": {
- "version": "6.19.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.19.0.tgz",
- "integrity": "sha512-H3GtYujOJdeKIMLKBT9PwlDhGrQfplABNF1G904w6r5ZXKWyv77aB0X9B+rhmaAwjtllHzaEkvi9mkGVZxs2Bw==",
- "license": "Apache-2.0",
+ "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": {
- "@mongodb-js/saslprep": "^1.1.9",
- "bson": "^6.10.4",
- "mongodb-connection-string-url": "^3.0.0"
+ "ms": "^2.1.3"
},
"engines": {
- "node": ">=16.20.1"
- },
- "peerDependencies": {
- "@aws-sdk/credential-providers": "^3.188.0",
- "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
- "gcp-metadata": "^5.2.0",
- "kerberos": "^2.0.1",
- "mongodb-client-encryption": ">=6.0.0 <7",
- "snappy": "^7.3.2",
- "socks": "^2.7.1"
+ "node": ">=6.0"
},
"peerDependenciesMeta": {
- "@aws-sdk/credential-providers": {
- "optional": true
- },
- "@mongodb-js/zstd": {
- "optional": true
- },
- "gcp-metadata": {
- "optional": true
- },
- "kerberos": {
- "optional": true
- },
- "mongodb-client-encryption": {
- "optional": true
- },
- "snappy": {
- "optional": true
- },
- "socks": {
+ "supports-color": {
"optional": true
}
}
},
- "node_modules/mongodb-connection-string-url": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz",
- "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@types/whatwg-url": "^11.0.2",
- "whatwg-url": "^14.1.0 || ^13.0.0"
- }
- },
- "node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
"license": "MIT"
},
- "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==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "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==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
"engines": {
"node": ">= 0.4"
},
@@ -1712,348 +1959,4362 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "ee-first": "1.1.1"
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
},
"engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "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==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
"license": "MIT",
"engines": {
- "node": ">=8"
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
}
},
- "node_modules/path-to-regexp": {
- "version": "0.1.12",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
- "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
- "license": "MIT"
- },
- "node_modules/pkce-challenge": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz",
- "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==",
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
"engines": {
- "node": ">=16.20.0"
+ "node": ">=8"
}
},
- "node_modules/proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "license": "MIT",
+ "node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
+ "esutils": "^2.0.2"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">=0.10.0"
}
},
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "license": "MIT",
+ "node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "license": "BSD-2-Clause",
"engines": {
- "node": ">=6"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
}
},
- "node_modules/qs": {
- "version": "6.13.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
- "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
- "license": "BSD-3-Clause",
+ "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": {
- "side-channel": "^1.0.6"
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
},
"engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">= 0.4"
}
},
- "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==",
+ "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==",
+ "license": "MIT"
+ },
+ "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.6"
+ "node": ">= 0.8"
}
},
- "node_modules/raw-body": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.1.tgz",
- "integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==",
+ "node_modules/es-abstract": {
+ "version": "1.24.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz",
+ "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.7.0",
- "unpipe": "1.0.0"
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.2",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.2.1",
+ "is-set": "^2.0.3",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.1",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.4",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.4",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "stop-iteration-iterator": "^1.1.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.19"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/raw-body/node_modules/iconv-lite": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
- "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
+ "es-errors": "^1.3.0"
},
"engines": {
- "node": ">=0.10.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
+ "node": ">= 0.4"
}
},
- "node_modules/resolve-pkg-maps": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
- "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"dev": true,
"license": "MIT",
- "funding": {
- "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
}
},
- "node_modules/router": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
- "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
+ "node_modules/es-shim-unscopables": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz",
+ "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==",
+ "dev": true,
"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"
+ "hasown": "^2.0.2"
},
"engines": {
- "node": ">= 18"
+ "node": ">= 0.4"
}
},
- "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==",
+ "node_modules/es-to-primitive": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "ms": "^2.1.3"
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
},
"engines": {
- "node": ">=6.0"
+ "node": ">= 0.4"
},
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "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/router/node_modules/path-to-regexp": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
- "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
+ "node_modules/esbuild": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
+ "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+ "dev": true,
+ "hasInstallScript": true,
"license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.18.20",
+ "@esbuild/android-arm64": "0.18.20",
+ "@esbuild/android-x64": "0.18.20",
+ "@esbuild/darwin-arm64": "0.18.20",
+ "@esbuild/darwin-x64": "0.18.20",
+ "@esbuild/freebsd-arm64": "0.18.20",
+ "@esbuild/freebsd-x64": "0.18.20",
+ "@esbuild/linux-arm": "0.18.20",
+ "@esbuild/linux-arm64": "0.18.20",
+ "@esbuild/linux-ia32": "0.18.20",
+ "@esbuild/linux-loong64": "0.18.20",
+ "@esbuild/linux-mips64el": "0.18.20",
+ "@esbuild/linux-ppc64": "0.18.20",
+ "@esbuild/linux-riscv64": "0.18.20",
+ "@esbuild/linux-s390x": "0.18.20",
+ "@esbuild/linux-x64": "0.18.20",
+ "@esbuild/netbsd-x64": "0.18.20",
+ "@esbuild/openbsd-x64": "0.18.20",
+ "@esbuild/sunos-x64": "0.18.20",
+ "@esbuild/win32-arm64": "0.18.20",
+ "@esbuild/win32-ia32": "0.18.20",
+ "@esbuild/win32-x64": "0.18.20"
}
},
- "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/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==",
"license": "MIT"
},
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "license": "MIT"
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
- "node_modules/send": {
- "version": "0.19.0",
- "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
- "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "node_modules/eslint": {
+ "version": "9.36.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz",
+ "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==",
+ "dev": true,
"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"
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.3.1",
+ "@eslint/core": "^0.15.2",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.36.0",
+ "@eslint/plugin-kit": "^0.3.5",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
},
"engines": {
- "node": ">= 0.8.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
}
},
- "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/eslint-import-resolver-node": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+ "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
+ "dev": true,
"license": "MIT",
- "engines": {
- "node": ">= 0.8"
+ "dependencies": {
+ "debug": "^3.2.7",
+ "is-core-module": "^2.13.0",
+ "resolve": "^1.22.4"
}
},
- "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==",
- "license": "MIT"
+ "node_modules/eslint-import-resolver-node/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
},
- "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==",
+ "node_modules/eslint-module-utils": {
+ "version": "2.12.1",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz",
+ "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.3",
- "send": "0.19.0"
+ "debug": "^3.2.7"
},
"engines": {
- "node": ">= 0.8.0"
+ "node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
}
},
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "license": "ISC"
+ "node_modules/eslint-module-utils/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
},
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "node_modules/eslint-plugin-import": {
+ "version": "2.32.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz",
+ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "shebang-regex": "^3.0.0"
+ "@rtsao/scc": "^1.1.0",
+ "array-includes": "^3.1.9",
+ "array.prototype.findlastindex": "^1.2.6",
+ "array.prototype.flat": "^1.3.3",
+ "array.prototype.flatmap": "^1.3.3",
+ "debug": "^3.2.7",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.9",
+ "eslint-module-utils": "^2.12.1",
+ "hasown": "^2.0.2",
+ "is-core-module": "^2.16.1",
+ "is-glob": "^4.0.3",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "object.groupby": "^1.0.3",
+ "object.values": "^1.2.1",
+ "semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.9",
+ "tsconfig-paths": "^3.15.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
}
},
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "node_modules/eslint-plugin-import/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
"license": "MIT",
- "engines": {
- "node": ">=8"
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
}
},
- "node_modules/side-channel": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
- "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "node_modules/eslint-plugin-import/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3",
- "side-channel-list": "^1.0.0",
- "side-channel-map": "^1.0.1",
- "side-channel-weakmap": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "ms": "^2.1.1"
}
},
- "node_modules/side-channel-list": {
- "version": "1.0.0",
+ "node_modules/eslint-plugin-import/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-plugin-jsdoc": {
+ "version": "50.8.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.8.0.tgz",
+ "integrity": "sha512-UyGb5755LMFWPrZTEqqvTJ3urLz1iqj+bYOHFNag+sw3NvaMWP9K2z+uIn37XfNALmQLQyrBlJ5mkiVPL7ADEg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@es-joy/jsdoccomment": "~0.50.2",
+ "are-docs-informative": "^0.0.2",
+ "comment-parser": "1.4.1",
+ "debug": "^4.4.1",
+ "escape-string-regexp": "^4.0.0",
+ "espree": "^10.3.0",
+ "esquery": "^1.6.0",
+ "parse-imports-exports": "^0.2.4",
+ "semver": "^7.7.2",
+ "spdx-expression-parse": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "5.5.4",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz",
+ "integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0",
+ "synckit": "^0.11.7"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-plugin-prettier"
+ },
+ "peerDependencies": {
+ "@types/eslint": ">=8.0.0",
+ "eslint": ">=8.0.0",
+ "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0",
+ "prettier": ">=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/eslint": {
+ "optional": true
+ },
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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/express": {
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "license": "MIT",
+ "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.12",
+ "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"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/express-server-example": {
+ "resolved": "packages/express-server",
+ "link": true
+ },
+ "node_modules/express/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-diff": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/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,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "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/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "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,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "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==",
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/foreground-child/node_modules/signal-exit": {
+ "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/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
+ "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "functions-have-names": "^1.2.3",
+ "hasown": "^2.0.2",
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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": {
+ "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": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
+ "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "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": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby/node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "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/sponsors/ljharb"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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": ">=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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/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"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-async-function": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/is-generator-function": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
+ "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.0",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "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/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/joycon": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
+ "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdoc-type-pratt-parser": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz",
+ "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "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,
+ "license": "MIT"
+ },
+ "node_modules/load-tsconfig": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz",
+ "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/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.4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/memory-pager": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/mongodb": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.20.0.tgz",
+ "integrity": "sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@mongodb-js/saslprep": "^1.3.0",
+ "bson": "^6.10.4",
+ "mongodb-connection-string-url": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=16.20.1"
+ },
+ "peerDependencies": {
+ "@aws-sdk/credential-providers": "^3.188.0",
+ "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
+ "gcp-metadata": "^5.2.0",
+ "kerberos": "^2.0.1",
+ "mongodb-client-encryption": ">=6.0.0 <7",
+ "snappy": "^7.3.2",
+ "socks": "^2.7.1"
+ },
+ "peerDependenciesMeta": {
+ "@aws-sdk/credential-providers": {
+ "optional": true
+ },
+ "@mongodb-js/zstd": {
+ "optional": true
+ },
+ "gcp-metadata": {
+ "optional": true
+ },
+ "kerberos": {
+ "optional": true
+ },
+ "mongodb-client-encryption": {
+ "optional": true
+ },
+ "snappy": {
+ "optional": true
+ },
+ "socks": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/mongodb-connection-string-url": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz",
+ "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/whatwg-url": "^11.0.2",
+ "whatwg-url": "^14.1.0 || ^13.0.0"
+ }
+ },
+ "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/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/nanda-points-facilitator": {
+ "resolved": "packages/facilitator",
+ "link": true
+ },
+ "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,
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.groupby": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
+ "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
+ "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/own-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
+ "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.6",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "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"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-imports-exports": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz",
+ "integrity": "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse-statements": "1.0.11"
+ }
+ },
+ "node_modules/parse-statements": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/parse-statements/-/parse-statements-1.0.11.tgz",
+ "integrity": "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "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"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "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"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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-to-regexp": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+ "license": "MIT"
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pirates": {
+ "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"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
+ "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "lilconfig": "^3.0.0",
+ "yaml": "^2.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "peerDependencies": {
+ "postcss": ">=8.0.9",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "postcss": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.2.tgz",
+ "integrity": "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/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==",
+ "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==",
+ "license": "MIT",
+ "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/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "3.29.5",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz",
+ "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=14.18.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/send/node_modules/debug/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.19.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "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"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "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/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "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.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
- "object-inspect": "^1.13.3"
+ "object-inspect": "^1.13.3"
+ },
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/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"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.8.0-beta.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
+ "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
+ "deprecated": "The work that was done in this beta branch won't be included in future versions",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "whatwg-url": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/source-map/node_modules/tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/source-map/node_modules/webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/source-map/node_modules/whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "node_modules/sparse-bitfield": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+ "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
+ "license": "MIT",
+ "dependencies": {
+ "memory-pager": "^1.0.2"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+ "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+ "dev": true,
+ "license": "CC-BY-3.0"
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
+ "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.22",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz",
+ "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/stop-iteration-iterator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+ "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
+ "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-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"
+ },
+ "engines": {
+ "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": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/sucrase": {
+ "version": "3.35.0",
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "commander": "^4.0.0",
+ "glob": "^10.3.10",
+ "lines-and-columns": "^1.1.6",
+ "mz": "^2.7.0",
+ "pirates": "^4.0.1",
+ "ts-interface-checker": "^0.1.9"
+ },
+ "bin": {
+ "sucrase": "bin/sucrase",
+ "sucrase-node": "bin/sucrase-node"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "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/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/synckit": {
+ "version": "0.11.11",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz",
+ "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pkgr/core": "^0.2.9"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/synckit"
+ }
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tree-kill": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "tree-kill": "cli.js"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/ts-interface-checker": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/tsconfig-paths": {
+ "version": "3.15.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
+ "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "node_modules/tsup": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/tsup/-/tsup-7.2.0.tgz",
+ "integrity": "sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bundle-require": "^4.0.0",
+ "cac": "^6.7.12",
+ "chokidar": "^3.5.1",
+ "debug": "^4.3.1",
+ "esbuild": "^0.18.2",
+ "execa": "^5.0.0",
+ "globby": "^11.0.3",
+ "joycon": "^3.0.1",
+ "postcss-load-config": "^4.0.1",
+ "resolve-from": "^5.0.0",
+ "rollup": "^3.2.5",
+ "source-map": "0.8.0-beta.0",
+ "sucrase": "^3.20.3",
+ "tree-kill": "^1.2.2"
+ },
+ "bin": {
+ "tsup": "dist/cli-default.js",
+ "tsup-node": "dist/cli-node.js"
+ },
+ "engines": {
+ "node": ">=16.14"
+ },
+ "peerDependencies": {
+ "@swc/core": "^1",
+ "postcss": "^8.4.12",
+ "typescript": ">=4.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tsup/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "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/tsx": {
+ "version": "4.20.5",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.5.tgz",
+ "integrity": "sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "~0.25.0",
+ "get-tsconfig": "^4.7.5"
+ },
+ "bin": {
+ "tsx": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/android-arm": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz",
+ "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/android-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz",
+ "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/android-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz",
+ "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz",
+ "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz",
+ "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz",
+ "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz",
+ "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-arm": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz",
+ "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz",
+ "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz",
+ "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz",
+ "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz",
+ "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz",
+ "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz",
+ "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz",
+ "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz",
+ "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz",
+ "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz",
+ "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz",
+ "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz",
+ "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz",
+ "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/win32-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz",
+ "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/esbuild": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz",
+ "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.10",
+ "@esbuild/android-arm": "0.25.10",
+ "@esbuild/android-arm64": "0.25.10",
+ "@esbuild/android-x64": "0.25.10",
+ "@esbuild/darwin-arm64": "0.25.10",
+ "@esbuild/darwin-x64": "0.25.10",
+ "@esbuild/freebsd-arm64": "0.25.10",
+ "@esbuild/freebsd-x64": "0.25.10",
+ "@esbuild/linux-arm": "0.25.10",
+ "@esbuild/linux-arm64": "0.25.10",
+ "@esbuild/linux-ia32": "0.25.10",
+ "@esbuild/linux-loong64": "0.25.10",
+ "@esbuild/linux-mips64el": "0.25.10",
+ "@esbuild/linux-ppc64": "0.25.10",
+ "@esbuild/linux-riscv64": "0.25.10",
+ "@esbuild/linux-s390x": "0.25.10",
+ "@esbuild/linux-x64": "0.25.10",
+ "@esbuild/netbsd-arm64": "0.25.10",
+ "@esbuild/netbsd-x64": "0.25.10",
+ "@esbuild/openbsd-arm64": "0.25.10",
+ "@esbuild/openbsd-x64": "0.25.10",
+ "@esbuild/openharmony-arm64": "0.25.10",
+ "@esbuild/sunos-x64": "0.25.10",
+ "@esbuild/win32-arm64": "0.25.10",
+ "@esbuild/win32-ia32": "0.25.10",
+ "@esbuild/win32-x64": "0.25.10"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
},
"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==",
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3"
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
@@ -2062,17 +6323,20 @@
"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==",
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
+ "dev": true,
"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"
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
},
"engines": {
"node": ">= 0.4"
@@ -2081,90 +6345,82 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/sparse-bitfield": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
- "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
+ "node_modules/typed-array-length": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
+ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "memory-pager": "^1.0.2"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "license": "MIT",
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0",
+ "reflect.getprototypeof": "^1.0.6"
+ },
"engines": {
- "node": ">=0.6"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/tr46": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
- "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
- "license": "MIT",
- "dependencies": {
- "punycode": "^2.3.1"
+ "node_modules/typescript": {
+ "version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
+ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
},
"engines": {
- "node": ">=18"
+ "node": ">=14.17"
}
},
- "node_modules/tsx": {
- "version": "4.20.5",
- "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.5.tgz",
- "integrity": "sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==",
+ "node_modules/typescript-eslint": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.44.1.tgz",
+ "integrity": "sha512-0ws8uWGrUVTjEeN2OM4K1pLKHK/4NiNP/vz6ns+LjT/6sqpaYzIVFajZb1fj/IDwpsrrHb3Jy0Qm5u9CPcKaeg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "esbuild": "~0.25.0",
- "get-tsconfig": "^4.7.5"
- },
- "bin": {
- "tsx": "dist/cli.mjs"
+ "@typescript-eslint/eslint-plugin": "8.44.1",
+ "@typescript-eslint/parser": "8.44.1",
+ "@typescript-eslint/typescript-estree": "8.44.1",
+ "@typescript-eslint/utils": "8.44.1"
},
"engines": {
- "node": ">=18.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
- "optionalDependencies": {
- "fsevents": "~2.3.3"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
}
},
- "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==",
+ "node_modules/unbox-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.24"
+ "call-bound": "^1.0.3",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
},
"engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/typescript": {
- "version": "5.9.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
- "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
+ "node": ">= 0.4"
},
- "engines": {
- "node": ">=14.17"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/undici-types": {
@@ -2187,6 +6443,7 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
@@ -2236,6 +6493,7 @@
"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"
@@ -2247,28 +6505,298 @@
"node": ">= 8"
}
},
- "node_modules/wrappy": {
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC"
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "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/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/zod": {
- "version": "3.25.76",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
- "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "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/sponsors/colinhacks"
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/zod-to-json-schema": {
- "version": "3.24.6",
- "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz",
- "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==",
+ "node_modules/x402-nanda-shared": {
+ "resolved": "packages/shared",
+ "link": true
+ },
+ "node_modules/yaml": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
+ "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
+ "dev": true,
"license": "ISC",
- "peerDependencies": {
- "zod": "^3.24.1"
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "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"
+ }
+ },
+ "packages/advanced-server": {
+ "name": "advanced-server-example",
+ "dependencies": {
+ "dotenv": "^16.4.7",
+ "express": "^4.18.2"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.24.0",
+ "@types/express": "^5.0.1",
+ "@typescript-eslint/eslint-plugin": "^8.29.1",
+ "@typescript-eslint/parser": "^8.29.1",
+ "eslint": "^9.24.0",
+ "eslint-plugin-import": "^2.31.0",
+ "eslint-plugin-jsdoc": "^50.6.9",
+ "eslint-plugin-prettier": "^5.2.6",
+ "prettier": "3.5.2",
+ "tsup": "^7.2.0",
+ "tsx": "^4.7.0",
+ "typescript": "^5.3.0"
+ }
+ },
+ "packages/express-server": {
+ "name": "express-server-example",
+ "dependencies": {
+ "dotenv": "^16.4.7",
+ "express": "^4.18.2",
+ "x402-nanda-shared": "file:../shared"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.24.0",
+ "@types/express": "^5.0.1",
+ "@typescript-eslint/eslint-plugin": "^8.29.1",
+ "@typescript-eslint/parser": "^8.29.1",
+ "eslint": "^9.24.0",
+ "eslint-plugin-import": "^2.31.0",
+ "eslint-plugin-jsdoc": "^50.6.9",
+ "eslint-plugin-prettier": "^5.2.6",
+ "prettier": "3.5.2",
+ "tsup": "^7.2.0",
+ "tsx": "^4.7.0",
+ "typescript": "^5.3.0"
+ }
+ },
+ "packages/facilitator": {
+ "name": "nanda-points-facilitator",
+ "version": "1.0.0",
+ "dependencies": {
+ "dotenv": "^16.4.7",
+ "express": "^4.18.2",
+ "mongodb": "^6.0.0",
+ "x402-nanda-shared": "file:../shared"
+ },
+ "devDependencies": {
+ "@types/express": "^5.0.1",
+ "tsup": "^7.2.0",
+ "tsx": "^4.7.0"
+ }
+ },
+ "packages/shared": {
+ "name": "x402-nanda-shared",
+ "version": "1.0.0",
+ "dependencies": {
+ "mongodb": "^6.0.0"
+ },
+ "devDependencies": {
+ "@types/express": "^5.0.1",
+ "tsup": "^7.2.0",
+ "typescript": "^5.3.0"
}
}
}
diff --git a/package.json b/package.json
index 122d86b..c8ae6cb 100644
--- a/package.json
+++ b/package.json
@@ -1,33 +1,53 @@
{
- "name": "nanda-points-mcp-server",
- "version": "0.2.0",
+ "name": "x402-nanda-points",
+ "version": "1.0.0",
+ "description": "x402-compliant server infrastructure using NANDA Points instead of blockchain settlement",
"private": true,
"type": "module",
+ "workspaces": [
+ "packages/*"
+ ],
"scripts": {
- "dev": "tsx src/mcp/server.ts",
- "build": "tsc -p tsconfig.json",
- "start": "node dist/combined-server.js",
- "seed": "tsx seed.js",
- "mcp:server": "tsx src/mcp/server.ts",
- "test:x402": "tsx tests/x402-np.test.ts",
- "test:x402-simple": "tsx tests/x402-simple.test.ts",
- "test:x402-full": "tsx run-comprehensive-test.ts",
- "api:server": "tsx src/api/server.ts",
- "combined:server": "tsx src/combined-server.ts"
- },
- "dependencies": {
- "@modelcontextprotocol/sdk": "^1.18.0",
- "mongodb": "^6.8.0",
- "dotenv": "^16.4.5",
- "zod": "^3.23.8",
- "express": "^4.19.2",
- "cors": "^2.8.5"
+ "dev": "npm run dev --workspace=express-server",
+ "dev:express": "npm run dev --workspace=express-server",
+ "dev:advanced": "npm run dev --workspace=advanced-server",
+ "dev:facilitator": "npm run dev --workspace=facilitator",
+ "build": "npm run build --workspaces",
+ "test": "npm run test --workspaces",
+ "lint": "npm run lint --workspaces",
+ "lint:check": "npm run lint:check --workspaces",
+ "format": "npm run format --workspaces",
+ "format:check": "npm run format:check --workspaces",
+ "seed": "node seed.js",
+ "clean": "rm -rf node_modules packages/*/node_modules packages/*/dist"
},
"devDependencies": {
- "@types/node": "^24.5.1",
- "@types/express": "^4.17.21",
- "@types/cors": "^2.8.17",
- "tsx": "^4.19.0",
- "typescript": "^5.5.4"
- }
-}
+ "@typescript-eslint/eslint-plugin": "^8.29.1",
+ "@typescript-eslint/parser": "^8.29.1",
+ "eslint": "^9.24.0",
+ "eslint-plugin-import": "^2.31.0",
+ "eslint-plugin-jsdoc": "^50.6.9",
+ "eslint-plugin-prettier": "^5.2.6",
+ "prettier": "3.5.2",
+ "tsx": "^4.7.0",
+ "typescript": "^5.3.0",
+ "typescript-eslint": "^8.29.1"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/projnanda/x402-nanda-points.git"
+ },
+ "keywords": [
+ "x402",
+ "payments",
+ "nanda-points",
+ "mcp",
+ "http-402",
+ "blockchain-alternative"
+ ],
+ "author": "NANDA Project",
+ "license": "MIT"
+}
\ No newline at end of file
diff --git a/packages/advanced-server/README.md b/packages/advanced-server/README.md
new file mode 100644
index 0000000..749d59e
--- /dev/null
+++ b/packages/advanced-server/README.md
@@ -0,0 +1,174 @@
+# x402 Advanced NANDA Points Server
+
+This is an advanced example of an Express.js server that demonstrates manual x402 payment handling using NANDA Points instead of blockchain transactions. This approach is useful for more complex scenarios, such as:
+
+- Asynchronous payment settlement
+- Custom payment validation logic
+- Complex routing requirements
+- Integration with existing authentication systems
+
+> **💡 For new development, consider using the [@nanda/payments-sdk](../../sdks/payments-sdk/) which provides a more developer-friendly API for adding payments to Express routes and MCP tools.**
+
+## Prerequisites
+
+- Node.js v20+
+- MongoDB running on localhost:27017
+- NANDA Points facilitator service running on localhost:3001
+- Valid NANDA Points agent for receiving payments
+
+## Setup
+
+1. Set environment variables:
+
+```bash
+# Agent name to receive payments
+AGENT_NAME=system
+# Facilitator service URL
+FACILITATOR_URL=http://localhost:3001
+# Server port
+PORT=3000
+```
+
+2. Install dependencies:
+```bash
+npm install
+```
+
+3. Start the server:
+```bash
+npm run dev
+```
+
+## Implementation Overview
+
+This advanced implementation provides a structured approach to handling payments with:
+
+1. Helper functions for creating payment requirements and verifying payments
+2. Support for delayed payment settlement
+3. Dynamic pricing capabilities
+4. Multiple payment requirement options
+5. Proper error handling and response formatting
+6. Integration with the x402 facilitator service
+
+## Testing the Server
+
+You can test the server using curl or any x402-compatible client:
+
+### Test HTTP 402 Response
+```bash
+curl -i http://localhost:3000/weather
+# Should return HTTP 402 with NANDA Points payment requirements
+```
+
+### Test with Payment
+```bash
+# First get payment requirements, then create payment via NANDA Points system
+# and include in X-PAYMENT header
+curl -H "X-PAYMENT: " http://localhost:3000/weather
+```
+
+## Example Endpoints
+
+The server includes example endpoints that demonstrate different payment scenarios:
+
+### Delayed Settlement
+- `/delayed-settlement` - Demonstrates asynchronous payment processing
+- Returns the weather data immediately without waiting for payment settlement
+- Processes payment asynchronously in the background
+- Useful for scenarios where immediate response is critical and payment settlement can be handled later
+
+### Dynamic Pricing
+- `/dynamic-price` - Shows how to implement variable pricing based on request parameters
+- Accepts a `multiplier` query parameter to adjust the base price
+- Demonstrates how to calculate and validate payments with dynamic amounts
+- Useful for implementing tiered pricing or demand-based pricing models
+
+### Multiple Payment Requirements
+- `/multiple-payment-requirements` - Illustrates how to accept multiple payment options
+- Allows clients to pay using different assets (e.g., USDC or USDT)
+- Supports multiple networks (e.g., Base and Base Sepolia)
+- Useful for providing flexibility in payment methods and networks
+
+## Response Format
+
+### Payment Required (402)
+```json
+{
+ "x402Version": 1,
+ "error": "X-PAYMENT header is required",
+ "accepts": [
+ {
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "maxAmountRequired": "1",
+ "resource": "http://localhost:3000/weather",
+ "description": "Access to weather data",
+ "mimeType": "application/json",
+ "payTo": "system",
+ "maxTimeoutSeconds": 60,
+ "asset": "NP",
+ "outputSchema": null,
+ "extra": {
+ "facilitatorUrl": "http://localhost:3001"
+ }
+ }
+ ]
+}
+```
+
+### Successful Response
+```json
+// Body
+{
+ "report": {
+ "weather": "sunny",
+ "temperature": 70
+ }
+}
+// Headers
+{
+ "X-PAYMENT-RESPONSE": "..." // Encoded response object
+}
+```
+
+## Extending the Example
+
+To add more paid endpoints with delayed payment settlement, you can follow this pattern:
+
+```typescript
+app.get("/your-endpoint", async (req, res) => {
+ const resource = `${req.protocol}://${req.headers.host}${req.originalUrl}` as Resource;
+ const paymentRequirements = [createExactPaymentRequirements(
+ "$0.001", // Your price
+ "base-sepolia", // Your network
+ resource,
+ "Description of your resource"
+ )];
+
+ const isValid = await verifyPayment(req, res, paymentRequirements);
+ if (!isValid) return;
+
+ // Return your protected resource immediately
+ res.json({
+ // Your response data
+ });
+
+ // Process payment asynchronously
+ try {
+ const settleResponse = await settle(
+ exact.evm.decodePayment(req.header("X-PAYMENT")!),
+ paymentRequirements[0]
+ );
+ const responseHeader = settleResponseHeader(settleResponse);
+ // In a real application, you would store this response header
+ // and associate it with the payment for later verification
+ console.log("Payment settled:", responseHeader);
+ } catch (error) {
+ console.error("Payment settlement failed:", error);
+ // In a real application, you would handle the failed payment
+ // by marking it for retry or notifying the user
+ }
+});
+```
+
+For dynamic pricing or multiple payment requirements, refer to the `/dynamic-price` and `/multiple-payment-requirements` endpoints in the example code for implementation details.
diff --git a/packages/advanced-server/eslint.config.js b/packages/advanced-server/eslint.config.js
new file mode 100644
index 0000000..e2fde7b
--- /dev/null
+++ b/packages/advanced-server/eslint.config.js
@@ -0,0 +1,73 @@
+import js from "@eslint/js";
+import ts from "@typescript-eslint/eslint-plugin";
+import tsParser from "@typescript-eslint/parser";
+import prettier from "eslint-plugin-prettier";
+import jsdoc from "eslint-plugin-jsdoc";
+import importPlugin from "eslint-plugin-import";
+
+export default [
+ {
+ ignores: ["dist/**", "node_modules/**"],
+ },
+ {
+ files: ["**/*.ts"],
+ languageOptions: {
+ parser: tsParser,
+ sourceType: "module",
+ ecmaVersion: 2020,
+ globals: {
+ process: "readonly",
+ __dirname: "readonly",
+ module: "readonly",
+ require: "readonly",
+ Buffer: "readonly",
+ console: "readonly",
+ exports: "readonly",
+ setTimeout: "readonly",
+ clearTimeout: "readonly",
+ setInterval: "readonly",
+ clearInterval: "readonly",
+ },
+ },
+ plugins: {
+ "@typescript-eslint": ts,
+ prettier: prettier,
+ jsdoc: jsdoc,
+ import: importPlugin,
+ },
+ rules: {
+ ...ts.configs.recommended.rules,
+ "import/first": "error",
+ "prettier/prettier": "error",
+ "@typescript-eslint/member-ordering": "error",
+ "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }],
+ "jsdoc/tag-lines": ["error", "any", { startLines: 1 }],
+ "jsdoc/check-alignment": "error",
+ "jsdoc/no-undefined-types": "off",
+ "jsdoc/check-param-names": "error",
+ "jsdoc/check-tag-names": "error",
+ "jsdoc/check-types": "error",
+ "jsdoc/implements-on-classes": "error",
+ "jsdoc/require-description": "error",
+ "jsdoc/require-jsdoc": [
+ "error",
+ {
+ require: {
+ FunctionDeclaration: true,
+ MethodDefinition: true,
+ ClassDeclaration: true,
+ ArrowFunctionExpression: false,
+ FunctionExpression: false,
+ },
+ },
+ ],
+ "jsdoc/require-param": "error",
+ "jsdoc/require-param-description": "error",
+ "jsdoc/require-param-type": "off",
+ "jsdoc/require-returns": "error",
+ "jsdoc/require-returns-description": "error",
+ "jsdoc/require-returns-type": "off",
+ "jsdoc/require-hyphen-before-param-description": ["error", "always"],
+ },
+ },
+];
diff --git a/packages/advanced-server/index.ts b/packages/advanced-server/index.ts
new file mode 100644
index 0000000..2d27117
--- /dev/null
+++ b/packages/advanced-server/index.ts
@@ -0,0 +1,276 @@
+import { config } from "dotenv";
+import express from "express";
+import { exact } from "x402/schemes";
+import {
+ Network,
+ PaymentPayload,
+ PaymentRequirements,
+ Price,
+ Resource,
+ settleResponseHeader,
+} from "x402/types";
+import { useFacilitator } from "x402/verify";
+import { processPriceToAtomicAmount, findMatchingPaymentRequirements } from "x402/shared";
+
+config();
+
+const facilitatorUrl = process.env.FACILITATOR_URL as Resource;
+const payTo = process.env.ADDRESS as `0x${string}`;
+
+if (!facilitatorUrl || !payTo) {
+ console.error("Missing required environment variables");
+ process.exit(1);
+}
+
+const app = express();
+const { verify, settle } = useFacilitator({ url: facilitatorUrl });
+const x402Version = 1;
+
+/**
+ * Creates payment requirements for a given price and network
+ *
+ * @param price - The price to be paid for the resource
+ * @param network - The blockchain network to use for payment
+ * @param resource - The resource being accessed
+ * @param description - Optional description of the payment
+ * @returns An array of payment requirements
+ */
+function createExactPaymentRequirements(
+ price: Price,
+ network: Network,
+ resource: Resource,
+ description = ""
+): PaymentRequirements {
+ const atomicAmountForAsset = processPriceToAtomicAmount(price, network);
+ if ("error" in atomicAmountForAsset) {
+ throw new Error(atomicAmountForAsset.error);
+ }
+ const { maxAmountRequired, asset } = atomicAmountForAsset;
+
+ return {
+ scheme: "exact",
+ network,
+ maxAmountRequired,
+ resource,
+ description,
+ mimeType: "",
+ payTo: payTo,
+ maxTimeoutSeconds: 60,
+ asset: asset.address,
+ outputSchema: undefined,
+ extra: {
+ name: asset.eip712.name,
+ version: asset.eip712.version,
+ },
+ };
+}
+
+/**
+ * Verifies a payment and handles the response
+ *
+ * @param req - The Express request object
+ * @param res - The Express response object
+ * @param paymentRequirements - The payment requirements to verify against
+ * @returns A promise that resolves to true if payment is valid, false otherwise
+ */
+async function verifyPayment(
+ req: express.Request,
+ res: express.Response,
+ paymentRequirements: PaymentRequirements[]
+): Promise {
+ const payment = req.header("X-PAYMENT");
+ if (!payment) {
+ res.status(402).json({
+ x402Version,
+ error: "X-PAYMENT header is required",
+ accepts: paymentRequirements,
+ });
+ return false;
+ }
+
+ let decodedPayment: PaymentPayload;
+ try {
+ decodedPayment = exact.evm.decodePayment(payment);
+ decodedPayment.x402Version = x402Version;
+ } catch (error) {
+ res.status(402).json({
+ x402Version,
+ error: error || "Invalid or malformed payment header",
+ accepts: paymentRequirements,
+ });
+ return false;
+ }
+
+ try {
+ const selectedPaymentRequirement =
+ findMatchingPaymentRequirements(paymentRequirements, decodedPayment) ||
+ paymentRequirements[0];
+ const response = await verify(decodedPayment, selectedPaymentRequirement);
+ if (!response.isValid) {
+ res.status(402).json({
+ x402Version,
+ error: response.invalidReason,
+ accepts: paymentRequirements,
+ payer: response.payer,
+ });
+ return false;
+ }
+ } catch (error) {
+ res.status(402).json({
+ x402Version,
+ error,
+ accepts: paymentRequirements,
+ });
+ return false;
+ }
+
+ return true;
+}
+
+// Delayed settlement example endpoint
+app.get("/delayed-settlement", async (req, res) => {
+ const resource = `${req.protocol}://${req.headers.host}${req.originalUrl}` as Resource;
+ const paymentRequirements = [
+ createExactPaymentRequirements(
+ "$0.001",
+ // network: "base" // uncomment for Base mainnet
+ "base-sepolia",
+ resource,
+ "Access to weather data (async)"
+ ),
+ ];
+
+ const isValid = await verifyPayment(req, res, paymentRequirements);
+ if (!isValid) return;
+
+ // Return weather data immediately
+ res.json({
+ report: {
+ weather: "sunny",
+ temperature: 70,
+ },
+ });
+
+ // Process payment asynchronously
+ try {
+ const settleResponse = await settle(
+ exact.evm.decodePayment(req.header("X-PAYMENT")!),
+ paymentRequirements[0]
+ );
+ const responseHeader = settleResponseHeader(settleResponse);
+ // In a real application, you would store this response header
+ // and associate it with the payment for later verification
+ console.log("Payment settled:", responseHeader);
+ } catch (error) {
+ console.error("Payment settlement failed:", error);
+ // In a real application, you would handle the failed payment
+ // by marking it for retry or notifying the user
+ }
+});
+
+// Dynamic price example endpoint
+app.get("/dynamic-price", async (req, res) => {
+ // Use query params, body, or external factors to determine if price is impacted
+ const multiplier = parseInt((req.query.multiplier as string) ?? "1");
+ // Adjust pricing based on impact from inputs
+ const price = 0.001 * multiplier;
+
+ const resource = `${req.protocol}://${req.headers.host}${req.originalUrl}` as Resource;
+ const paymentRequirements = [
+ createExactPaymentRequirements(
+ price, // Expect dynamic pricing
+ // network: "base" // uncomment for Base mainnet
+ "base-sepolia",
+ resource,
+ "Access to weather data"
+ ),
+ ];
+
+ const isValid = await verifyPayment(req, res, paymentRequirements);
+ if (!isValid) return;
+
+ try {
+ // Process payment synchronously
+ const settleResponse = await settle(
+ exact.evm.decodePayment(req.header("X-PAYMENT")!),
+ paymentRequirements[0]
+ );
+ const responseHeader = settleResponseHeader(settleResponse);
+ res.setHeader("X-PAYMENT-RESPONSE", responseHeader);
+
+ // Return the weather data
+ res.json({
+ report: {
+ success: "sunny",
+ temperature: 70,
+ },
+ });
+ } catch (error) {
+ res.status(402).json({
+ x402Version,
+ error,
+ accepts: paymentRequirements,
+ });
+ }
+});
+
+// Multiple payment requirements example endpoint
+app.get("/multiple-payment-requirements", async (req, res) => {
+ const resource = `${req.protocol}://${req.headers.host}${req.originalUrl}` as Resource;
+
+ // Payment requirements is an array. You can mix and match tokens, prices, and networks.
+ const paymentRequirements = [
+ createExactPaymentRequirements("$0.001", "base", resource),
+ createExactPaymentRequirements(
+ {
+ amount: "1000",
+ asset: {
+ address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
+ decimals: 6,
+ eip712: {
+ name: "USDC",
+ version: "2",
+ },
+ },
+ },
+ // network: "base" // uncomment for Base mainnet
+ "base-sepolia",
+ resource
+ ),
+ ];
+
+ const isValid = await verifyPayment(req, res, paymentRequirements);
+ if (!isValid) return;
+
+ try {
+ // Process payment synchronously
+ const decodedPayment = exact.evm.decodePayment(req.header("X-PAYMENT")!);
+
+ // Find the matching payment requirement
+ const selectedPaymentRequirement =
+ findMatchingPaymentRequirements(paymentRequirements, decodedPayment) ||
+ paymentRequirements[0];
+
+ const settleResponse = await settle(decodedPayment, selectedPaymentRequirement);
+ const responseHeader = settleResponseHeader(settleResponse);
+ res.setHeader("X-PAYMENT-RESPONSE", responseHeader);
+
+ // Return the weather data
+ res.json({
+ report: {
+ success: "sunny",
+ temperature: 70,
+ },
+ });
+ } catch (error) {
+ res.status(402).json({
+ x402Version,
+ error,
+ accepts: paymentRequirements,
+ });
+ }
+});
+
+app.listen(3000, () => {
+ console.log(`Server listening at http://localhost:3000`);
+});
diff --git a/packages/advanced-server/package.json b/packages/advanced-server/package.json
new file mode 100644
index 0000000..70eabfc
--- /dev/null
+++ b/packages/advanced-server/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "advanced-server-example",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "tsx index.ts",
+ "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"",
+ "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"",
+ "lint": "eslint . --ext .ts --fix",
+ "lint:check": "eslint . --ext .ts"
+ },
+ "dependencies": {
+ "dotenv": "^16.4.7",
+ "express": "^4.18.2"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.24.0",
+ "eslint": "^9.24.0",
+ "eslint-plugin-jsdoc": "^50.6.9",
+ "eslint-plugin-prettier": "^5.2.6",
+ "@typescript-eslint/eslint-plugin": "^8.29.1",
+ "@typescript-eslint/parser": "^8.29.1",
+ "eslint-plugin-import": "^2.31.0",
+ "prettier": "3.5.2",
+ "tsup": "^7.2.0",
+ "tsx": "^4.7.0",
+ "typescript": "^5.3.0",
+ "@types/express": "^5.0.1"
+ }
+}
diff --git a/packages/advanced-server/tsconfig.json b/packages/advanced-server/tsconfig.json
new file mode 100644
index 0000000..2e4c2c7
--- /dev/null
+++ b/packages/advanced-server/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./dist",
+ "rootDir": "."
+ },
+ "include": ["index.ts"],
+ "exclude": ["dist", "node_modules"]
+}
diff --git a/packages/express-server/README.md b/packages/express-server/README.md
new file mode 100644
index 0000000..b1f3dc6
--- /dev/null
+++ b/packages/express-server/README.md
@@ -0,0 +1,136 @@
+# x402 NANDA Points Express Server
+
+This Express.js server demonstrates x402 protocol compliance using NANDA Points instead of blockchain payments. It's forked from Coinbase's x402 Express server example and adapted for MongoDB/NP settlement.
+
+> **💡 For new development, consider using the [@nanda/payments-sdk](../../sdks/payments-sdk/) which provides a more developer-friendly API for adding payments to Express routes.**
+
+## Features
+
+- **x402 Protocol Compliance**: Returns proper HTTP 402 responses with payment requirements
+- **NANDA Points Integration**: Uses "nanda-points" scheme instead of blockchain/USDC
+- **Express Middleware**: Drop-in `npPaymentMiddleware` for automatic payment handling
+- **MongoDB Backend**: Replaces blockchain verification with MongoDB transactions
+
+## Prerequisites
+
+- Node.js v20+
+- MongoDB running on localhost:27017 (for payment verification)
+- NANDA Points facilitator running on localhost:3001
+
+## Quick Start
+
+1. Install dependencies:
+```bash
+npm install
+```
+
+2. Set environment variables:
+```bash
+# Copy and edit .env file
+FACILITATOR_URL=http://localhost:3001
+ADDRESS=system # Agent name to receive payments
+PORT=3000
+```
+
+3. Start the server:
+```bash
+npm run dev
+```
+
+## Testing the Server
+
+### Test HTTP 402 Response (No Payment)
+```bash
+curl -i http://localhost:3000/weather
+# Returns: HTTP/1.1 402 Payment Required
+```
+
+### Test Free Endpoint
+```bash
+curl http://localhost:3000/health
+# Returns: {"status":"healthy",...}
+```
+
+### Expected 402 Response Format
+```json
+{
+ "x402Version": 1,
+ "error": "X-PAYMENT header is required",
+ "accepts": [{
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "maxAmountRequired": "1",
+ "resource": "http://localhost:3000/weather",
+ "description": "Access to weather data",
+ "mimeType": "application/json",
+ "payTo": "system",
+ "maxTimeoutSeconds": 60,
+ "asset": "NP",
+ "extra": {
+ "facilitatorUrl": "http://localhost:3001"
+ }
+ }]
+}
+```
+
+## Endpoints
+
+- `GET /health` - Free health check endpoint
+- `GET /weather` - Weather data (costs 1 NP)
+- `GET /premium/content` - Premium content (costs 10 NP)
+- `GET /premium/analysis` - Premium analysis (costs 10 NP)
+
+## Adding Paid Endpoints
+
+Use the `npPaymentMiddleware` from `x402-nanda-shared`:
+
+```typescript
+import { npPaymentMiddleware } from "x402-nanda-shared";
+
+app.use(
+ npPaymentMiddleware(
+ {
+ "GET /my-endpoint": {
+ priceNP: 5, // 5 NANDA Points
+ recipient: "system",
+ description: "My paid endpoint",
+ maxTimeoutSeconds: 60,
+ },
+ "/premium/*": {
+ priceNP: 20, // 20 NP for all premium routes
+ recipient: "system",
+ description: "Premium features",
+ maxTimeoutSeconds: 60,
+ }
+ },
+ facilitatorUrl
+ )
+);
+
+app.get("/my-endpoint", (req, res) => {
+ res.json({ data: "This endpoint requires 5 NP payment" });
+});
+```
+
+## Payment Flow
+
+1. Client requests paid endpoint without payment
+2. Server returns HTTP 402 with payment requirements
+3. Client processes payment via NANDA Points system
+4. Client retries with `X-PAYMENT` header containing payment proof
+5. Server verifies payment with facilitator
+6. Server executes request and returns data with `X-PAYMENT-RESPONSE` header
+
+## Differences from Coinbase x402
+
+- **Payment Scheme**: "nanda-points" instead of EVM blockchain schemes
+- **Settlement**: MongoDB transactions instead of smart contracts
+- **Authentication**: Agent names instead of wallet signatures
+- **Asset**: "NP" (NANDA Points) instead of USDC
+- **Network**: "nanda-network" instead of blockchain networks
+
+## Related Packages
+
+- [`../shared/`](../shared/) - Shared utilities and middleware
+- [`../facilitator/`](../facilitator/) - NANDA Points facilitator service
+- [`../advanced-server/`](../advanced-server/) - Manual payment handling example
\ No newline at end of file
diff --git a/packages/express-server/eslint.config.js b/packages/express-server/eslint.config.js
new file mode 100644
index 0000000..e2fde7b
--- /dev/null
+++ b/packages/express-server/eslint.config.js
@@ -0,0 +1,73 @@
+import js from "@eslint/js";
+import ts from "@typescript-eslint/eslint-plugin";
+import tsParser from "@typescript-eslint/parser";
+import prettier from "eslint-plugin-prettier";
+import jsdoc from "eslint-plugin-jsdoc";
+import importPlugin from "eslint-plugin-import";
+
+export default [
+ {
+ ignores: ["dist/**", "node_modules/**"],
+ },
+ {
+ files: ["**/*.ts"],
+ languageOptions: {
+ parser: tsParser,
+ sourceType: "module",
+ ecmaVersion: 2020,
+ globals: {
+ process: "readonly",
+ __dirname: "readonly",
+ module: "readonly",
+ require: "readonly",
+ Buffer: "readonly",
+ console: "readonly",
+ exports: "readonly",
+ setTimeout: "readonly",
+ clearTimeout: "readonly",
+ setInterval: "readonly",
+ clearInterval: "readonly",
+ },
+ },
+ plugins: {
+ "@typescript-eslint": ts,
+ prettier: prettier,
+ jsdoc: jsdoc,
+ import: importPlugin,
+ },
+ rules: {
+ ...ts.configs.recommended.rules,
+ "import/first": "error",
+ "prettier/prettier": "error",
+ "@typescript-eslint/member-ordering": "error",
+ "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }],
+ "jsdoc/tag-lines": ["error", "any", { startLines: 1 }],
+ "jsdoc/check-alignment": "error",
+ "jsdoc/no-undefined-types": "off",
+ "jsdoc/check-param-names": "error",
+ "jsdoc/check-tag-names": "error",
+ "jsdoc/check-types": "error",
+ "jsdoc/implements-on-classes": "error",
+ "jsdoc/require-description": "error",
+ "jsdoc/require-jsdoc": [
+ "error",
+ {
+ require: {
+ FunctionDeclaration: true,
+ MethodDefinition: true,
+ ClassDeclaration: true,
+ ArrowFunctionExpression: false,
+ FunctionExpression: false,
+ },
+ },
+ ],
+ "jsdoc/require-param": "error",
+ "jsdoc/require-param-description": "error",
+ "jsdoc/require-param-type": "off",
+ "jsdoc/require-returns": "error",
+ "jsdoc/require-returns-description": "error",
+ "jsdoc/require-returns-type": "off",
+ "jsdoc/require-hyphen-before-param-description": ["error", "always"],
+ },
+ },
+];
diff --git a/packages/express-server/index.ts b/packages/express-server/index.ts
new file mode 100644
index 0000000..e4a5d91
--- /dev/null
+++ b/packages/express-server/index.ts
@@ -0,0 +1,106 @@
+import { config } from "dotenv";
+import express from "express";
+import { npPaymentMiddleware } from "x402-nanda-shared";
+
+config();
+
+const facilitatorUrl = process.env.FACILITATOR_URL || "http://localhost:3001";
+const payTo = process.env.ADDRESS || "system"; // Agent name instead of blockchain address
+
+if (!facilitatorUrl || !payTo) {
+ console.error("Missing required environment variables: FACILITATOR_URL, ADDRESS");
+ process.exit(1);
+}
+
+const app = express();
+
+// Apply NANDA Points payment middleware
+app.use(
+ npPaymentMiddleware(
+ {
+ "/premium/*": {
+ priceNP: 10, // 10 NANDA Points for premium content
+ recipient: payTo,
+ description: "Access to premium content",
+ maxTimeoutSeconds: 60,
+ },
+ },
+ facilitatorUrl
+ )
+);
+
+// Free endpoint (no payment required)
+app.get("/health", (req, res) => {
+ res.json({
+ status: "healthy",
+ server: "x402-nanda-express",
+ version: "1.0.0",
+ facilitator: facilitatorUrl,
+ });
+});
+
+// Free endpoint (no payment required)
+app.get("/weather", (req, res) => {
+ res.json({
+ report: {
+ weather: "sunny",
+ temperature: 72,
+ location: "San Francisco",
+ timestamp: new Date().toISOString(),
+ },
+ cost: "Free",
+ message: "Weather data accessed for free!",
+ });
+});
+
+// Premium paid endpoint - requires 10 NP
+app.get("/premium/content", (req, res) => {
+ res.json({
+ content: "This is premium content available for 10 NANDA Points",
+ features: [
+ "Advanced analytics",
+ "Real-time updates",
+ "Priority support",
+ "Extended API limits",
+ ],
+ cost: "10 NP",
+ message: "Premium content accessed successfully!",
+ });
+});
+
+// Another premium endpoint with different content
+app.get("/premium/analysis", (req, res) => {
+ res.json({
+ analysis: {
+ insights: [
+ "Market trends indicate growth",
+ "User engagement up 25%",
+ "Revenue projections look positive",
+ ],
+ confidence: 0.92,
+ generated_at: new Date().toISOString(),
+ },
+ cost: "10 NP",
+ message: "Advanced analysis completed using NANDA Points!",
+ });
+});
+
+const PORT = process.env.PORT || 3000;
+
+app.listen(PORT, () => {
+ console.log(`🚀 x402 NANDA Points Express Server running at http://localhost:${PORT}`);
+ console.log(`🏦 Using facilitator: ${facilitatorUrl}`);
+ console.log(`💰 Payment recipient: ${payTo}`);
+ console.log("");
+ console.log("📡 Endpoints:");
+ console.log(` GET /health - Free health check`);
+ console.log(` GET /weather - Free weather data`);
+ console.log(` GET /premium/content - Premium content (10 NP)`);
+ console.log(` GET /premium/analysis - Premium analysis (10 NP)`);
+ console.log("");
+ console.log("🔧 Test with curl:");
+ console.log(` curl http://localhost:${PORT}/weather`);
+ console.log(" (Free endpoint, returns weather data)");
+});
+
+export { app };
diff --git a/packages/express-server/package.json b/packages/express-server/package.json
new file mode 100644
index 0000000..ea9fbe9
--- /dev/null
+++ b/packages/express-server/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "express-server-example",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "tsx index.ts",
+ "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"",
+ "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"",
+ "lint": "eslint . --ext .ts --fix",
+ "lint:check": "eslint . --ext .ts"
+ },
+ "dependencies": {
+ "dotenv": "^16.4.7",
+ "express": "^4.18.2",
+ "x402-nanda-shared": "file:../shared"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.24.0",
+ "@types/express": "^5.0.1",
+ "@typescript-eslint/eslint-plugin": "^8.29.1",
+ "@typescript-eslint/parser": "^8.29.1",
+ "eslint": "^9.24.0",
+ "eslint-plugin-import": "^2.31.0",
+ "eslint-plugin-jsdoc": "^50.6.9",
+ "eslint-plugin-prettier": "^5.2.6",
+ "prettier": "3.5.2",
+ "tsup": "^7.2.0",
+ "tsx": "^4.7.0",
+ "typescript": "^5.3.0"
+ }
+}
diff --git a/packages/express-server/tsconfig.json b/packages/express-server/tsconfig.json
new file mode 100644
index 0000000..0bd91cb
--- /dev/null
+++ b/packages/express-server/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./dist",
+ "rootDir": "."
+ },
+ "include": ["index.ts"],
+ "exclude": ["dist", "node_modules"],
+ "references": [
+ { "path": "../shared" }
+ ]
+}
diff --git a/packages/facilitator/README.md b/packages/facilitator/README.md
new file mode 100644
index 0000000..5b9f854
--- /dev/null
+++ b/packages/facilitator/README.md
@@ -0,0 +1,234 @@
+# NANDA Points Facilitator Service
+
+x402-compliant facilitator service that handles NANDA Points payment verification and settlement using MongoDB instead of blockchain transactions. This service implements the standard x402 facilitator API endpoints.
+
+## Features
+
+- **x402 Facilitator API**: Standard `/verify`, `/settle`, `/supported` endpoints
+- **NANDA Points Integration**: Handles "nanda-points" payment scheme
+- **MongoDB Backend**: Replaces blockchain verification with MongoDB transactions
+- **Agent-based Authentication**: Uses agent names instead of wallet signatures
+- **Transaction Management**: Creates and tracks payment receipts
+
+## Prerequisites
+
+- Node.js v20+
+- MongoDB running on localhost:27017
+- Existing NANDA Points database schema (agents, wallets, transactions, receipts)
+
+## Quick Start
+
+1. Install dependencies:
+```bash
+npm install
+```
+
+2. Set environment variables:
+```bash
+MONGO_URI=mongodb://localhost:27017
+DB_NAME=nanda_points
+PORT=3001
+```
+
+3. Start the facilitator:
+```bash
+npm run dev
+```
+
+## API Endpoints
+
+### POST /verify
+
+Verify a payment against payment requirements.
+
+**Request:**
+```json
+{
+ "payment": {
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "amount": "1",
+ "to": "system",
+ "from": "client-agent",
+ "txId": "unique-transaction-id",
+ "timestamp": 1234567890,
+ "x402Version": 1
+ },
+ "paymentRequirements": {
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "maxAmountRequired": "1",
+ "resource": "http://localhost:3000/weather",
+ "description": "Weather data access",
+ "payTo": "system",
+ "maxTimeoutSeconds": 60,
+ "asset": "NP"
+ }
+}
+```
+
+**Response (Success):**
+```json
+{
+ "isValid": true,
+ "payer": "client-agent"
+}
+```
+
+**Response (Failure):**
+```json
+{
+ "isValid": false,
+ "invalidReason": "Insufficient balance",
+ "payer": "client-agent"
+}
+```
+
+### POST /settle
+
+Execute payment settlement and create transaction records.
+
+**Request:** Same as `/verify`
+
+**Response (Success):**
+```json
+{
+ "success": true,
+ "txId": "unique-transaction-id",
+ "amount": "1",
+ "from": "client-agent",
+ "to": "system",
+ "timestamp": 1234567890
+}
+```
+
+**Response (Failure):**
+```json
+{
+ "success": false,
+ "errorReason": "Payment verification failed"
+}
+```
+
+### GET /supported
+
+Get supported payment schemes.
+
+**Response:**
+```json
+{
+ "kinds": [{
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "asset": "NP"
+ }]
+}
+```
+
+## Payment Flow
+
+1. **Client Request**: Client makes request to protected resource without payment
+2. **402 Response**: Resource server returns HTTP 402 with payment requirements
+3. **Payment Verification**: Client calls `/verify` to validate payment capability
+4. **Payment Settlement**: After successful resource access, server calls `/settle` to execute payment
+5. **Transaction Recording**: Facilitator creates transaction and receipt records in MongoDB
+
+## MongoDB Integration
+
+The facilitator integrates with existing NANDA Points collections:
+
+### Collections Used
+- `agents` - Agent registration and metadata
+- `wallets` - Agent balances and wallet information
+- `transactions` - Payment transaction records
+- `receipts` - Payment receipt records
+
+### Transaction Flow
+1. Verify agent exists and has sufficient balance
+2. Create transaction record with pending status
+3. Update sender/recipient wallet balances
+4. Create payment receipt
+5. Update transaction status to completed
+
+## Configuration
+
+Environment variables:
+
+```bash
+# MongoDB connection
+MONGO_URI=mongodb://localhost:27017
+DB_NAME=nanda_points
+
+# Server configuration
+PORT=3001
+HOST=localhost
+
+# Optional: Enable debug logging
+DEBUG=true
+```
+
+## Testing the Facilitator
+
+### Test /supported endpoint
+```bash
+curl http://localhost:3001/supported
+```
+
+### Test /verify endpoint
+```bash
+curl -X POST http://localhost:3001/verify \
+ -H "Content-Type: application/json" \
+ -d '{
+ "payment": {
+ "scheme": "nanda-points",
+ "amount": "1",
+ "from": "test-agent",
+ "to": "system",
+ "txId": "test-tx-123"
+ },
+ "paymentRequirements": {
+ "scheme": "nanda-points",
+ "maxAmountRequired": "1",
+ "payTo": "system"
+ }
+ }'
+```
+
+## Error Handling
+
+The facilitator returns appropriate HTTP status codes:
+
+- `200` - Success
+- `400` - Bad request (invalid payment format)
+- `402` - Payment verification failed
+- `500` - Internal server error
+
+Error responses include detailed `errorReason` or `invalidReason` fields.
+
+## Security Considerations
+
+- **Agent Authentication**: Payments are linked to agent names in the database
+- **Transaction IDs**: Must be unique to prevent double-spending
+- **Balance Validation**: Always checks sufficient balance before settlement
+- **Atomic Operations**: Uses MongoDB transactions for balance updates
+
+## Deployment
+
+The facilitator can be deployed as:
+
+1. **Standalone Service**: Independent facilitator for multiple resource servers
+2. **Embedded**: Bundled with resource servers for simplified deployment
+3. **Containerized**: Docker deployment with MongoDB connection
+
+## Differences from Blockchain Facilitators
+
+- **No Smart Contracts**: Direct MongoDB operations instead of blockchain calls
+- **Agent Names**: Uses string identifiers instead of wallet addresses
+- **Instant Settlement**: No block confirmation delays
+- **Centralized**: Single MongoDB instance instead of distributed blockchain
+
+## Related Packages
+
+- [`../shared/`](../shared/) - Common types and utilities
+- [`../express-server/`](../express-server/) - Example Express server using this facilitator
+- [`../advanced-server/`](../advanced-server/) - Advanced server with manual payment handling
\ No newline at end of file
diff --git a/packages/facilitator/package.json b/packages/facilitator/package.json
new file mode 100644
index 0000000..cf48870
--- /dev/null
+++ b/packages/facilitator/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "nanda-points-facilitator",
+ "version": "1.0.0",
+ "description": "NANDA Points facilitator service implementing x402 facilitator API",
+ "private": true,
+ "type": "module",
+ "main": "dist/index.js",
+ "scripts": {
+ "dev": "tsx src/index.ts",
+ "build": "tsup src/index.ts --format esm --dts",
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "lint": "eslint . --ext .ts --fix",
+ "lint:check": "eslint . --ext .ts",
+ "format": "prettier --write \"**/*.{ts,js,json,md}\"",
+ "format:check": "prettier --check \"**/*.{ts,js,json,md}\""
+ },
+ "dependencies": {
+ "express": "^4.18.2",
+ "dotenv": "^16.4.7",
+ "mongodb": "^6.0.0",
+ "x402-nanda-shared": "file:../shared"
+ },
+ "devDependencies": {
+ "@types/express": "^5.0.1",
+ "tsup": "^7.2.0",
+ "tsx": "^4.7.0"
+ }
+}
\ No newline at end of file
diff --git a/packages/facilitator/src/index.ts b/packages/facilitator/src/index.ts
new file mode 100644
index 0000000..00c6b27
--- /dev/null
+++ b/packages/facilitator/src/index.ts
@@ -0,0 +1,377 @@
+/**
+ * NANDA Points Facilitator Server
+ * Implements x402 facilitator API with MongoDB/NP backend
+ */
+
+import { config } from "dotenv";
+import express from "express";
+import { Db } from "mongodb";
+import {
+ connectToMongoDB,
+ NPFacilitatorConfig,
+ PaymentPayload,
+ PaymentRequirements,
+ VerificationResponse,
+ SettlementResponse,
+ SupportedResponse,
+ mongoUtils,
+ nandaPoints,
+ npUtils,
+ NPVerificationError,
+ NPSettlementError,
+} from "x402-nanda-shared";
+
+config();
+
+const app = express();
+app.use(express.json());
+
+// Configuration
+const facilitatorConfig: NPFacilitatorConfig = {
+ mongoUri: process.env.MONGODB_URI || "mongodb://localhost:27017",
+ dbName: process.env.NP_DB_NAME || "nanda_points",
+ baseUrl: process.env.FACILITATOR_BASE_URL || "http://localhost:3000",
+};
+
+let database: Db | null = null;
+
+// Initialize MongoDB connection
+async function initializeDatabase() {
+ if (!database) {
+ database = await connectToMongoDB(facilitatorConfig);
+ }
+ return database;
+}
+
+/**
+ * GET /supported
+ * Returns supported payment schemes (x402 standard endpoint)
+ */
+app.get("/supported", async (req, res) => {
+ try {
+ const response: SupportedResponse = {
+ kinds: [
+ {
+ scheme: "nanda-points",
+ network: "nanda-network",
+ asset: "NP",
+ extra: {
+ facilitatorUrl: `${facilitatorConfig.baseUrl}/facilitator`,
+ description: "NANDA Points payment scheme using MongoDB backend",
+ scale: 0,
+ currency: "NP",
+ },
+ },
+ ],
+ };
+
+ res.json(response);
+ } catch (error) {
+ console.error("Error in /supported:", error);
+ res.status(500).json({ error: "Internal server error" });
+ }
+});
+
+/**
+ * POST /verify
+ * Verify payment without settling (x402 standard endpoint)
+ */
+app.post("/verify", async (req, res) => {
+ try {
+ const { payment, paymentRequirements } = req.body as {
+ payment: PaymentPayload;
+ paymentRequirements: PaymentRequirements;
+ };
+
+ await initializeDatabase();
+
+ const verification = await verifyPayment(payment, paymentRequirements);
+ res.json(verification);
+ } catch (error) {
+ console.error("Error in /verify:", error);
+ if (error instanceof NPVerificationError) {
+ res.status(402).json({
+ isValid: false,
+ invalidReason: error.message,
+ details: error.details,
+ });
+ } else {
+ res.status(500).json({ error: "Internal server error" });
+ }
+ }
+});
+
+/**
+ * POST /settle
+ * Verify and settle payment (x402 standard endpoint)
+ */
+app.post("/settle", async (req, res) => {
+ try {
+ const { payment, paymentRequirements } = req.body as {
+ payment: PaymentPayload;
+ paymentRequirements: PaymentRequirements;
+ };
+
+ await initializeDatabase();
+
+ // First verify the payment
+ const verification = await verifyPayment(payment, paymentRequirements);
+ if (!verification.isValid) {
+ return res.status(402).json({
+ success: false,
+ errorReason: verification.invalidReason,
+ txId: payment.txId,
+ });
+ }
+
+ // Then settle it (update balances, create receipt)
+ const settlement = await settlePayment(payment);
+ res.json(settlement);
+ } catch (error) {
+ console.error("Error in /settle:", error);
+ if (error instanceof NPSettlementError) {
+ res.status(402).json({
+ success: false,
+ errorReason: error.message,
+ details: error.details,
+ });
+ } else {
+ res.status(500).json({ error: "Internal server error" });
+ }
+ }
+});
+
+/**
+ * Verify payment against NANDA Points system
+ */
+async function verifyPayment(
+ payment: PaymentPayload,
+ requirements: PaymentRequirements
+): Promise {
+ try {
+ // Validate payment payload structure
+ if (!nandaPoints.validatePayment(payment)) {
+ throw new NPVerificationError("Invalid payment payload structure");
+ }
+
+ // Check scheme compatibility
+ if (payment.scheme !== "nanda-points" || requirements.scheme !== "nanda-points") {
+ throw new NPVerificationError("Unsupported payment scheme");
+ }
+
+ // Parse amounts
+ const paymentAmount = npUtils.parseAmount(payment.amount);
+ const requiredAmount = npUtils.parseAmount(requirements.maxAmountRequired);
+
+ // Check amount is sufficient
+ if (paymentAmount < requiredAmount) {
+ throw new NPVerificationError(
+ `Insufficient payment amount: ${paymentAmount} < ${requiredAmount}`,
+ { paymentAmount, requiredAmount }
+ );
+ }
+
+ // Check recipient matches
+ if (payment.payTo !== requirements.payTo) {
+ throw new NPVerificationError(
+ `Payment recipient mismatch: ${payment.payTo} !== ${requirements.payTo}`,
+ { paymentRecipient: payment.payTo, requiredRecipient: requirements.payTo }
+ );
+ }
+
+ // Validate payer agent exists and has sufficient balance
+ const validation = await mongoUtils.validateAgentAndBalance(
+ database,
+ payment.from,
+ paymentAmount
+ );
+
+ if (!validation.valid) {
+ throw new NPVerificationError(validation.reason ?? "Validation failed", {
+ agent: payment.from,
+ balance: validation.balance,
+ required: paymentAmount,
+ });
+ }
+
+ // Validate recipient agent exists
+ const recipient = await mongoUtils.findAgent(database, payment.payTo);
+ if (!recipient) {
+ throw new NPVerificationError(`Recipient agent not found: ${payment.payTo}`);
+ }
+
+ // Check if transaction already exists (prevent double-spending)
+ const existingTx = await mongoUtils.findTransaction(database, payment.txId);
+ if (existingTx) {
+ // If transaction exists and is completed, payment is valid
+ if (existingTx.status === "completed") {
+ return {
+ isValid: true,
+ payer: payment.from,
+ amount: payment.amount,
+ txId: payment.txId,
+ };
+ } else {
+ throw new NPVerificationError("Transaction exists but not completed", {
+ txId: payment.txId,
+ status: existingTx.status,
+ });
+ }
+ }
+
+ return {
+ isValid: true,
+ payer: payment.from,
+ amount: payment.amount,
+ txId: payment.txId,
+ };
+ } catch (error) {
+ if (error instanceof NPVerificationError) {
+ return {
+ isValid: false,
+ invalidReason: error.message,
+ payer: payment.from,
+ };
+ }
+ throw error;
+ }
+}
+
+/**
+ * Settle payment in NANDA Points system
+ */
+async function settlePayment(payment: PaymentPayload): Promise {
+ try {
+ // Check if already settled
+ const existingReceipt = await mongoUtils.findReceipt(database, payment.txId);
+ if (existingReceipt) {
+ return {
+ success: true,
+ txId: payment.txId,
+ amount: payment.amount,
+ from: payment.from,
+ to: payment.payTo,
+ timestamp: Date.now(),
+ receipt: existingReceipt,
+ };
+ }
+
+ // Execute actual NP transaction with MongoDB balance updates
+ const paymentAmount = npUtils.parseAmount(payment.amount);
+
+ // Execute real NP transaction with MongoDB
+ const receipt = await executeNPTransaction(
+ payment.from,
+ payment.payTo,
+ paymentAmount,
+ payment.txId
+ );
+
+ return {
+ success: true,
+ txId: payment.txId,
+ amount: payment.amount,
+ from: payment.from,
+ to: payment.payTo,
+ timestamp: Date.now(),
+ receipt,
+ };
+ } catch (error) {
+ throw new NPSettlementError("Settlement failed", error);
+ }
+}
+
+/**
+ * Execute real NP transaction using MongoDB
+ * Based on the working implementation from main branch
+ */
+async function executeNPTransaction(from: string, to: string, amount: number, txId: string) {
+ const createdAt = new Date().toISOString();
+
+ // Get collection references
+ const walletCollection = database.collection("wallets");
+ const transactionCollection = database.collection("transactions");
+ const receiptCollection = database.collection("receipts");
+
+ // 1. Ensure both wallets exist and check balance
+ const fromWallet = await walletCollection.findOne({ agent_name: from });
+ const toWallet = await walletCollection.findOne({ agent_name: to });
+
+ if (!fromWallet) throw new Error(`Sender wallet not found: ${from}`);
+ if (!toWallet) throw new Error(`Receiver wallet not found: ${to}`);
+ if (fromWallet.balanceMinor < amount)
+ throw new Error(`Insufficient funds: ${fromWallet.balanceMinor} < ${amount}`);
+
+ // 2. Deduct from sender's wallet
+ const updatedFromWallet = await walletCollection.findOneAndUpdate(
+ { agent_name: from },
+ { $inc: { balanceMinor: -amount }, $set: { updatedAt: createdAt } },
+ { returnDocument: "after" }
+ );
+ if (!updatedFromWallet) throw new Error("Failed to update sender wallet");
+
+ // 3. Add to receiver's wallet
+ const updatedToWallet = await walletCollection.findOneAndUpdate(
+ { agent_name: to },
+ { $inc: { balanceMinor: amount }, $set: { updatedAt: createdAt } },
+ { returnDocument: "after" }
+ );
+ if (!updatedToWallet) throw new Error("Failed to update receiver wallet");
+
+ // 4. Record transaction
+ const transaction = {
+ txId,
+ fromAgent: from,
+ toAgent: to,
+ amountMinor: amount,
+ currency: "NP",
+ scale: 0,
+ createdAt,
+ status: "completed",
+ error: null,
+ task: "x402-payment",
+ };
+ await transactionCollection.insertOne(transaction);
+
+ // 5. Create receipt
+ const receipt = {
+ txId,
+ issuedAt: createdAt,
+ fromAgent: from,
+ toAgent: to,
+ amountMinor: amount,
+ fromBalanceAfter: updatedFromWallet.balanceMinor,
+ toBalanceAfter: updatedToWallet.balanceMinor,
+ };
+ await receiptCollection.insertOne(receipt);
+
+ console.log(`✅ Real NP transaction completed: ${from} → ${to}, ${amount} NP`);
+ console.log(
+ ` Balances: ${from}=${updatedFromWallet.balanceMinor}, ${to}=${updatedToWallet.balanceMinor}`
+ );
+
+ return receipt;
+}
+
+// Health check endpoint
+app.get("/health", (req, res) => {
+ res.json({
+ status: "healthy",
+ service: "nanda-points-facilitator",
+ version: "1.0.0",
+ schemes: ["nanda-points"],
+ });
+});
+
+const PORT = process.env.FACILITATOR_PORT || 3001;
+
+app.listen(PORT, () => {
+ console.log(`🏦 NANDA Points Facilitator running at http://localhost:${PORT}`);
+ console.log(`📡 Endpoints:`);
+ console.log(` GET /supported - Get supported payment schemes`);
+ console.log(` POST /verify - Verify payment`);
+ console.log(` POST /settle - Settle payment`);
+ console.log(` GET /health - Health check`);
+});
+
+export { app };
diff --git a/packages/facilitator/tsconfig.json b/packages/facilitator/tsconfig.json
new file mode 100644
index 0000000..5b0ab01
--- /dev/null
+++ b/packages/facilitator/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./dist",
+ "rootDir": "./src"
+ },
+ "include": ["src/**/*"],
+ "exclude": ["dist", "node_modules"],
+ "references": [
+ { "path": "../shared" }
+ ]
+}
\ No newline at end of file
diff --git a/packages/shared/README.md b/packages/shared/README.md
new file mode 100644
index 0000000..f361816
--- /dev/null
+++ b/packages/shared/README.md
@@ -0,0 +1,221 @@
+# x402 NANDA Points Shared Package
+
+Common utilities, types, and middleware for building x402-compliant servers using NANDA Points. This package replaces `x402-express` and provides the core functionality for payment-gated endpoints.
+
+## Features
+
+- **x402 Protocol Types**: Standard interfaces for payment requirements and payloads
+- **NANDA Points Scheme**: "nanda-points" payment scheme implementation
+- **Express Middleware**: Drop-in replacement for `x402-express`
+- **MongoDB Integration**: Transaction utilities for NANDA Points settlement
+- **Facilitator Client**: HTTP client for facilitator API communication
+
+## Installation
+
+```bash
+npm install x402-nanda-shared
+```
+
+## Core Components
+
+### Payment Middleware
+
+Replace `x402-express` middleware with `npPaymentMiddleware`:
+
+```typescript
+import { npPaymentMiddleware } from "x402-nanda-shared";
+
+app.use(
+ npPaymentMiddleware(
+ {
+ "GET /weather": {
+ priceNP: 1,
+ recipient: "system",
+ description: "Weather data access",
+ maxTimeoutSeconds: 60,
+ },
+ "/premium/*": {
+ priceNP: 10,
+ recipient: "system",
+ description: "Premium content",
+ maxTimeoutSeconds: 60,
+ }
+ },
+ "http://localhost:3001" // facilitator URL
+ )
+);
+```
+
+### Payment Scheme
+
+The NANDA Points scheme handles payment encoding/decoding:
+
+```typescript
+import { nandaPoints } from "x402-nanda-shared";
+
+// Decode X-PAYMENT header
+const payment = nandaPoints.decodePayment(xPaymentHeader);
+
+// Create payment requirements
+const requirements = nandaPoints.createPaymentRequirements(
+ {
+ priceNP: 5,
+ recipient: "agent-name",
+ description: "Access to feature",
+ maxTimeoutSeconds: 60
+ },
+ "http://localhost:3000/endpoint",
+ "http://localhost:3001"
+);
+```
+
+### Facilitator Client
+
+Communicate with the NANDA Points facilitator:
+
+```typescript
+import { createNPFacilitatorClient } from "x402-nanda-shared";
+
+const facilitator = createNPFacilitatorClient("http://localhost:3001");
+
+// Verify payment
+const verification = await facilitator.verify(payment, requirements);
+
+// Settle payment after successful request
+const settlement = await facilitator.settle(payment, requirements);
+
+// Get supported payment schemes
+const supported = await facilitator.supported();
+```
+
+### MongoDB Utilities
+
+Work with existing NANDA Points database schema:
+
+```typescript
+import { connectToMongoDB, mongoUtils } from "x402-nanda-shared";
+
+// Connect to database
+const db = await connectToMongoDB({
+ mongoUri: "mongodb://localhost:27017",
+ dbName: "nanda_points"
+});
+
+// Check agent balance
+const balance = await mongoUtils.getAgentBalance(db, "agent-name");
+
+// Validate payment capability
+const validation = await mongoUtils.validateAgentAndBalance(
+ db,
+ "agent-name",
+ requiredAmount
+);
+```
+
+## Types
+
+### Core Interfaces
+
+```typescript
+interface PaymentRequirements {
+ scheme: "nanda-points";
+ network: "nanda-network";
+ maxAmountRequired: string;
+ resource: string;
+ description: string;
+ payTo: string; // Agent name
+ maxTimeoutSeconds: number;
+ asset: "NP";
+ extra?: {
+ facilitatorUrl?: string;
+ };
+}
+
+interface PaymentPayload {
+ scheme: "nanda-points";
+ network: "nanda-network";
+ amount: string;
+ to: string;
+ from: string;
+ txId: string;
+ timestamp: number;
+ x402Version: number;
+}
+```
+
+### Configuration Types
+
+```typescript
+interface NPPaymentConfig {
+ priceNP: number; // Price in NANDA Points
+ recipient: string; // Agent name to receive payment
+ description: string; // Human-readable description
+ maxTimeoutSeconds: number; // Payment timeout
+}
+
+interface NPRoutesConfig {
+ [route: string]: NPPaymentConfig;
+}
+```
+
+## Error Handling
+
+The package includes specific error types for payment failures:
+
+```typescript
+import { NPPaymentError, NPVerificationError, NPSettlementError } from "x402-nanda-shared";
+
+try {
+ await facilitator.verify(payment, requirements);
+} catch (error) {
+ if (error instanceof NPVerificationError) {
+ // Handle verification failure
+ } else if (error instanceof NPSettlementError) {
+ // Handle settlement failure
+ }
+}
+```
+
+## Migration from x402-express
+
+### Before (x402-express)
+```typescript
+import { paymentMiddleware } from "x402-express";
+
+app.use(paymentMiddleware(payTo, {
+ "GET /endpoint": {
+ price: "$0.001",
+ network: "base-sepolia"
+ }
+}, facilitatorUrl));
+```
+
+### After (x402-nanda-shared)
+```typescript
+import { npPaymentMiddleware } from "x402-nanda-shared";
+
+app.use(npPaymentMiddleware({
+ "GET /endpoint": {
+ priceNP: 1,
+ recipient: "agent-name",
+ description: "Endpoint access",
+ maxTimeoutSeconds: 60
+ }
+}, facilitatorUrl));
+```
+
+## Facilitator Integration
+
+This package expects a NANDA Points facilitator service running with these endpoints:
+
+- `POST /verify` - Verify payment against requirements
+- `POST /settle` - Execute payment settlement
+- `GET /supported` - Get supported payment schemes
+
+The facilitator handles the actual MongoDB transactions and NANDA Points balance management.
+
+## Related Packages
+
+- [`../facilitator/`](../facilitator/) - NANDA Points facilitator service
+- [`../express-server/`](../express-server/) - Example Express server
+- [`../advanced-server/`](../advanced-server/) - Advanced manual payment handling
\ No newline at end of file
diff --git a/packages/shared/package.json b/packages/shared/package.json
new file mode 100644
index 0000000..afd1d5d
--- /dev/null
+++ b/packages/shared/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "x402-nanda-shared",
+ "version": "1.0.0",
+ "description": "Shared utilities and types for x402 NANDA Points implementation",
+ "private": true,
+ "type": "module",
+ "main": "dist/index.js",
+ "scripts": {
+ "build": "tsup src/index.ts --format esm --dts",
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "lint": "eslint . --ext .ts --fix",
+ "lint:check": "eslint . --ext .ts",
+ "format": "prettier --write \"**/*.{ts,js,json,md}\"",
+ "format:check": "prettier --check \"**/*.{ts,js,json,md}\""
+ },
+ "dependencies": {
+ "mongodb": "^6.0.0"
+ },
+ "devDependencies": {
+ "tsup": "^7.2.0",
+ "typescript": "^5.3.0",
+ "@types/express": "^5.0.1"
+ }
+}
\ No newline at end of file
diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts
new file mode 100644
index 0000000..d2e75fe
--- /dev/null
+++ b/packages/shared/src/index.ts
@@ -0,0 +1,41 @@
+/**
+ * x402 NANDA Points Shared Package
+ * Common types and utilities for NANDA Points x402 implementation
+ */
+
+// Types
+export type {
+ PaymentRequirements,
+ PaymentPayload,
+ VerificationResponse,
+ SettlementResponse,
+ SupportedResponse,
+ NPReceipt,
+ NPAgent,
+ NPWallet,
+ NPTransaction,
+ NPFacilitatorConfig,
+ NPPaymentConfig,
+ NPRoutesConfig,
+ Resource,
+ Network,
+ Scheme,
+} from "./types.js";
+
+// Error classes
+export { NPPaymentError, NPVerificationError, NPSettlementError } from "./types.js";
+
+// NANDA Points scheme
+export { nandaPoints, npUtils } from "./nanda-points-scheme.js";
+
+// MongoDB utilities
+export {
+ connectToMongoDB,
+ getAgentCollection,
+ getWalletCollection,
+ mongoUtils,
+} from "./mongodb.js";
+
+// Express middleware
+export { npPaymentMiddleware, createNPFacilitatorClient } from "./middleware.js";
+export type { NPFacilitatorClient } from "./middleware.js";
diff --git a/packages/shared/src/middleware.ts b/packages/shared/src/middleware.ts
new file mode 100644
index 0000000..816f354
--- /dev/null
+++ b/packages/shared/src/middleware.ts
@@ -0,0 +1,251 @@
+/**
+ * NANDA Points Express middleware
+ * Replaces x402-express with NP-specific implementation
+ */
+
+import { NextFunction, Request, Response } from "express";
+import {
+ PaymentRequirements,
+ PaymentPayload,
+ NPRoutesConfig,
+ NPPaymentConfig,
+ NPPaymentError,
+} from "./types.js";
+import { nandaPoints } from "./nanda-points-scheme.js";
+
+export interface NPFacilitatorClient {
+ verify(
+ payment: PaymentPayload,
+ requirements: PaymentRequirements
+ ): Promise<{
+ isValid: boolean;
+ invalidReason?: string;
+ payer?: string;
+ }>;
+ settle(
+ payment: PaymentPayload,
+ requirements: PaymentRequirements
+ ): Promise<{
+ success: boolean;
+ txId: string;
+ amount: string;
+ from: string;
+ to: string;
+ timestamp: number;
+ errorReason?: string;
+ }>;
+ supported(): Promise<{
+ kinds: Array<{
+ scheme: "nanda-points";
+ network: "nanda-network";
+ asset: "NP";
+ }>;
+ }>;
+}
+
+/**
+ * Create NP facilitator client
+ * Replaces x402's useFacilitator()
+ */
+export function createNPFacilitatorClient(facilitatorUrl: string): NPFacilitatorClient {
+ return {
+ async verify(payment, requirements) {
+ const response = await fetch(`${facilitatorUrl}/verify`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ payment, paymentRequirements: requirements }),
+ });
+
+ if (!response.ok) {
+ const error = await response.json();
+ return {
+ isValid: false,
+ invalidReason: error.invalidReason || "Verification failed",
+ };
+ }
+
+ return await response.json();
+ },
+
+ async settle(payment, requirements) {
+ const response = await fetch(`${facilitatorUrl}/settle`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ payment, paymentRequirements: requirements }),
+ });
+
+ const result = await response.json();
+ if (!response.ok) {
+ throw new NPPaymentError("Settlement failed", "SETTLEMENT_ERROR", result);
+ }
+
+ return result;
+ },
+
+ async supported() {
+ const response = await fetch(`${facilitatorUrl}/supported`);
+ if (!response.ok) {
+ throw new NPPaymentError("Failed to get supported schemes", "FACILITATOR_ERROR");
+ }
+ return await response.json();
+ },
+ };
+}
+
+/**
+ * Payment middleware for NANDA Points
+ * Replaces x402-express paymentMiddleware
+ */
+export function npPaymentMiddleware(routes: NPRoutesConfig, facilitatorUrl: string) {
+ const facilitator = createNPFacilitatorClient(facilitatorUrl);
+ const x402Version = 1;
+
+ return async function npPaymentMiddleware(
+ req: Request,
+ res: Response,
+ next: NextFunction
+ ): Promise {
+ // Find matching route
+ const routeConfig = findMatchingRoute(routes, req.path, req.method);
+ if (!routeConfig) {
+ return next(); // No payment required for this route
+ }
+
+ const resource = `${req.protocol}://${req.headers.host}${req.originalUrl}`;
+ const paymentRequirements = nandaPoints.createPaymentRequirements(
+ routeConfig,
+ resource,
+ facilitatorUrl
+ );
+
+ const payment = req.header("X-PAYMENT");
+
+ // No payment provided - return 402
+ if (!payment) {
+ res.status(402).json({
+ x402Version,
+ error: "X-PAYMENT header is required",
+ accepts: [paymentRequirements],
+ });
+ return;
+ }
+
+ // Decode and validate payment
+ let decodedPayment: PaymentPayload;
+ try {
+ decodedPayment = nandaPoints.decodePayment(payment);
+ decodedPayment.x402Version = x402Version;
+ } catch (error) {
+ res.status(402).json({
+ x402Version,
+ error: error instanceof NPPaymentError ? error.message : "Invalid payment header",
+ accepts: [paymentRequirements],
+ });
+ return;
+ }
+
+ // Verify payment
+ try {
+ const verification = await facilitator.verify(decodedPayment, paymentRequirements);
+ if (!verification.isValid) {
+ res.status(402).json({
+ x402Version,
+ error: verification.invalidReason,
+ accepts: [paymentRequirements],
+ payer: verification.payer,
+ });
+ return;
+ }
+ } catch (error) {
+ res.status(402).json({
+ x402Version,
+ error: error instanceof Error ? error.message : "Payment verification failed",
+ accepts: [paymentRequirements],
+ });
+ return;
+ }
+
+ // Intercept response to settle payment after successful request
+ const originalEnd = res.end.bind(res);
+ let endArgs: Parameters | null = null;
+
+ res.end = function (chunk: unknown, encoding?: BufferEncoding, cb?: () => void) {
+ endArgs = [chunk, encoding, cb];
+ return res;
+ } as typeof res.end;
+
+ // Continue to route handler
+ await next();
+
+ // If response was successful, settle payment
+ if (res.statusCode < 400) {
+ try {
+ const settlement = await facilitator.settle(decodedPayment, paymentRequirements);
+ if (settlement.success) {
+ // Create X-PAYMENT-RESPONSE header
+ const responseHeader = btoa(
+ JSON.stringify({
+ txId: settlement.txId,
+ amount: settlement.amount,
+ from: settlement.from,
+ to: settlement.to,
+ timestamp: settlement.timestamp,
+ })
+ );
+ res.setHeader("X-PAYMENT-RESPONSE", responseHeader);
+ }
+ } catch (error) {
+ console.error("Payment settlement failed:", error);
+ // Continue anyway - don't fail the response for settlement issues
+ }
+ }
+
+ // Send the original response
+ res.end = originalEnd;
+ if (endArgs) {
+ originalEnd(...endArgs);
+ }
+ };
+}
+
+/**
+ * Find matching route configuration
+ */
+function findMatchingRoute(
+ routes: NPRoutesConfig,
+ path: string,
+ method: string
+): NPPaymentConfig | null {
+ // Check exact matches first
+ const exactKey = `${method.toUpperCase()} ${path}`;
+ if (routes[exactKey]) {
+ return routes[exactKey];
+ }
+
+ // Check pattern matches
+ for (const [route, config] of Object.entries(routes)) {
+ if (matchesRoute(route, path, method)) {
+ return config;
+ }
+ }
+
+ return null;
+}
+
+/**
+ * Check if path matches route pattern
+ */
+function matchesRoute(route: string, path: string, method: string): boolean {
+ const [routeMethod, routePath] = route.includes(" ") ? route.split(" ", 2) : ["*", route];
+
+ // Check method
+ if (routeMethod !== "*" && routeMethod.toUpperCase() !== method.toUpperCase()) {
+ return false;
+ }
+
+ // Convert route pattern to regex
+ const pattern = routePath.replace(/\*/g, ".*").replace(/\//g, "\\/");
+
+ const regex = new RegExp(`^${pattern}$`);
+ return regex.test(path);
+}
diff --git a/packages/shared/src/mongodb.ts b/packages/shared/src/mongodb.ts
new file mode 100644
index 0000000..4d847eb
--- /dev/null
+++ b/packages/shared/src/mongodb.ts
@@ -0,0 +1,144 @@
+/**
+ * MongoDB utilities for NANDA Points
+ * Integrates with existing MongoDB schema
+ */
+
+import { MongoClient, Db, Collection } from "mongodb";
+import { NPAgent, NPWallet, NPTransaction, NPReceipt, NPFacilitatorConfig } from "./types.js";
+
+let client: MongoClient | null = null;
+let db: Db | null = null;
+
+/**
+ * Connect to MongoDB using existing connection settings
+ */
+export async function connectToMongoDB(config: NPFacilitatorConfig): Promise {
+ if (db) {
+ return db;
+ }
+
+ try {
+ client = new MongoClient(config.mongoUri);
+ await client.connect();
+ db = client.db(config.dbName);
+
+ console.log(`Connected to MongoDB: ${config.dbName}`);
+ return db;
+ } catch (error) {
+ console.error("Failed to connect to MongoDB:", error);
+ throw error;
+ }
+}
+
+/**
+ * Get agents collection (existing schema)
+ */
+export function getAgentCollection(database: Db): Collection {
+ return database.collection("agents");
+}
+
+/**
+ * Get wallets collection (existing schema)
+ */
+export function getWalletCollection(database: Db): Collection {
+ return database.collection("wallets");
+}
+
+/**
+ * Get transactions collection (existing schema)
+ */
+export function getTransactionCollection(database: Db): Collection {
+ return database.collection("transactions");
+}
+
+/**
+ * Get receipts collection (existing schema)
+ */
+export function getReceiptCollection(database: Db): Collection {
+ return database.collection("receipts");
+}
+
+/**
+ * Close MongoDB connection
+ */
+export async function closeConnection(): Promise {
+ if (client) {
+ await client.close();
+ client = null;
+ db = null;
+ }
+}
+
+/**
+ * MongoDB transaction utilities
+ */
+export const mongoUtils = {
+ /**
+ * Find agent by name
+ */
+ async findAgent(database: Db, agentName: string): Promise {
+ const agentCollection = getAgentCollection(database);
+ return await agentCollection.findOne({ agent_name: agentName });
+ },
+
+ /**
+ * Find wallet by agent name
+ */
+ async findWallet(database: Db, agentName: string): Promise {
+ const walletCollection = getWalletCollection(database);
+ return await walletCollection.findOne({ agent_name: agentName });
+ },
+
+ /**
+ * Find transaction by ID
+ */
+ async findTransaction(database: Db, txId: string): Promise {
+ const transactionCollection = getTransactionCollection(database);
+ return await transactionCollection.findOne({ txId });
+ },
+
+ /**
+ * Find receipt by transaction ID
+ */
+ async findReceipt(database: Db, txId: string): Promise {
+ const receiptCollection = getReceiptCollection(database);
+ return await receiptCollection.findOne({ txId });
+ },
+
+ /**
+ * Get agent balance
+ */
+ async getAgentBalance(database: Db, agentName: string): Promise {
+ const wallet = await mongoUtils.findWallet(database, agentName);
+ return wallet ? wallet.balanceMinor : null;
+ },
+
+ /**
+ * Check if agent exists and has sufficient balance
+ */
+ async validateAgentAndBalance(
+ database: Db,
+ agentName: string,
+ requiredAmount: number
+ ): Promise<{ valid: boolean; reason?: string; balance?: number }> {
+ const agent = await mongoUtils.findAgent(database, agentName);
+ if (!agent) {
+ return { valid: false, reason: "Agent not found" };
+ }
+
+ const wallet = await mongoUtils.findWallet(database, agentName);
+ if (!wallet) {
+ return { valid: false, reason: "Agent wallet not found" };
+ }
+
+ if (wallet.balanceMinor < requiredAmount) {
+ return {
+ valid: false,
+ reason: "Insufficient balance",
+ balance: wallet.balanceMinor,
+ };
+ }
+
+ return { valid: true, balance: wallet.balanceMinor };
+ },
+};
diff --git a/packages/shared/src/nanda-points-scheme.ts b/packages/shared/src/nanda-points-scheme.ts
new file mode 100644
index 0000000..7bf6346
--- /dev/null
+++ b/packages/shared/src/nanda-points-scheme.ts
@@ -0,0 +1,161 @@
+/**
+ * NANDA Points payment scheme implementation
+ * Replaces the EVM blockchain schemes from x402
+ */
+
+import {
+ PaymentPayload,
+ PaymentRequirements,
+ NPPaymentError,
+ Resource,
+ NPPaymentConfig,
+} from "./types.js";
+
+/**
+ * NANDA Points payment scheme
+ * Replaces x402's exact.evm scheme
+ */
+export const nandaPoints = {
+ /**
+ * Create payment requirements for NANDA Points
+ */
+ createPaymentRequirements(
+ config: NPPaymentConfig,
+ resource: Resource,
+ facilitatorUrl: string
+ ): PaymentRequirements {
+ return {
+ scheme: "nanda-points",
+ network: "nanda-network",
+ maxAmountRequired: config.priceNP.toString(),
+ resource,
+ description: config.description || `Payment of ${config.priceNP} NP required`,
+ mimeType: "application/json",
+ payTo: config.recipient,
+ maxTimeoutSeconds: config.maxTimeoutSeconds || 60,
+ asset: "NP",
+ outputSchema: undefined,
+ extra: {
+ facilitatorUrl,
+ },
+ };
+ },
+
+ /**
+ * Encode payment payload for NANDA Points
+ * Replaces exact.evm.encodePayment()
+ */
+ encodePayment(payload: PaymentPayload): string {
+ try {
+ return btoa(JSON.stringify(payload));
+ } catch (error) {
+ throw new NPPaymentError("Failed to encode payment payload", "ENCODING_ERROR", error);
+ }
+ },
+
+ /**
+ * Decode payment payload from X-PAYMENT header
+ * Replaces exact.evm.decodePayment()
+ */
+ decodePayment(xPaymentHeader: string): PaymentPayload {
+ try {
+ const decoded = JSON.parse(atob(xPaymentHeader));
+
+ // Validate required fields
+ if (!decoded.scheme || decoded.scheme !== "nanda-points") {
+ throw new NPPaymentError("Invalid payment scheme", "INVALID_SCHEME", {
+ expected: "nanda-points",
+ received: decoded.scheme,
+ });
+ }
+
+ if (!decoded.payTo || !decoded.amount || !decoded.from || !decoded.txId) {
+ throw new NPPaymentError("Missing required payment fields", "INVALID_PAYLOAD", decoded);
+ }
+
+ return {
+ x402Version: decoded.x402Version || 1,
+ scheme: "nanda-points",
+ network: "nanda-network",
+ payTo: decoded.payTo,
+ amount: decoded.amount,
+ from: decoded.from,
+ txId: decoded.txId,
+ timestamp: decoded.timestamp || Date.now(),
+ extra: decoded.extra,
+ };
+ } catch (error) {
+ if (error instanceof NPPaymentError) {
+ throw error;
+ }
+ throw new NPPaymentError("Failed to decode payment payload", "DECODING_ERROR", error);
+ }
+ },
+
+ /**
+ * Create a payment payload for NANDA Points transaction
+ */
+ createPaymentPayload(from: string, to: string, amount: number, txId: string): PaymentPayload {
+ return {
+ x402Version: 1,
+ scheme: "nanda-points",
+ network: "nanda-network",
+ payTo: to,
+ amount: amount.toString(),
+ from,
+ txId,
+ timestamp: Date.now(),
+ };
+ },
+
+ /**
+ * Validate payment payload structure
+ */
+ validatePayment(payload: PaymentPayload): boolean {
+ return !!(
+ payload.scheme === "nanda-points" &&
+ payload.network === "nanda-network" &&
+ payload.payTo &&
+ payload.amount &&
+ payload.from &&
+ payload.txId
+ );
+ },
+};
+
+/**
+ * Utility functions for NANDA Points amounts
+ */
+export const npUtils = {
+ /**
+ * Convert NP amount to minor units (same as major for NP, scale=0)
+ */
+ toMinorUnits(amount: number): number {
+ return amount; // NP scale is 0, so minor = major
+ },
+
+ /**
+ * Convert minor units to NP amount
+ */
+ toMajorUnits(minorUnits: number): number {
+ return minorUnits; // NP scale is 0, so major = minor
+ },
+
+ /**
+ * Parse amount from string (handles both integer and decimal)
+ */
+ parseAmount(amount: string): number {
+ const parsed = parseFloat(amount);
+ if (isNaN(parsed) || parsed < 0) {
+ throw new NPPaymentError("Invalid amount format", "INVALID_AMOUNT", { amount });
+ }
+ return Math.floor(parsed); // NP amounts are integers
+ },
+
+ /**
+ * Format amount for display
+ */
+ formatAmount(amount: number): string {
+ return `${amount} NP`;
+ },
+};
diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts
new file mode 100644
index 0000000..335bace
--- /dev/null
+++ b/packages/shared/src/types.ts
@@ -0,0 +1,152 @@
+/**
+ * x402 types adapted for NANDA Points
+ */
+
+// Core x402 types that we maintain compatibility with
+export interface PaymentRequirements {
+ scheme: "nanda-points";
+ network: "nanda-network";
+ maxAmountRequired: string;
+ resource: string;
+ description: string;
+ mimeType: string;
+ payTo: string; // Agent name instead of blockchain address
+ maxTimeoutSeconds: number;
+ asset: "NP"; // NANDA Points
+ outputSchema?: unknown;
+ extra?: {
+ facilitatorUrl?: string;
+ [key: string]: unknown;
+ };
+}
+
+export interface PaymentPayload {
+ x402Version: number;
+ scheme: "nanda-points";
+ network: "nanda-network";
+ payTo: string; // Agent name
+ amount: string; // NP amount
+ from: string; // Paying agent name
+ txId: string; // NP transaction ID
+ timestamp: number;
+ extra?: {
+ [key: string]: unknown;
+ };
+}
+
+export interface VerificationResponse {
+ isValid: boolean;
+ invalidReason?: string;
+ payer?: string;
+ amount?: string;
+ txId?: string;
+}
+
+export interface SettlementResponse {
+ success: boolean;
+ txId: string;
+ amount: string;
+ from: string;
+ to: string;
+ timestamp: number;
+ errorReason?: string;
+ receipt?: NPReceipt;
+}
+
+export interface SupportedResponse {
+ kinds: Array<{
+ scheme: "nanda-points";
+ network: "nanda-network";
+ asset: "NP";
+ extra?: {
+ facilitatorUrl: string;
+ [key: string]: unknown;
+ };
+ }>;
+}
+
+// NANDA Points specific types
+export interface NPReceipt {
+ txId: string;
+ fromAgent: string;
+ toAgent: string;
+ amountMinor: number;
+ amountPoints: number;
+ timestamp: string;
+ fromBalanceAfter: number;
+ toBalanceAfter: number;
+}
+
+export interface NPAgent {
+ agent_name: string;
+ walletId: string;
+ serviceCharge: number;
+ // ... other agent fields
+}
+
+export interface NPWallet {
+ walletId: string;
+ agent_name: string;
+ balanceMinor: number;
+ currency: "NP";
+ scale: 0;
+ createdAt: string;
+ updatedAt: string;
+}
+
+export interface NPTransaction {
+ txId: string;
+ fromAgent: string;
+ toAgent: string;
+ amountMinor: number;
+ status: "completed" | "pending" | "failed";
+ timestamp: string;
+ description?: string;
+}
+
+// Configuration types
+export interface NPFacilitatorConfig {
+ mongoUri: string;
+ dbName: string;
+ baseUrl?: string;
+}
+
+export interface NPPaymentConfig {
+ priceNP: number;
+ recipient: string;
+ description?: string;
+ maxTimeoutSeconds?: number;
+}
+
+// Route configuration (adapted from x402-express)
+export type NPRoutesConfig = {
+ [route: string]: NPPaymentConfig;
+};
+
+export type Resource = string;
+export type Network = "nanda-network";
+export type Scheme = "nanda-points";
+
+// Error types
+export class NPPaymentError extends Error {
+ constructor(
+ message: string,
+ public code: string,
+ public details?: unknown
+ ) {
+ super(message);
+ this.name = "NPPaymentError";
+ }
+}
+
+export class NPVerificationError extends NPPaymentError {
+ constructor(message: string, details?: unknown) {
+ super(message, "VERIFICATION_FAILED", details);
+ }
+}
+
+export class NPSettlementError extends NPPaymentError {
+ constructor(message: string, details?: unknown) {
+ super(message, "SETTLEMENT_FAILED", details);
+ }
+}
diff --git a/packages/shared/tsconfig.json b/packages/shared/tsconfig.json
new file mode 100644
index 0000000..9d2428e
--- /dev/null
+++ b/packages/shared/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./dist",
+ "rootDir": "./src"
+ },
+ "include": ["src/**/*"],
+ "exclude": ["dist", "node_modules"]
+}
\ No newline at end of file
diff --git a/python-adapter/.env.example b/python-adapter/.env.example
new file mode 100644
index 0000000..68909f0
--- /dev/null
+++ b/python-adapter/.env.example
@@ -0,0 +1,24 @@
+# NANDA Adapter Configuration
+
+# Server Configuration
+UI_PORT=5000
+HOST=0.0.0.0
+DEBUG=False
+
+# Agent Bridge Configuration
+AGENT_PORT=3000
+AGENT_ID=default_agent
+
+# NANDA Points Payment Configuration
+FACILITATOR_URL=http://localhost:3001
+AGENT_NAME=nanda-adapter
+
+# Optional: SSL Configuration
+SSL_CERT_PATH=
+SSL_KEY_PATH=
+
+# Optional: Claude API for enhanced agent bridge
+CLAUDE_API_KEY=
+
+# Optional: Agent Registry
+REGISTRY_URL=http://localhost:8000
\ No newline at end of file
diff --git a/python-adapter/README.md b/python-adapter/README.md
new file mode 100644
index 0000000..e56d8f1
--- /dev/null
+++ b/python-adapter/README.md
@@ -0,0 +1,583 @@
+# NANDA Points Python SDK
+
+A production-ready Python SDK for integrating NANDA Points payments into web applications and services. Transform any endpoint into a paid service with just a decorator.
+
+## Quick Start
+
+```python
+from nanda_payments_sdk import quick_setup, PaymentRequirement
+from flask import Flask
+
+app = Flask(__name__)
+
+# One-line setup
+payments = quick_setup(
+ facilitator_url="http://localhost:3001",
+ agent_name="my-app"
+)
+
+# Transform any route into paid with a decorator
+@app.route('/api/premium', methods=['POST'])
+@payments['require_payment'](PaymentRequirement(amount=10, description="Premium API access"))
+def premium_endpoint():
+ return {"result": "premium content"}
+
+if __name__ == '__main__':
+ app.run()
+```
+
+That's it! Your endpoint now requires 10 NANDA Points per request.
+
+## Features
+
+- **🚀 Zero-Config Setup**: Get started with `quick_setup()` in seconds
+- **🎯 Flask Integration**: Seamless `@require_payment` decorator
+- **📦 Client & Server Tools**: Both request creation and payment verification
+- **🔒 x402 Compliant**: Follows HTTP 402 Payment Required standard
+- **💎 Production Ready**: Type hints, error handling, comprehensive logging
+- **🧪 Easy Testing**: Built-in test utilities and examples
+
+## Installation
+
+```bash
+# Install the SDK
+pip install -r requirements.txt
+
+# Or install individually
+pip install flask requests python_a2a anthropic
+```
+
+## Core Concepts
+
+### 1. Payment Requirements
+Define what payment you need:
+
+```python
+from nanda_payments_sdk import PaymentRequirement
+
+# Simple requirement
+req = PaymentRequirement(amount=10, description="API access")
+
+# Advanced requirement
+req = PaymentRequirement(
+ amount=50,
+ description="Premium weather data",
+ recipient="weather-service", # Optional: override default recipient
+ timeout=60000 # Optional: payment timeout in ms
+)
+```
+
+### 2. Server-Side Protection
+Protect Flask routes with payments:
+
+```python
+from nanda_payments_sdk import require_payment, create_payment_config
+
+# Manual setup
+config = create_payment_config(
+ facilitator_url="http://localhost:3001",
+ agent_name="my-service"
+)
+
+@app.route('/api/data')
+@require_payment(PaymentRequirement(amount=25), config)
+def get_data():
+ return {"data": "valuable information"}
+```
+
+### 3. Client-Side Payment Creation
+Create payments to send with requests:
+
+```python
+from nanda_payments_sdk import create_and_encode_payment, send_paid_request
+
+# Create payment header
+payment_header = create_and_encode_payment(
+ from_agent="my-client",
+ to_agent="api-server",
+ amount=25,
+ facilitator_url="http://localhost:3001",
+ resource="http://api.example.com/data"
+)
+
+# Use with any HTTP client
+import requests
+response = requests.post(
+ "http://api.example.com/data",
+ headers={"X-PAYMENT": payment_header},
+ json={"query": "weather"}
+)
+
+# Or use built-in client
+response = send_paid_request(
+ url="http://api.example.com/data",
+ from_agent="my-client",
+ to_agent="api-server",
+ amount=25,
+ facilitator_url="http://localhost:3001",
+ data={"query": "weather"}
+)
+```
+
+## Complete Example: Weather API
+
+Here's a complete paid weather service:
+
+```python
+from flask import Flask, request, jsonify
+from nanda_payments_sdk import quick_setup, PaymentRequirement
+
+app = Flask(__name__)
+
+# Setup payments
+payments = quick_setup(
+ facilitator_url="http://localhost:3001",
+ agent_name="weather-api"
+)
+
+# Free tier: basic weather
+@app.route('/weather/basic', methods=['GET'])
+def basic_weather():
+ location = request.args.get('location', 'Unknown')
+ return {"weather": f"Sunny in {location}", "tier": "basic"}
+
+# Premium tier: detailed forecast (costs 10 NP)
+@app.route('/weather/premium', methods=['POST'])
+@payments['require_payment'](PaymentRequirement(
+ amount=10,
+ description="Premium weather forecast"
+))
+def premium_weather():
+ data = request.json
+ location = data.get('location', 'Unknown')
+ return {
+ "weather": f"Detailed forecast for {location}",
+ "temperature": 72,
+ "humidity": 65,
+ "wind_speed": 8,
+ "forecast": ["Sunny", "Partly cloudy", "Rain"],
+ "tier": "premium"
+ }
+
+# Ultra tier: AI-powered analysis (costs 50 NP)
+@app.route('/weather/ai', methods=['POST'])
+@payments['require_payment'](PaymentRequirement(
+ amount=50,
+ description="AI weather analysis"
+))
+def ai_weather():
+ data = request.json
+ location = data.get('location', 'Unknown')
+ return {
+ "weather": f"AI-powered analysis for {location}",
+ "insights": "Perfect day for outdoor activities",
+ "recommendations": ["Bring sunglasses", "Light jacket for evening"],
+ "confidence": 0.95,
+ "tier": "ai"
+ }
+
+if __name__ == '__main__':
+ app.run(debug=True)
+```
+
+### Testing the Weather API
+
+```python
+# Test script for weather API
+from nanda_payments_sdk import send_paid_request
+
+# Free endpoint - no payment needed
+import requests
+response = requests.get('http://localhost:5000/weather/basic?location=Boston')
+print("Basic:", response.json())
+
+# Premium endpoint - requires 10 NP
+response = send_paid_request(
+ url='http://localhost:5000/weather/premium',
+ from_agent='weather-client',
+ to_agent='weather-api',
+ amount=10,
+ facilitator_url='http://localhost:3001',
+ data={'location': 'Boston'}
+)
+print("Premium:", response.json())
+
+# AI endpoint - requires 50 NP
+response = send_paid_request(
+ url='http://localhost:5000/weather/ai',
+ from_agent='weather-client',
+ to_agent='weather-api',
+ amount=50,
+ facilitator_url='http://localhost:3001',
+ data={'location': 'Boston'}
+)
+print("AI:", response.json())
+```
+
+## Advanced Usage
+
+### Custom Error Handling
+
+```python
+from nanda_payments_sdk import NPPaymentError, NPVerificationError
+
+@app.route('/api/custom')
+@payments['require_payment'](PaymentRequirement(amount=10))
+def custom_endpoint():
+ try:
+ # Your business logic
+ return {"result": "success"}
+ except NPVerificationError as e:
+ # Payment verification failed
+ return {"error": f"Payment failed: {e.code}"}, 402
+ except NPPaymentError as e:
+ # General payment error
+ return {"error": str(e)}, 500
+```
+
+### Manual Payment Processing
+
+```python
+from nanda_payments_sdk import (
+ create_facilitator_client,
+ decode_payment,
+ create_payment_requirements
+)
+
+@app.route('/api/manual', methods=['POST'])
+def manual_payment():
+ # Get payment from header
+ x_payment = request.headers.get('X-PAYMENT')
+ if not x_payment:
+ return {"error": "Payment required"}, 402
+
+ # Decode payment
+ payment = decode_payment(x_payment)
+
+ # Create requirements
+ requirements = create_payment_requirements(
+ amount=15,
+ resource=request.url,
+ description="Manual processing",
+ pay_to="my-service",
+ facilitator_url="http://localhost:3001"
+ )
+
+ # Verify with facilitator
+ facilitator = create_facilitator_client("http://localhost:3001")
+ verification = facilitator.verify(payment, requirements)
+
+ if not verification['isValid']:
+ return {"error": verification['invalidReason']}, 402
+
+ # Process request
+ result = {"message": "Manually processed"}
+
+ # Settle payment
+ try:
+ settlement = facilitator.settle(payment, requirements)
+ print(f"Payment settled: {settlement['txId']}")
+ except Exception as e:
+ print(f"Settlement warning: {e}")
+
+ return result
+```
+
+### Environment Configuration
+
+```python
+# .env file
+FACILITATOR_URL=http://localhost:3001
+AGENT_NAME=my-service
+UI_PORT=5000
+DEBUG=True
+
+# Load in your app
+import os
+from dotenv import load_dotenv
+
+load_dotenv()
+
+payments = quick_setup(
+ facilitator_url=os.getenv('FACILITATOR_URL'),
+ agent_name=os.getenv('AGENT_NAME')
+)
+```
+
+## API Reference
+
+### Quick Setup
+
+```python
+def quick_setup(facilitator_url: str, agent_name: str) -> Dict[str, Any]
+```
+One-line setup returning configured payment tools.
+
+**Returns:**
+- `config`: Payment configuration
+- `facilitator`: Facilitator client
+- `require_payment`: Decorator factory
+- `create_payment_requirements`: Requirements builder
+
+### Payment Requirement
+
+```python
+@dataclass
+class PaymentRequirement:
+ amount: int # NANDA Points required
+ description: str = "Payment required" # Payment description
+ recipient: Optional[str] = None # Override recipient
+ timeout: int = 30000 # Timeout in milliseconds
+```
+
+### Decorator Usage
+
+```python
+@require_payment(requirement: PaymentRequirement, config: PaymentConfig)
+def protected_function():
+ # Your code here
+ pass
+```
+
+### Client Functions
+
+```python
+# Create payment payload
+payment = create_payment(
+ from_agent="client",
+ to_agent="server",
+ amount=10,
+ facilitator_url="http://localhost:3001"
+)
+
+# Encode for HTTP header
+header = encode_payment(payment)
+
+# One-step creation and encoding
+header = create_and_encode_payment(
+ from_agent="client",
+ to_agent="server",
+ amount=10,
+ facilitator_url="http://localhost:3001"
+)
+
+# Send HTTP request with payment
+response = send_paid_request(
+ url="http://api.example.com/endpoint",
+ from_agent="client",
+ to_agent="server",
+ amount=10,
+ facilitator_url="http://localhost:3001",
+ data={"key": "value"}
+)
+```
+
+### Error Types
+
+```python
+NPPaymentError # Base payment error
+NPVerificationError # Payment verification failed
+NPSettlementError # Payment settlement failed
+NPNetworkError # Facilitator communication failed
+```
+
+## Testing & Development
+
+### Run the Examples
+
+```bash
+# Start the example adapter
+python run_ui_agent_https_with_payments.py
+
+# Test payment flow
+python test_paid_flow.py
+
+# Test all endpoints
+python test_endpoints.py
+```
+
+### Test Without Payment (Expected 402)
+
+```bash
+curl -i -X POST http://localhost:5000/api/send \
+ -H "Content-Type: application/json" \
+ -d '{"message": "test", "client_id": "test"}'
+```
+
+**Expected Response:**
+```json
+{
+ "x402Version": 1,
+ "error": "X-PAYMENT header is required",
+ "accepts": [{
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "maxAmountRequired": "10",
+ "resource": "http://localhost:5000/api/send",
+ "description": "Send message to agent bridge",
+ "payTo": "classify-agent",
+ "asset": "NP"
+ }]
+}
+```
+
+### Test With Payment
+
+```python
+from nanda_payments_sdk import send_paid_request
+
+response = send_paid_request(
+ url="http://localhost:5000/api/send",
+ from_agent="claude-desktop",
+ to_agent="classify-agent",
+ amount=10,
+ facilitator_url="http://localhost:3001",
+ data={
+ "message": "Hello, paid world!",
+ "conversation_id": "test-conv",
+ "client_id": "claude-desktop"
+ }
+)
+
+print(f"Status: {response.status_code}")
+print(f"Response: {response.json()}")
+```
+
+## Prerequisites
+
+1. **Python 3.8+**
+2. **NANDA Points Facilitator** running on port 3001
+3. **MongoDB** for agent wallet storage
+4. **Agent accounts** with sufficient NANDA Points balance
+
+### Setup Facilitator
+
+```bash
+# In another terminal
+cd ../packages/facilitator
+npm install
+npm run dev
+```
+
+### Setup MongoDB & Agents
+
+```bash
+# Start MongoDB
+mongod
+
+# Seed agent accounts (if needed)
+cd ../packages/facilitator
+npm run seed
+```
+
+## Production Deployment
+
+### Environment Variables
+
+```bash
+export FACILITATOR_URL=https://facilitator.nanda.network
+export AGENT_NAME=my-production-service
+export UI_PORT=8080
+export DEBUG=False
+```
+
+### With Gunicorn
+
+```bash
+pip install gunicorn
+gunicorn -w 4 -b 0.0.0.0:8080 run_ui_agent_https_with_payments:app
+```
+
+### Docker Deployment
+
+```dockerfile
+FROM python:3.11-slim
+
+WORKDIR /app
+COPY requirements.txt .
+RUN pip install -r requirements.txt
+
+COPY . .
+EXPOSE 5000
+
+CMD ["python", "run_ui_agent_https_with_payments.py"]
+```
+
+## Troubleshooting
+
+### Common Issues
+
+**"Facilitator connection failed"**
+```python
+# Check facilitator status
+from nanda_payments_sdk import create_facilitator_client
+
+facilitator = create_facilitator_client("http://localhost:3001")
+try:
+ status = facilitator.supported()
+ print("✅ Facilitator connected:", status)
+except Exception as e:
+ print("❌ Facilitator error:", e)
+```
+
+**"Agent not found"**
+```bash
+# Check available agents in database
+mongo
+> use nanda_points
+> db.agents.find({}, {name: 1, balance: 1})
+```
+
+**"Insufficient balance"**
+```python
+# The facilitator manages balances automatically
+# Ensure your agents have been seeded with initial balance
+```
+
+### Debug Mode
+
+```python
+import logging
+logging.basicConfig(level=logging.DEBUG)
+
+# Now all payment operations will show detailed logs
+```
+
+### Test Without Facilitator
+
+```python
+# The SDK gracefully handles facilitator unavailability
+# Protected routes will return HTTP 500 instead of 402
+```
+
+## Examples & Use Cases
+
+### API Monetization
+Transform any REST API into a paid service with per-endpoint pricing.
+
+### Content Paywalls
+Protect premium content, articles, or media with micro-payments.
+
+### Computational Services
+Charge for expensive operations like AI inference, data processing, or analysis.
+
+### Rate Limiting
+Use payments as a natural rate limiting mechanism.
+
+### Freemium Models
+Offer free tiers alongside paid premium features.
+
+## Contributing
+
+1. Ensure all code passes linting: `python -m flake8 *.py`
+2. Test payment flows thoroughly
+3. Update documentation for API changes
+4. Maintain backward compatibility
+
+## License
+
+Same license as the NANDA Points project.
+
+---
+
+**Ready to monetize your Python APIs? Start with `quick_setup()` and see the magic happen! 🚀**
\ No newline at end of file
diff --git a/python-adapter/agent_bridge.py b/python-adapter/agent_bridge.py
new file mode 100644
index 0000000..63a1b7d
--- /dev/null
+++ b/python-adapter/agent_bridge.py
@@ -0,0 +1,204 @@
+import os
+import json
+import time
+import asyncio
+import logging
+from python_a2a import run_server, AgentBridge as BaseAgentBridge
+import requests
+from anthropic import Anthropic
+
+
+class AgentBridge(BaseAgentBridge):
+ def __init__(self, name="agent_bridge", registry_url=None, claude_api_key=None):
+ super().__init__(name)
+ self.registry_url = registry_url or os.getenv(
+ "REGISTRY_URL", "http://localhost:8000"
+ )
+ self.claude_client = None
+
+ if claude_api_key or os.getenv("CLAUDE_API_KEY"):
+ self.claude_client = Anthropic(
+ api_key=claude_api_key or os.getenv("CLAUDE_API_KEY")
+ )
+
+ self.conversations = {}
+
+ # Setup logging
+ logging.basicConfig(level=logging.INFO)
+ self.logger = logging.getLogger(__name__)
+
+ async def handle_message(self, message, metadata=None):
+ """Main message handling logic"""
+ try:
+ sender = metadata.get("sender", "unknown") if metadata else "unknown"
+ conversation_id = metadata.get("conversation_id") if metadata else None
+
+ self.logger.info(f"Received message from {sender}: {message[:100]}...")
+
+ # Store conversation
+ if conversation_id:
+ if conversation_id not in self.conversations:
+ self.conversations[conversation_id] = []
+
+ self.conversations[conversation_id].append(
+ {
+ "timestamp": time.time(),
+ "sender": sender,
+ "message": message,
+ "metadata": metadata,
+ }
+ )
+
+ # Process message based on type
+ if message.startswith("/mcp"):
+ return await self.handle_mcp_query(message, metadata)
+ elif message.startswith("/claude"):
+ return await self.handle_claude_query(message, metadata)
+ elif message.startswith("/send"):
+ return await self.handle_send_to_agent(message, metadata)
+ else:
+ return await self.improve_message(message, metadata)
+
+ except Exception as e:
+ self.logger.error(f"Error handling message: {e}")
+ return f"Error processing message: {str(e)}"
+
+ async def improve_message(self, message, metadata=None):
+ """Improve message using Claude AI or default processing"""
+ try:
+ if self.claude_client:
+ response = self.claude_client.messages.create(
+ model="claude-3-sonnet-20240229",
+ max_tokens=1000,
+ messages=[
+ {
+ "role": "user",
+ "content": f"Please improve this message while maintaining its meaning: {message}",
+ }
+ ],
+ )
+ return response.content[0].text
+ else:
+ # Default improvement without Claude
+ return f"Processed: {message}"
+
+ except Exception as e:
+ self.logger.error(f"Error improving message: {e}")
+ return f"Default response: {message}"
+
+ async def handle_mcp_query(self, message, metadata=None):
+ """Handle MCP server queries"""
+ try:
+ # Extract MCP command
+ command = message[4:].strip() # Remove '/mcp'
+
+ # This would normally query an MCP server
+ # For now, return a mock response
+ return f"MCP Query Result: {command}"
+
+ except Exception as e:
+ return f"MCP Error: {str(e)}"
+
+ async def handle_claude_query(self, message, metadata=None):
+ """Handle direct Claude queries"""
+ try:
+ if not self.claude_client:
+ return "Claude API not configured"
+
+ query = message[7:].strip() # Remove '/claude'
+
+ response = self.claude_client.messages.create(
+ model="claude-3-sonnet-20240229",
+ max_tokens=1500,
+ messages=[{"role": "user", "content": query}],
+ )
+
+ return response.content[0].text
+
+ except Exception as e:
+ return f"Claude Error: {str(e)}"
+
+ async def handle_send_to_agent(self, message, metadata=None):
+ """Send message to specific agent"""
+ try:
+ parts = message[5:].strip().split(" ", 1) # Remove '/send'
+ if len(parts) < 2:
+ return "Usage: /send "
+
+ agent_name, agent_message = parts
+
+ # This would normally send to the specified agent
+ # For now, return a mock response
+ return f"Message sent to {agent_name}: {agent_message}"
+
+ except Exception as e:
+ return f"Send Error: {str(e)}"
+
+ async def register_with_registry(self):
+ """Register this agent with the registry"""
+ try:
+ registration_data = {
+ "name": self.name,
+ "url": f"http://localhost:{self.port}",
+ "capabilities": ["message_processing", "claude_ai", "mcp_queries"],
+ "status": "active",
+ }
+
+ response = requests.post(
+ f"{self.registry_url}/register", json=registration_data, timeout=5
+ )
+
+ if response.status_code == 200:
+ self.logger.info(
+ f"Successfully registered with registry: {self.registry_url}"
+ )
+ else:
+ self.logger.warning(
+ f"Registry registration failed: {response.status_code}"
+ )
+
+ except Exception as e:
+ self.logger.warning(f"Could not register with registry: {e}")
+
+ def get_conversation_history(self, conversation_id):
+ """Get conversation history"""
+ return self.conversations.get(conversation_id, [])
+
+ def get_all_conversations(self):
+ """Get all conversation IDs"""
+ return list(self.conversations.keys())
+
+
+def create_agent_bridge(name="agent_bridge", port=3000, **kwargs):
+ """Factory function to create an agent bridge"""
+ bridge = AgentBridge(name, **kwargs)
+ bridge.port = port
+ return bridge
+
+
+def main():
+ # Configuration from environment
+ name = os.getenv("AGENT_NAME", "agent_bridge")
+ port = int(os.getenv("AGENT_PORT", 3000))
+ registry_url = os.getenv("REGISTRY_URL")
+ claude_api_key = os.getenv("CLAUDE_API_KEY")
+
+ # Create and configure agent bridge
+ bridge = create_agent_bridge(
+ name=name, port=port, registry_url=registry_url, claude_api_key=claude_api_key
+ )
+
+ print(f"Starting Agent Bridge: {name}")
+ print(f"Port: {port}")
+ print(f"Registry: {registry_url}")
+ print(f"Claude API: {'Configured' if claude_api_key else 'Not configured'}")
+
+ # Register with registry in background
+ asyncio.create_task(bridge.register_with_registry())
+
+ # Start the server
+ run_server(bridge, port=port)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python-adapter/nanda_payments_sdk.py b/python-adapter/nanda_payments_sdk.py
new file mode 100644
index 0000000..8e739f1
--- /dev/null
+++ b/python-adapter/nanda_payments_sdk.py
@@ -0,0 +1,797 @@
+"""
+NANDA Points Python SDK
+
+A production-ready Python SDK for integrating NANDA Points payments into
+applications.
+Provides both server-side (Flask decorators) and client-side (payment creation)
+capabilities following the x402 payment protocol.
+
+Features:
+- Server-side payment verification and settlement
+- Client-side payment creation and encoding
+- Flask integration with decorators
+- Type-safe interfaces with full IntelliSense support
+- Comprehensive error handling
+
+Example:
+ # Server-side payment protection
+ from nanda_payments_sdk import require_payment, PaymentRequirement
+
+ @app.route('/api/premium')
+ @require_payment(PaymentRequirement(amount=10, description="Premium API"))
+ def premium_endpoint():
+ return {"data": "premium content"}
+
+ # Client-side payment creation
+ from nanda_payments_sdk import send_paid_request
+
+ response = send_paid_request(
+ url="http://localhost:5000/api/premium",
+ from_agent="my-agent",
+ to_agent="server-agent",
+ amount=10,
+ facilitator_url="http://localhost:3001"
+ )
+"""
+
+import base64
+import json
+import time
+import uuid
+from dataclasses import dataclass, field
+from functools import wraps
+from typing import Any, Dict, Optional
+
+import requests
+from flask import jsonify, request
+
+
+# =============================================================================
+# Core Data Structures
+# =============================================================================
+
+
+@dataclass
+class PaymentRequirement:
+ """Configuration for payment requirements on protected endpoints.
+
+ Args:
+ amount: NANDA Points required for access
+ description: Human-readable description of what the payment covers
+ recipient: Optional specific recipient (defaults to configured agent)
+ timeout: Payment timeout in milliseconds
+ """
+
+ amount: int
+ description: str = "Payment required"
+ recipient: Optional[str] = None
+ timeout: int = 30000
+
+
+@dataclass
+class PaymentConfig:
+ """Configuration for NANDA Points integration.
+
+ Args:
+ facilitator_url: URL of the NANDA Points facilitator service
+ agent_name: Name of this agent for payment processing
+ timeout: Default timeout for facilitator requests in milliseconds
+ retry_count: Number of retries for failed requests
+ retry_delay: Delay between retries in milliseconds
+ """
+
+ facilitator_url: str
+ agent_name: str
+ timeout: int = 30000
+ retry_count: int = 3
+ retry_delay: int = 1000
+
+
+@dataclass
+class PaymentPayload:
+ """x402 compliant payment payload structure.
+
+ Represents a payment according to the x402 protocol specification.
+ All fields follow the x402 naming conventions.
+ """
+
+ x402_version: int = 1
+ scheme: str = "nanda-points"
+ network: str = "nanda-network"
+ pay_to: str = ""
+ amount: str = ""
+ from_agent: str = ""
+ tx_id: str = ""
+ timestamp: int = 0
+ extra: Optional[Dict[str, Any]] = field(default_factory=dict)
+
+
+@dataclass
+class PaymentRequirements:
+ """x402 compliant payment requirements structure.
+
+ Specifies what payment is required for a particular resource.
+ Used in HTTP 402 responses and facilitator verification.
+ """
+
+ scheme: str = "nanda-points"
+ network: str = "nanda-network"
+ max_amount_required: str = ""
+ resource: str = ""
+ description: str = ""
+ mime_type: str = "application/json"
+ pay_to: str = ""
+ max_timeout_seconds: int = 60
+ asset: str = "NP"
+ extra: Optional[Dict[str, Any]] = field(default_factory=dict)
+
+
+# =============================================================================
+# Exception Classes
+# =============================================================================
+
+
+class NPPaymentError(Exception):
+ """Base exception for NANDA Points payment errors.
+
+ Args:
+ message: Error description
+ code: Error code for programmatic handling
+ details: Additional error context
+ """
+
+ def __init__(self, message: str, code: str = "PAYMENT_ERROR", details: Any = None):
+ super().__init__(message)
+ self.code = code
+ self.details = details
+
+
+class NPVerificationError(NPPaymentError):
+ """Payment verification failed."""
+
+ def __init__(self, message: str, details: Any = None):
+ super().__init__(message, "VERIFICATION_FAILED", details)
+
+
+class NPSettlementError(NPPaymentError):
+ """Payment settlement failed."""
+
+ def __init__(self, message: str, details: Any = None):
+ super().__init__(message, "SETTLEMENT_FAILED", details)
+
+
+class NPNetworkError(NPPaymentError):
+ """Network communication error."""
+
+ def __init__(self, message: str, details: Any = None):
+ super().__init__(message, "NETWORK_ERROR", details)
+
+
+# =============================================================================
+# Facilitator Client
+# =============================================================================
+
+
+class FacilitatorClient:
+ """Client for communicating with NANDA Points facilitator service.
+
+ Handles verification and settlement of payments through the facilitator's
+ REST API endpoints.
+
+ Args:
+ facilitator_url: Base URL of the facilitator service
+ """
+
+ def __init__(self, facilitator_url: str):
+ self.facilitator_url = facilitator_url.rstrip("/")
+ self.session = requests.Session()
+
+ def verify(
+ self, payment: PaymentPayload, requirements: PaymentRequirements
+ ) -> Dict[str, Any]:
+ """Verify payment against requirements without settling.
+
+ Args:
+ payment: Payment payload to verify
+ requirements: Payment requirements to verify against
+
+ Returns:
+ Verification result from facilitator
+
+ Raises:
+ NPNetworkError: If communication with facilitator fails
+ """
+ try:
+ response = self.session.post(
+ f"{self.facilitator_url}/verify",
+ json={
+ "payment": self._payload_to_dict(payment),
+ "paymentRequirements": self._requirements_to_dict(requirements),
+ },
+ timeout=10,
+ )
+ response.raise_for_status()
+ return response.json()
+ except requests.RequestException as e:
+ raise NPNetworkError(f"Failed to verify payment: {e}")
+
+ def settle(
+ self, payment: PaymentPayload, requirements: PaymentRequirements
+ ) -> Dict[str, Any]:
+ """Verify and settle payment.
+
+ Args:
+ payment: Payment payload to settle
+ requirements: Payment requirements
+
+ Returns:
+ Settlement result from facilitator
+
+ Raises:
+ NPNetworkError: If communication with facilitator fails
+ """
+ try:
+ response = self.session.post(
+ f"{self.facilitator_url}/settle",
+ json={
+ "payment": self._payload_to_dict(payment),
+ "paymentRequirements": self._requirements_to_dict(requirements),
+ },
+ timeout=10,
+ )
+ response.raise_for_status()
+ return response.json()
+ except requests.RequestException as e:
+ raise NPNetworkError(f"Failed to settle payment: {e}")
+
+ def supported(self) -> Dict[str, Any]:
+ """Get supported payment schemes from facilitator.
+
+ Returns:
+ Supported payment schemes information
+
+ Raises:
+ NPNetworkError: If communication with facilitator fails
+ """
+ try:
+ response = self.session.get(f"{self.facilitator_url}/supported", timeout=10)
+ response.raise_for_status()
+ return response.json()
+ except requests.RequestException as e:
+ raise NPNetworkError(f"Failed to get supported schemes: {e}")
+
+ def _payload_to_dict(self, payment: PaymentPayload) -> Dict[str, Any]:
+ """Convert PaymentPayload to facilitator API format."""
+ return {
+ "x402Version": payment.x402_version,
+ "scheme": payment.scheme,
+ "network": payment.network,
+ "payTo": payment.pay_to,
+ "amount": payment.amount,
+ "from": payment.from_agent,
+ "txId": payment.tx_id,
+ "timestamp": payment.timestamp,
+ "extra": payment.extra or {},
+ }
+
+ def _requirements_to_dict(self, req: PaymentRequirements) -> Dict[str, Any]:
+ """Convert PaymentRequirements to facilitator API format."""
+ return {
+ "scheme": req.scheme,
+ "network": req.network,
+ "maxAmountRequired": req.max_amount_required,
+ "resource": req.resource,
+ "description": req.description,
+ "mimeType": req.mime_type,
+ "payTo": req.pay_to,
+ "maxTimeoutSeconds": req.max_timeout_seconds,
+ "asset": req.asset,
+ "extra": req.extra or {},
+ }
+
+
+# =============================================================================
+# Configuration and Setup Functions
+# =============================================================================
+
+
+def create_payment_config(
+ facilitator_url: str, agent_name: str, **kwargs
+) -> PaymentConfig:
+ """Create payment configuration with defaults.
+
+ Args:
+ facilitator_url: URL of the NANDA Points facilitator
+ agent_name: Name of this agent
+ **kwargs: Additional configuration options
+
+ Returns:
+ Configured PaymentConfig instance
+ """
+ return PaymentConfig(
+ facilitator_url=facilitator_url,
+ agent_name=agent_name,
+ timeout=kwargs.get("timeout", 30000),
+ retry_count=kwargs.get("retry_count", 3),
+ retry_delay=kwargs.get("retry_delay", 1000),
+ )
+
+
+def create_facilitator_client(facilitator_url: str) -> FacilitatorClient:
+ """Create facilitator client instance.
+
+ Args:
+ facilitator_url: URL of the NANDA Points facilitator
+
+ Returns:
+ Configured FacilitatorClient instance
+ """
+ return FacilitatorClient(facilitator_url)
+
+
+def create_payment_requirements(
+ amount: int,
+ resource: str,
+ description: str,
+ pay_to: str,
+ facilitator_url: str,
+ **kwargs,
+) -> PaymentRequirements:
+ """Create payment requirements object.
+
+ Args:
+ amount: NANDA Points required
+ resource: Resource being protected
+ description: Payment description
+ pay_to: Payment recipient
+ facilitator_url: Facilitator URL
+ **kwargs: Additional requirements options
+
+ Returns:
+ Configured PaymentRequirements instance
+ """
+ return PaymentRequirements(
+ max_amount_required=str(amount),
+ resource=resource,
+ description=description,
+ pay_to=pay_to,
+ mime_type=kwargs.get("mime_type", "application/json"),
+ max_timeout_seconds=kwargs.get("max_timeout_seconds", 60),
+ extra={"facilitatorUrl": facilitator_url, **kwargs.get("extra", {})},
+ )
+
+
+# =============================================================================
+# Payment Processing Functions
+# =============================================================================
+
+
+def decode_payment(x_payment_header: str) -> PaymentPayload:
+ """Decode payment from X-PAYMENT header.
+
+ Args:
+ x_payment_header: Base64 encoded payment from HTTP header
+
+ Returns:
+ Decoded PaymentPayload
+
+ Raises:
+ NPPaymentError: If payment cannot be decoded
+ """
+ try:
+ decoded_bytes = base64.b64decode(x_payment_header)
+ payment_data = json.loads(decoded_bytes.decode("utf-8"))
+
+ return PaymentPayload(
+ x402_version=payment_data.get("x402Version", 1),
+ scheme=payment_data.get("scheme", "nanda-points"),
+ network=payment_data.get("network", "nanda-network"),
+ pay_to=payment_data.get("payTo", ""),
+ amount=payment_data.get("amount", ""),
+ from_agent=payment_data.get("from", ""),
+ tx_id=payment_data.get("txId", ""),
+ timestamp=payment_data.get("timestamp", 0),
+ extra=payment_data.get("extra"),
+ )
+ except Exception as e:
+ raise NPPaymentError(f"Invalid payment header: {e}", "INVALID_PAYMENT")
+
+
+def require_payment(requirement: PaymentRequirement, config: PaymentConfig):
+ """Flask decorator to require payment for a route.
+
+ Automatically handles payment verification and settlement for Flask routes.
+ Returns HTTP 402 with payment requirements if no valid payment provided.
+
+ Args:
+ requirement: Payment requirement configuration
+ config: Payment system configuration
+
+ Returns:
+ Flask route decorator
+
+ Example:
+ @app.route('/api/premium')
+ @require_payment(PaymentRequirement(amount=10), config)
+ def premium_endpoint():
+ return {"data": "premium content"}
+ """
+
+ def decorator(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ # Get payment header
+ x_payment = request.headers.get("X-PAYMENT")
+
+ if not x_payment:
+ # Return HTTP 402 with payment requirements
+ requirements = create_payment_requirements(
+ amount=requirement.amount,
+ resource=request.url,
+ description=requirement.description,
+ pay_to=requirement.recipient or config.agent_name,
+ facilitator_url=config.facilitator_url,
+ )
+
+ return (
+ jsonify(
+ {
+ "x402Version": 1,
+ "error": "X-PAYMENT header is required",
+ "accepts": [
+ {
+ "scheme": requirements.scheme,
+ "network": requirements.network,
+ "maxAmountRequired": requirements.max_amount_required,
+ "resource": requirements.resource,
+ "description": requirements.description,
+ "mimeType": requirements.mime_type,
+ "payTo": requirements.pay_to,
+ "maxTimeoutSeconds": requirements.max_timeout_seconds,
+ "asset": requirements.asset,
+ "extra": requirements.extra,
+ }
+ ],
+ }
+ ),
+ 402,
+ )
+
+ try:
+ # Decode and verify payment
+ payment = decode_payment(x_payment)
+ facilitator = create_facilitator_client(config.facilitator_url)
+
+ requirements = create_payment_requirements(
+ amount=requirement.amount,
+ resource=request.url,
+ description=requirement.description,
+ pay_to=requirement.recipient or config.agent_name,
+ facilitator_url=config.facilitator_url,
+ )
+
+ # Verify payment
+ verification = facilitator.verify(payment, requirements)
+
+ if not verification.get("isValid"):
+ return (
+ jsonify(
+ {
+ "x402Version": 1,
+ "error": verification.get(
+ "invalidReason", "Payment verification failed"
+ ),
+ "accepts": [
+ {
+ "scheme": requirements.scheme,
+ "network": requirements.network,
+ "maxAmountRequired": requirements.max_amount_required,
+ "resource": requirements.resource,
+ "description": requirements.description,
+ "mimeType": requirements.mime_type,
+ "payTo": requirements.pay_to,
+ "maxTimeoutSeconds": requirements.max_timeout_seconds,
+ "asset": requirements.asset,
+ "extra": requirements.extra,
+ }
+ ],
+ }
+ ),
+ 402,
+ )
+
+ # Execute the original function
+ result = func(*args, **kwargs)
+
+ # Settle payment after successful execution
+ try:
+ settlement = facilitator.settle(payment, requirements)
+ print(f"✅ Payment settled: {settlement.get('txId')}")
+ except Exception as e:
+ print(f"⚠️ Settlement warning: {e}")
+ # Don't fail the response for settlement issues
+
+ return result
+
+ except NPPaymentError as e:
+ return (
+ jsonify(
+ {
+ "x402Version": 1,
+ "error": str(e),
+ "code": e.code,
+ "details": e.details,
+ }
+ ),
+ 402,
+ )
+
+ except Exception as e:
+ return jsonify({"error": f"Payment processing failed: {str(e)}"}), 500
+
+ return wrapper
+
+ return decorator
+
+
+# =============================================================================
+# Client-Side Payment Functions
+# =============================================================================
+
+
+def create_payment(
+ from_agent: str,
+ to_agent: str,
+ amount: int,
+ facilitator_url: str,
+ resource: str = "",
+ description: str = "NANDA Points payment",
+) -> PaymentPayload:
+ """Create a payment payload for client-side use.
+
+ Args:
+ from_agent: Paying agent name
+ to_agent: Receiving agent name
+ amount: Amount in NANDA Points
+ facilitator_url: Facilitator URL
+ resource: Optional resource being paid for
+ description: Payment description
+
+ Returns:
+ PaymentPayload ready for encoding
+ """
+ return PaymentPayload(
+ x402_version=1,
+ scheme="nanda-points",
+ network="nanda-network",
+ pay_to=to_agent,
+ amount=str(amount),
+ from_agent=from_agent,
+ tx_id=str(uuid.uuid4()),
+ timestamp=int(time.time() * 1000),
+ extra={
+ "facilitatorUrl": facilitator_url,
+ "resource": resource,
+ "description": description,
+ },
+ )
+
+
+def encode_payment(payment: PaymentPayload) -> str:
+ """Encode payment payload as base64 for X-PAYMENT header.
+
+ Args:
+ payment: PaymentPayload to encode
+
+ Returns:
+ Base64 encoded payment string for X-PAYMENT header
+ """
+ # Convert PaymentPayload to dict with correct field names for x402 protocol
+ payment_dict = {
+ "x402Version": payment.x402_version,
+ "scheme": payment.scheme,
+ "network": payment.network,
+ "payTo": payment.pay_to,
+ "amount": payment.amount,
+ "from": payment.from_agent,
+ "txId": payment.tx_id,
+ "timestamp": payment.timestamp,
+ "extra": payment.extra or {},
+ }
+
+ # Serialize to JSON and encode as base64
+ json_str = json.dumps(payment_dict, separators=(",", ":"))
+ return base64.b64encode(json_str.encode("utf-8")).decode("utf-8")
+
+
+def create_and_encode_payment(
+ from_agent: str,
+ to_agent: str,
+ amount: int,
+ facilitator_url: str,
+ resource: str = "",
+ description: str = "NANDA Points payment",
+) -> str:
+ """Convenience function to create and encode payment in one step.
+
+ Args:
+ from_agent: Paying agent name
+ to_agent: Receiving agent name
+ amount: Amount in NANDA Points
+ facilitator_url: Facilitator URL
+ resource: Optional resource being paid for
+ description: Payment description
+
+ Returns:
+ Base64 encoded payment string ready for X-PAYMENT header
+ """
+ payment = create_payment(
+ from_agent, to_agent, amount, facilitator_url, resource, description
+ )
+ return encode_payment(payment)
+
+
+def send_paid_request(
+ url: str,
+ from_agent: str,
+ to_agent: str,
+ amount: int,
+ facilitator_url: str,
+ data: Optional[Dict[str, Any]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ method: str = "POST",
+) -> requests.Response:
+ """Send HTTP request with NANDA Points payment.
+
+ Args:
+ url: Target URL
+ from_agent: Paying agent name
+ to_agent: Receiving agent name
+ amount: Payment amount in NANDA Points
+ facilitator_url: Facilitator URL
+ data: Request body data
+ headers: Additional headers
+ method: HTTP method
+
+ Returns:
+ Response object
+
+ Example:
+ response = send_paid_request(
+ url="http://localhost:5000/api/premium",
+ from_agent="my-agent",
+ to_agent="server-agent",
+ amount=10,
+ facilitator_url="http://localhost:3001",
+ data={"message": "Hello, paid world!"}
+ )
+ """
+ # Create payment
+ payment_header = create_and_encode_payment(
+ from_agent=from_agent,
+ to_agent=to_agent,
+ amount=amount,
+ facilitator_url=facilitator_url,
+ resource=url,
+ description=f"Payment for {method} {url}",
+ )
+
+ # Prepare headers
+ request_headers = {"Content-Type": "application/json", "X-PAYMENT": payment_header}
+ if headers:
+ request_headers.update(headers)
+
+ # Send request
+ session = requests.Session()
+ if method.upper() == "POST":
+ return session.post(url, json=data, headers=request_headers, timeout=30)
+ elif method.upper() == "GET":
+ return session.get(url, headers=request_headers, timeout=30)
+ else:
+ return session.request(
+ method, url, json=data, headers=request_headers, timeout=30
+ )
+
+
+# =============================================================================
+# Quick Setup Functions
+# =============================================================================
+
+
+def quick_setup(facilitator_url: str, agent_name: str) -> Dict[str, Any]:
+ """Quick setup for Python applications.
+
+ Provides a convenient way to initialize NANDA Points integration
+ with all necessary components.
+
+ Args:
+ facilitator_url: URL of the NANDA Points facilitator
+ agent_name: Name of this agent
+
+ Returns:
+ Dictionary containing configured components:
+ - config: PaymentConfig instance
+ - facilitator: FacilitatorClient instance
+ - require_payment: Configured decorator function
+ - create_payment_requirements: Configured requirements function
+
+ Example:
+ payments = quick_setup("http://localhost:3001", "my-agent")
+
+ @app.route('/api/premium')
+ @payments['require_payment'](PaymentRequirement(amount=10))
+ def premium_endpoint():
+ return {"data": "premium content"}
+ """
+ config = create_payment_config(facilitator_url, agent_name)
+ facilitator = create_facilitator_client(facilitator_url)
+
+ def create_requirement_decorator(requirement: PaymentRequirement):
+ return require_payment(requirement, config)
+
+ return {
+ "config": config,
+ "facilitator": facilitator,
+ "require_payment": create_requirement_decorator,
+ "create_payment_requirements": lambda **kwargs: create_payment_requirements(
+ pay_to=agent_name, facilitator_url=facilitator_url, **kwargs
+ ),
+ }
+
+
+# =============================================================================
+# Module Exports
+# =============================================================================
+
+__all__ = [
+ # Core data structures
+ "PaymentRequirement",
+ "PaymentConfig",
+ "PaymentPayload",
+ "PaymentRequirements",
+ # Exception classes
+ "NPPaymentError",
+ "NPVerificationError",
+ "NPSettlementError",
+ "NPNetworkError",
+ # Client classes
+ "FacilitatorClient",
+ # Configuration functions
+ "create_payment_config",
+ "create_facilitator_client",
+ "create_payment_requirements",
+ # Server-side functions
+ "decode_payment",
+ "require_payment",
+ # Client-side functions
+ "create_payment",
+ "encode_payment",
+ "create_and_encode_payment",
+ "send_paid_request",
+ # Setup functions
+ "quick_setup",
+]
+
+
+# =============================================================================
+# Example Usage and Testing
+# =============================================================================
+
+if __name__ == "__main__":
+ # Test the SDK
+ config = create_payment_config(
+ facilitator_url="http://localhost:3001", agent_name="test-adapter"
+ )
+
+ facilitator = create_facilitator_client(config.facilitator_url)
+
+ try:
+ supported = facilitator.supported()
+ print("✅ Facilitator connection successful")
+ print(f" Supported schemes: {supported}")
+ except Exception as e:
+ print(f"❌ Facilitator connection failed: {e}")
+
+ print("\n📦 NANDA Points Python SDK loaded successfully!")
+ print(f" Facilitator: {config.facilitator_url}")
+ print(f" Agent: {config.agent_name}")
diff --git a/python-adapter/requirements.txt b/python-adapter/requirements.txt
new file mode 100644
index 0000000..a34a22e
--- /dev/null
+++ b/python-adapter/requirements.txt
@@ -0,0 +1,21 @@
+# NANDA Adapter with Payments - Python Dependencies
+
+# Core web framework
+flask==3.0.0
+flask-cors==4.0.0
+
+# HTTP client for facilitator communication
+requests==2.31.0
+
+# Agent-to-Agent communication (this would need to be installed separately)
+# python_a2a
+
+# Development and testing
+python-dotenv==1.0.0
+
+# Optional: for production deployments
+gunicorn==21.2.0
+waitress==2.1.2
+
+# Optional: for enhanced logging
+structlog==23.2.0
\ No newline at end of file
diff --git a/python-adapter/run_ui_agent_https.py b/python-adapter/run_ui_agent_https.py
new file mode 100644
index 0000000..54bd30a
--- /dev/null
+++ b/python-adapter/run_ui_agent_https.py
@@ -0,0 +1,229 @@
+import os
+import json
+import uuid
+import threading
+from flask import Flask, request, jsonify, Response
+from flask_cors import CORS
+from python_a2a import A2AClient
+import time
+
+app = Flask(__name__)
+CORS(app)
+
+# Global variables
+messages = []
+latest_message = ""
+client_map = {}
+
+
+def get_agent_port():
+ return int(os.getenv("AGENT_PORT", 3000))
+
+
+def get_ui_port():
+ return int(os.getenv("UI_PORT", 5000))
+
+
+def get_agent_id():
+ return os.getenv("AGENT_ID", "default_agent")
+
+
+def get_agent_url():
+ port = get_agent_port()
+ return f"http://localhost:{port}"
+
+
+@app.route("/api/health", methods=["GET"])
+def health_check():
+ return jsonify(
+ {
+ "status": "healthy",
+ "timestamp": time.time(),
+ "agent_port": get_agent_port(),
+ "ui_port": get_ui_port(),
+ }
+ )
+
+
+@app.route("/api/agents/list", methods=["GET"])
+def list_agents():
+ # This would normally fetch from a registry
+ return jsonify(
+ {
+ "agents": [
+ {"name": "local_agent", "url": get_agent_url(), "status": "active"}
+ ]
+ }
+ )
+
+
+@app.route("/api/send", methods=["POST"])
+def send_message():
+ global latest_message
+
+ try:
+ data = request.get_json()
+ message = data.get("message")
+ conversation_id = data.get("conversation_id", str(uuid.uuid4()))
+ client_id = data.get("client_id", "default_client")
+
+ if not message:
+ return jsonify({"error": "Message is required"}), 400
+
+ # Create A2A client for communication with agent bridge
+ agent_url = get_agent_url()
+ client = A2AClient(agent_url)
+
+ # Prepare metadata
+ metadata = {
+ "conversation_id": conversation_id,
+ "client_id": client_id,
+ "timestamp": time.time(),
+ "agent_id": get_agent_id(),
+ }
+
+ # Send message to agent bridge
+ response = client.send_message(message, metadata)
+
+ # Store message
+ message_record = {
+ "id": str(uuid.uuid4()),
+ "message": message,
+ "response": response,
+ "conversation_id": conversation_id,
+ "client_id": client_id,
+ "timestamp": time.time(),
+ "agent_id": get_agent_id(),
+ }
+
+ messages.append(message_record)
+ latest_message = response
+
+ # Store client mapping
+ client_map[client_id] = {
+ "conversation_id": conversation_id,
+ "last_activity": time.time(),
+ }
+
+ return jsonify(
+ {
+ "response": response,
+ "conversation_id": conversation_id,
+ "agent_id": get_agent_id(),
+ "message_id": message_record["id"],
+ "timestamp": message_record["timestamp"],
+ }
+ )
+
+ except Exception as e:
+ return jsonify({"error": str(e)}), 500
+
+
+@app.route("/api/receive_message", methods=["POST"])
+def receive_message():
+ global latest_message
+
+ try:
+ data = request.get_json()
+ message = data.get("message")
+ conversation_id = data.get("conversation_id")
+ client_id = data.get("client_id", "agent_bridge")
+
+ if not message:
+ return jsonify({"error": "Message is required"}), 400
+
+ # Store received message
+ message_record = {
+ "id": str(uuid.uuid4()),
+ "message": message,
+ "conversation_id": conversation_id,
+ "client_id": client_id,
+ "timestamp": time.time(),
+ "type": "received",
+ }
+
+ messages.append(message_record)
+ latest_message = message
+
+ return jsonify(
+ {
+ "status": "received",
+ "message_id": message_record["id"],
+ "timestamp": message_record["timestamp"],
+ }
+ )
+
+ except Exception as e:
+ return jsonify({"error": str(e)}), 500
+
+
+@app.route("/api/render", methods=["GET"])
+def render_latest():
+ return jsonify({"message": latest_message, "timestamp": time.time()})
+
+
+@app.route("/api/messages/stream", methods=["GET"])
+def stream_messages():
+ def generate():
+ while True:
+ if messages:
+ latest = messages[-1]
+ yield f"data: {json.dumps(latest)}\n\n"
+ time.sleep(1)
+
+ return Response(generate(), mimetype="text/event-stream")
+
+
+@app.route("/api/messages", methods=["GET"])
+def get_messages():
+ limit = request.args.get("limit", 50, type=int)
+ offset = request.args.get("offset", 0, type=int)
+
+ paginated_messages = messages[offset : offset + limit]
+
+ return jsonify(
+ {
+ "messages": paginated_messages,
+ "total": len(messages),
+ "limit": limit,
+ "offset": offset,
+ }
+ )
+
+
+@app.route("/api/conversations/", methods=["GET"])
+def get_conversation(conversation_id):
+ conversation_messages = [
+ m for m in messages if m.get("conversation_id") == conversation_id
+ ]
+
+ return jsonify(
+ {
+ "conversation_id": conversation_id,
+ "messages": conversation_messages,
+ "count": len(conversation_messages),
+ }
+ )
+
+
+def run_app():
+ port = get_ui_port()
+ host = os.getenv("HOST", "0.0.0.0")
+ debug = os.getenv("DEBUG", "False").lower() == "true"
+
+ # SSL configuration
+ ssl_cert = os.getenv("SSL_CERT_PATH")
+ ssl_key = os.getenv("SSL_KEY_PATH")
+
+ ssl_context = None
+ if ssl_cert and ssl_key:
+ ssl_context = (ssl_cert, ssl_key)
+
+ print(f"Starting NANDA Adapter UI Agent on {host}:{port}")
+ print(f"Agent Bridge URL: {get_agent_url()}")
+
+ app.run(host=host, port=port, debug=debug, ssl_context=ssl_context)
+
+
+if __name__ == "__main__":
+ run_app()
diff --git a/python-adapter/run_ui_agent_https_with_payments.py b/python-adapter/run_ui_agent_https_with_payments.py
new file mode 100644
index 0000000..078eb9a
--- /dev/null
+++ b/python-adapter/run_ui_agent_https_with_payments.py
@@ -0,0 +1,412 @@
+"""
+NANDA Adapter with Payment Integration
+Modified version of run_ui_agent_https.py with NANDA Points payment requirements
+"""
+
+import os
+import json
+import uuid
+import threading
+from flask import Flask, request, jsonify, Response
+from flask_cors import CORS
+from python_a2a import A2AClient
+import time
+
+# Import NANDA Payments SDK
+from nanda_payments_sdk import (
+ quick_setup,
+ PaymentRequirement,
+ require_payment,
+ create_payment_config,
+ NPPaymentError,
+)
+
+app = Flask(__name__)
+CORS(app)
+
+# Global variables
+messages = []
+latest_message = ""
+client_map = {}
+
+# Payment configuration
+FACILITATOR_URL = os.getenv("FACILITATOR_URL", "http://localhost:3001")
+AGENT_NAME = os.getenv("AGENT_NAME", "nanda-adapter")
+
+
+def get_agent_port():
+ return int(os.getenv("AGENT_PORT", 3000))
+
+
+def get_ui_port():
+ return int(os.getenv("UI_PORT", 5000))
+
+
+def get_agent_id():
+ return os.getenv("AGENT_ID", "default_agent")
+
+
+def get_agent_url():
+ port = get_agent_port()
+ return f"http://localhost:{port}"
+
+
+# Initialize NANDA Payments
+print("🔧 Initializing NANDA Payments...")
+try:
+ payments = quick_setup(facilitator_url=FACILITATOR_URL, agent_name=AGENT_NAME)
+ print(f"✅ NANDA Payments initialized")
+ print(f" Facilitator: {FACILITATOR_URL}")
+ print(f" Agent: {AGENT_NAME}")
+except Exception as e:
+ print(f"❌ Failed to initialize NANDA Payments: {e}")
+ payments = None
+
+# Payment requirements
+SEND_MESSAGE_REQUIREMENT = PaymentRequirement(
+ amount=10, description="Send message to agent bridge" # 10 NANDA Points
+)
+
+RECEIVE_MESSAGE_REQUIREMENT = PaymentRequirement(
+ amount=5, description="Receive message from agent bridge" # 5 NANDA Points
+)
+
+# ==============================================================================
+# FREE ENDPOINTS (unchanged from original)
+# ==============================================================================
+
+
+@app.route("/api/health", methods=["GET"])
+def health_check():
+ return jsonify(
+ {
+ "status": "healthy",
+ "timestamp": time.time(),
+ "agent_port": get_agent_port(),
+ "ui_port": get_ui_port(),
+ "payments": "enabled" if payments else "disabled",
+ "facilitator": FACILITATOR_URL,
+ "agent_name": AGENT_NAME,
+ }
+ )
+
+
+@app.route("/api/agents/list", methods=["GET"])
+def list_agents():
+ # This would normally fetch from a registry
+ return jsonify(
+ {
+ "agents": [
+ {"name": "local_agent", "url": get_agent_url(), "status": "active"}
+ ]
+ }
+ )
+
+
+@app.route("/api/render", methods=["GET"])
+def render_latest():
+ return jsonify({"message": latest_message, "timestamp": time.time()})
+
+
+@app.route("/api/messages/stream", methods=["GET"])
+def stream_messages():
+ def generate():
+ while True:
+ if messages:
+ latest = messages[-1]
+ yield f"data: {json.dumps(latest, default=str)}\n\n"
+ time.sleep(1)
+
+ return Response(generate(), mimetype="text/event-stream")
+
+
+@app.route("/api/messages", methods=["GET"])
+def get_messages():
+ limit = request.args.get("limit", 50, type=int)
+ offset = request.args.get("offset", 0, type=int)
+
+ paginated_messages = messages[offset : offset + limit]
+
+ return jsonify(
+ {
+ "messages": paginated_messages,
+ "total": len(messages),
+ "limit": limit,
+ "offset": offset,
+ }
+ )
+
+
+@app.route("/api/conversations/", methods=["GET"])
+def get_conversation(conversation_id):
+ conversation_messages = [
+ m for m in messages if m.get("conversation_id") == conversation_id
+ ]
+
+ return jsonify(
+ {
+ "conversation_id": conversation_id,
+ "messages": conversation_messages,
+ "count": len(conversation_messages),
+ }
+ )
+
+
+@app.route("/api/stats", methods=["GET"])
+def get_stats():
+ """Payment and usage statistics"""
+ total_messages = len(messages)
+ paid_messages = len([m for m in messages if m.get("payment_verified")])
+ total_revenue = paid_messages * 10 # Assuming 10 NP average per message
+
+ return jsonify(
+ {
+ "total_messages": total_messages,
+ "paid_messages": paid_messages,
+ "free_requests": total_messages - paid_messages,
+ "total_revenue_np": total_revenue,
+ "facilitator_url": FACILITATOR_URL,
+ "agent_name": AGENT_NAME,
+ "timestamp": time.time(),
+ }
+ )
+
+
+# ==============================================================================
+# PAID ENDPOINTS (with NANDA Points requirements)
+# ==============================================================================
+
+
+@app.route("/api/send", methods=["POST"])
+@require_payment(SEND_MESSAGE_REQUIREMENT, payments["config"] if payments else None)
+def send_message():
+ """Send message to agent bridge - REQUIRES 10 NANDA POINTS"""
+ global latest_message
+
+ try:
+ data = request.get_json()
+ message = data.get("message")
+ conversation_id = data.get("conversation_id", str(uuid.uuid4()))
+ client_id = data.get("client_id", "default_client")
+
+ if not message:
+ return jsonify({"error": "Message is required"}), 400
+
+ print(f"💰 Processing paid message from {client_id}")
+ print(f" Message: {message[:100]}...")
+ print(f" Payment verified: 10 NP")
+
+ # Create A2A client for communication with agent bridge
+ agent_url = get_agent_url()
+ client = A2AClient(agent_url)
+
+ # Prepare metadata
+ metadata = {
+ "conversation_id": conversation_id,
+ "client_id": client_id,
+ "timestamp": time.time(),
+ "agent_id": get_agent_id(),
+ "payment_verified": True,
+ "payment_amount": "10 NP",
+ }
+
+ # Send message to agent bridge
+ try:
+ response = client.send_message(message, metadata)
+ except Exception as e:
+ # Mock response if agent bridge is not available
+ response = f"Agent bridge response: Processed '{message[:50]}...' (Bridge may be offline: {e})"
+
+ # Store message with payment info
+ message_record = {
+ "id": str(uuid.uuid4()),
+ "message": message,
+ "response": response,
+ "conversation_id": conversation_id,
+ "client_id": client_id,
+ "timestamp": time.time(),
+ "agent_id": get_agent_id(),
+ "payment_verified": True,
+ "payment_amount": "10 NP",
+ "cost": "10 NP",
+ }
+
+ messages.append(message_record)
+ latest_message = response
+
+ # Store client mapping
+ client_map[client_id] = {
+ "conversation_id": conversation_id,
+ "last_activity": time.time(),
+ }
+
+ print(f"✅ Message processed and payment settled")
+
+ return jsonify(
+ {
+ "response": response,
+ "conversation_id": conversation_id,
+ "agent_id": get_agent_id(),
+ "message_id": message_record["id"],
+ "timestamp": message_record["timestamp"],
+ "cost": "10 NP",
+ "payment_verified": True,
+ "success": True,
+ }
+ )
+
+ except NPPaymentError:
+ # Payment errors are handled by the decorator
+ raise
+ except Exception as e:
+ print(f"❌ Error in send_message: {e}")
+ return jsonify({"error": str(e)}), 500
+
+
+@app.route("/api/receive_message", methods=["POST"])
+@require_payment(RECEIVE_MESSAGE_REQUIREMENT, payments["config"] if payments else None)
+def receive_message():
+ """Receive message from agent bridge - REQUIRES 5 NANDA POINTS"""
+ global latest_message
+
+ try:
+ data = request.get_json()
+ message = data.get("message")
+ conversation_id = data.get("conversation_id")
+ client_id = data.get("client_id", "agent_bridge")
+
+ if not message:
+ return jsonify({"error": "Message is required"}), 400
+
+ print(f"💰 Processing paid received message")
+ print(f" From: {client_id}")
+ print(f" Payment verified: 5 NP")
+
+ # Store received message with payment info
+ message_record = {
+ "id": str(uuid.uuid4()),
+ "message": message,
+ "conversation_id": conversation_id,
+ "client_id": client_id,
+ "timestamp": time.time(),
+ "type": "received",
+ "payment_verified": True,
+ "payment_amount": "5 NP",
+ "cost": "5 NP",
+ }
+
+ messages.append(message_record)
+ latest_message = message
+
+ print(f"✅ Received message processed and payment settled")
+
+ return jsonify(
+ {
+ "status": "received",
+ "message_id": message_record["id"],
+ "timestamp": message_record["timestamp"],
+ "cost": "5 NP",
+ "payment_verified": True,
+ "success": True,
+ }
+ )
+
+ except NPPaymentError:
+ # Payment errors are handled by the decorator
+ raise
+ except Exception as e:
+ print(f"❌ Error in receive_message: {e}")
+ return jsonify({"error": str(e)}), 500
+
+
+# ==============================================================================
+# PAYMENT TESTING ENDPOINTS
+# ==============================================================================
+
+
+@app.route("/api/test/payment-info", methods=["GET"])
+def test_payment_info():
+ """Test endpoint to get payment configuration info"""
+ return jsonify(
+ {
+ "facilitator_url": FACILITATOR_URL,
+ "agent_name": AGENT_NAME,
+ "payment_requirements": {
+ "send_message": {
+ "amount": SEND_MESSAGE_REQUIREMENT.amount,
+ "description": SEND_MESSAGE_REQUIREMENT.description,
+ },
+ "receive_message": {
+ "amount": RECEIVE_MESSAGE_REQUIREMENT.amount,
+ "description": RECEIVE_MESSAGE_REQUIREMENT.description,
+ },
+ },
+ "payment_sdk_loaded": payments is not None,
+ }
+ )
+
+
+@app.route("/api/test/send-free", methods=["POST"])
+def test_send_free():
+ """Free version of send for testing comparison"""
+ data = request.get_json()
+ message = data.get("message", "Test message")
+
+ return jsonify(
+ {
+ "response": f"Free response to: {message}",
+ "cost": "FREE",
+ "timestamp": time.time(),
+ "note": "This is the free version. Compare with /api/send which requires payment.",
+ }
+ )
+
+
+def run_app():
+ port = get_ui_port()
+ host = os.getenv("HOST", "0.0.0.0")
+ debug = os.getenv("DEBUG", "False").lower() == "true"
+
+ # SSL configuration
+ ssl_cert = os.getenv("SSL_CERT_PATH")
+ ssl_key = os.getenv("SSL_KEY_PATH")
+
+ ssl_context = None
+ if ssl_cert and ssl_key:
+ ssl_context = (ssl_cert, ssl_key)
+
+ print("\n🚀 NANDA Adapter with Payments Started")
+ print("=" * 45)
+ print(f" Server: http://{host}:{port}")
+ print(f" Agent Bridge: {get_agent_url()}")
+ print(f" Agent Name: {AGENT_NAME}")
+ print(f" Facilitator: {FACILITATOR_URL}")
+ print("")
+ print("📡 Available Endpoints:")
+ print(" GET /api/health - Health check (FREE)")
+ print(" GET /api/agents/list - List agents (FREE)")
+ print(" GET /api/messages/stream - SSE stream (FREE)")
+ print(" POST /api/send - Send message (10 NP) 💰")
+ print(" POST /api/receive_message - Receive message (5 NP) 💰")
+ print(" GET /api/render - Latest message (FREE)")
+ print(" GET /api/conversations/:id - Conversation history (FREE)")
+ print(" GET /api/messages - All messages (FREE)")
+ print(" GET /api/stats - Payment statistics (FREE)")
+ print(" GET /api/test/payment-info - Payment config (FREE)")
+ print(" POST /api/test/send-free - Free send test (FREE)")
+ print("")
+ print("💰 Payment Requirements:")
+ print(" /api/send: 10 NANDA Points")
+ print(" /api/receive_message: 5 NANDA Points")
+ print("")
+ if payments:
+ print("✅ NANDA Payments enabled and ready!")
+ else:
+ print("⚠️ NANDA Payments disabled - check facilitator connection")
+ print("")
+
+ app.run(host=host, port=port, debug=debug, ssl_context=ssl_context)
+
+
+if __name__ == "__main__":
+ run_app()
diff --git a/python-adapter/test_endpoints.py b/python-adapter/test_endpoints.py
new file mode 100755
index 0000000..7b57d6c
--- /dev/null
+++ b/python-adapter/test_endpoints.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+"""
+Test script for NANDA Adapter with Payment Integration
+Tests both free and paid endpoints
+"""
+
+import requests
+import json
+import time
+import base64
+
+BASE_URL = "http://localhost:5000"
+
+
+def test_endpoint(method, path, data=None, headers=None, expected_status=200):
+ """Test an endpoint and return response"""
+ url = f"{BASE_URL}{path}"
+
+ try:
+ if method.upper() == "GET":
+ response = requests.get(url, headers=headers)
+ elif method.upper() == "POST":
+ response = requests.post(url, json=data, headers=headers)
+ else:
+ print(f"❌ Unsupported method: {method}")
+ return None
+
+ print(f"📡 {method} {path}")
+ print(f" Status: {response.status_code}")
+
+ if response.status_code == expected_status:
+ print(" ✅ Expected status")
+ else:
+ print(f" ⚠️ Expected {expected_status}, got {response.status_code}")
+
+ try:
+ result = response.json()
+ print(f" Response: {json.dumps(result, indent=2)}")
+ return result
+ except:
+ print(f" Response: {response.text}")
+ return response.text
+
+ except Exception as e:
+ print(f"❌ Error testing {path}: {e}")
+ return None
+
+
+def main():
+ print("🧪 Testing NANDA Adapter with Payment Integration")
+ print("=" * 55)
+
+ # Test 1: Health check (FREE)
+ print("\n1. 🔍 Testing Health Check (FREE)")
+ print("-" * 35)
+ test_endpoint("GET", "/api/health")
+
+ # Test 2: Agent list (FREE)
+ print("\n2. 🔍 Testing Agent List (FREE)")
+ print("-" * 32)
+ test_endpoint("GET", "/api/agents/list")
+
+ # Test 3: Payment info (FREE)
+ print("\n3. 🔍 Testing Payment Info (FREE)")
+ print("-" * 33)
+ test_endpoint("GET", "/api/test/payment-info")
+
+ # Test 4: Free send test (FREE)
+ print("\n4. 🔍 Testing Free Send (FREE)")
+ print("-" * 30)
+ test_endpoint(
+ "POST", "/api/test/send-free", {"message": "This is a free test message"}
+ )
+
+ # Test 5: Send message without payment (should return 402)
+ print("\n5. 💰 Testing /api/send WITHOUT Payment (Should return HTTP 402)")
+ print("-" * 66)
+ test_endpoint(
+ "POST",
+ "/api/send",
+ {
+ "message": "Hello, agent!",
+ "conversation_id": "test-conv-1",
+ "client_id": "test-client",
+ },
+ expected_status=402,
+ )
+
+ # Test 6: Receive message without payment (should return 402)
+ print(
+ "\n6. 💰 Testing /api/receive_message WITHOUT Payment (Should return HTTP 402)"
+ )
+ print("-" * 78)
+ test_endpoint(
+ "POST",
+ "/api/receive_message",
+ {
+ "message": "Response from agent bridge",
+ "conversation_id": "test-conv-1",
+ "client_id": "agent-bridge",
+ },
+ expected_status=402,
+ )
+
+ # Test 7: Statistics (FREE)
+ print("\n7. 🔍 Testing Statistics (FREE)")
+ print("-" * 30)
+ test_endpoint("GET", "/api/stats")
+
+ # Test 8: Messages list (FREE)
+ print("\n8. 🔍 Testing Messages List (FREE)")
+ print("-" * 33)
+ test_endpoint("GET", "/api/messages?limit=5")
+
+ print("\n" + "=" * 55)
+ print("✅ Test completed!")
+ print("")
+ print("Expected Results:")
+ print("- Health check: Should return 200 with server status")
+ print("- Agent list: Should return 200 with mock agents")
+ print("- Payment info: Should show payment configuration")
+ print("- Free send: Should return 200 with free response")
+ print("- /api/send without payment: Should return 402 with payment requirements")
+ print(
+ "- /api/receive_message without payment: Should return 402 with payment requirements"
+ )
+ print("- Statistics: Should show payment stats")
+ print("")
+ print("To test WITH payment:")
+ print("1. Ensure NANDA Points facilitator is running on localhost:3001")
+ print("2. Create a valid NANDA Points payment")
+ print("3. Include X-PAYMENT header with base64-encoded payment")
+ print("")
+ print("Example with payment:")
+ print("curl -X POST http://localhost:5000/api/send \\")
+ print(" -H 'Content-Type: application/json' \\")
+ print(" -H 'X-PAYMENT: ' \\")
+ print(' -d \'{"message": "Hello!", "conversation_id": "test"}\'')
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python-adapter/test_paid_flow.py b/python-adapter/test_paid_flow.py
new file mode 100644
index 0000000..0b187f1
--- /dev/null
+++ b/python-adapter/test_paid_flow.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+"""
+Test script for complete NANDA Points payment flow
+Tests the enhanced Python SDK with client-side payment creation
+"""
+
+import sys
+import os
+
+sys.path.append(os.path.dirname(os.path.abspath(__file__)))
+
+from nanda_payments_sdk import (
+ create_payment,
+ encode_payment,
+ create_and_encode_payment,
+ send_paid_request,
+)
+
+
+def test_payment_creation():
+ """Test payment creation and encoding"""
+ print("🧪 Testing payment creation...")
+
+ payment = create_payment(
+ from_agent="claude-desktop",
+ to_agent="nanda-adapter",
+ amount=10,
+ facilitator_url="http://localhost:3001",
+ resource="http://localhost:5000/api/send",
+ description="Test message payment",
+ )
+
+ print(f"✅ Payment created:")
+ print(f" From: {payment.from_agent}")
+ print(f" To: {payment.pay_to}")
+ print(f" Amount: {payment.amount} NP")
+ print(f" TxID: {payment.tx_id}")
+
+ # Test encoding
+ encoded = encode_payment(payment)
+ print(f"✅ Payment encoded (length: {len(encoded)})")
+ print(f" Base64: {encoded[:50]}...")
+
+ return payment, encoded
+
+
+def test_convenience_function():
+ """Test convenience function"""
+ print("\n🧪 Testing convenience function...")
+
+ encoded = create_and_encode_payment(
+ from_agent="claude-desktop",
+ to_agent="nanda-adapter",
+ amount=10,
+ facilitator_url="http://localhost:3001",
+ resource="http://localhost:5000/api/send",
+ description="Convenience function test",
+ )
+
+ print(f"✅ One-step payment creation and encoding")
+ print(f" Base64: {encoded[:50]}...")
+
+ return encoded
+
+
+def test_manual_curl_equivalent():
+ """Test manual payment creation for curl comparison"""
+ print("\n🧪 Creating payment for manual curl test...")
+
+ payment_header = create_and_encode_payment(
+ from_agent="claude-desktop",
+ to_agent="nanda-adapter",
+ amount=10,
+ facilitator_url="http://localhost:3001",
+ resource="http://localhost:5000/api/send",
+ description="Hi, I'm steve.",
+ )
+
+ print(f"✅ Payment header created:")
+ print(f"X-PAYMENT: {payment_header}")
+ print(f"\n📋 Manual curl command:")
+ print(f"curl -i -X POST http://localhost:5000/api/send \\")
+ print(f' -H "Content-Type: application/json" \\')
+ print(f' -H "X-PAYMENT: {payment_header}" \\')
+ print(
+ f' -d \'{{"message": "Hi, I\'m steve.", "conversation_id": "steve-conv-3", "client_id": "claude-desktop"}}\''
+ )
+
+ return payment_header
+
+
+def test_sdk_http_client():
+ """Test SDK's built-in HTTP client"""
+ print("\n🧪 Testing SDK HTTP client...")
+
+ try:
+ response = send_paid_request(
+ url="http://localhost:5000/api/send",
+ from_agent="claude-desktop",
+ to_agent="nanda-adapter",
+ amount=10,
+ facilitator_url="http://localhost:3001",
+ data={
+ "message": "Hi, I'm steve using the Python SDK!",
+ "conversation_id": "steve-conv-sdk",
+ "client_id": "claude-desktop",
+ },
+ )
+
+ print(f"✅ HTTP request sent")
+ print(f" Status: {response.status_code}")
+ print(f" Response: {response.text[:200]}...")
+
+ return response
+
+ except Exception as e:
+ print(f"❌ HTTP request failed: {e}")
+ return None
+
+
+if __name__ == "__main__":
+ print("🚀 NANDA Points Python SDK - Complete Flow Test")
+ print("=" * 55)
+
+ # Test basic payment creation
+ payment, encoded = test_payment_creation()
+
+ # Test convenience function
+ encoded_convenience = test_convenience_function()
+
+ # Test manual curl approach
+ manual_payment = test_manual_curl_equivalent()
+
+ # Test SDK HTTP client
+ response = test_sdk_http_client()
+
+ print("\n" + "=" * 55)
+ print("✅ All SDK functions tested successfully!")
+ print("💡 You can now:")
+ print(" 1. Use the manual curl command above")
+ print(" 2. Use send_paid_request() for Python HTTP requests")
+ print(" 3. Create your own payments with create_payment()")
diff --git a/run-updated-test.ts b/run-updated-test.ts
deleted file mode 100644
index acced5a..0000000
--- a/run-updated-test.ts
+++ /dev/null
@@ -1,282 +0,0 @@
-#!/usr/bin/env tsx
-
-import { Client } from "@modelcontextprotocol/sdk/client/index.js";
-import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
-import { writeFile } from 'fs/promises';
-
-const SERVER_URL = "http://localhost:3000/mcp";
-const LOG_FILE = "test.log";
-
-async function logToFile(message: string) {
- const timestamp = new Date().toISOString();
- const logLine = `[${timestamp}] ${message}\n`;
- await writeFile(LOG_FILE, logLine, { flag: 'a' });
- console.log(message);
-}
-
-async function clearLogFile() {
- await writeFile(LOG_FILE, '');
-}
-
-async function runComprehensiveTests() {
- await clearLogFile();
- await logToFile("🚀 Starting Updated x402-NP Test Suite");
- await logToFile(`Server URL: ${SERVER_URL}`);
- await logToFile("");
-
- const client = new Client(
- { name: "x402-test-client", version: "1.0.0" },
- { capabilities: {} }
- );
-
- const transport = new StreamableHTTPClientTransport(new URL(SERVER_URL));
-
- try {
- await logToFile("🔌 Connecting to MCP server...");
- await client.connect(transport);
- await logToFile("✅ Connected successfully!");
- await logToFile("");
-
- // Test 1: List all tools
- await logToFile("============================================================");
- await logToFile("TEST: List all available tools");
- await logToFile("============================================================");
- await logToFile("📤 MCP REQUEST:");
- await logToFile("Tool: listTools");
- await logToFile("Arguments: {}");
-
- const toolsResult = await client.listTools();
- await logToFile("📥 TOOLS LIST:");
- toolsResult.tools.forEach((tool, index) => {
- logToFile(` ${index + 1}. ${tool.name} - ${tool.description}`);
- });
- await logToFile("");
-
- // Test 2: Get payment information (free tool)
- await logToFile("============================================================");
- await logToFile("TEST: Get payment information (free tool)");
- await logToFile("============================================================");
- await logToFile("📤 MCP REQUEST:");
- await logToFile("Tool: getPaymentInfo");
- await logToFile("Arguments: {}");
-
- const paymentInfoResult = await client.callTool({
- name: "getPaymentInfo",
- arguments: {}
- });
-
- const paymentInfo = JSON.parse(paymentInfoResult.content[0].text);
- await logToFile("📥 MCP RESPONSE:");
- await logToFile("Response: " + JSON.stringify(paymentInfo, null, 2));
- await logToFile("Status: SUCCESS - Free tool worked");
- await logToFile("");
-
- // Test 3: Call getBalance (now free)
- await logToFile("============================================================");
- await logToFile("TEST: Call getBalance (now free)");
- await logToFile("============================================================");
- await logToFile("📤 MCP REQUEST:");
- await logToFile("Tool: getBalance");
- await logToFile("Arguments: " + JSON.stringify({ agent_name: "claude-desktop" }, null, 2));
-
- const balanceResult = await client.callTool({
- name: "getBalance",
- arguments: { agent_name: "claude-desktop" }
- });
-
- const balanceResponse = JSON.parse(balanceResult.content[0].text);
- await logToFile("📥 MCP RESPONSE:");
- await logToFile("Response: " + JSON.stringify(balanceResponse, null, 2));
-
- if (balanceResponse.error) {
- await logToFile("❌ UNEXPECTED: Free tool failed");
- await logToFile(` Error: ${balanceResponse.error}`);
- } else {
- await logToFile("✅ SUCCESS: Free tool worked correctly");
- await logToFile(` Got balance: ${balanceResponse.balancePoints} NP for ${balanceResponse.agent_name}`);
- }
- await logToFile("");
-
- // Test 4: Call getReceipt (now free)
- await logToFile("============================================================");
- await logToFile("TEST: Call getReceipt (now free)");
- await logToFile("============================================================");
- await logToFile("📤 MCP REQUEST:");
- await logToFile("Tool: getReceipt");
- await logToFile("Arguments: " + JSON.stringify({ txId: "test-receipt-id" }, null, 2));
-
- const receiptResult = await client.callTool({
- name: "getReceipt",
- arguments: { txId: "test-receipt-id" }
- });
-
- const receiptResponse = JSON.parse(receiptResult.content[0].text);
- await logToFile("📥 MCP RESPONSE:");
- await logToFile("Response: " + JSON.stringify(receiptResponse, null, 2));
-
- if (receiptResponse.error === "NOT_FOUND") {
- await logToFile("✅ SUCCESS: Free tool worked correctly (receipt not found as expected)");
- } else if (receiptResponse.error) {
- await logToFile("❌ UNEXPECTED: Free tool failed");
- await logToFile(` Error: ${receiptResponse.error}`);
- } else {
- await logToFile("✅ SUCCESS: Free tool worked and found receipt");
- }
- await logToFile("");
-
- // Test 5: Call getTimestamp without payment (should require payment)
- await logToFile("============================================================");
- await logToFile("TEST: Call getTimestamp without payment (should require payment)");
- await logToFile("============================================================");
- await logToFile("📤 MCP REQUEST:");
- await logToFile("Tool: getTimestamp");
- await logToFile("Arguments: {}");
-
- const timestampResult = await client.callTool({
- name: "getTimestamp",
- arguments: {}
- });
-
- const timestampResponse = JSON.parse(timestampResult.content[0].text);
- await logToFile("📥 MCP RESPONSE:");
- await logToFile("Response: " + JSON.stringify(timestampResponse, null, 2));
-
- if (timestampResponse.error === "PAYMENT_REQUIRED") {
- await logToFile("✅ EXPECTED: Payment required correctly detected");
- } else {
- await logToFile("❌ UNEXPECTED: Paid tool worked without payment");
- }
- await logToFile("");
-
- // Test 6: Make payment for getTimestamp
- await logToFile("============================================================");
- await logToFile("TEST: Make payment for getTimestamp access");
- await logToFile("============================================================");
- await logToFile("📤 MCP REQUEST:");
- await logToFile("Tool: initiateTransaction");
- await logToFile("Arguments: " + JSON.stringify({
- from: "claude-desktop",
- to: "system",
- amount: 1
- }, null, 2));
-
- const paymentResult = await client.callTool({
- name: "initiateTransaction",
- arguments: {
- from: "claude-desktop",
- to: "system",
- amount: 1
- }
- });
-
- const payment = JSON.parse(paymentResult.content[0].text);
- await logToFile("📥 MCP RESPONSE:");
- await logToFile("Response: " + JSON.stringify(payment, null, 2));
-
- if (payment.error) {
- await logToFile("❌ Payment failed: " + payment.error);
- } else {
- await logToFile("✅ Payment successful! TxId: " + payment.txId);
-
- // Test 7: Use payment to access getTimestamp
- await logToFile("");
- await logToFile("============================================================");
- await logToFile("TEST: Access getTimestamp with payment proof");
- await logToFile("============================================================");
- await logToFile("📤 MCP REQUEST:");
- await logToFile("Tool: getTimestamp");
- await logToFile("Arguments: " + JSON.stringify({
- _paymentAgent: "claude-desktop",
- _paymentTxId: payment.txId,
- _paymentAmount: "1"
- }, null, 2));
-
- const paidTimestampResult = await client.callTool({
- name: "getTimestamp",
- arguments: {
- _paymentAgent: "claude-desktop",
- _paymentTxId: payment.txId,
- _paymentAmount: "1"
- }
- });
-
- const paidTimestampResponse = JSON.parse(paidTimestampResult.content[0].text);
- await logToFile("📥 MCP RESPONSE:");
- await logToFile("Response: " + JSON.stringify(paidTimestampResponse, null, 2));
-
- if (paidTimestampResponse.error) {
- await logToFile("❌ UNEXPECTED: Payment verification failed");
- await logToFile(` Error: ${paidTimestampResponse.error}`);
- } else {
- await logToFile("🎉 SUCCESS! x402-NP payment flow completed for getTimestamp");
- await logToFile(` Server timestamp: ${paidTimestampResponse.timestamp}`);
- }
- }
- await logToFile("");
-
- // Test Summary
- await logToFile("📊 TEST SUMMARY");
- await logToFile("================");
- await logToFile("✅ MCP connection successful");
- await logToFile("✅ Tool listing successful");
- await logToFile("✅ Free tools (getBalance, getReceipt) working correctly");
- await logToFile("✅ Paid tool (getTimestamp) requiring payment correctly");
- await logToFile("✅ Payment flow working end-to-end");
- await logToFile("");
-
- await client.close();
- await logToFile("✅ Disconnected from server");
- await logToFile("");
-
- // Test direct HTTP calls
- await logToFile("🌐 Testing Direct HTTP Calls");
- await logToFile("==============================");
- await logToFile("");
-
- // Health check
- await logToFile("📤 HTTP REQUEST: GET /health");
- const healthResponse = await fetch("http://localhost:3000/health");
- await logToFile(`📥 HTTP RESPONSE: ${healthResponse.status} ${healthResponse.statusText}`);
- const healthData = await healthResponse.json();
- await logToFile("Response: " + JSON.stringify(healthData, null, 2));
- await logToFile("");
-
- // Direct MCP call (should fail without session)
- await logToFile("📤 HTTP REQUEST: POST /mcp");
- await logToFile("Headers: Content-Type: application/json, Accept: application/json");
- const directMcpBody = {
- jsonrpc: "2.0",
- method: "tools/call",
- params: {
- name: "getBalance",
- arguments: { agent_name: "claude-desktop" }
- },
- id: 1
- };
- await logToFile("Body: " + JSON.stringify(directMcpBody, null, 2));
-
- const directMcpResponse = await fetch("http://localhost:3000/mcp", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "Accept": "application/json"
- },
- body: JSON.stringify(directMcpBody)
- });
-
- await logToFile(`📥 HTTP RESPONSE: ${directMcpResponse.status} ${directMcpResponse.statusText}`);
- await logToFile("Headers: " + JSON.stringify(Object.fromEntries(directMcpResponse.headers.entries()), null, 2));
- const directMcpData = await directMcpResponse.json();
- await logToFile("Error response: " + JSON.stringify(directMcpData));
- await logToFile("");
-
- await logToFile("📋 Complete test log saved to: " + LOG_FILE);
-
- } catch (error) {
- await logToFile("❌ Test failed: " + String(error));
- await client.close();
- throw error;
- }
-}
-
-runComprehensiveTests().catch(console.error);
\ No newline at end of file
diff --git a/schemas/agents.json b/schemas/agents.json
deleted file mode 100644
index 03d47b2..0000000
--- a/schemas/agents.json
+++ /dev/null
@@ -1,82 +0,0 @@
-{
- "_id": {
- "$oid": "68cb46c84ae9e05eed65eb6d"
- },
- "agent_name": "classify-agent",
- "capabilities": {
- "modalities": [
- "text"
- ],
- "streaming": false,
- "batch": false,
- "authentication": {
- "methods": [],
- "requiredScopes": []
- }
- },
- "certification": {
- "level": "verified",
- "issuer": "NANDA",
- "issuanceDate": "2025-09-17",
- "expirationDate": "2025-10-17"
- },
- "created_at": "2025-09-17T23:39:52.080Z",
- "description": "Classification Agent",
- "documentationUrl": "",
- "email": "classify@example.com",
- "endpoints": {
- "static": [
- "https://agents.example.com/classify"
- ],
- "adaptive_resolver": {
- "url": "",
- "policies": []
- }
- },
- "evaluations": {
- "performanceScore": 0,
- "availability90d": "",
- "lastAudited": "",
- "auditTrail": "",
- "auditorID": ""
- },
- "id": "ff93a701-e415-490b-8a29-8b312ba9a098",
- "jurisdiction": "USA",
- "label": "classify",
- "provider": {
- "name": "NANDA",
- "url": "https://projectnanda.org",
- "did": ""
- },
- "serviceCharge": 10,
- "skills": [
- {
- "id": "chat",
- "description": "personal AI agent and chatbot",
- "inputModes": [
- "text"
- ],
- "outputModes": [
- "text"
- ],
- "supportedLanguages": [
- "en"
- ]
- }
- ],
- "telemetry": {
- "enabled": false,
- "retention": "7d",
- "sampling": 0.1,
- "metrics": {
- "latency_p95_ms": 0,
- "throughput_rps": 0,
- "error_rate": 0,
- "availability": ""
- }
- },
- "updated_at": "2025-09-17T23:39:52.080Z",
- "username": "classify-agent",
- "version": "1.0",
- "walletId": "0d7689d2-b6da-4ddb-a446-09f6681ac7e4"
- }
\ No newline at end of file
diff --git a/schemas/receipts.json b/schemas/receipts.json
deleted file mode 100644
index 95bbb51..0000000
--- a/schemas/receipts.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "_id": {
- "$oid": "68cb488f942c9a336988b052"
- },
- "txId": "c9cc0632-d61a-4e72-86db-266541fcd16b",
- "issuedAt": "2025-09-17T23:47:27.006Z",
- "fromAgent": "payer_agent",
- "toAgent": "classify-agent",
- "amountMinor": 10,
- "fromBalanceAfter": 990,
- "toBalanceAfter": 1010
- }
\ No newline at end of file
diff --git a/schemas/transactions.json b/schemas/transactions.json
deleted file mode 100644
index 701454a..0000000
--- a/schemas/transactions.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "_id": {
- "$oid": "68cb488e942c9a336988b051"
- },
- "txId": "c9cc0632-d61a-4e72-86db-266541fcd16b",
- "fromAgent": "payer_agent",
- "toAgent": "classify-agent",
- "amountMinor": 10,
- "currency": "NP",
- "scale": 0,
- "createdAt": "2025-09-17T23:47:26.981Z",
- "status": "completed",
- "error": null,
- "task": "image_classification_task"
- }
\ No newline at end of file
diff --git a/schemas/wallets.json b/schemas/wallets.json
deleted file mode 100644
index b0d0dd6..0000000
--- a/schemas/wallets.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "_id": {
- "$oid": "68cb46c84ae9e05eed65eb6f"
- },
- "agent_name": "classify-agent",
- "balanceMinor": 1010,
- "createdAt": "2025-09-17T23:39:52.328Z",
- "currency": "NP",
- "scale": 0,
- "updatedAt": "2025-09-17T23:47:26.998Z",
- "walletId": "0d7689d2-b6da-4ddb-a446-09f6681ac7e4"
- }
\ No newline at end of file
diff --git a/sdks/payments-sdk/README.md b/sdks/payments-sdk/README.md
new file mode 100644
index 0000000..50043b8
--- /dev/null
+++ b/sdks/payments-sdk/README.md
@@ -0,0 +1,491 @@
+# @nanda/payments-sdk
+
+A TypeScript SDK for integrating NANDA Points payments into MCP servers and Express.js applications. This SDK provides server-side utilities for developers who want to monetize their tools using the x402 payment protocol.
+
+## Overview
+
+The NANDA Payments SDK is designed to be the **"only way"** developers integrate NANDA Points payments into their MCP (Model Context Protocol) servers. It abstracts the complexity of the x402 protocol while providing developer-friendly APIs that feel as natural as adding any other middleware.
+
+### Key Features
+
+- **🔧 MCP Tool Monetization**: Convert free tools to paid tools with a simple decorator
+- **⚡ Quick Setup**: Get started with payments in 3 lines of code
+- **🛡️ Type Safety**: Full TypeScript support with comprehensive type definitions
+- **🌐 Express Middleware**: Route-level payment protection for HTTP APIs
+- **🔄 x402 Compliant**: Follows Coinbase's x402 reference implementation
+- **📦 Zero Dependencies**: Minimal external dependencies beyond essential HTTP libraries
+
+## Installation
+
+```bash
+npm install @nanda/payments-sdk
+```
+
+## Quick Start
+
+### MCP Server Integration
+
+```typescript
+import { quickSetup } from '@nanda/payments-sdk';
+
+// 1. Quick setup for MCP servers
+const payments = await quickSetup({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'my-mcp-server'
+});
+
+// 2. Convert free tool to paid tool
+const freeWeatherTool = (args) => getBasicWeather(args.location);
+
+const paidWeatherTool = payments.requirePayment({
+ amount: 50, // 50 NANDA Points
+ description: 'Premium weather data with forecasts'
+})(freeWeatherTool);
+
+// 3. Create new paid tool
+const premiumAnalyticsTool = payments.createPaidTool(
+ 'premium_analytics',
+ { amount: 100, description: 'Advanced analytics data' },
+ async (args) => {
+ return await getAdvancedAnalytics(args.dataset);
+ }
+);
+```
+
+### Express.js API Integration
+
+```typescript
+import express from 'express';
+import { paymentMiddleware, createPaymentConfig } from '@nanda/payments-sdk';
+
+const app = express();
+
+// Configure payment settings
+const config = createPaymentConfig({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'api-server'
+});
+
+// Apply payment requirements to specific routes
+app.use(paymentMiddleware({
+ '/api/premium': { amount: 25, description: 'Premium API access' },
+ '/api/analytics': { amount: 50, description: 'Analytics data' },
+ 'POST /api/compute': { amount: 100, description: 'Heavy computation' }
+}, config));
+
+// Your protected routes
+app.get('/api/premium', (req, res) => {
+ res.json({ data: 'premium content' });
+});
+```
+
+## API Reference
+
+### Core Functions
+
+#### `quickSetup(config)`
+
+Rapid configuration for MCP servers. Returns an object with configured payment utilities.
+
+```typescript
+const payments = await quickSetup({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'my-server'
+});
+```
+
+**Returns:**
+- `config`: Payment configuration object
+- `requirePayment`: Function to wrap existing tools with payment requirements
+- `createPaidTool`: Function to create new payment-protected tools
+- `facilitator`: Direct facilitator client for advanced usage
+
+#### `requirePayment(requirement, config)`
+
+Decorator function that wraps existing tools with payment requirements.
+
+```typescript
+const paidTool = requirePayment({
+ amount: 50,
+ description: 'Premium tool access',
+ recipient: 'service-provider', // optional
+ timeout: 30000 // optional
+}, config)(originalTool);
+```
+
+#### `createPaidTool(name, requirement, config, handler)`
+
+Creates a new payment-protected tool with MCP-compatible structure.
+
+```typescript
+const tool = createPaidTool(
+ 'weather_premium',
+ { amount: 100, description: 'Premium weather analysis' },
+ config,
+ async (args) => {
+ return await getPremiumWeather(args.location);
+ }
+);
+```
+
+#### `paymentMiddleware(routes, config)`
+
+Express middleware for route-level payment protection.
+
+```typescript
+app.use(paymentMiddleware({
+ '/api/protected': { amount: 25, description: 'Protected endpoint' }
+}, config));
+```
+
+#### `createPaymentConfig(config)`
+
+Creates a payment configuration with defaults.
+
+```typescript
+const config = createPaymentConfig({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'my-service',
+ timeout: 30000, // optional
+ retryCount: 3, // optional
+ retryDelay: 1000 // optional
+});
+```
+
+### Type Definitions
+
+#### `ToolPaymentRequirement`
+
+```typescript
+interface ToolPaymentRequirement {
+ amount: number; // NANDA Points required
+ description?: string; // Human-readable description
+ recipient?: string; // Payment recipient (defaults to agentName)
+ timeout?: number; // Payment timeout in milliseconds
+}
+```
+
+#### `PaymentConfig`
+
+```typescript
+interface PaymentConfig {
+ facilitatorUrl: string; // NANDA Points facilitator URL
+ agentName: string; // Your service/agent name
+ timeout?: number; // Request timeout (default: 30000ms)
+ retryCount?: number; // Retry attempts (default: 3)
+ retryDelay?: number; // Delay between retries (default: 1000ms)
+}
+```
+
+## Payment Flow
+
+### 1. Tool Execution Without Payment
+
+When a paid tool is called without payment, it throws an `NPPaymentError` with payment requirements:
+
+```typescript
+try {
+ await paidTool(args);
+} catch (error) {
+ if (error.code === 'PAYMENT_REQUIRED') {
+ console.log('Payment required:', error.details.requirements);
+ // Client should create payment and retry
+ }
+}
+```
+
+### 2. HTTP API Payment Flow
+
+For Express routes, the middleware returns HTTP 402 with x402-compliant response:
+
+```json
+{
+ "x402Version": 1,
+ "error": "X-PAYMENT header is required",
+ "accepts": [
+ {
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "maxAmountRequired": "25",
+ "resource": "https://api.example.com/premium",
+ "description": "Premium API access",
+ "payTo": "api-server",
+ "asset": "NP"
+ }
+ ]
+}
+```
+
+### 3. Payment Verification
+
+The SDK automatically:
+1. Extracts payment from `X-PAYMENT` header or context
+2. Verifies payment with the NANDA Points facilitator
+3. Executes the protected function/route
+4. Settles the payment after successful execution
+
+## Error Handling
+
+The SDK provides typed error classes for different scenarios:
+
+```typescript
+import {
+ NPPaymentError,
+ NPVerificationError,
+ NPSettlementError,
+ NPNetworkError
+} from '@nanda/payments-sdk';
+
+try {
+ await paidTool(args);
+} catch (error) {
+ if (error instanceof NPPaymentError) {
+ switch (error.code) {
+ case 'PAYMENT_REQUIRED':
+ // Handle payment requirement
+ break;
+ case 'VERIFICATION_FAILED':
+ // Handle verification failure
+ break;
+ case 'PAYMENT_ERROR':
+ // Handle general payment error
+ break;
+ }
+ }
+}
+```
+
+## Advanced Usage
+
+### Custom Facilitator Client
+
+```typescript
+import { createFacilitatorClient } from '@nanda/payments-sdk';
+
+const facilitator = createFacilitatorClient('http://localhost:3001');
+
+// Check supported payment schemes
+const supported = await facilitator.supported();
+
+// Verify payment manually
+const verification = await facilitator.verify(payment, requirements);
+
+// Settle payment manually
+const settlement = await facilitator.settle(payment, requirements);
+```
+
+### Manual Payment Requirements
+
+```typescript
+import { createPaymentRequirements } from '@nanda/payments-sdk';
+
+const requirements = createPaymentRequirements(
+ 100, // amount
+ 'https://api.example.com/resource', // resource
+ 'Payment for premium access', // description
+ 'service-provider', // recipient
+ 'http://localhost:3001' // facilitator URL
+);
+```
+
+## Configuration
+
+### Environment Variables
+
+The SDK respects these environment variables for default configuration:
+
+```bash
+FACILITATOR_URL=http://localhost:3001
+AGENT_NAME=my-service
+PAYMENT_TIMEOUT=30000
+PAYMENT_RETRY_COUNT=3
+PAYMENT_RETRY_DELAY=1000
+```
+
+### Production Configuration
+
+For production deployments:
+
+```typescript
+const config = createPaymentConfig({
+ facilitatorUrl: process.env.FACILITATOR_URL || 'https://facilitator.nanda.ai',
+ agentName: process.env.AGENT_NAME || 'production-service',
+ timeout: 10000, // Lower timeout for production
+ retryCount: 2,
+ retryDelay: 500
+});
+```
+
+## Examples
+
+### Complete MCP Server
+
+```typescript
+import { Server } from '@modelcontextprotocol/sdk/server/index.js';
+import { quickSetup } from '@nanda/payments-sdk';
+
+const payments = await quickSetup({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'weather-service'
+});
+
+const server = new Server(
+ { name: 'weather-service', version: '1.0.0' },
+ { capabilities: { tools: {} } }
+);
+
+// Free tool
+server.setRequestHandler(ListToolsRequestSchema, async () => ({
+ tools: [
+ {
+ name: 'basic_weather',
+ description: 'Get basic weather information',
+ inputSchema: { type: 'object', properties: { location: { type: 'string' } } }
+ },
+ payments.createPaidTool(
+ 'premium_weather',
+ { amount: 50, description: 'Premium weather with forecasts' },
+ async (args) => getPremiumWeather(args.location)
+ )
+ ]
+}));
+```
+
+### Express API with Mixed Routes
+
+```typescript
+import express from 'express';
+import { paymentMiddleware, createPaymentConfig } from '@nanda/payments-sdk';
+
+const app = express();
+const config = createPaymentConfig({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'data-api'
+});
+
+// Free endpoints
+app.get('/api/health', (req, res) => res.json({ status: 'ok' }));
+app.get('/api/public', (req, res) => res.json({ data: 'public data' }));
+
+// Protected endpoints
+app.use(paymentMiddleware({
+ '/api/premium': { amount: 25, description: 'Premium data access' },
+ '/api/analytics': { amount: 50, description: 'Analytics data' },
+ 'POST /api/process': { amount: 100, description: 'Data processing' }
+}, config));
+
+app.get('/api/premium', (req, res) => {
+ res.json({ data: 'premium content', timestamp: Date.now() });
+});
+
+app.get('/api/analytics', (req, res) => {
+ res.json({
+ analytics: { users: 1250, revenue: 15750 },
+ timestamp: Date.now()
+ });
+});
+
+app.post('/api/process', (req, res) => {
+ // Heavy computation that requires payment
+ const result = processLargeDataset(req.body.dataset);
+ res.json({ result, processingTime: result.duration });
+});
+```
+
+## Testing
+
+### Mock Facilitator
+
+For testing, you can create a mock facilitator that always approves payments:
+
+```typescript
+import { createFacilitatorClient } from '@nanda/payments-sdk';
+
+// In tests, use a mock facilitator
+const mockConfig = createPaymentConfig({
+ facilitatorUrl: 'http://localhost:3999', // Test facilitator
+ agentName: 'test-service'
+});
+
+// Test your paid tools
+const paidTool = requirePayment({ amount: 10 }, mockConfig)(originalTool);
+```
+
+## Troubleshooting
+
+### Common Issues
+
+**1. "Payment required" error when expecting free access**
+- Ensure the tool/route is not wrapped with payment requirements
+- Check if middleware is applied to the correct routes
+
+**2. "Payment verification failed"**
+- Verify the facilitator URL is correct and accessible
+- Check that the payment payload format matches requirements
+- Ensure sufficient balance in the payer's account
+
+**3. "Facilitator connection failed"**
+- Check network connectivity to facilitator
+- Verify facilitator is running and healthy
+- Check firewall and proxy settings
+
+**4. TypeScript compilation errors**
+- Ensure you're using TypeScript 4.5+
+- Import types correctly: `import type { PaymentConfig } from '@nanda/payments-sdk'`
+- Enable `strict` mode for better type checking
+
+### Debug Mode
+
+Enable debug logging by setting the environment variable:
+
+```bash
+DEBUG=nanda:payments npm start
+```
+
+## Migration Guide
+
+### From Manual x402 Implementation
+
+If you're currently handling x402 payments manually:
+
+1. **Replace payment verification logic**:
+ ```typescript
+ // Before: Manual verification
+ if (!req.headers['x-payment']) {
+ return res.status(402).json({ error: 'Payment required' });
+ }
+
+ // After: SDK middleware
+ app.use(paymentMiddleware({
+ '/api/route': { amount: 25, description: 'API access' }
+ }, config));
+ ```
+
+2. **Replace facilitator calls**:
+ ```typescript
+ // Before: Manual facilitator calls
+ const response = await fetch(`${facilitatorUrl}/verify`, { ... });
+
+ // After: SDK facilitator client
+ const facilitator = createFacilitatorClient(facilitatorUrl);
+ const verification = await facilitator.verify(payment, requirements);
+ ```
+
+### From Other Payment Systems
+
+The SDK is designed to be the primary payment system for NANDA Points. If migrating from other systems:
+
+1. Replace existing payment decorators with `requirePayment()`
+2. Update payment amount units to NANDA Points
+3. Replace HTTP status codes with x402-compliant responses
+4. Update client integrations to use x402 protocol
+
+## Support and Contributing
+
+- **Issues**: Report bugs and request features on [GitHub Issues](https://github.com/projnanda/nanda-payments/issues)
+- **Documentation**: Find more examples and guides in the [project documentation](https://github.com/projnanda/nanda-payments/docs)
+- **Contributing**: See [CONTRIBUTING.md](https://github.com/projnanda/nanda-payments/blob/main/CONTRIBUTING.md) for development setup
+
+## License
+
+MIT License - see [LICENSE](https://github.com/projnanda/nanda-payments/blob/main/LICENSE) for details.
\ No newline at end of file
diff --git a/sdks/payments-sdk/package-lock.json b/sdks/payments-sdk/package-lock.json
new file mode 100644
index 0000000..023cafe
--- /dev/null
+++ b/sdks/payments-sdk/package-lock.json
@@ -0,0 +1,3561 @@
+{
+ "name": "@nanda/payments-sdk",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@nanda/payments-sdk",
+ "version": "1.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "express": "^4.19.0",
+ "mongodb": "^6.0.0"
+ },
+ "devDependencies": {
+ "@types/express": "^5.0.1",
+ "@types/node": "^20.0.0",
+ "tsup": "^7.2.0",
+ "typescript": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "optionalDependencies": {
+ "@modelcontextprotocol/sdk": "*"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+ "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+ "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+ "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
+ "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+ "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+ "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+ "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+ "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+ "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+ "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+ "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+ "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+ "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+ "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+ "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+ "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+ "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+ "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+ "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "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/@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/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/@modelcontextprotocol/sdk": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.18.1.tgz",
+ "integrity": "sha512-d//GE8/Yh7aC3e7p+kZG8JqqEAwwDUmAfvH1quogtbk+ksS6E0RR6toKKESPYYZVre0meqkJb27zb+dhqE9Sgw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ajv": "^6.12.6",
+ "content-type": "^1.0.5",
+ "cors": "^2.8.5",
+ "cross-spawn": "^7.0.5",
+ "eventsource": "^3.0.2",
+ "eventsource-parser": "^3.0.0",
+ "express": "^5.0.1",
+ "express-rate-limit": "^7.5.0",
+ "pkce-challenge": "^5.0.0",
+ "raw-body": "^3.0.0",
+ "zod": "^3.23.8",
+ "zod-to-json-schema": "^3.24.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/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",
+ "optional": true,
+ "dependencies": {
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
+ "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.0",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.6.3",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.0",
+ "raw-body": "^3.0.0",
+ "type-is": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
+ "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/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",
+ "optional": true,
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/node_modules/express": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
+ "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "accepts": "^2.0.0",
+ "body-parser": "^2.2.0",
+ "content-disposition": "^1.0.0",
+ "content-type": "^1.0.5",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.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/@modelcontextprotocol/sdk/node_modules/finalhandler": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
+ "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
+ "license": "MIT",
+ "optional": true,
+ "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": ">= 0.8"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/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",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/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",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/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",
+ "optional": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/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",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
+ "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/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",
+ "optional": true
+ },
+ "node_modules/@modelcontextprotocol/sdk/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",
+ "optional": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/node_modules/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/node_modules/send": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
+ "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "debug": "^4.3.5",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "mime-types": "^3.0.1",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
+ "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/node_modules/type-is": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "content-type": "^1.0.5",
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@mongodb-js/saslprep": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.0.tgz",
+ "integrity": "sha512-zlayKCsIjYb7/IdfqxorK5+xUMyi4vOKcFy10wKJYc63NSdKI8mNME+uJqfatkPmOSMMUiojrL58IePKBm3gvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "sparse-bitfield": "^3.0.3"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "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/@types/body-parser": {
+ "version": "1.19.6",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
+ "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/express": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz",
+ "integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^5.0.0",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "5.0.7",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.7.tgz",
+ "integrity": "sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/http-errors": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
+ "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/mime": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
+ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "20.19.17",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.17.tgz",
+ "integrity": "sha512-gfehUI8N1z92kygssiuWvLiwcbOB3IRktR6hTDgJlXMYh5OvkPSRmgfoBUmfZt+vhwJtX7v1Yw4KvvAf7c5QKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
+ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/send": {
+ "version": "0.17.5",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz",
+ "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz",
+ "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-errors": "*",
+ "@types/node": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/webidl-conversions": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
+ "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/whatwg-url": {
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
+ "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/webidl-conversions": "*"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "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/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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/body-parser/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==",
+ "license": "MIT",
+ "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/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/bson": {
+ "version": "6.10.4",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz",
+ "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.20.1"
+ }
+ },
+ "node_modules/bundle-require": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.2.1.tgz",
+ "integrity": "sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "load-tsconfig": "^0.2.3"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "esbuild": ">=0.17"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "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/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "devOptional": 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==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "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/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
+ "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.18.20",
+ "@esbuild/android-arm64": "0.18.20",
+ "@esbuild/android-x64": "0.18.20",
+ "@esbuild/darwin-arm64": "0.18.20",
+ "@esbuild/darwin-x64": "0.18.20",
+ "@esbuild/freebsd-arm64": "0.18.20",
+ "@esbuild/freebsd-x64": "0.18.20",
+ "@esbuild/linux-arm": "0.18.20",
+ "@esbuild/linux-arm64": "0.18.20",
+ "@esbuild/linux-ia32": "0.18.20",
+ "@esbuild/linux-loong64": "0.18.20",
+ "@esbuild/linux-mips64el": "0.18.20",
+ "@esbuild/linux-ppc64": "0.18.20",
+ "@esbuild/linux-riscv64": "0.18.20",
+ "@esbuild/linux-s390x": "0.18.20",
+ "@esbuild/linux-x64": "0.18.20",
+ "@esbuild/netbsd-x64": "0.18.20",
+ "@esbuild/openbsd-x64": "0.18.20",
+ "@esbuild/sunos-x64": "0.18.20",
+ "@esbuild/win32-arm64": "0.18.20",
+ "@esbuild/win32-ia32": "0.18.20",
+ "@esbuild/win32-x64": "0.18.20"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "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/eventsource": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
+ "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "eventsource-parser": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/eventsource-parser": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz",
+ "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "license": "MIT",
+ "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.12",
+ "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"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/express-rate-limit": {
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz",
+ "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/express-rate-limit"
+ },
+ "peerDependencies": {
+ "express": ">= 4.11"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.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==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "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,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "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==",
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.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/foreground-child/node_modules/signal-exit": {
+ "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/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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": {
+ "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": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "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": {
+ "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,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/sponsors/ljharb"
+ }
+ },
+ "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.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/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"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "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,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "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",
+ "optional": true
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "devOptional": true,
+ "license": "ISC"
+ },
+ "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/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/joycon": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
+ "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "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,
+ "license": "MIT"
+ },
+ "node_modules/load-tsconfig": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz",
+ "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/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.4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/memory-pager": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/mongodb": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.20.0.tgz",
+ "integrity": "sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@mongodb-js/saslprep": "^1.3.0",
+ "bson": "^6.10.4",
+ "mongodb-connection-string-url": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=16.20.1"
+ },
+ "peerDependencies": {
+ "@aws-sdk/credential-providers": "^3.188.0",
+ "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
+ "gcp-metadata": "^5.2.0",
+ "kerberos": "^2.0.1",
+ "mongodb-client-encryption": ">=6.0.0 <7",
+ "snappy": "^7.3.2",
+ "socks": "^2.7.1"
+ },
+ "peerDependenciesMeta": {
+ "@aws-sdk/credential-providers": {
+ "optional": true
+ },
+ "@mongodb-js/zstd": {
+ "optional": true
+ },
+ "gcp-metadata": {
+ "optional": true
+ },
+ "kerberos": {
+ "optional": true
+ },
+ "mongodb-client-encryption": {
+ "optional": true
+ },
+ "snappy": {
+ "optional": true
+ },
+ "socks": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/mongodb-connection-string-url": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz",
+ "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/whatwg-url": "^11.0.2",
+ "whatwg-url": "^14.1.0 || ^13.0.0"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/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/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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-to-regexp": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+ "license": "MIT"
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pirates": {
+ "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"
+ }
+ },
+ "node_modules/pkce-challenge": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz",
+ "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
+ "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "lilconfig": "^3.0.0",
+ "yaml": "^2.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "peerDependencies": {
+ "postcss": ">=8.0.9",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "postcss": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.1.tgz",
+ "integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.7.0",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/raw-body/node_modules/iconv-lite": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
+ "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "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/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "3.29.5",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz",
+ "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=14.18.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "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",
+ "optional": true,
+ "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": ">= 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",
+ "optional": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "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",
+ "optional": true
+ },
+ "node_modules/router/node_modules/path-to-regexp": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
+ "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
+ "license": "MIT",
+ "optional": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "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"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/send": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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==",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.19.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "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.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/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"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.8.0-beta.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
+ "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
+ "deprecated": "The work that was done in this beta branch won't be included in future versions",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "whatwg-url": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/source-map/node_modules/tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/source-map/node_modules/webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/source-map/node_modules/whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "node_modules/sparse-bitfield": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+ "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
+ "license": "MIT",
+ "dependencies": {
+ "memory-pager": "^1.0.2"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.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": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
+ "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-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"
+ },
+ "engines": {
+ "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-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/sucrase": {
+ "version": "3.35.0",
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "commander": "^4.0.0",
+ "glob": "^10.3.10",
+ "lines-and-columns": "^1.1.6",
+ "mz": "^2.7.0",
+ "pirates": "^4.0.1",
+ "ts-interface-checker": "^0.1.9"
+ },
+ "bin": {
+ "sucrase": "bin/sucrase",
+ "sucrase-node": "bin/sucrase-node"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tree-kill": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "tree-kill": "cli.js"
+ }
+ },
+ "node_modules/ts-interface-checker": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/tsup": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/tsup/-/tsup-7.2.0.tgz",
+ "integrity": "sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bundle-require": "^4.0.0",
+ "cac": "^6.7.12",
+ "chokidar": "^3.5.1",
+ "debug": "^4.3.1",
+ "esbuild": "^0.18.2",
+ "execa": "^5.0.0",
+ "globby": "^11.0.3",
+ "joycon": "^3.0.1",
+ "postcss-load-config": "^4.0.1",
+ "resolve-from": "^5.0.0",
+ "rollup": "^3.2.5",
+ "source-map": "0.8.0-beta.0",
+ "sucrase": "^3.20.3",
+ "tree-kill": "^1.2.2"
+ },
+ "bin": {
+ "tsup": "dist/cli-default.js",
+ "tsup-node": "dist/cli-node.js"
+ },
+ "engines": {
+ "node": ">=16.14"
+ },
+ "peerDependencies": {
+ "@swc/core": "^1",
+ "postcss": "^8.4.12",
+ "typescript": ">=4.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tsup/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"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tsup/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/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
+ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "devOptional": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "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",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "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/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "license": "ISC",
+ "optional": true
+ },
+ "node_modules/yaml": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
+ "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ }
+ },
+ "node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "license": "MIT",
+ "optional": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/zod-to-json-schema": {
+ "version": "3.24.6",
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz",
+ "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==",
+ "license": "ISC",
+ "optional": true,
+ "peerDependencies": {
+ "zod": "^3.24.1"
+ }
+ }
+ }
+}
diff --git a/sdks/payments-sdk/package.json b/sdks/payments-sdk/package.json
new file mode 100644
index 0000000..4202d85
--- /dev/null
+++ b/sdks/payments-sdk/package.json
@@ -0,0 +1,72 @@
+{
+ "name": "@nanda/payments-sdk",
+ "version": "1.0.0",
+ "description": "NANDA Points payments SDK for x402-compliant servers and clients",
+ "type": "module",
+ "main": "dist/index.js",
+ "types": "dist/index.d.ts",
+ "exports": {
+ ".": {
+ "import": "./dist/index.js",
+ "types": "./dist/index.d.ts"
+ },
+ "./server": {
+ "import": "./dist/server/index.js",
+ "types": "./dist/server/index.d.ts"
+ },
+ "./client": {
+ "import": "./dist/client/index.js",
+ "types": "./dist/client/index.d.ts"
+ }
+ },
+ "files": [
+ "dist/**/*",
+ "README.md"
+ ],
+ "scripts": {
+ "build": "tsup src/index.ts src/server/index.ts --format esm --dts",
+ "dev": "tsup src/index.ts src/server/index.ts --format esm --dts --watch",
+ "test": "node --test dist/**/*.test.js",
+ "lint": "eslint . --ext .ts --fix",
+ "lint:check": "eslint . --ext .ts",
+ "format": "prettier --write \"**/*.{ts,js,json,md}\"",
+ "format:check": "prettier --check \"**/*.{ts,js,json,md}\"",
+ "prepublishOnly": "npm run build"
+ },
+ "dependencies": {
+ "express": "^4.19.0",
+ "mongodb": "^6.0.0"
+ },
+ "devDependencies": {
+ "@types/express": "^5.0.1",
+ "@types/node": "^20.0.0",
+ "tsup": "^7.2.0",
+ "typescript": "^5.3.0"
+ },
+ "optionalDependencies": {
+ "@modelcontextprotocol/sdk": "*"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/projnanda/x402-nanda-points.git",
+ "directory": "sdks/payments-sdk"
+ },
+ "keywords": [
+ "nanda-points",
+ "x402",
+ "payments",
+ "sdk",
+ "typescript",
+ "mcp",
+ "server",
+ "monetization"
+ ],
+ "author": "NANDA Project",
+ "license": "MIT",
+ "publishConfig": {
+ "access": "public"
+ }
+}
\ No newline at end of file
diff --git a/sdks/payments-sdk/src/examples/mcp-server-example.ts b/sdks/payments-sdk/src/examples/mcp-server-example.ts
new file mode 100644
index 0000000..393d61c
--- /dev/null
+++ b/sdks/payments-sdk/src/examples/mcp-server-example.ts
@@ -0,0 +1,260 @@
+/**
+ * Example MCP Server using @nanda/payments-sdk
+ *
+ * This demonstrates the "only way" for MCP developers to add payment requirements
+ * to their tools going forward.
+ *
+ * Before: All tools are free
+ * After: Some tools require NANDA Points payment
+ */
+
+import { Server } from '@modelcontextprotocol/sdk/server/index.js';
+import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
+import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
+
+// Import our NANDA Payments SDK
+import { quickSetup, ToolPaymentRequirement } from '@nanda/payments-sdk';
+
+// Initialize payment configuration
+const payments = quickSetup({
+ facilitatorUrl: process.env.FACILITATOR_URL || 'http://localhost:3001',
+ agentName: process.env.AGENT_NAME || 'example-mcp-server'
+});
+
+// Create MCP server
+const server = new Server(
+ {
+ name: 'nanda-payments-example',
+ version: '1.0.0',
+ },
+ {
+ capabilities: {
+ tools: {},
+ },
+ }
+);
+
+// ============================================================================
+// FREE TOOLS (unchanged from original MCP server)
+// ============================================================================
+
+/**
+ * Free weather tool - no payment required
+ * This is how tools work normally in MCP
+ */
+async function getWeatherTool(args: { location: string }) {
+ return {
+ content: [
+ {
+ type: 'text',
+ text: `Weather in ${args.location}: Sunny, 72°F. This is a free tool!`
+ }
+ ]
+ };
+}
+
+/**
+ * Free time tool - no payment required
+ */
+async function getCurrentTimeTool() {
+ return {
+ content: [
+ {
+ type: 'text',
+ text: `Current time: ${new Date().toISOString()}. This is also free!`
+ }
+ ]
+ };
+}
+
+// ============================================================================
+// PAID TOOLS (new with SDK)
+// ============================================================================
+
+/**
+ * Premium weather analysis - requires 5 NP payment
+ * This shows how to add payment requirements to existing tools
+ */
+const premiumWeatherRequirement: ToolPaymentRequirement = {
+ amount: 5,
+ description: 'Premium weather analysis with forecasts',
+ recipient: 'weather-service'
+};
+
+async function premiumWeatherTool(args: { location: string }) {
+ // This tool now requires payment before execution
+ return {
+ content: [
+ {
+ type: 'text',
+ text: `PREMIUM Weather Analysis for ${args.location}:
+
+🌤️ Current: Sunny, 72°F, Humidity 45%
+📈 Forecast:
+ - Tomorrow: Partly cloudy, High 75°F, Low 62°F
+ - This Week: Mild temperatures, 20% chance rain Thursday
+ - Air Quality: Good (AQI 42)
+ - UV Index: 6 (High)
+ - Wind: 8 mph NW
+
+💰 Payment received: 5 NP. Thank you for using premium services!`
+ }
+ ]
+ };
+}
+
+/**
+ * Code analysis tool - requires 10 NP payment
+ * Shows how to create a completely new paid tool
+ */
+const codeAnalysisRequirement: ToolPaymentRequirement = {
+ amount: 10,
+ description: 'Advanced code analysis and recommendations',
+ recipient: 'code-analyzer'
+};
+
+async function codeAnalysisTool(args: { code: string, language?: string }) {
+ return {
+ content: [
+ {
+ type: 'text',
+ text: `🔍 Advanced Code Analysis Results:
+
+Code Quality Score: 8.5/10
+Language: ${args.language || 'auto-detected'}
+
+📊 Analysis:
+- Complexity: Medium
+- Maintainability: High
+- Performance: Good
+- Security: No issues found
+
+💡 Recommendations:
+- Consider adding unit tests
+- Extract magic numbers to constants
+- Add error handling for edge cases
+
+💰 Analysis cost: 10 NP. Premium analysis complete!`
+ }
+ ]
+ };
+}
+
+// ============================================================================
+// MCP SERVER SETUP
+// ============================================================================
+
+// List all available tools
+server.setRequestHandler(ListToolsRequestSchema, async () => {
+ return {
+ tools: [
+ // Free tools
+ {
+ name: 'weather',
+ description: 'Get current weather for a location (FREE)',
+ inputSchema: {
+ type: 'object',
+ properties: {
+ location: {
+ type: 'string',
+ description: 'Location to get weather for'
+ }
+ },
+ required: ['location']
+ }
+ },
+ {
+ name: 'time',
+ description: 'Get current time (FREE)',
+ inputSchema: {
+ type: 'object',
+ properties: {}
+ }
+ },
+ // Paid tools - note the payment info in description
+ {
+ name: 'premium-weather',
+ description: 'Premium weather analysis with forecasts (5 NP)',
+ inputSchema: {
+ type: 'object',
+ properties: {
+ location: {
+ type: 'string',
+ description: 'Location for premium weather analysis'
+ }
+ },
+ required: ['location']
+ }
+ },
+ {
+ name: 'code-analysis',
+ description: 'Advanced code analysis and recommendations (10 NP)',
+ inputSchema: {
+ type: 'object',
+ properties: {
+ code: {
+ type: 'string',
+ description: 'Code to analyze'
+ },
+ language: {
+ type: 'string',
+ description: 'Programming language (optional)'
+ }
+ },
+ required: ['code']
+ }
+ }
+ ]
+ };
+});
+
+// Handle tool calls
+server.setRequestHandler(CallToolRequestSchema, async (request) => {
+ const { name, arguments: args } = request.params;
+
+ switch (name) {
+ // Free tools - work as normal
+ case 'weather':
+ return await getWeatherTool(args as { location: string });
+
+ case 'time':
+ return await getCurrentTimeTool();
+
+ // Paid tools - wrapped with payment requirements
+ case 'premium-weather':
+ // Use SDK to require payment before tool execution
+ const paidWeatherTool = payments.requirePayment(premiumWeatherRequirement)(
+ premiumWeatherTool
+ );
+ return await paidWeatherTool(args as { location: string });
+
+ case 'code-analysis':
+ // Use SDK to require payment for code analysis
+ const paidCodeTool = payments.requirePayment(codeAnalysisRequirement)(
+ codeAnalysisTool
+ );
+ return await paidCodeTool(args as { code: string, language?: string });
+
+ default:
+ throw new Error(`Unknown tool: ${name}`);
+ }
+});
+
+// ============================================================================
+// START SERVER
+// ============================================================================
+
+async function main() {
+ const transport = new StdioServerTransport();
+ await server.connect(transport);
+ console.error('NANDA Payments MCP Server running...');
+ console.error('Free tools: weather, time');
+ console.error('Paid tools: premium-weather (5 NP), code-analysis (10 NP)');
+}
+
+main().catch((error) => {
+ console.error('Server error:', error);
+ process.exit(1);
+});
+
+export { main };
\ No newline at end of file
diff --git a/sdks/payments-sdk/src/index.ts b/sdks/payments-sdk/src/index.ts
new file mode 100644
index 0000000..a53b28a
--- /dev/null
+++ b/sdks/payments-sdk/src/index.ts
@@ -0,0 +1,80 @@
+/**
+ * @nanda/payments-sdk
+ *
+ * NANDA Points payments SDK for x402-compliant servers and clients
+ * Primary focus: MCP server developers who want to monetize their tools
+ */
+
+// Main server-side exports (primary use case)
+export {
+ createPaymentConfig,
+ requirePayment,
+ createPaidTool,
+ paymentMiddleware,
+ createFacilitatorClient,
+ createPaymentRequirements,
+} from "./server/index.js";
+
+// Core types
+export type {
+ PaymentConfig,
+ ToolPaymentRequirement,
+ PaymentRequirements,
+ PaymentPayload,
+ VerificationResponse,
+ SettlementResponse,
+ NPReceipt,
+ NPAgent,
+ NPWallet,
+ NPTransaction,
+} from "./shared/types.js";
+
+// Import types for internal use
+import type { ToolPaymentRequirement } from "./shared/types.js";
+
+// Error classes
+export {
+ NPPaymentError,
+ NPVerificationError,
+ NPSettlementError,
+ NPNetworkError,
+} from "./shared/types.js";
+
+// Convenience functions
+export { createPaymentConfig as createConfig } from "./server/index.js";
+
+/**
+ * Quick setup function for MCP servers
+ *
+ * @example
+ * ```typescript
+ * import { quickSetup } from '@nanda/payments-sdk';
+ *
+ * const payments = quickSetup({
+ * facilitatorUrl: 'http://localhost:3001',
+ * agentName: 'my-mcp-server'
+ * });
+ *
+ * // Use payments.requirePayment() or payments.createPaidTool()
+ * ```
+ */
+export async function quickSetup(config: { facilitatorUrl: string; agentName: string }) {
+ const server = await import("./server/index.js");
+
+ const paymentConfig = server.createPaymentConfig(config);
+
+ return {
+ config: paymentConfig,
+ requirePayment: (requirement: ToolPaymentRequirement) =>
+ server.requirePayment(requirement, paymentConfig),
+ createPaidTool: >(
+ name: string,
+ requirement: ToolPaymentRequirement,
+ handler: (args: T, context?: any) => Promise
+ ) => server.createPaidTool(name, requirement, paymentConfig, handler),
+ facilitator: server.createFacilitatorClient(config.facilitatorUrl),
+ };
+}
+
+// Re-export everything from server for convenience
+export * from "./server/index.js";
\ No newline at end of file
diff --git a/sdks/payments-sdk/src/server/index.ts b/sdks/payments-sdk/src/server/index.ts
new file mode 100644
index 0000000..d46b4fb
--- /dev/null
+++ b/sdks/payments-sdk/src/server/index.ts
@@ -0,0 +1,278 @@
+/**
+ * Server-side utilities for NANDA Points payments
+ * Focused on MCP server developers who want to monetize their tools
+ */
+
+import {
+ PaymentConfig,
+ ToolPaymentRequirement,
+ PaymentRequirements,
+ PaymentPayload,
+ NPPaymentError,
+} from "../shared/types.js";
+import { createFacilitatorClient, createPaymentRequirements } from "../shared/facilitator.js";
+
+export * from "../shared/types.js";
+export { createFacilitatorClient, createPaymentRequirements } from "../shared/facilitator.js";
+
+/**
+ * Create payment configuration for your server
+ */
+export function createPaymentConfig(config: PaymentConfig): PaymentConfig {
+ return {
+ timeout: 30000,
+ retryCount: 3,
+ retryDelay: 1000,
+ ...config,
+ };
+}
+
+/**
+ * Require payment for a tool or function
+ * This is the main API for MCP server developers
+ */
+export function requirePayment any>(
+ requirement: ToolPaymentRequirement,
+ config: PaymentConfig
+) {
+ const facilitator = createFacilitatorClient(config.facilitatorUrl);
+
+ return function (originalTool: T): T {
+ return (async (...args: any[]) => {
+ // Extract payment from the first argument if it contains payment context
+ const firstArg = args[0];
+ const paymentHeader = firstArg?.headers?.["x-payment"] || firstArg?.payment;
+
+ if (!paymentHeader) {
+ // Return payment requirements
+ const requirements = createPaymentRequirements(
+ requirement.amount,
+ "tool://function",
+ requirement.description || "Payment required for tool execution",
+ requirement.recipient || config.agentName,
+ config.facilitatorUrl
+ );
+
+ throw new NPPaymentError(
+ "Payment required",
+ "PAYMENT_REQUIRED",
+ { requirements }
+ );
+ }
+
+ try {
+ // Decode and verify payment
+ const payment: PaymentPayload = typeof paymentHeader === 'string'
+ ? JSON.parse(atob(paymentHeader))
+ : paymentHeader;
+
+ const requirements = createPaymentRequirements(
+ requirement.amount,
+ "tool://function",
+ requirement.description || "Payment for tool execution",
+ requirement.recipient || config.agentName,
+ config.facilitatorUrl
+ );
+
+ // Verify payment
+ const verification = await facilitator.verify(payment, requirements);
+ if (!verification.isValid) {
+ throw new NPPaymentError(
+ "Payment verification failed",
+ "VERIFICATION_FAILED",
+ verification
+ );
+ }
+
+ // Execute the original tool
+ const result = await originalTool(...args);
+
+ // Settle payment after successful execution
+ try {
+ await facilitator.settle(payment, requirements);
+ } catch (settlementError) {
+ console.warn("Payment settlement failed:", settlementError);
+ // Don't fail the response for settlement issues
+ }
+
+ return result;
+
+ } catch (error) {
+ if (error instanceof NPPaymentError) {
+ throw error;
+ }
+ throw new NPPaymentError(
+ "Payment processing failed",
+ "PAYMENT_ERROR",
+ error
+ );
+ }
+ }) as T;
+ };
+}
+
+/**
+ * Create a payment-protected MCP tool handler
+ * This integrates with the @modelcontextprotocol/sdk patterns
+ */
+export function createPaidTool>(
+ toolName: string,
+ requirement: ToolPaymentRequirement,
+ config: PaymentConfig,
+ handler: (args: T, context?: any) => Promise
+) {
+ const facilitator = createFacilitatorClient(config.facilitatorUrl);
+
+ return {
+ name: toolName,
+ description: requirement.description || `Tool requiring ${requirement.amount} NP`,
+ inputSchema: {
+ type: "object",
+ properties: {},
+ },
+ handler: async (args: T, context?: any) => {
+ // Extract payment from context (this would come from MCP request headers)
+ const paymentHeader = context?.headers?.["x-payment"];
+
+ if (!paymentHeader) {
+ // Return payment requirements instead of executing tool
+ const requirements = createPaymentRequirements(
+ requirement.amount,
+ `tool://${toolName}`,
+ requirement.description || `Payment required for ${toolName}`,
+ requirement.recipient || config.agentName,
+ config.facilitatorUrl
+ );
+
+ throw new NPPaymentError(
+ "Payment required",
+ "PAYMENT_REQUIRED",
+ { requirements }
+ );
+ }
+
+ try {
+ // Decode payment
+ const payment: PaymentPayload = JSON.parse(atob(paymentHeader));
+
+ // Create requirements for verification
+ const requirements = createPaymentRequirements(
+ requirement.amount,
+ `tool://${toolName}`,
+ requirement.description || `Payment for ${toolName}`,
+ requirement.recipient || config.agentName,
+ config.facilitatorUrl
+ );
+
+ // Verify payment
+ const verification = await facilitator.verify(payment, requirements);
+ if (!verification.isValid) {
+ throw new NPPaymentError(
+ "Payment verification failed",
+ "VERIFICATION_FAILED",
+ verification
+ );
+ }
+
+ // Execute the tool
+ const result = await handler(args, context);
+
+ // Settle payment after successful execution
+ try {
+ await facilitator.settle(payment, requirements);
+ } catch (settlementError) {
+ console.warn("Payment settlement failed:", settlementError);
+ // Don't fail the response for settlement issues
+ }
+
+ return result;
+
+ } catch (error) {
+ if (error instanceof NPPaymentError) {
+ throw error;
+ }
+ throw new NPPaymentError(
+ "Payment processing failed",
+ "PAYMENT_ERROR",
+ error
+ );
+ }
+ }
+ };
+}
+
+/**
+ * Express middleware for payment verification
+ * For developers using Express.js servers
+ */
+export function paymentMiddleware(
+ routes: Record,
+ config: PaymentConfig
+) {
+ const facilitator = createFacilitatorClient(config.facilitatorUrl);
+
+ return async (req: any, res: any, next: any) => {
+ const routeConfig = routes[req.path] || routes[`${req.method} ${req.path}`];
+
+ if (!routeConfig) {
+ return next(); // No payment required
+ }
+
+ const payment = req.header("X-PAYMENT");
+
+ if (!payment) {
+ const requirements = createPaymentRequirements(
+ routeConfig.amount,
+ `${req.protocol}://${req.headers.host}${req.originalUrl}`,
+ routeConfig.description || `Payment required`,
+ routeConfig.recipient || config.agentName,
+ config.facilitatorUrl
+ );
+
+ return res.status(402).json({
+ x402Version: 1,
+ error: "X-PAYMENT header is required",
+ accepts: [requirements],
+ });
+ }
+
+ try {
+ const decodedPayment: PaymentPayload = JSON.parse(atob(payment));
+ const requirements = createPaymentRequirements(
+ routeConfig.amount,
+ `${req.protocol}://${req.headers.host}${req.originalUrl}`,
+ routeConfig.description || `Payment required`,
+ routeConfig.recipient || config.agentName,
+ config.facilitatorUrl
+ );
+
+ const verification = await facilitator.verify(decodedPayment, requirements);
+ if (!verification.isValid) {
+ return res.status(402).json({
+ x402Version: 1,
+ error: verification.invalidReason,
+ accepts: [requirements],
+ });
+ }
+
+ // Store payment info for settlement after successful response
+ req.payment = decodedPayment;
+ req.paymentRequirements = requirements;
+
+ return next();
+
+ } catch (error) {
+ return res.status(402).json({
+ x402Version: 1,
+ error: "Invalid payment header",
+ accepts: [createPaymentRequirements(
+ routeConfig.amount,
+ `${req.protocol}://${req.headers.host}${req.originalUrl}`,
+ routeConfig.description || `Payment required`,
+ routeConfig.recipient || config.agentName,
+ config.facilitatorUrl
+ )],
+ });
+ }
+ };
+}
\ No newline at end of file
diff --git a/sdks/payments-sdk/src/shared/facilitator.ts b/sdks/payments-sdk/src/shared/facilitator.ts
new file mode 100644
index 0000000..88fd7ec
--- /dev/null
+++ b/sdks/payments-sdk/src/shared/facilitator.ts
@@ -0,0 +1,116 @@
+/**
+ * NANDA Points facilitator client
+ * Handles communication with the NANDA Points facilitator service
+ */
+
+import {
+ PaymentRequirements,
+ PaymentPayload,
+ VerificationResponse,
+ SettlementResponse,
+ SupportedResponse,
+ NPPaymentError,
+} from "./types.js";
+
+export interface FacilitatorClient {
+ verify(
+ payment: PaymentPayload,
+ requirements: PaymentRequirements
+ ): Promise;
+ settle(
+ payment: PaymentPayload,
+ requirements: PaymentRequirements
+ ): Promise;
+ supported(): Promise;
+}
+
+/**
+ * Create NANDA Points facilitator client
+ * Provides x402-compliant communication with the facilitator
+ */
+export function createFacilitatorClient(facilitatorUrl: string): FacilitatorClient {
+ return {
+ async verify(payment, requirements) {
+ const response = await fetch(`${facilitatorUrl}/verify`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ "User-Agent": "@nanda/payments-sdk"
+ },
+ body: JSON.stringify({ payment, paymentRequirements: requirements }),
+ });
+
+ if (!response.ok) {
+ const error = await response.json();
+ return {
+ isValid: false,
+ invalidReason: error.invalidReason || "Verification failed",
+ };
+ }
+
+ return await response.json();
+ },
+
+ async settle(payment, requirements) {
+ const response = await fetch(`${facilitatorUrl}/settle`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ "User-Agent": "@nanda/payments-sdk"
+ },
+ body: JSON.stringify({ payment, paymentRequirements: requirements }),
+ });
+
+ const result = await response.json();
+ if (!response.ok) {
+ throw new NPPaymentError("Settlement failed", "SETTLEMENT_ERROR", result);
+ }
+
+ return result;
+ },
+
+ async supported() {
+ const response = await fetch(`${facilitatorUrl}/supported`, {
+ headers: {
+ "User-Agent": "@nanda/payments-sdk"
+ }
+ });
+
+ if (!response.ok) {
+ throw new NPPaymentError("Failed to get supported schemes", "FACILITATOR_ERROR");
+ }
+
+ return await response.json();
+ },
+ };
+}
+
+/**
+ * Create payment requirements for NANDA Points
+ */
+export function createPaymentRequirements(
+ amount: number,
+ resource: string,
+ description: string,
+ payTo: string,
+ facilitatorUrl: string,
+ options: {
+ timeout?: number;
+ mimeType?: string;
+ } = {}
+): PaymentRequirements {
+ return {
+ scheme: "nanda-points",
+ network: "nanda-network",
+ maxAmountRequired: amount.toString(),
+ resource,
+ description,
+ mimeType: options.mimeType || "application/json",
+ payTo,
+ maxTimeoutSeconds: options.timeout || 60,
+ asset: "NP",
+ extra: {
+ facilitatorUrl,
+ },
+ };
+}
\ No newline at end of file
diff --git a/sdks/payments-sdk/src/shared/types.ts b/sdks/payments-sdk/src/shared/types.ts
new file mode 100644
index 0000000..002562a
--- /dev/null
+++ b/sdks/payments-sdk/src/shared/types.ts
@@ -0,0 +1,154 @@
+/**
+ * Core x402 and NANDA Points types for the payments SDK
+ */
+
+// Core x402 types that maintain compatibility with the protocol
+export interface PaymentRequirements {
+ scheme: "nanda-points";
+ network: "nanda-network";
+ maxAmountRequired: string;
+ resource: string;
+ description: string;
+ mimeType: string;
+ payTo: string; // Agent name instead of blockchain address
+ maxTimeoutSeconds: number;
+ asset: "NP"; // NANDA Points
+ outputSchema?: unknown;
+ extra?: {
+ facilitatorUrl?: string;
+ [key: string]: unknown;
+ };
+}
+
+export interface PaymentPayload {
+ x402Version: number;
+ scheme: "nanda-points";
+ network: "nanda-network";
+ payTo: string; // Agent name
+ amount: string; // NP amount
+ from: string; // Paying agent name
+ txId: string; // NP transaction ID
+ timestamp: number;
+ extra?: {
+ [key: string]: unknown;
+ };
+}
+
+export interface VerificationResponse {
+ isValid: boolean;
+ invalidReason?: string;
+ payer?: string;
+ amount?: string;
+ txId?: string;
+}
+
+export interface SettlementResponse {
+ success: boolean;
+ txId: string;
+ amount: string;
+ from: string;
+ to: string;
+ timestamp: number;
+ errorReason?: string;
+ receipt?: NPReceipt;
+}
+
+export interface SupportedResponse {
+ kinds: Array<{
+ scheme: "nanda-points";
+ network: "nanda-network";
+ asset: "NP";
+ extra?: {
+ facilitatorUrl: string;
+ [key: string]: unknown;
+ };
+ }>;
+}
+
+// NANDA Points specific types
+export interface NPReceipt {
+ txId: string;
+ fromAgent: string;
+ toAgent: string;
+ amountMinor: number;
+ amountPoints: number;
+ timestamp: string;
+ fromBalanceAfter: number;
+ toBalanceAfter: number;
+}
+
+export interface NPAgent {
+ agent_name: string;
+ walletId: string;
+ serviceCharge: number;
+}
+
+export interface NPWallet {
+ walletId: string;
+ agent_name: string;
+ balanceMinor: number;
+ currency: "NP";
+ scale: 0;
+ createdAt: string;
+ updatedAt: string;
+}
+
+export interface NPTransaction {
+ txId: string;
+ fromAgent: string;
+ toAgent: string;
+ amountMinor: number;
+ status: "completed" | "pending" | "failed";
+ timestamp: string;
+ description?: string;
+}
+
+// SDK Configuration types
+export interface PaymentConfig {
+ facilitatorUrl: string;
+ agentName: string;
+ timeout?: number;
+ retryCount?: number;
+ retryDelay?: number;
+}
+
+export interface ToolPaymentRequirement {
+ amount: number;
+ description?: string;
+ recipient?: string;
+ timeout?: number;
+}
+
+// Error classes
+export class NPPaymentError extends Error {
+ constructor(
+ message: string,
+ public code: string,
+ public details?: unknown
+ ) {
+ super(message);
+ this.name = "NPPaymentError";
+ }
+}
+
+export class NPVerificationError extends NPPaymentError {
+ constructor(message: string, details?: unknown) {
+ super(message, "VERIFICATION_FAILED", details);
+ }
+}
+
+export class NPSettlementError extends NPPaymentError {
+ constructor(message: string, details?: unknown) {
+ super(message, "SETTLEMENT_FAILED", details);
+ }
+}
+
+export class NPNetworkError extends NPPaymentError {
+ constructor(message: string, details?: unknown) {
+ super(message, "NETWORK_ERROR", details);
+ }
+}
+
+// Utility types
+export type RequestMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS";
+export type PaymentStatus = "success" | "payment_required" | "error";
\ No newline at end of file
diff --git a/sdks/payments-sdk/tsconfig.json b/sdks/payments-sdk/tsconfig.json
new file mode 100644
index 0000000..b9e00e0
--- /dev/null
+++ b/sdks/payments-sdk/tsconfig.json
@@ -0,0 +1,26 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./dist",
+ "rootDir": "./src",
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true,
+ "strict": true,
+ "exactOptionalPropertyTypes": false,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "moduleResolution": "node",
+ "allowSyntheticDefaultImports": true,
+ "resolveJsonModule": true
+ },
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "node_modules",
+ "dist",
+ "**/*.test.ts"
+ ]
+}
\ No newline at end of file
diff --git a/src/api/README.md b/src/api/README.md
deleted file mode 100644
index 0b52337..0000000
--- a/src/api/README.md
+++ /dev/null
@@ -1,176 +0,0 @@
-# Nanda Points API Documentation
-
-This API provides endpoints for the UI teams to access wallet, transaction, and receipt information from the MongoDB backend.
-
-## Base URL
-
-- Development: `http://localhost:8080/api`
-- Production: `http://your-domain:8080/api`
-
-## Running the API Server
-
-```bash
-# Install dependencies
-npm install
-
-# Start the API server
-npm run api:server
-```
-
-## Endpoints
-
-### Wallets
-
-#### Get Wallet by Agent Name
-
-- **GET** `/wallets/agent/:agentName`
-- **Description**: Retrieves wallet information by agent name
-- **Parameters**:
- - `agentName` (string): The name of the agent
-- **Response**: Wallet object or 404 if not found
-
-#### Get All Wallets
-
-- **GET** `/wallets`
-- **Description**: Retrieves all wallets in the system
-- **Response**: Array of wallet objects
-
-#### Get Wallet by Wallet ID
-
-- **GET** `/wallets/id/:walletId`
-- **Description**: Retrieves wallet information by wallet ID
-- **Parameters**:
- - `walletId` (string): The unique wallet identifier
-- **Response**: Wallet object or 404 if not found
-
-### Transactions
-
-#### Get All Transactions
-
-- **GET** `/transactions`
-- **Description**: Retrieves all transactions in the system
-- **Response**: Array of transaction objects
-
-#### Get Transactions by Agent Name
-
-- **GET** `/transactions/agent/:agentName`
-- **Description**: Retrieves all transactions (sent and received) for a specific agent
-- **Parameters**:
- - `agentName` (string): The name of the agent
-- **Response**: Array of transaction objects
-
-#### Get Transaction by Transaction ID
-
-- **GET** `/transactions/id/:txId`
-- **Description**: Retrieves a specific transaction by its transaction ID
-- **Parameters**:
- - `txId` (string): The unique transaction identifier
-- **Response**: Transaction object or 404 if not found
-
-### Receipts
-
-#### Get All Receipts
-
-- **GET** `/receipts`
-- **Description**: Retrieves all receipts in the system
-- **Response**: Array of receipt objects
-
-#### Get Receipts by Agent Name
-
-- **GET** `/receipts/agent/:agentName`
-- **Description**: Retrieves all receipts (sent and received) for a specific agent
-- **Parameters**:
- - `agentName` (string): The name of the agent
-- **Response**: Array of receipt objects
-
-#### Get Receipt by Receipt ID
-
-- **GET** `/receipts/id/:id`
-- **Description**: Retrieves a specific receipt by its MongoDB \_id
-- **Parameters**:
- - `id` (string): The MongoDB ObjectId of the receipt
-- **Response**: Receipt object or 404 if not found
-
-#### Get Receipt by Transaction ID
-
-- **GET** `/receipts/transaction/:txId`
-- **Description**: Retrieves a receipt by its associated transaction ID
-- **Parameters**:
- - `txId` (string): The transaction ID associated with the receipt
-- **Response**: Receipt object or 404 if not found
-
-### Health Check
-
-#### API Health Check
-
-- **GET** `/health`
-- **Description**: Returns the health status of the API
-- **Response**: `{ "status": "OK", "message": "Nanda Points API is running" }`
-
-## Data Models
-
-### Wallet
-
-```typescript
-interface Wallet {
- _id?: ObjectId | string;
- walletId: string;
- agent_name: string;
- balanceMinor: MinorUnits;
- createdAt: string;
- updatedAt: string;
-}
-```
-
-### Transaction
-
-```typescript
-interface Txn {
- _id?: ObjectId | string;
- txId: string;
- fromAgent: string;
- toAgent: string;
- amountMinor: MinorUnits;
- currency: "NP";
- scale: 0;
- createdAt: string;
- status: "completed" | "rejected";
- error?: string | null;
- task: string; // Task that the transaction was completed for
-}
-```
-
-### Receipt
-
-```typescript
-interface Receipt {
- _id?: ObjectId | string;
- txId: string;
- issuedAt: string;
- fromAgent: string;
- toAgent: string;
- amountMinor: MinorUnits;
- fromBalanceAfter: MinorUnits;
- toBalanceAfter: MinorUnits;
-}
-```
-
-## Error Handling
-
-All endpoints return appropriate HTTP status codes:
-
-- `200`: Success
-- `404`: Resource not found
-- `500`: Internal server error
-
-Error responses follow this format:
-
-```json
-{
- "error": "Error message description"
-}
-```
-
-## CORS
-
-The API server includes CORS middleware to allow cross-origin requests from UI applications.
diff --git a/src/api/index.ts b/src/api/index.ts
deleted file mode 100644
index 88480af..0000000
--- a/src/api/index.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Router } from 'express';
-import walletApi from './walletApi.js';
-import transactionApi from './transactionApi.js';
-import receiptApi from './receiptApi.js';
-
-const router = Router();
-
-// Mount API routes
-router.use('/wallets', walletApi);
-router.use('/transactions', transactionApi);
-router.use('/receipts', receiptApi);
-
-// Health check endpoint
-router.get('/health', (req, res) => {
- res.json({ status: 'OK', message: 'Nanda Points API is running' });
-});
-
-export default router;
diff --git a/src/api/receiptApi.ts b/src/api/receiptApi.ts
deleted file mode 100644
index 6a9d8b7..0000000
--- a/src/api/receiptApi.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { Router } from 'express';
-import { Receipts } from '../services/database.js';
-
-const router = Router();
-
-// Get all receipts
-router.get('/', async (req, res) => {
- try {
- const receipts = await Receipts.find({}).toArray();
- res.json(receipts);
- } catch (error) {
- console.error('Error fetching all receipts:', error);
- res.status(500).json({ error: 'Internal server error' });
- }
-});
-
-// Get receipts by agent name (both sent and received)
-router.get('/agent/:agentName', async (req, res) => {
- try {
- const { agentName } = req.params;
- const receipts = await Receipts.find({
- $or: [
- { fromAgent: agentName },
- { toAgent: agentName }
- ]
- }).toArray();
-
- res.json(receipts);
- } catch (error) {
- console.error('Error fetching receipts by agent name:', error);
- res.status(500).json({ error: 'Internal server error' });
- }
-});
-
-// Get receipt by receipt ID (MongoDB _id)
-router.get('/id/:id', async (req, res) => {
- try {
- const { id } = req.params;
- const receipt = await Receipts.findOne({ _id: id });
-
- if (!receipt) {
- return res.status(404).json({ error: 'Receipt not found' });
- }
-
- res.json(receipt);
- } catch (error) {
- console.error('Error fetching receipt by ID:', error);
- res.status(500).json({ error: 'Internal server error' });
- }
-});
-
-// Get receipt by transaction ID
-router.get('/transaction/:txId', async (req, res) => {
- try {
- const { txId } = req.params;
- const receipt = await Receipts.findOne({ txId });
-
- if (!receipt) {
- return res.status(404).json({ error: 'Receipt not found' });
- }
-
- res.json(receipt);
- } catch (error) {
- console.error('Error fetching receipt by transaction ID:', error);
- res.status(500).json({ error: 'Internal server error' });
- }
-});
-
-export default router;
diff --git a/src/api/server.ts b/src/api/server.ts
deleted file mode 100644
index a8091e3..0000000
--- a/src/api/server.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import express from 'express';
-import cors from 'cors';
-import { initMongo } from '../services/index.js';
-import apiRoutes from './index.js';
-
-// Environment configuration
-const API_PORT = process.env.API_PORT ? parseInt(process.env.API_PORT, 10) : 8080;
-const HOST = process.env.HOST || 'localhost';
-
-// Initialize MongoDB connection
-await initMongo();
-
-// Create Express app
-const app = express();
-
-// Middleware
-app.use(cors());
-app.use(express.json());
-
-// Mount API routes
-app.use('/api', apiRoutes);
-
-// Root endpoint
-app.get('/', (req, res) => {
- res.json({
- message: 'Nanda Points API Server',
- version: '0.2.0',
- endpoints: {
- wallets: '/api/wallets',
- transactions: '/api/transactions',
- receipts: '/api/receipts',
- health: '/api/health'
- }
- });
-});
-
-// Start the API server
-app.listen(API_PORT, HOST, () => {
- console.log(`🚀 NANDA Points API Server running at http://${HOST}:${API_PORT}`);
- console.log(`📡 API endpoints: http://${HOST}:${API_PORT}/api`);
- console.log(`💊 Health check: http://${HOST}:${API_PORT}/api/health`);
-});
diff --git a/src/api/transactionApi.ts b/src/api/transactionApi.ts
deleted file mode 100644
index 9eb4e25..0000000
--- a/src/api/transactionApi.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { Router } from 'express';
-import { Transactions } from '../services/database.js';
-
-const router = Router();
-
-// Get all transactions
-router.get('/', async (req, res) => {
- try {
- const transactions = await Transactions.find({}).toArray();
- res.json(transactions);
- } catch (error) {
- console.error('Error fetching all transactions:', error);
- res.status(500).json({ error: 'Internal server error' });
- }
-});
-
-// Get transactions by agent name (both sent and received)
-router.get('/agent/:agentName', async (req, res) => {
- try {
- const { agentName } = req.params;
- const transactions = await Transactions.find({
- $or: [
- { fromAgent: agentName },
- { toAgent: agentName }
- ]
- }).toArray();
-
- res.json(transactions);
- } catch (error) {
- console.error('Error fetching transactions by agent name:', error);
- res.status(500).json({ error: 'Internal server error' });
- }
-});
-
-// Get transaction by transaction ID
-router.get('/id/:txId', async (req, res) => {
- try {
- const { txId } = req.params;
- const transaction = await Transactions.findOne({ txId });
-
- if (!transaction) {
- return res.status(404).json({ error: 'Transaction not found' });
- }
-
- res.json(transaction);
- } catch (error) {
- console.error('Error fetching transaction by ID:', error);
- res.status(500).json({ error: 'Internal server error' });
- }
-});
-
-export default router;
diff --git a/src/api/walletApi.ts b/src/api/walletApi.ts
deleted file mode 100644
index 61e43b8..0000000
--- a/src/api/walletApi.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { Router } from 'express';
-import { Wallets } from '../services/database.js';
-
-const router = Router();
-
-// Get wallet by agent name
-router.get('/agent/:agentName', async (req, res) => {
- try {
- const { agentName } = req.params;
- const wallet = await Wallets.findOne({ agent_name: agentName });
-
- if (!wallet) {
- return res.status(404).json({ error: 'Wallet not found' });
- }
-
- res.json(wallet);
- } catch (error) {
- console.error('Error fetching wallet by agent name:', error);
- res.status(500).json({ error: 'Internal server error' });
- }
-});
-
-// Get all wallets
-router.get('/', async (req, res) => {
- try {
- const wallets = await Wallets.find({}).toArray();
- res.json(wallets);
- } catch (error) {
- console.error('Error fetching all wallets:', error);
- res.status(500).json({ error: 'Internal server error' });
- }
-});
-
-// Get wallet by wallet ID
-router.get('/id/:walletId', async (req, res) => {
- try {
- const { walletId } = req.params;
- const wallet = await Wallets.findOne({ walletId });
-
- if (!wallet) {
- return res.status(404).json({ error: 'Wallet not found' });
- }
-
- res.json(wallet);
- } catch (error) {
- console.error('Error fetching wallet by ID:', error);
- res.status(500).json({ error: 'Internal server error' });
- }
-});
-
-export default router;
diff --git a/src/combined-server.ts b/src/combined-server.ts
deleted file mode 100644
index cd8339d..0000000
--- a/src/combined-server.ts
+++ /dev/null
@@ -1,332 +0,0 @@
-import express from "express";
-import { randomUUID } from "node:crypto";
-import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
-import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
-import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
-import { z } from "zod";
-import cors from "cors";
-import { NP } from "./models/index.js";
-import { initMongo } from "./services/index.js";
-import { getAgentWithWallet, getAgent, setAgentServiceCharge } from "./routes/agentRoutes.js";
-import { attachWallet } from "./routes/walletRoutes.js";
-import { getBalanceMinor } from "./routes/walletRoutes.js";
-import { transfer } from "./routes/transactionRoutes.js";
-import { getReceiptByTx } from "./routes/receiptRoutes.js";
-import apiRoutes from "./api/index.js";
-import { withPayment, NPToolConfig } from "./middleware/x402-mcp.js";
-
-// Environment configuration
-const MCP_PORT = process.env.MCP_PORT ? parseInt(process.env.MCP_PORT, 10) : 3000;
-const API_PORT = process.env.API_PORT ? parseInt(process.env.API_PORT, 10) : 8080;
-const HOST = process.env.HOST || '0.0.0.0';
-
-// Initialize MongoDB connection
-await initMongo();
-
-// Create Express app
-const app = express();
-app.use(express.json());
-app.use(cors());
-
-// Configure paid tools for x402-NP payment system
-const paidToolsConfig: { [toolName: string]: NPToolConfig } = {
- "getTimestamp": {
- priceNP: 1,
- recipient: "system", // System agent receives payments
- description: "Get current server timestamp"
- }
-};
-
-// Map to store transports by session ID for stateful connections
-const transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};
-
-// Create MCP server instance
-const server = new McpServer({ name: "nanda-points", version: "0.2.0" });
-
-server.registerTool(
- "getBalance",
- {
- title: "Get Balance (NP)",
- description: "Returns NP balance for an agent. Returns error if agent does not exist.",
- inputSchema: { agent_name: z.string().min(1) }
- },
- async ({ agent_name }) => {
- const agentWithWallet = await getAgentWithWallet(agent_name);
- if (!agentWithWallet) {
- return { content: [{ type: "text", text: JSON.stringify({ error: "AGENT_NOT_FOUND", agent_name }, null, 2) }] };
- }
- const balMinor = await getBalanceMinor(agent_name);
- const payload = { agent_name, currency: NP.code, scale: NP.scale, balanceMinor: balMinor, balancePoints: NP.toMajorUnits(balMinor) };
- return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
- }
-);
-
-server.registerTool(
- "initiateTransaction",
- {
- title: "Initiate Transaction (NP)",
- description: "Transfer NP from one agent to another and record ledger + receipt. Returns error if either agent does not exist.",
- inputSchema: {
- from: z.string().min(1),
- to: z.string().min(1),
- amount: z.number().int().positive(),
- task: z.string().min(1).describe("Task that the transaction was completed for")
- }
- },
- async ({ from, to, amount, task }) => {
- const fromAgent = await getAgentWithWallet(from);
- const toAgent = await getAgentWithWallet(to);
-
- if (!fromAgent) {
- return { content: [{ type: "text", text: JSON.stringify({ error: "SENDER_AGENT_NOT_FOUND", agent_name: from }, null, 2) }] };
- }
- if (!toAgent) {
- return { content: [{ type: "text", text: JSON.stringify({ error: "RECEIVER_AGENT_NOT_FOUND", agent_name: to }, null, 2) }] };
- }
-
- try {
- const { tx, receipt, payload } = await transfer(from, to, NP.toMinorUnits(amount), task);
- const result = {
- txId: tx.txId,
- status: tx.status,
- amountPoints: amount,
- currency: tx.currency,
- scale: tx.scale,
- from: tx.fromAgent,
- to: tx.toAgent,
- createdAt: tx.createdAt,
- receipt,
- payload // Receipt sent immediately to payer
- };
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
- } catch (err: any) {
- return { content: [{ type: "text", text: JSON.stringify({ error: String(err?.message || err) }, null, 2) }] };
- }
- }
-);
-
-server.registerTool(
- "getReceipt",
- { title: "Get Receipt", description: "Return receipt for a transaction id.", inputSchema: { txId: z.string().min(1) } },
- async ({ txId }) => {
- const r = await getReceiptByTx(txId);
- return { content: [{ type: "text", text: JSON.stringify(r ?? { error: "NOT_FOUND" }, null, 2) }] };
- }
-);
-
-server.registerTool(
- "getTimestamp",
- {
- title: "Get Server Timestamp",
- description: "Returns current server timestamp. Requires payment: 1 NP to system.",
- inputSchema: {
- _paymentAgent: z.string().optional(),
- _paymentTxId: z.string().optional(),
- _paymentAmount: z.string().optional()
- }
- },
- withPayment("getTimestamp", paidToolsConfig.getTimestamp, async () => {
- const timestamp = new Date().toISOString();
- const unixTimestamp = Math.floor(Date.now() / 1000);
-
- return {
- content: [{
- type: "text",
- text: JSON.stringify({
- timestamp,
- unixTimestamp,
- serverTime: timestamp,
- timezone: "UTC"
- }, null, 2)
- }]
- };
- })
-);
-
-server.registerTool(
- "setServiceCharge",
- { title: "Set Service Charge (NP)", description: "Set per-call service charge (points) on agent facts. Returns error if agent does not exist.", inputSchema: { agent_name: z.string().min(1), serviceChargePoints: z.number().int().nonnegative() } },
- async ({ agent_name, serviceChargePoints }) => {
- const agent = await getAgent(agent_name);
- if (!agent) {
- return { content: [{ type: "text", text: JSON.stringify({ error: "AGENT_NOT_FOUND", agent_name }, null, 2) }] };
- }
- await setAgentServiceCharge(agent_name, serviceChargePoints);
- const updated = await getAgent(agent_name);
- return { content: [{ type: "text", text: JSON.stringify({ agent_name, serviceCharge: updated?.serviceCharge }, null, 2) }] };
- }
-);
-
-server.registerTool(
- "getPaymentInfo",
- {
- title: "Get Payment Information",
- description: "Get x402-NP payment requirements for all paid tools. This tool is free to use.",
- inputSchema: {}
- },
- async () => {
- const paymentInfo = {
- protocol: "x402-np",
- currency: NP.code,
- scale: NP.scale,
- tools: paidToolsConfig,
- instructions: {
- steps: [
- "To use a paid tool, first call it normally to get a 402 Payment Required response",
- "Use the initiateTransaction tool to pay the required amount to the specified recipient",
- "Include the transaction ID in the X-PAYMENT-TX-ID header",
- "Include your agent name in the X-PAYMENT-AGENT header",
- "Include the payment amount in the X-PAYMENT-AMOUNT header",
- "Retry the original tool call with these headers"
- ]
- }
- };
- return { content: [{ type: "text", text: JSON.stringify(paymentInfo, null, 2) }] };
- }
-);
-
-server.registerTool(
- "attachWallet",
- {
- title: "Attach Wallet to Agent",
- description: "Attach a wallet to an agent. If the agent doesn't have a wallet, creates a new one and attaches it. If agent already has a wallet, returns the existing wallet. Returns error if agent does not exist.",
- inputSchema: {
- agent_name: z.string().min(1),
- seedPoints: z.number().int().nonnegative().optional().describe("Initial points to seed the wallet with (default: 1000)")
- }
- },
- async ({ agent_name, seedPoints }) => {
- const result = await attachWallet(agent_name, seedPoints);
- if (!result) {
- return { content: [{ type: "text", text: JSON.stringify({ error: "AGENT_NOT_FOUND", agent_name }, null, 2) }] };
- }
- return { content: [{ type: "text", text: JSON.stringify({
- agent_name,
- walletId: result.wallet.walletId,
- balanceMinor: result.wallet.balanceMinor,
- balancePoints: NP.toMajorUnits(result.wallet.balanceMinor),
- message: "Wallet successfully attached to agent"
- }, null, 2) }] };
- }
-);
-
-// MCP POST endpoint handler
-const mcpPostHandler = async (req: express.Request, res: express.Response) => {
- const sessionId = req.headers['mcp-session-id'] as string | undefined;
-
- if (sessionId) {
- console.log(`Received MCP request for session: ${sessionId}`);
- } else {
- console.log('New MCP request:', req.body);
- }
-
- try {
- let transport: StreamableHTTPServerTransport;
-
- if (sessionId && transports[sessionId]) {
- // Reuse existing transport
- transport = transports[sessionId];
- } else if (!sessionId && isInitializeRequest(req.body)) {
- // New initialization request
- transport = new StreamableHTTPServerTransport({
- sessionIdGenerator: () => randomUUID(),
- onsessioninitialized: (sessionId: string) => {
- // Store the transport by session ID when session is initialized
- console.log(`Session initialized with ID: ${sessionId}`);
- transports[sessionId] = transport;
- }
- });
-
- // Set up onclose handler to clean up transport when closed
- transport.onclose = () => {
- const sid = transport.sessionId;
- if (sid && transports[sid]) {
- console.log(`Transport closed for session ${sid}, removing from transports map`);
- delete transports[sid];
- }
- };
-
- // Connect the transport to the MCP server BEFORE handling the request
- await server.connect(transport);
- await transport.handleRequest(req, res, req.body);
- return; // Already handled
- } else {
- // Invalid request - no session ID or not initialization request
- res.status(400).json({
- jsonrpc: '2.0',
- error: {
- code: -32000,
- message: 'Bad Request: No valid session ID provided',
- },
- id: null,
- });
- return;
- }
-
- // Handle the request with existing transport
- await transport.handleRequest(req, res, req.body);
- } catch (error) {
- console.error('Error handling MCP request:', error);
- if (!res.headersSent) {
- res.status(500).json({
- jsonrpc: '2.0',
- error: {
- code: -32603,
- message: 'Internal server error',
- },
- id: null,
- });
- }
- }
-};
-
-// Handle GET requests for SSE streams
-const mcpGetHandler = async (req: express.Request, res: express.Response) => {
- const sessionId = req.headers['mcp-session-id'] as string | undefined;
-
- if (!sessionId || !transports[sessionId]) {
- res.status(400).send('Invalid or missing session ID');
- return;
- }
-
- console.log(`Establishing SSE stream for session ${sessionId}`);
- const transport = transports[sessionId];
- await transport.handleRequest(req, res);
-};
-
-// Set up MCP routes
-app.post('/mcp', mcpPostHandler);
-app.get('/mcp', mcpGetHandler);
-
-// Mount API routes
-app.use('/api', apiRoutes);
-
-// Health check endpoints
-app.get('/health', (req, res) => {
- res.json({ status: 'healthy', server: 'nanda-points-combined', version: '0.2.0' });
-});
-
-app.get('/api/health', (req, res) => {
- res.json({ status: 'OK', message: 'Nanda Points API is running' });
-});
-
-// Root endpoint
-app.get('/', (req, res) => {
- res.json({
- message: 'Nanda Points Combined Server',
- version: '0.2.0',
- services: {
- mcp: `http://${HOST}:${MCP_PORT}/mcp`,
- api: `http://${HOST}:${API_PORT}/api`,
- health: `http://${HOST}:${MCP_PORT}/health`
- }
- });
-});
-
-// Start the combined server
-app.listen(MCP_PORT, HOST, () => {
- console.log(`🚀 NANDA Points Combined Server running at http://${HOST}:${MCP_PORT}`);
- console.log(`📡 MCP endpoint: http://${HOST}:${MCP_PORT}/mcp`);
- console.log(`🌐 API endpoints: http://${HOST}:${MCP_PORT}/api`);
- console.log(`💊 Health check: http://${HOST}:${MCP_PORT}/health`);
-});
diff --git a/src/mcp/server.ts b/src/mcp/server.ts
deleted file mode 100644
index cc1a012..0000000
--- a/src/mcp/server.ts
+++ /dev/null
@@ -1,327 +0,0 @@
-import express from "express";
-import { randomUUID } from "node:crypto";
-import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
-import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
-import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
-import { z } from "zod";
-import { NP } from "../models/index.js";
-import { initMongo } from "../services/index.js";
-import { getAgentWithWallet, getAgent, setAgentServiceCharge } from "../routes/agentRoutes.js";
-import { attachWallet } from "../routes/walletRoutes.js";
-import { getBalanceMinor } from "../routes/walletRoutes.js";
-import { transfer } from "../routes/transactionRoutes.js";
-import { getReceiptByTx } from "../routes/receiptRoutes.js";
-import { withPayment, NPToolConfig } from "../middleware/x402-mcp.js";
-
-
-// Environment configuration
-const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3000;
-const HOST = process.env.HOST || 'localhost';
-
-// Initialize MongoDB connection
-await initMongo();
-
-console.log("🚨 DEBUG: Server starting with PAYMENT SYSTEM - v2.3 (getTimestamp PAID, getBalance/getReceipt FREE)");
-
-// Create Express app
-const app = express();
-app.use(express.json());
-
-// Configure paid tools for x402-NP payment system
-const paidToolsConfig: { [toolName: string]: NPToolConfig } = {
- "getTimestamp": {
- priceNP: 1,
- recipient: "system", // System agent receives payments
- description: "Get current server timestamp"
- }
-};
-
-// Map to store transports by session ID for stateful connections
-const transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};
-
-// Create MCP server instance
-const server = new McpServer({ name: "nanda-points", version: "0.2.0" });
-
-server.registerTool(
- "getBalance",
- {
- title: "Get Balance (NP)",
- description: "Returns NP balance for an agent. Returns error if agent does not exist. This tool is free to use.",
- inputSchema: {
- agent_name: z.string().min(1)
- }
- },
- async (args) => {
- const agent_name = args.agent_name as string;
-
- const agentWithWallet = await getAgentWithWallet(agent_name);
- if (!agentWithWallet) {
- return { content: [{ type: "text", text: JSON.stringify({ error: "AGENT_NOT_FOUND", agent_name }, null, 2) }] };
- }
-
- const balMinor = await getBalanceMinor(agent_name);
- const payload = { agent_name, currency: NP.code, scale: NP.scale, balanceMinor: balMinor, balancePoints: NP.toMajorUnits(balMinor) };
- return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
- }
-);
-
-server.registerTool(
- "initiateTransaction",
- {
- title: "Initiate Transaction (NP)",
-
- description: "Transfer NP from one agent to another and record ledger + receipt. Returns error if either agent does not exist. This tool is free to use.",
- inputSchema: {
- from: z.string().min(1),
- to: z.string().min(1),
- amount: z.number().int().positive(),
- task: z.string().min(1).describe("Task that the transaction was completed for")
- }
- },
- async ({ from, to, amount, task }) => {
- const fromAgent = await getAgentWithWallet(from);
- const toAgent = await getAgentWithWallet(to);
-
- if (!fromAgent) {
- return { content: [{ type: "text", text: JSON.stringify({ error: "SENDER_AGENT_NOT_FOUND", agent_name: from }, null, 2) }] };
- }
- if (!toAgent) {
- return { content: [{ type: "text", text: JSON.stringify({ error: "RECEIVER_AGENT_NOT_FOUND", agent_name: to }, null, 2) }] };
- }
-
- try {
-
- const { tx, receipt, payload } = await transfer(from, to, NP.toMinorUnits(amount), task);
- const result = {
- txId: tx.txId,
- status: tx.status,
- amountPoints: amount,
- currency: tx.currency,
- scale: tx.scale,
- from: tx.fromAgent,
- to: tx.toAgent,
- createdAt: tx.createdAt,
- receipt,
- payload // Receipt sent immediately to payer
- };
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
- } catch (err: any) {
- return { content: [{ type: "text", text: JSON.stringify({ error: String(err?.message || err) }, null, 2) }] };
- }
- }
-);
-
-server.registerTool(
- "getReceipt",
- {
- title: "Get Receipt",
- description: "Return receipt for a transaction id. This tool is free to use.",
- inputSchema: {
- txId: z.string().min(1)
- }
- },
- async (args) => {
- const txId = args.txId as string;
- const r = await getReceiptByTx(txId);
- return { content: [{ type: "text", text: JSON.stringify(r ?? { error: "NOT_FOUND" }, null, 2) }] };
- }
-);
-
-server.registerTool(
- "getTimestamp",
- {
- title: "Get Server Timestamp",
- description: "Returns current server timestamp. Requires payment: 1 NP to system.",
- inputSchema: {
- _paymentAgent: z.string().optional(),
- _paymentTxId: z.string().optional(),
- _paymentAmount: z.string().optional()
- }
- },
- withPayment("getTimestamp", paidToolsConfig.getTimestamp, async () => {
- const timestamp = new Date().toISOString();
- const unixTimestamp = Math.floor(Date.now() / 1000);
-
- return {
- content: [{
- type: "text",
- text: JSON.stringify({
- timestamp,
- unixTimestamp,
- serverTime: timestamp,
- timezone: "UTC"
- }, null, 2)
- }]
- };
- })
-);
-
-server.registerTool(
- "setServiceCharge",
- { title: "Set Service Charge (NP)", description: "Set per-call service charge (points) on agent facts. Returns error if agent does not exist.", inputSchema: { agent_name: z.string().min(1), serviceChargePoints: z.number().int().nonnegative() } },
- async (args) => {
- const agent_name = args.agent_name as string;
- const serviceChargePoints = args.serviceChargePoints as number;
- const agent = await getAgent(agent_name);
- if (!agent) {
- return { content: [{ type: "text", text: JSON.stringify({ error: "AGENT_NOT_FOUND", agent_name }, null, 2) }] };
- }
- await setAgentServiceCharge(agent_name, serviceChargePoints);
- const updated = await getAgent(agent_name);
- return { content: [{ type: "text", text: JSON.stringify({ agent_name, serviceCharge: updated?.serviceCharge }, null, 2) }] };
- }
-);
-
-server.registerTool(
- "getPaymentInfo",
- {
- title: "Get Payment Information",
- description: "Get x402-NP payment requirements for all paid tools. This tool is free to use.",
- inputSchema: {}
- },
- async () => {
- const paymentInfo = {
- protocol: "x402-np",
- currency: NP.code,
- scale: NP.scale,
- tools: paidToolsConfig,
- instructions: {
- steps: [
- "To use a paid tool, first call it normally to get a 402 Payment Required response",
- "Use the initiateTransaction tool to pay the required amount to the specified recipient",
- "Include the transaction ID in the X-PAYMENT-TX-ID header",
- "Include your agent name in the X-PAYMENT-AGENT header",
- "Include the payment amount in the X-PAYMENT-AMOUNT header",
- "Retry the original tool call with these headers"
- ]
- }
- };
- return { content: [{ type: "text", text: JSON.stringify(paymentInfo, null, 2) }] };
- }
-);
-
- server.registerTool(
- "attachWallet",
- {
- title: "Attach Wallet to Agent",
- description: "Attach a wallet to an agent. If the agent doesn't have a wallet, creates a new one and attaches it. If agent already has a wallet, returns the existing wallet. Returns error if agent does not exist.",
- inputSchema: {
- agent_name: z.string().min(1),
- seedPoints: z.number().int().nonnegative().optional().describe("Initial points to seed the wallet with (default: 1000)")
- }
- },
- async ({ agent_name, seedPoints }) => {
- const result = await attachWallet(agent_name, seedPoints);
- if (!result) {
- return { content: [{ type: "text", text: JSON.stringify({ error: "AGENT_NOT_FOUND", agent_name }, null, 2) }] };
- }
- return { content: [{ type: "text", text: JSON.stringify({
- agent_name,
- walletId: result.wallet.walletId,
- balanceMinor: result.wallet.balanceMinor,
- balancePoints: NP.toMajorUnits(result.wallet.balanceMinor),
- message: "Wallet successfully attached to agent"
- }, null, 2) }] };
-
- }
-);
-
-// MCP POST endpoint handler
-const mcpPostHandler = async (req: express.Request, res: express.Response) => {
- const sessionId = req.headers['mcp-session-id'] as string | undefined;
-
- if (sessionId) {
- console.log(`Received MCP request for session: ${sessionId}`);
- } else {
- console.log('New MCP request:', req.body);
- }
-
- try {
- let transport: StreamableHTTPServerTransport;
-
- if (sessionId && transports[sessionId]) {
- // Reuse existing transport
- transport = transports[sessionId];
- } else if (!sessionId && isInitializeRequest(req.body)) {
- // New initialization request
- transport = new StreamableHTTPServerTransport({
- sessionIdGenerator: () => randomUUID(),
- onsessioninitialized: (sessionId: string) => {
- // Store the transport by session ID when session is initialized
- console.log(`Session initialized with ID: ${sessionId}`);
- transports[sessionId] = transport;
- }
- });
-
- // Set up onclose handler to clean up transport when closed
- transport.onclose = () => {
- const sid = transport.sessionId;
- if (sid && transports[sid]) {
- console.log(`Transport closed for session ${sid}, removing from transports map`);
- delete transports[sid];
- }
- };
-
- // Connect the transport to the MCP server BEFORE handling the request
- await server.connect(transport);
- await transport.handleRequest(req, res, req.body);
- return; // Already handled
- } else {
- // Invalid request - no session ID or not initialization request
- res.status(400).json({
- jsonrpc: '2.0',
- error: {
- code: -32000,
- message: 'Bad Request: No valid session ID provided',
- },
- id: null,
- });
- return;
- }
-
- // Handle the request with existing transport
- await transport.handleRequest(req, res, req.body);
- } catch (error) {
- console.error('Error handling MCP request:', error);
- if (!res.headersSent) {
- res.status(500).json({
- jsonrpc: '2.0',
- error: {
- code: -32603,
- message: 'Internal server error',
- },
- id: null,
- });
- }
- }
-};
-
-// Handle GET requests for SSE streams
-const mcpGetHandler = async (req: express.Request, res: express.Response) => {
- const sessionId = req.headers['mcp-session-id'] as string | undefined;
-
- if (!sessionId || !transports[sessionId]) {
- res.status(400).send('Invalid or missing session ID');
- return;
- }
-
- console.log(`Establishing SSE stream for session ${sessionId}`);
- const transport = transports[sessionId];
- await transport.handleRequest(req, res);
-};
-
-// Set up MCP routes
-app.post('/mcp', mcpPostHandler);
-app.get('/mcp', mcpGetHandler);
-
-// Health check endpoint
-app.get('/health', (_req, res) => {
- res.json({ status: 'healthy', server: 'nanda-points-mcp', version: '0.2.0' });
-});
-
-// Start the HTTP server
-app.listen(PORT, HOST, () => {
- console.log(`🚀 NANDA Points MCP Server running at http://${HOST}:${PORT}`);
- console.log(`📡 MCP endpoint: http://${HOST}:${PORT}/mcp`);
- console.log(`💊 Health check: http://${HOST}:${PORT}/health`);
-});
diff --git a/src/middleware/x402-mcp.ts b/src/middleware/x402-mcp.ts
deleted file mode 100644
index 99e94a6..0000000
--- a/src/middleware/x402-mcp.ts
+++ /dev/null
@@ -1,204 +0,0 @@
-import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
-import { getReceiptByTx } from '../routes/receiptRoutes.js';
-import { getAgentWithWallet } from '../routes/agentRoutes.js';
-import { NP } from '../models/index.js';
-import type { Receipt } from '../models/receipt.js';
-
-export interface NPToolConfig {
- readonly priceNP: number; // Price in NP points
- readonly recipient: string; // Receiving agent name
- readonly description?: string;
-}
-
-interface PaymentHeaders {
- readonly agent: string;
- readonly txId: string;
- readonly amount: string;
-}
-
-// MCP tool handler type - takes parsed arguments and returns result
-type MCPToolHandler = (args: Record) => Promise;
-
-/**
- * Wraps an MCP tool handler with x402-NP payment verification
- */
-export function withPayment(
- toolName: string,
- config: NPToolConfig,
- handler: MCPToolHandler
-): MCPToolHandler {
- return async (args: Record): Promise => {
- console.log(`🔍 Payment wrapper called for ${toolName} with args:`, args);
-
- // Extract payment headers from the arguments
- const paymentHeaders = extractPaymentHeaders(args);
-
- if (!paymentHeaders) {
- console.log(`💰 No payment provided for ${toolName}, requiring payment`);
- // Return 402 Payment Required response
- return createPaymentRequiredResponse(toolName, config);
- }
-
- console.log(`🔐 Payment headers found for ${toolName}:`, paymentHeaders);
-
- // Verify payment
- const verificationResult = await verifyPayment(paymentHeaders, config);
- if (!verificationResult.success) {
- console.log(`❌ Payment verification failed for ${toolName}:`, verificationResult.error);
- return createErrorResponse(verificationResult.error!);
- }
-
- console.log(`✅ Payment verified: ${paymentHeaders.agent} paid ${verificationResult.amount} NP to ${config.recipient} for ${toolName}`);
-
- // Payment verified, execute the original handler with cleaned args
- const cleanArgs = { ...args };
- delete cleanArgs._paymentAgent;
- delete cleanArgs._paymentTxId;
- delete cleanArgs._paymentAmount;
-
- return await handler(cleanArgs);
- };
-}
-
-function extractPaymentHeaders(args: Record): PaymentHeaders | null {
- // In MCP, we need to pass payment info through the arguments
- // This is a limitation of the MCP protocol - we'll use special argument fields
- const agent = args._paymentAgent as string;
- const txId = args._paymentTxId as string;
- const amount = args._paymentAmount as string;
-
- if (!agent || !txId || !amount) {
- return null;
- }
-
- return { agent, txId, amount };
-}
-
-function createPaymentRequiredResponse(toolName: string, config: NPToolConfig): CallToolResult {
- const paymentInfo = {
- error: 'PAYMENT_REQUIRED',
- protocol: 'x402-np',
- tool: toolName,
- price: {
- amount: config.priceNP,
- currency: NP.code,
- scale: NP.scale,
- recipient: config.recipient
- },
- description: config.description ?? `Payment required for ${toolName}`,
- instructions: {
- steps: [
- `Use initiateTransaction tool to transfer ${config.priceNP} NP from your agent to ${config.recipient}`,
- 'Include the payment details when calling this tool:',
- '- Add "_paymentAgent": "your-agent-name" to arguments',
- '- Add "_paymentTxId": "transaction-id" to arguments',
- '- Add "_paymentAmount": "amount-paid" to arguments',
- 'Retry the tool call with payment arguments'
- ]
- }
- };
-
- return {
- content: [{
- type: 'text',
- text: JSON.stringify(paymentInfo, null, 2)
- }]
- };
-}
-
-interface PaymentVerificationResult {
- readonly success: boolean;
- readonly error?: {
- readonly message: string;
- readonly data?: unknown;
- };
- readonly amount?: number;
- readonly receipt?: Receipt;
-}
-
-async function verifyPayment(
- headers: PaymentHeaders,
- toolConfig: NPToolConfig
-): Promise {
- // Verify payment amount matches tool price
- const amountNP = parseFloat(headers.amount);
- if (Number.isNaN(amountNP) || amountNP !== toolConfig.priceNP) {
- return {
- success: false,
- error: {
- message: 'Invalid payment amount',
- data: {
- expected: toolConfig.priceNP,
- received: amountNP
- }
- }
- };
- }
-
- // Verify paying agent exists
- const payingAgent = await getAgentWithWallet(headers.agent);
- if (!payingAgent) {
- return {
- success: false,
- error: {
- message: 'Invalid payment agent',
- data: { agent: headers.agent }
- }
- };
- }
-
- // Verify payment receipt
- const receipt = await getReceiptByTx(headers.txId);
- if (!receipt) {
- return {
- success: false,
- error: {
- message: 'Payment receipt not found',
- data: { txId: headers.txId }
- }
- };
- }
-
- // Verify receipt details match payment
- const receiptAmountNP = NP.toMajorUnits(receipt.amountMinor);
- if (receipt.fromAgent !== headers.agent ||
- receipt.toAgent !== toolConfig.recipient ||
- receiptAmountNP !== toolConfig.priceNP) {
- return {
- success: false,
- error: {
- message: 'Payment verification failed',
- data: {
- expected: {
- from: headers.agent,
- to: toolConfig.recipient,
- amount: toolConfig.priceNP
- },
- actual: {
- from: receipt.fromAgent,
- to: receipt.toAgent,
- amount: receiptAmountNP
- }
- }
- }
- };
- }
-
- return {
- success: true,
- amount: amountNP,
- receipt
- };
-}
-
-function createErrorResponse(error: { message: string; data?: unknown }): CallToolResult {
- return {
- content: [{
- type: 'text',
- text: JSON.stringify({
- error: error.message,
- details: error.data
- }, null, 2)
- }]
- };
-}
\ No newline at end of file
diff --git a/src/models/Agent.ts b/src/models/Agent.ts
deleted file mode 100644
index 16afb3c..0000000
--- a/src/models/Agent.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-
-// === Agent Facts ===
-// Based on the provided agent format with serviceCharge added
-export interface AgentFacts {
- _id?: string; // registry id (e.g., "agt_8f21c9"); Mongo may also supply ObjectId if omitted
- id: string; // unique agent identifier
- agent_name: string;
- label: string;
- description: string;
- version: string;
- documentationUrl: string;
- jurisdiction: string;
- provider: {
- name: string;
- url: string;
- did: string;
- };
- endpoints: {
- static: string[];
- adaptive_resolver: {
- url: string;
- policies: any[];
- };
- };
- capabilities: {
- modalities: string[];
- streaming: boolean;
- batch: boolean;
- authentication: {
- methods: any[];
- requiredScopes: any[];
- };
- };
- skills: Array<{
- id: string;
- description: string;
- inputModes: string[];
- outputModes: string[];
- supportedLanguages: string[];
- }>;
- evaluations: {
- performanceScore: number;
- availability90d: string;
- lastAudited: string;
- auditTrail: string;
- auditorID: string;
- };
- telemetry: {
- enabled: boolean;
- retention: string;
- sampling: number;
- metrics: {
- latency_p95_ms: number;
- throughput_rps: number;
- error_rate: number;
- availability: string;
- };
- };
- certification: {
- level: string;
- issuer: string;
- issuanceDate: string;
- expirationDate: string;
- };
- username: string;
- email: string;
- created_at: string; // ISO
- updated_at: string; // ISO
-
- // Added: wallet ID and service charge
- walletId?: string; // unique wallet identifier
- serviceCharge?: number; // default 10 NP, in POINTS (not minor units)
-}
diff --git a/src/models/Transaction.ts b/src/models/Transaction.ts
deleted file mode 100644
index 3e029cb..0000000
--- a/src/models/Transaction.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { ObjectId } from 'mongodb';
-import { MinorUnits } from './points';
-
-export interface Txn {
- _id?: ObjectId | string; // Mongo _id
- txId: string; // uuid string
- fromAgent: string; // agent_name of sender
- toAgent: string; // agent_name of receiver
- amountMinor: MinorUnits;
- currency: "NP";
- scale: 0;
- createdAt: string;
- status: "completed" | "rejected";
- error?: string | null;
- task: string; // task that the transaction was completed for
-}
diff --git a/src/models/Wallet.ts b/src/models/Wallet.ts
deleted file mode 100644
index a9c3d1f..0000000
--- a/src/models/Wallet.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { ObjectId } from 'mongodb';
-import { MinorUnits } from './points';
-
-// Wallet (linked by agent_name; NOT embedded on agent facts)
-export interface Wallet {
- _id?: ObjectId | string;
- walletId: string; // unique wallet identifier
- agent_name: string; // FK to AgentFacts.agent_name
- balanceMinor: MinorUnits; // >= 0, always in NP minor units
- createdAt: string;
- updatedAt: string;
-}
diff --git a/src/models/index.ts b/src/models/index.ts
deleted file mode 100644
index e94ec81..0000000
--- a/src/models/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-// Re-export all models and utilities
-export * from './points.js';
-export * from './agent.js';
-export * from './wallet.js';
-export * from './transaction.js';
-export * from './receipt.js';
diff --git a/src/models/points.ts b/src/models/points.ts
deleted file mode 100644
index 403e40e..0000000
--- a/src/models/points.ts
+++ /dev/null
@@ -1,217 +0,0 @@
-/**
- * Points Schema and Management
- *
- * Centralized points definitions, validation, and conversion logic.
- * Supports multiple point systems with different scales and properties.
- */
-
-// Base types for point amounts
-export type MinorUnits = number & { readonly __brand: unique symbol }; // Branded type for integer validation
-export type MajorUnits = number; // User-facing amounts (e.g., dollars, points)
-
-// Helper to create validated MinorUnits
-export function createMinorUnits(value: number): MinorUnits {
- if (!Number.isInteger(value)) {
- throw new TypeError(`MinorUnits must be an integer, got: ${value}`);
- }
- if (value < 0) {
- throw new RangeError(`MinorUnits must be non-negative, got: ${value}`);
- }
- return value as MinorUnits;
-}
-
-// Result types using discriminated unions
-export type ValidationResult =
- | { valid: true }
- | { valid: false; error: string };
-
-export type ParseResult =
- | { success: true; amount: MinorUnits }
- | { success: false; error: string };
-
-/**
- * Points Definition Schema
- *
- * Defines all properties and behaviors of a point system
- */
-export interface PointsDefinition {
- /** Points code (ISO-like, e.g., "USD", "NP") */
- readonly code: string;
-
- /** Human-readable name */
- readonly name: string;
-
- /** Points symbol for display */
- readonly symbol: string;
-
- /** Number of decimal places (e.g., 2 for USD cents, 0 for whole units) */
- readonly scale: number;
-
- /** Smallest unit name (e.g., "cent", "satoshi", "wei") */
- readonly minorUnitName: string;
-
- /** Major unit name (e.g., "dollar", "point", "token") */
- readonly majorUnitName: string;
-
- /** Maximum amount allowed in minor units */
- readonly maxAmount: MinorUnits;
-
- /** Minimum amount allowed in minor units */
- readonly minAmount: MinorUnits;
-}
-
-/**
- * Points Operations Interface
- *
- * Provides all operations for a specific point system
- */
-export interface PointsOperations {
- /** Convert major units to minor units for storage */
- toMinorUnits(majorAmount: MajorUnits): MinorUnits;
-
- /** Convert minor units to major units for display */
- toMajorUnits(minorAmount: MinorUnits): MajorUnits;
-
- /** Format amount for user display */
- format(minorAmount: MinorUnits): string;
-
- /** Validate amount is within points limits */
- validate(minorAmount: MinorUnits): ValidationResult;
-
- /** Parse user input string to minor units */
- parse(input: string): ParseResult;
-}
-
-/**
- * Complete Points Implementation
- */
-export class Points implements PointsOperations {
- constructor(private definition: PointsDefinition) {}
-
- get code(): string { return this.definition.code; }
- get name(): string { return this.definition.name; }
- get symbol(): string { return this.definition.symbol; }
- get scale(): number { return this.definition.scale; }
- get majorUnitName(): string { return this.definition.majorUnitName; }
- get minorUnitName(): string { return this.definition.minorUnitName; }
-
- toMinorUnits(majorAmount: MajorUnits): MinorUnits {
- const factor = Math.pow(10, this.definition.scale);
- return createMinorUnits(Math.trunc(majorAmount * factor));
- }
-
- toMajorUnits(minorAmount: MinorUnits): MajorUnits {
- const factor = Math.pow(10, this.definition.scale);
- return minorAmount / factor;
- }
-
- format(minorAmount: MinorUnits): string {
- const majorAmount = this.toMajorUnits(minorAmount);
- const formatted = this.definition.scale === 0
- ? majorAmount.toString()
- : majorAmount.toFixed(this.definition.scale);
-
- return `${formatted} ${this.definition.symbol}`;
- }
-
- validate(minorAmount: MinorUnits): ValidationResult {
- if (!Number.isInteger(minorAmount)) {
- return { valid: false, error: "Amount must be an integer in minor units" };
- }
-
- if (minorAmount < this.definition.minAmount) {
- return { valid: false, error: `Amount below minimum (${this.format(this.definition.minAmount)})` };
- }
-
- if (minorAmount > this.definition.maxAmount) {
- return { valid: false, error: `Amount above maximum (${this.format(this.definition.maxAmount)})` };
- }
-
- return { valid: true };
- }
-
- parse(input: string): ParseResult {
- const cleaned = input.trim().replace(this.definition.symbol, '').trim();
- const parsed = parseFloat(cleaned);
-
- if (isNaN(parsed)) {
- return { success: false, error: `Invalid ${this.definition.name} amount: "${input}"` };
- }
-
- const minorAmount = this.toMinorUnits(parsed);
- const validation = this.validate(minorAmount);
-
- if (!validation.valid) {
- return { success: false, error: validation.error };
- }
-
- return { success: true, amount: minorAmount };
- }
-}
-
-// =====================================================
-// NANDA Points (NP) Definition
-// =====================================================
-
-/**
- * NANDA Points Definition
- *
- * - Whole number points (no fractional units)
- * - 1:1 mapping between major and minor units
- * - Symbol: "NP"
- * - Scale: 0 (no decimal places)
- */
-export const NANDA_POINTS_DEFINITION: PointsDefinition = {
- code: "NP",
- name: "NANDA Points",
- symbol: "NP",
- scale: 0,
- minorUnitName: "point",
- majorUnitName: "point",
- maxAmount: createMinorUnits(Number.MAX_SAFE_INTEGER), // ~9 quadrillion points
- minAmount: createMinorUnits(0)
-} as const;
-
-/**
- * Global NANDA Points Instance
- *
- * Use this singleton for all NP operations throughout the application
- */
-export const NP = new Points(NANDA_POINTS_DEFINITION);
-
-// =====================================================
-// Legacy Compatibility Exports
-// =====================================================
-
-/** @deprecated Use NP.code instead */
-export const NP_CURRENCY = NP.code;
-
-/** @deprecated Use NP.scale instead */
-export const NP_SCALE = NP.scale;
-
-/** @deprecated Use NP.toMinorUnits() instead */
-export const toMinor = (points: MajorUnits): MinorUnits => NP.toMinorUnits(points);
-
-/** @deprecated Use NP.toMajorUnits() instead */
-export const toPoints = (minor: MinorUnits): MajorUnits => NP.toMajorUnits(minor);
-
-/** @deprecated Use MinorUnits type instead */
-export type Minor = MinorUnits;
-
-// =====================================================
-// Points Registry (for future multi-points support)
-// =====================================================
-
-export const SUPPORTED_POINTS = {
- NP: NP
-} as const;
-
-export type SupportedPointsCode = keyof typeof SUPPORTED_POINTS;
-
-export function getPoints(code: SupportedPointsCode): Points {
- return SUPPORTED_POINTS[code];
-}
-
-export function isSupportedPoints(code: string): code is SupportedPointsCode {
- return code in SUPPORTED_POINTS;
-}
\ No newline at end of file
diff --git a/src/models/receipt.ts b/src/models/receipt.ts
deleted file mode 100644
index ab7a789..0000000
--- a/src/models/receipt.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { ObjectId } from 'mongodb';
-import { MinorUnits } from './points';
-
-export interface Receipt {
- _id?: ObjectId | string;
- txId: string; // mirrors transaction
- issuedAt: string;
- fromAgent: string; // agent_name of sender
- toAgent: string; // agent_name of receiver
- amountMinor: MinorUnits;
- fromBalanceAfter: MinorUnits;
- toBalanceAfter: MinorUnits;
-}
diff --git a/src/routes/agentRoutes.ts b/src/routes/agentRoutes.ts
deleted file mode 100644
index da08882..0000000
--- a/src/routes/agentRoutes.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { ensureAgent, getAgent, setAgentServiceCharge } from '../services/agentService.js';
-import { getWallet } from '../services/walletService.js';
-import { AgentFacts, Wallet } from '../models/index.js';
-
-export async function getAgentWithWallet(agent_name: string): Promise<{ agent: AgentFacts; wallet: Wallet } | null> {
- const agent = await ensureAgent(agent_name);
- if (!agent) {
- return null;
- }
- const wallet = await getWallet(agent_name);
- if (!wallet) {
- return null;
- }
- return { agent, wallet };
-}
-
-export { ensureAgent, getAgent, setAgentServiceCharge };
diff --git a/src/routes/index.ts b/src/routes/index.ts
deleted file mode 100644
index 3e7f60d..0000000
--- a/src/routes/index.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Re-export all routes
-export * from './agentRoutes.js';
-export * from './walletRoutes.js';
-export * from './transactionRoutes.js';
-export * from './receiptRoutes.js';
diff --git a/src/routes/receiptRoutes.ts b/src/routes/receiptRoutes.ts
deleted file mode 100644
index 93d2a20..0000000
--- a/src/routes/receiptRoutes.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { getReceiptByTx } from '../services/receiptService.js';
-import { Receipt } from '../models/index.js';
-
-export { getReceiptByTx };
diff --git a/src/routes/transactionRoutes.ts b/src/routes/transactionRoutes.ts
deleted file mode 100644
index 1d4af20..0000000
--- a/src/routes/transactionRoutes.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { transfer } from '../services/transactionService.js';
-import { Txn, Receipt } from '../models/index.js';
-
-export { transfer };
diff --git a/src/routes/walletRoutes.ts b/src/routes/walletRoutes.ts
deleted file mode 100644
index de2212e..0000000
--- a/src/routes/walletRoutes.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { getWallet, getBalanceMinor, ensureWallet, attachWallet } from '../services/walletService.js';
-import { Wallet } from '../models/index.js';
-
-export { getWallet, getBalanceMinor, ensureWallet, attachWallet };
diff --git a/src/services/agentService.ts b/src/services/agentService.ts
deleted file mode 100644
index 4d0aeca..0000000
--- a/src/services/agentService.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { randomUUID } from "crypto";
-import { Agents } from './database.js';
-import { AgentFacts } from '../models/index.js';
-
-export const DEFAULT_SERVICE_CHARGE_POINTS = 10;
-
-function nowIso() { return new Date().toISOString(); }
-
-export async function ensureAgent(
- agent_name: string
-): Promise {
- // Only verify if agent exists, don't create if missing
- return await Agents.findOne({ agent_name });
-}
-
-export async function getAgent(agent_name: string): Promise {
- return Agents.findOne({ agent_name });
-}
-
-export async function setAgentServiceCharge(agent_name: string, serviceChargePoints: number): Promise {
- await Agents.updateOne({ agent_name }, { $set: { serviceCharge: serviceChargePoints, updated_at: nowIso() } });
-}
diff --git a/src/services/database.ts b/src/services/database.ts
deleted file mode 100644
index e9fcf04..0000000
--- a/src/services/database.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Collection } from "mongodb";
-import { client, db, initMongo as initMongoShared, closeMongo as closeMongoShared } from "../utils/mongo.js";
-import { AgentFacts, Wallet, Txn, Receipt } from "../models/index.js";
-
-let Agents: Collection;
-let Wallets: Collection;
-let Transactions: Collection;
-let Receipts: Collection;
-
-export async function initMongo() {
- await initMongoShared();
- Agents = db.collection("agents");
- Wallets = db.collection("wallets");
- Transactions = db.collection("transactions");
- Receipts = db.collection("receipts");
-
- await Promise.all([
- Agents.createIndex({ agent_name: 1 }, { unique: true }),
- Agents.createIndex({ walletId: 1 }, { unique: true, sparse: true }),
- Wallets.createIndex({ walletId: 1 }, { unique: true }),
- Wallets.createIndex({ agent_name: 1 }, { unique: true }),
- Transactions.createIndex({ txId: 1 }, { unique: true }),
- Receipts.createIndex({ txId: 1 }, { unique: true }),
- ]);
-}
-
-export async function closeMongo() {
- await closeMongoShared();
-}
-
-export { Agents, Wallets, Transactions, Receipts };
diff --git a/src/services/index.ts b/src/services/index.ts
deleted file mode 100644
index 1323514..0000000
--- a/src/services/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-// Re-export all services
-export * from './database.js';
-export * from './agentService.js';
-export * from './walletService.js';
-export * from './transactionService.js';
-export * from './receiptService.js';
diff --git a/src/services/receiptService.ts b/src/services/receiptService.ts
deleted file mode 100644
index b3d5f68..0000000
--- a/src/services/receiptService.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { Receipts } from './database.js';
-import { Receipt } from '../models/index.js';
-
-export async function getReceiptByTx(txId: string): Promise {
- return Receipts.findOne({ txId });
-}
diff --git a/src/services/transactionService.ts b/src/services/transactionService.ts
deleted file mode 100644
index 7f6d52e..0000000
--- a/src/services/transactionService.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { randomUUID } from "crypto";
-import { Wallets, Transactions, Receipts } from './database.js';
-import { Txn, Receipt, MinorUnits } from '../models/index.js';
-
-function nowIso() { return new Date().toISOString(); }
-
-export async function transfer(fromAgent: string, toAgent: string, amountMinor: MinorUnits, task: string): Promise<{ tx: Txn; receipt: Receipt; payload: Receipt }> {
- const createdAt = nowIso();
- const txId = randomUUID();
-
- // 1. Ensure both wallets exist and check balance
- const fromWallet = await Wallets.findOne({ agent_name: fromAgent });
- const toWallet = await Wallets.findOne({ agent_name: toAgent });
-
- if (!fromWallet) throw new Error("SENDER_WALLET_NOT_FOUND");
- if (!toWallet) throw new Error("RECEIVER_WALLET_NOT_FOUND");
- if (fromWallet.balanceMinor < amountMinor) throw new Error("INSUFFICIENT_FUNDS");
-
- // 2. Deduct from sender's wallet
- const updatedFromWallet = await Wallets.findOneAndUpdate(
- { agent_name: fromAgent },
- { $inc: { balanceMinor: -amountMinor }, $set: { updatedAt: nowIso() } },
- { returnDocument: "after" }
- );
- if (!updatedFromWallet) throw new Error("FAILED_TO_UPDATE_SENDER_WALLET");
-
- // 3. Add to receiver's wallet
- const updatedToWallet = await Wallets.findOneAndUpdate(
- { agent_name: toAgent },
- { $inc: { balanceMinor: amountMinor }, $set: { updatedAt: nowIso() } },
- { returnDocument: "after" }
- );
- if (!updatedToWallet) throw new Error("FAILED_TO_UPDATE_RECEIVER_WALLET");
-
- // 4. Record transaction
- const tx: Txn = {
- txId,
- fromAgent,
- toAgent,
- amountMinor,
- currency: "NP",
- scale: 0,
- createdAt,
- status: "completed",
- error: null,
- task,
- };
- await Transactions.insertOne(tx);
-
- // 5. Create receipt
- const receipt: Receipt = {
- txId,
- issuedAt: nowIso(),
- fromAgent,
- toAgent,
- amountMinor,
- fromBalanceAfter: updatedFromWallet.balanceMinor,
- toBalanceAfter: updatedToWallet.balanceMinor,
- };
- await Receipts.insertOne(receipt);
-
- return { tx, receipt, payload: receipt };
-}
diff --git a/src/services/walletService.ts b/src/services/walletService.ts
deleted file mode 100644
index 0c1f25a..0000000
--- a/src/services/walletService.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { randomUUID } from "crypto";
-import { Wallets, Agents } from './database.js';
-import { Wallet, NP, createMinorUnits, MinorUnits, AgentFacts } from '../models/index.js';
-
-export const DEFAULT_SEED_POINTS = 1000; // new agent seed
-
-function nowIso() { return new Date().toISOString(); }
-
-export async function ensureWallet(agent_name: string, seedPoints?: number): Promise {
- const createdAt = nowIso();
- const seedMinor = NP.toMinorUnits(seedPoints ?? DEFAULT_SEED_POINTS);
-
- let wallet = await Wallets.findOne({ agent_name });
- if (!wallet) {
- const walletId = randomUUID();
- const toInsertWallet: Wallet = {
- walletId,
- agent_name,
- balanceMinor: seedMinor,
- createdAt,
- updatedAt: createdAt
- };
- try {
- await Wallets.insertOne(toInsertWallet);
- } catch (e: any) {
- if (!(e && e.code === 11000)) throw e;
- }
- wallet = await Wallets.findOne({ agent_name });
- }
-
- return wallet!;
-}
-
-export async function getWallet(agent_name: string): Promise {
- return Wallets.findOne({ agent_name });
-}
-
-export async function getBalanceMinor(agent_name: string): Promise {
- const w = await getWallet(agent_name);
- return w?.balanceMinor ?? createMinorUnits(0);
-}
-
-export async function attachWallet(agent_name: string, seedPoints?: number): Promise<{ agent: AgentFacts; wallet: Wallet } | null> {
- // First verify the agent exists
- const agent = await Agents.findOne({ agent_name });
- if (!agent) {
- return null;
- }
-
- // Check if agent already has a wallet attached
- if (agent.walletId) {
- const existingWallet = await getWallet(agent_name);
- if (existingWallet) {
- return { agent, wallet: existingWallet };
- }
- }
-
- // Create a new wallet for the agent
- const wallet = await ensureWallet(agent_name, seedPoints ?? DEFAULT_SEED_POINTS);
-
- // Update the agent with the walletId
- await Agents.updateOne(
- { agent_name },
- { $set: { walletId: wallet.walletId, updated_at: nowIso() } }
- );
-
- // Return the updated agent with the wallet
- const updatedAgent = await Agents.findOne({ agent_name });
- return { agent: updatedAgent!, wallet };
-}
diff --git a/src/utils/mongo.ts b/src/utils/mongo.ts
deleted file mode 100644
index f1913a8..0000000
--- a/src/utils/mongo.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import 'dotenv/config';
-import { MongoClient, Db } from 'mongodb';
-
-export const DEFAULT_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017';
-export const DEFAULT_DB = process.env.NP_DB_NAME || 'nanda_points';
-
-export let client: MongoClient;
-export let db: Db;
-
-/**
- * Initialize a single shared Mongo connection and DB handle.
- * Safe to call multiple times; connects only once.
- */
-export async function initMongo() {
- if (client) return;
- client = new MongoClient(DEFAULT_URI);
- await client.connect();
- db = client.db(DEFAULT_DB);
-}
-
-export async function closeMongo() {
- if (client) {
- await client.close();
- }
-}
diff --git a/test-adapter/.env.example b/test-adapter/.env.example
new file mode 100644
index 0000000..d420db8
--- /dev/null
+++ b/test-adapter/.env.example
@@ -0,0 +1,17 @@
+# NANDA Adapter Configuration
+PORT=8080
+HOST=0.0.0.0
+
+# NANDA Points Configuration
+FACILITATOR_URL=http://localhost:3001
+AGENT_NAME=nanda-adapter
+
+# Agent Bridge Configuration (if connecting to local bridge)
+AGENT_BRIDGE_URL=http://localhost:3000
+
+# Optional: Claude API Key for message improvement
+CLAUDE_API_KEY=your_claude_api_key_here
+
+# Optional: SSL Configuration
+SSL_CERT_PATH=
+SSL_KEY_PATH=
\ No newline at end of file
diff --git a/test-adapter/README.md b/test-adapter/README.md
new file mode 100644
index 0000000..5fb82c3
--- /dev/null
+++ b/test-adapter/README.md
@@ -0,0 +1,388 @@
+# NANDA Adapter with Payment Integration
+
+A TypeScript adaptation of the [NANDA Adapter](https://github.com/projnanda/adapter) with integrated NANDA Points payment requirements. This implementation demonstrates how to add payment protection to the `/api/send` route using the `@nanda/payments-sdk`.
+
+## Overview
+
+This adapter provides the same functionality as the Python original but adds payment requirements to key endpoints:
+
+- **`/api/send`** - Requires 10 NANDA Points per message
+- **`/api/receive_message`** - Requires 5 NANDA Points per received message
+- All other endpoints remain free for compatibility
+
+## Features
+
+- 🔗 **Agent Bridge Communication**: Mirrors the Python adapter's A2A messaging
+- 💰 **Payment Integration**: Uses `@nanda/payments-sdk` for seamless payment handling
+- 🔄 **Real-time Updates**: Server-Sent Events (SSE) for live message streaming
+- 📊 **Message Management**: Conversation tracking and message history
+- 🏥 **Health Monitoring**: Status endpoints and payment statistics
+- ⚡ **x402 Compliant**: Returns proper HTTP 402 responses for payment requirements
+
+## Quick Start
+
+### Prerequisites
+
+- Node.js 20+
+- MongoDB running on localhost:27017
+- NANDA Points facilitator running on localhost:3001
+- Existing NANDA Points agent account
+
+### Installation
+
+```bash
+# Clone and navigate to test adapter
+cd test-adapter
+
+# Install dependencies
+npm install
+
+# Copy environment configuration
+cp .env.example .env
+# Edit .env with your settings
+```
+
+### Configuration
+
+Edit `.env` file:
+
+```bash
+# Server Configuration
+PORT=8080
+HOST=0.0.0.0
+
+# NANDA Points Configuration
+FACILITATOR_URL=http://localhost:3001
+AGENT_NAME=nanda-adapter
+
+# Agent Bridge Configuration
+AGENT_BRIDGE_URL=http://localhost:3000
+```
+
+### Start the Server
+
+```bash
+npm run dev
+```
+
+Your adapter will be running at `http://localhost:8080`
+
+## API Endpoints
+
+### Free Endpoints
+
+| Method | Endpoint | Description |
+|--------|----------|-------------|
+| `GET` | `/api/health` | Health check and server status |
+| `GET` | `/api/agents/list` | List available agents |
+| `GET` | `/api/messages/stream` | Server-Sent Events stream |
+| `GET` | `/api/render` | Get latest message |
+| `GET` | `/api/conversations/:id` | Get conversation history |
+| `GET` | `/api/messages` | Get all messages (paginated) |
+| `GET` | `/api/stats` | Payment and usage statistics |
+
+### Paid Endpoints 💰
+
+| Method | Endpoint | Cost | Description |
+|--------|----------|------|-------------|
+| `POST` | `/api/send` | 10 NP | Send message to agent bridge |
+| `POST` | `/api/receive_message` | 5 NP | Receive message from agent bridge |
+
+## Usage Examples
+
+### Test Free Endpoints
+
+```bash
+# Health check
+curl http://localhost:8080/api/health
+
+# List agents
+curl http://localhost:8080/api/agents/list
+
+# Get statistics
+curl http://localhost:8080/api/stats
+```
+
+### Test Paid Endpoints
+
+#### Without Payment (Returns HTTP 402)
+
+```bash
+curl -X POST http://localhost:8080/api/send \
+ -H "Content-Type: application/json" \
+ -d '{
+ "message": "Hello, agent!",
+ "conversation_id": "test-conv-1",
+ "client_id": "test-client"
+ }'
+```
+
+**Response:**
+```json
+{
+ "x402Version": 1,
+ "error": "X-PAYMENT header is required",
+ "accepts": [{
+ "scheme": "nanda-points",
+ "network": "nanda-network",
+ "maxAmountRequired": "10",
+ "resource": "http://localhost:8080/api/send",
+ "description": "Send message to agent bridge",
+ "payTo": "nanda-adapter",
+ "asset": "NP",
+ "extra": {
+ "facilitatorUrl": "http://localhost:3001"
+ }
+ }]
+}
+```
+
+#### With Payment
+
+```bash
+# First create a payment via NANDA Points system, then:
+curl -X POST http://localhost:8080/api/send \
+ -H "Content-Type: application/json" \
+ -H "X-PAYMENT: " \
+ -d '{
+ "message": "Hello, agent!",
+ "conversation_id": "test-conv-1",
+ "client_id": "test-client"
+ }'
+```
+
+**Response:**
+```json
+{
+ "success": true,
+ "message_id": "msg_1234567890_abc123",
+ "conversation_id": "test-conv-1",
+ "client_id": "test-client",
+ "response": "Agent processed: \"Hello, agent!\" - Response generated for conversation test-conv-1",
+ "timestamp": "2024-01-15T10:30:00.000Z",
+ "cost": "10 NP",
+ "payment_verified": true
+}
+```
+
+## Server-Sent Events (SSE)
+
+Connect to the message stream for real-time updates:
+
+```javascript
+const eventSource = new EventSource('http://localhost:8080/api/messages/stream');
+
+eventSource.onmessage = function(event) {
+ const message = JSON.parse(event.data);
+ console.log('New message:', message);
+};
+```
+
+## Payment Flow
+
+1. **Client Request**: Client sends message to `/api/send` without payment
+2. **HTTP 402 Response**: Server returns payment requirements
+3. **Payment Creation**: Client creates NANDA Points payment
+4. **Paid Request**: Client retries with `X-PAYMENT` header
+5. **Message Processing**: Server verifies payment and processes message
+6. **Agent Response**: Message sent to agent bridge, response returned
+7. **Settlement**: Payment settled in background
+
+## Implementation Details
+
+### Key Differences from Python Original
+
+- **TypeScript**: Fully typed implementation with comprehensive error handling
+- **Payment Integration**: Native NANDA Points payment requirements
+- **Express Framework**: Uses Express.js instead of Flask
+- **SDK Integration**: Leverages `@nanda/payments-sdk` for payment handling
+- **x402 Compliance**: Follows standard x402 protocol patterns
+
+### Message Flow
+
+```mermaid
+sequenceDiagram
+ participant C as Client
+ participant A as Adapter
+ participant F as Facilitator
+ participant B as Agent Bridge
+
+ C->>A: POST /api/send (no payment)
+ A->>C: HTTP 402 Payment Required
+
+ C->>C: Create NANDA Points payment
+ C->>A: POST /api/send (with X-PAYMENT)
+ A->>F: Verify payment
+ F->>A: Payment valid
+
+ A->>B: Send message to agent bridge
+ B->>A: Agent response
+ A->>F: Settle payment
+ A->>C: Response + X-PAYMENT-RESPONSE
+```
+
+### Data Structures
+
+```typescript
+interface Message {
+ id: string;
+ content: string;
+ timestamp: string;
+ conversationId: string;
+ clientId: string;
+ response?: string;
+}
+
+interface Agent {
+ name: string;
+ url: string;
+ status: 'online' | 'offline';
+}
+```
+
+## Development
+
+### Build and Run
+
+```bash
+# Development mode
+npm run dev
+
+# Build for production
+npm run build
+
+# Run production build
+npm start
+```
+
+### Environment Variables
+
+| Variable | Default | Description |
+|----------|---------|-------------|
+| `PORT` | 8080 | Server port |
+| `HOST` | 0.0.0.0 | Server host |
+| `FACILITATOR_URL` | http://localhost:3001 | NANDA Points facilitator |
+| `AGENT_NAME` | nanda-adapter | Agent name for payments |
+| `AGENT_BRIDGE_URL` | http://localhost:3000 | Local agent bridge URL |
+| `CLAUDE_API_KEY` | - | Optional Claude API key |
+
+## Testing with x402 Clients
+
+This adapter is compatible with any x402-compliant client:
+
+```bash
+# Using x402-axios (example)
+npm install x402-axios
+```
+
+```typescript
+import { X402Client } from 'x402-axios';
+
+const client = new X402Client({
+ facilitatorUrl: 'http://localhost:3001',
+ agentName: 'my-client'
+});
+
+const response = await client.post('http://localhost:8080/api/send', {
+ message: 'Hello from x402 client!',
+ conversation_id: 'x402-test',
+ client_id: 'x402-client'
+});
+
+console.log('Agent response:', response.data);
+```
+
+## Monitoring and Analytics
+
+### Payment Statistics
+
+The `/api/stats` endpoint provides payment analytics:
+
+```json
+{
+ "total_messages": 150,
+ "paid_messages": 120,
+ "free_requests": 30,
+ "total_revenue_np": 1200,
+ "uptime": 3600,
+ "timestamp": "2024-01-15T10:30:00.000Z"
+}
+```
+
+### Message History
+
+Access conversation history and message logs:
+
+```bash
+# Get specific conversation
+curl http://localhost:8080/api/conversations/test-conv-1
+
+# Get recent messages
+curl http://localhost:8080/api/messages?limit=10&offset=0
+```
+
+## Deployment
+
+### Docker Deployment (Optional)
+
+Create `Dockerfile`:
+
+```dockerfile
+FROM node:20-alpine
+WORKDIR /app
+COPY package*.json ./
+RUN npm ci --only=production
+COPY dist ./dist
+EXPOSE 8080
+CMD ["npm", "start"]
+```
+
+### Production Considerations
+
+- Set up proper SSL certificates
+- Configure environment variables securely
+- Monitor payment settlement success rates
+- Implement proper logging and error tracking
+- Set up health checks and monitoring
+
+## Troubleshooting
+
+### Common Issues
+
+1. **Payment verification fails**
+ - Check facilitator URL is correct and accessible
+ - Verify agent exists in NANDA Points system
+ - Ensure sufficient balance in payer account
+
+2. **Agent bridge connection fails**
+ - Verify AGENT_BRIDGE_URL is correct
+ - Check if agent bridge is running and accessible
+ - Review network configuration and firewall settings
+
+3. **TypeScript compilation errors**
+ - Ensure you're using Node.js 20+
+ - Check that all dependencies are installed
+ - Verify tsconfig.json configuration
+
+### Debug Mode
+
+Enable debug logging:
+
+```bash
+DEBUG=nanda:* npm run dev
+```
+
+## Integration with Original Python Adapter
+
+This TypeScript adapter can work alongside the original Python adapter:
+
+- **Drop-in replacement**: Same API endpoints and response formats
+- **Payment enhancement**: Adds payment requirements without breaking existing clients
+- **Backward compatibility**: Free endpoints remain unchanged
+- **Gradual migration**: Can gradually move endpoints to paid model
+
+## Related Projects
+
+- **Original Adapter**: [https://github.com/projnanda/adapter](https://github.com/projnanda/adapter)
+- **NANDA Payments SDK**: [../sdks/payments-sdk/](../sdks/payments-sdk/)
+- **x402 Protocol**: [https://github.com/coinbase/x402](https://github.com/coinbase/x402)
\ No newline at end of file
diff --git a/test-adapter/package-lock.json b/test-adapter/package-lock.json
new file mode 100644
index 0000000..4b2768a
--- /dev/null
+++ b/test-adapter/package-lock.json
@@ -0,0 +1,1582 @@
+{
+ "name": "nanda-adapter-test",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "nanda-adapter-test",
+ "version": "1.0.0",
+ "dependencies": {
+ "@nanda/payments-sdk": "file:../sdks/payments-sdk",
+ "cors": "^2.8.5",
+ "dotenv": "^16.3.1",
+ "express": "^4.18.2"
+ },
+ "devDependencies": {
+ "@types/cors": "^2.8.17",
+ "@types/express": "^4.17.21",
+ "@types/node": "^20.10.0",
+ "tsx": "^4.6.2",
+ "typescript": "^5.3.3"
+ }
+ },
+ "../sdks/payments-sdk": {
+ "name": "@nanda/payments-sdk",
+ "version": "1.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "express": "^4.19.0",
+ "mongodb": "^6.0.0"
+ },
+ "devDependencies": {
+ "@types/express": "^5.0.1",
+ "@types/node": "^20.0.0",
+ "tsup": "^7.2.0",
+ "typescript": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "optionalDependencies": {
+ "@modelcontextprotocol/sdk": "*"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz",
+ "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz",
+ "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz",
+ "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz",
+ "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz",
+ "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz",
+ "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz",
+ "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz",
+ "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz",
+ "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz",
+ "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz",
+ "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz",
+ "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz",
+ "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz",
+ "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz",
+ "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz",
+ "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz",
+ "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz",
+ "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz",
+ "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz",
+ "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz",
+ "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz",
+ "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz",
+ "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz",
+ "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz",
+ "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz",
+ "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@nanda/payments-sdk": {
+ "resolved": "../sdks/payments-sdk",
+ "link": true
+ },
+ "node_modules/@types/body-parser": {
+ "version": "1.19.6",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
+ "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/cors": {
+ "version": "2.8.19",
+ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz",
+ "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/express": {
+ "version": "4.17.23",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz",
+ "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.33",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "4.19.6",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
+ "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/http-errors": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
+ "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/mime": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
+ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "20.19.17",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.17.tgz",
+ "integrity": "sha512-gfehUI8N1z92kygssiuWvLiwcbOB3IRktR6hTDgJlXMYh5OvkPSRmgfoBUmfZt+vhwJtX7v1Yw4KvvAf7c5QKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
+ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/send": {
+ "version": "0.17.5",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz",
+ "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz",
+ "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-errors": "*",
+ "@types/node": "*",
+ "@types/send": "*"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "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/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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/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==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "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/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==",
+ "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/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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz",
+ "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.10",
+ "@esbuild/android-arm": "0.25.10",
+ "@esbuild/android-arm64": "0.25.10",
+ "@esbuild/android-x64": "0.25.10",
+ "@esbuild/darwin-arm64": "0.25.10",
+ "@esbuild/darwin-x64": "0.25.10",
+ "@esbuild/freebsd-arm64": "0.25.10",
+ "@esbuild/freebsd-x64": "0.25.10",
+ "@esbuild/linux-arm": "0.25.10",
+ "@esbuild/linux-arm64": "0.25.10",
+ "@esbuild/linux-ia32": "0.25.10",
+ "@esbuild/linux-loong64": "0.25.10",
+ "@esbuild/linux-mips64el": "0.25.10",
+ "@esbuild/linux-ppc64": "0.25.10",
+ "@esbuild/linux-riscv64": "0.25.10",
+ "@esbuild/linux-s390x": "0.25.10",
+ "@esbuild/linux-x64": "0.25.10",
+ "@esbuild/netbsd-arm64": "0.25.10",
+ "@esbuild/netbsd-x64": "0.25.10",
+ "@esbuild/openbsd-arm64": "0.25.10",
+ "@esbuild/openbsd-x64": "0.25.10",
+ "@esbuild/openharmony-arm64": "0.25.10",
+ "@esbuild/sunos-x64": "0.25.10",
+ "@esbuild/win32-arm64": "0.25.10",
+ "@esbuild/win32-ia32": "0.25.10",
+ "@esbuild/win32-x64": "0.25.10"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "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/express": {
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "license": "MIT",
+ "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.12",
+ "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"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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": {
+ "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": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
+ "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "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/sponsors/ljharb"
+ }
+ },
+ "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.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "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.4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+ "license": "MIT"
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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==",
+ "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==",
+ "license": "MIT",
+ "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/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
+ "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"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/send": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "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"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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==",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.19.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "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.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tsx": {
+ "version": "4.20.5",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.5.tgz",
+ "integrity": "sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "~0.25.0",
+ "get-tsconfig": "^4.7.5"
+ },
+ "bin": {
+ "tsx": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
+ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ }
+ }
+}
diff --git a/test-adapter/package.json b/test-adapter/package.json
new file mode 100644
index 0000000..7f8cea6
--- /dev/null
+++ b/test-adapter/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "nanda-adapter-test",
+ "version": "1.0.0",
+ "description": "TypeScript adapter with NANDA Points payment integration",
+ "main": "dist/index.js",
+ "type": "module",
+ "scripts": {
+ "dev": "tsx src/index.ts",
+ "build": "tsc",
+ "start": "node dist/index.js"
+ },
+ "dependencies": {
+ "@nanda/payments-sdk": "file:../sdks/payments-sdk",
+ "express": "^4.18.2",
+ "cors": "^2.8.5",
+ "dotenv": "^16.3.1"
+ },
+ "devDependencies": {
+ "@types/express": "^4.17.21",
+ "@types/cors": "^2.8.17",
+ "@types/node": "^20.10.0",
+ "tsx": "^4.6.2",
+ "typescript": "^5.3.3"
+ }
+}
\ No newline at end of file
diff --git a/test-adapter/src/index.ts b/test-adapter/src/index.ts
new file mode 100644
index 0000000..5e513db
--- /dev/null
+++ b/test-adapter/src/index.ts
@@ -0,0 +1,440 @@
+/**
+ * NANDA Adapter with Payment Integration
+ *
+ * TypeScript adaptation of the Python adapter with NANDA Points payment requirements
+ * for the /api/send endpoint. Based on https://github.com/projnanda/adapter
+ */
+
+import express from 'express';
+import cors from 'cors';
+import { config } from 'dotenv';
+import {
+ quickSetup,
+ paymentMiddleware,
+ createPaymentConfig,
+ type ToolPaymentRequirement
+} from '@nanda/payments-sdk';
+
+// Load environment variables
+config();
+
+const app = express();
+
+// Middleware
+app.use(cors());
+app.use(express.json());
+
+// Configuration
+const PORT = parseInt(process.env.PORT || '8080', 10);
+const HOST = process.env.HOST || '0.0.0.0';
+const FACILITATOR_URL = process.env.FACILITATOR_URL || 'http://localhost:3001';
+const AGENT_NAME = process.env.AGENT_NAME || 'nanda-adapter';
+const AGENT_BRIDGE_URL = process.env.AGENT_BRIDGE_URL || 'http://localhost:3000';
+
+// In-memory storage for messages and conversations (similar to Python version)
+interface Message {
+ id: string;
+ content: string;
+ timestamp: string;
+ conversationId: string;
+ clientId: string;
+ response?: string;
+}
+
+interface Agent {
+ name: string;
+ url: string;
+ status: 'online' | 'offline';
+}
+
+const messages: Message[] = [];
+const conversations = new Map();
+const connectedClients = new Set();
+
+// Mock agent registry (in real implementation, this would come from a registry service)
+const mockAgents: Agent[] = [
+ { name: 'claude-agent', url: 'http://localhost:3000', status: 'online' },
+ { name: 'gpt-agent', url: 'http://localhost:3001', status: 'online' },
+ { name: 'local-bridge', url: AGENT_BRIDGE_URL, status: 'online' }
+];
+
+/**
+ * Initialize NANDA Payments for the adapter
+ */
+async function initializePayments() {
+ try {
+ const payments = await quickSetup({
+ facilitatorUrl: FACILITATOR_URL,
+ agentName: AGENT_NAME
+ });
+
+ console.log(`✅ NANDA Payments initialized for agent: ${AGENT_NAME}`);
+ console.log(` Facilitator: ${FACILITATOR_URL}`);
+
+ return payments;
+ } catch (error) {
+ console.error('❌ Failed to initialize NANDA Payments:', error);
+ throw error;
+ }
+}
+
+/**
+ * Simulate message sending to agent bridge (similar to Python A2AClient)
+ */
+async function sendToAgentBridge(message: string, conversationId: string, clientId: string): Promise {
+ // In a real implementation, this would make HTTP requests to the agent bridge
+ // For now, we'll simulate the response
+
+ console.log(`📤 Sending to agent bridge: ${AGENT_BRIDGE_URL}`);
+ console.log(` Message: ${message.substring(0, 100)}...`);
+ console.log(` Conversation: ${conversationId}`);
+ console.log(` Client: ${clientId}`);
+
+ // Simulate processing delay
+ await new Promise(resolve => setTimeout(resolve, 1000));
+
+ // Mock response (in real implementation, would come from actual agent)
+ return `Agent processed: "${message}" - Response generated for conversation ${conversationId}`;
+}
+
+/**
+ * Generate unique message ID
+ */
+function generateMessageId(): string {
+ return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
+}
+
+/**
+ * Send message to SSE clients
+ */
+function broadcastMessage(message: Message) {
+ const data = JSON.stringify(message);
+ connectedClients.forEach(client => {
+ try {
+ client.write(`data: ${data}\n\n`);
+ } catch (error) {
+ // Remove disconnected clients
+ connectedClients.delete(client);
+ }
+ });
+}
+
+// ==============================================================================
+// API ROUTES
+// ==============================================================================
+
+/**
+ * Health check endpoint (free)
+ */
+app.get('/api/health', (req, res) => {
+ res.json({
+ status: 'healthy',
+ service: 'nanda-adapter',
+ version: '1.0.0',
+ timestamp: new Date().toISOString(),
+ payments: 'enabled'
+ });
+});
+
+/**
+ * List available agents (free)
+ */
+app.get('/api/agents/list', (req, res) => {
+ res.json({
+ agents: mockAgents,
+ count: mockAgents.length,
+ timestamp: new Date().toISOString()
+ });
+});
+
+/**
+ * Get latest message (free)
+ */
+app.get('/api/render', (req, res) => {
+ const latest = messages[messages.length - 1];
+ res.json({
+ message: latest || null,
+ timestamp: new Date().toISOString()
+ });
+});
+
+/**
+ * Server-Sent Events for message streaming (free)
+ */
+app.get('/api/messages/stream', (req, res) => {
+ // Set SSE headers
+ res.writeHead(200, {
+ 'Content-Type': 'text/event-stream',
+ 'Cache-Control': 'no-cache',
+ 'Connection': 'keep-alive',
+ 'Access-Control-Allow-Origin': '*',
+ 'Access-Control-Allow-Headers': 'Cache-Control'
+ });
+
+ // Add client to set
+ connectedClients.add(res);
+
+ // Send initial connection message
+ res.write(`data: ${JSON.stringify({ type: 'connected', timestamp: new Date().toISOString() })}\n\n`);
+
+ // Handle client disconnect
+ req.on('close', () => {
+ connectedClients.delete(res);
+ });
+});
+
+// ==============================================================================
+// PAYMENT-PROTECTED ROUTES
+// ==============================================================================
+
+// Configure payment requirements for protected routes
+const paymentConfig = createPaymentConfig({
+ facilitatorUrl: FACILITATOR_URL,
+ agentName: AGENT_NAME
+});
+
+// Apply payment middleware to protected routes
+app.use(paymentMiddleware({
+ 'POST /api/send': {
+ amount: 10, // 10 NANDA Points per message
+ description: 'Send message to agent bridge',
+ timeout: 30000
+ },
+ 'POST /api/receive_message': {
+ amount: 5, // 5 NANDA Points per received message
+ description: 'Receive message from agent bridge',
+ timeout: 30000
+ }
+}, paymentConfig));
+
+/**
+ * Send message to agent bridge (PAID - 10 NP)
+ * Main endpoint that mirrors the Python adapter's /api/send functionality
+ */
+app.post('/api/send', async (req, res) => {
+ try {
+ const { message, conversation_id, client_id } = req.body;
+
+ // Validate required fields
+ if (!message) {
+ return res.status(400).json({
+ error: 'Message is required',
+ code: 'MISSING_MESSAGE'
+ });
+ }
+
+ // Generate IDs if not provided
+ const conversationId = conversation_id || `conv_${Date.now()}`;
+ const clientId = client_id || `client_${Date.now()}`;
+ const messageId = generateMessageId();
+
+ console.log(`💰 Paid message received from ${clientId}`);
+ console.log(` Payment verified, processing message...`);
+
+ // Send to agent bridge
+ const agentResponse = await sendToAgentBridge(message, conversationId, clientId);
+
+ // Create message record
+ const messageRecord: Message = {
+ id: messageId,
+ content: message,
+ timestamp: new Date().toISOString(),
+ conversationId,
+ clientId,
+ response: agentResponse
+ };
+
+ // Store message
+ messages.push(messageRecord);
+
+ // Update conversation
+ if (!conversations.has(conversationId)) {
+ conversations.set(conversationId, []);
+ }
+ conversations.get(conversationId)!.push(messageRecord);
+
+ // Broadcast to SSE clients
+ broadcastMessage(messageRecord);
+
+ // Return response (matches Python adapter format)
+ res.json({
+ success: true,
+ message_id: messageId,
+ conversation_id: conversationId,
+ client_id: clientId,
+ response: agentResponse,
+ timestamp: messageRecord.timestamp,
+ cost: '10 NP',
+ payment_verified: true
+ });
+
+ } catch (error) {
+ console.error('Error in /api/send:', error);
+ res.status(500).json({
+ error: 'Failed to process message',
+ code: 'PROCESSING_ERROR',
+ details: error instanceof Error ? error.message : 'Unknown error'
+ });
+ }
+});
+
+/**
+ * Receive message from agent bridge (PAID - 5 NP)
+ * Endpoint for agent bridge to send messages back
+ */
+app.post('/api/receive_message', async (req, res) => {
+ try {
+ const { message, conversation_id, client_id, metadata } = req.body;
+
+ if (!message) {
+ return res.status(400).json({
+ error: 'Message is required',
+ code: 'MISSING_MESSAGE'
+ });
+ }
+
+ const messageId = generateMessageId();
+ const messageRecord: Message = {
+ id: messageId,
+ content: message,
+ timestamp: new Date().toISOString(),
+ conversationId: conversation_id || 'unknown',
+ clientId: client_id || 'agent-bridge'
+ };
+
+ // Store message
+ messages.push(messageRecord);
+
+ // Broadcast to SSE clients
+ broadcastMessage(messageRecord);
+
+ console.log(`💰 Received paid message from agent bridge`);
+ console.log(` Message ID: ${messageId}`);
+
+ res.json({
+ success: true,
+ message_id: messageId,
+ received_at: messageRecord.timestamp,
+ cost: '5 NP',
+ payment_verified: true
+ });
+
+ } catch (error) {
+ console.error('Error in /api/receive_message:', error);
+ res.status(500).json({
+ error: 'Failed to receive message',
+ code: 'RECEIVE_ERROR',
+ details: error instanceof Error ? error.message : 'Unknown error'
+ });
+ }
+});
+
+// ==============================================================================
+// DEBUG/ADMIN ROUTES (FREE)
+// ==============================================================================
+
+/**
+ * Get conversation history (free)
+ */
+app.get('/api/conversations/:id', (req, res) => {
+ const conversationId = req.params.id;
+ const conversation = conversations.get(conversationId) || [];
+
+ res.json({
+ conversation_id: conversationId,
+ messages: conversation,
+ count: conversation.length,
+ timestamp: new Date().toISOString()
+ });
+});
+
+/**
+ * Get all messages (free, for debugging)
+ */
+app.get('/api/messages', (req, res) => {
+ const limit = parseInt(req.query.limit as string) || 50;
+ const offset = parseInt(req.query.offset as string) || 0;
+
+ const paginatedMessages = messages.slice(offset, offset + limit);
+
+ res.json({
+ messages: paginatedMessages,
+ total: messages.length,
+ limit,
+ offset,
+ timestamp: new Date().toISOString()
+ });
+});
+
+/**
+ * Get payment statistics (free)
+ */
+app.get('/api/stats', (req, res) => {
+ const totalMessages = messages.length;
+ const paidMessages = messages.filter(m => m.response).length;
+ const totalRevenue = paidMessages * 10; // 10 NP per message
+
+ res.json({
+ total_messages: totalMessages,
+ paid_messages: paidMessages,
+ free_requests: totalMessages - paidMessages,
+ total_revenue_np: totalRevenue,
+ uptime: process.uptime(),
+ timestamp: new Date().toISOString()
+ });
+});
+
+// ==============================================================================
+// SERVER STARTUP
+// ==============================================================================
+
+async function startServer() {
+ try {
+ // Initialize payments
+ await initializePayments();
+
+ // Start server
+ app.listen(PORT, HOST, () => {
+ console.log('🚀 NANDA Adapter Server Started');
+ console.log('=================================');
+ console.log(` Server: http://${HOST}:${PORT}`);
+ console.log(` Agent: ${AGENT_NAME}`);
+ console.log(` Facilitator: ${FACILITATOR_URL}`);
+ console.log('');
+ console.log('📡 Available Endpoints:');
+ console.log(' GET /api/health - Health check (FREE)');
+ console.log(' GET /api/agents/list - List agents (FREE)');
+ console.log(' GET /api/messages/stream - SSE stream (FREE)');
+ console.log(' POST /api/send - Send message (10 NP) 💰');
+ console.log(' POST /api/receive_message - Receive message (5 NP) 💰');
+ console.log(' GET /api/render - Latest message (FREE)');
+ console.log(' GET /api/conversations/:id - Conversation history (FREE)');
+ console.log(' GET /api/messages - All messages (FREE)');
+ console.log(' GET /api/stats - Payment statistics (FREE)');
+ console.log('');
+ console.log('💰 Payment Requirements:');
+ console.log(' /api/send: 10 NANDA Points');
+ console.log(' /api/receive_message: 5 NANDA Points');
+ console.log('');
+ console.log('✅ Ready to accept paid requests!');
+ });
+
+ } catch (error) {
+ console.error('❌ Failed to start server:', error);
+ process.exit(1);
+ }
+}
+
+// Handle graceful shutdown
+process.on('SIGINT', () => {
+ console.log('\n🛑 Shutting down NANDA Adapter...');
+ process.exit(0);
+});
+
+process.on('SIGTERM', () => {
+ console.log('\n🛑 Shutting down NANDA Adapter...');
+ process.exit(0);
+});
+
+// Start the server
+startServer().catch(console.error);
\ No newline at end of file
diff --git a/test-adapter/test-endpoints.sh b/test-adapter/test-endpoints.sh
new file mode 100755
index 0000000..41ab31d
--- /dev/null
+++ b/test-adapter/test-endpoints.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+
+# NANDA Adapter Test Script
+# Tests both free and paid endpoints
+
+echo "🧪 Testing NANDA Adapter Endpoints"
+echo "=================================="
+
+BASE_URL="http://localhost:8080"
+
+echo ""
+echo "1. 🔍 Testing Health Check (FREE)"
+echo "--------------------------------"
+curl -s "$BASE_URL/api/health" | jq '.'
+
+echo ""
+echo "2. 🔍 Testing Agent List (FREE)"
+echo "------------------------------"
+curl -s "$BASE_URL/api/agents/list" | jq '.'
+
+echo ""
+echo "3. 💰 Testing /api/send WITHOUT Payment (Should return HTTP 402)"
+echo "----------------------------------------------------------------"
+curl -i -X POST "$BASE_URL/api/send" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "message": "Hello, agent!",
+ "conversation_id": "test-conv-1",
+ "client_id": "test-client"
+ }'
+
+echo ""
+echo ""
+echo "4. 🔍 Testing Statistics (FREE)"
+echo "------------------------------"
+curl -s "$BASE_URL/api/stats" | jq '.'
+
+echo ""
+echo "5. 🔍 Testing Messages List (FREE)"
+echo "---------------------------------"
+curl -s "$BASE_URL/api/messages?limit=5" | jq '.'
+
+echo ""
+echo "6. 💰 Testing /api/receive_message WITHOUT Payment (Should return HTTP 402)"
+echo "--------------------------------------------------------------------------"
+curl -i -X POST "$BASE_URL/api/receive_message" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "message": "Response from agent bridge",
+ "conversation_id": "test-conv-1",
+ "client_id": "agent-bridge"
+ }'
+
+echo ""
+echo ""
+echo "✅ Test completed!"
+echo ""
+echo "Expected Results:"
+echo "- Health check: Should return 200 with server status"
+echo "- Agent list: Should return 200 with mock agents"
+echo "- /api/send without payment: Should return 402 with payment requirements"
+echo "- /api/receive_message without payment: Should return 402 with payment requirements"
+echo "- Statistics: Should show 0 paid messages initially"
+echo ""
+echo "To test WITH payment:"
+echo "1. Ensure NANDA Points facilitator is running on localhost:3001"
+echo "2. Create a valid NANDA Points payment"
+echo "3. Include X-PAYMENT header with base64-encoded payment"
\ No newline at end of file
diff --git a/test-adapter/tsconfig.json b/test-adapter/tsconfig.json
new file mode 100644
index 0000000..2dbea79
--- /dev/null
+++ b/test-adapter/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "module": "ESNext",
+ "moduleResolution": "node",
+ "outDir": "./dist",
+ "rootDir": "./src",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "allowSyntheticDefaultImports": true,
+ "resolveJsonModule": true,
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true
+ },
+ "include": ["src/**/*"],
+ "exclude": ["node_modules", "dist"]
+}
\ No newline at end of file
diff --git a/test.log b/test.log
deleted file mode 100644
index 1487e5f..0000000
--- a/test.log
+++ /dev/null
@@ -1,225 +0,0 @@
-[2025-09-21T13:41:08.234Z] 🚀 Starting Updated x402-NP Test Suite
-[2025-09-21T13:41:08.234Z] Server URL: http://localhost:3000/mcp
-[2025-09-21T13:41:08.235Z]
-[2025-09-21T13:41:08.247Z] 🔌 Connecting to MCP server...
-[2025-09-21T13:41:08.285Z] ✅ Connected successfully!
-[2025-09-21T13:41:08.286Z]
-[2025-09-21T13:41:08.286Z] ============================================================
-[2025-09-21T13:41:08.287Z] TEST: List all available tools
-[2025-09-21T13:41:08.287Z] ============================================================
-[2025-09-21T13:41:08.287Z] 📤 MCP REQUEST:
-[2025-09-21T13:41:08.287Z] Tool: listTools
-[2025-09-21T13:41:08.287Z] Arguments: {}
-[2025-09-21T13:41:08.291Z] 📥 TOOLS LIST:
-[2025-09-21T13:41:08.291Z] 1. getBalance - Returns NP balance for an agent. Returns error if agent does not exist. This tool is free to use.
-[2025-09-21T13:41:08.291Z] 2. initiateTransaction - Transfer NP from one agent to another and record ledger + receipt. Returns error if either agent does not exist. This tool is free to use.
-[2025-09-21T13:41:08.291Z] 4. getTimestamp - Returns current server timestamp. Requires payment: 1 NP to system.
-[2025-09-21T13:41:08.291Z] 5. setServiceCharge - Set per-call service charge (points) on agent facts. Returns error if agent does not exist.
-[2025-09-21T13:41:08.291Z] 3. getReceipt - Return receipt for a transaction id. This tool is free to use.
-[2025-09-21T13:41:08.291Z]
-[2025-09-21T13:41:08.291Z] 6. getPaymentInfo - Get x402-NP payment requirements for all paid tools. This tool is free to use.
-[2025-09-21T13:41:08.291Z] ============================================================
-[2025-09-21T13:41:08.291Z] TEST: Get payment information (free tool)
-[2025-09-21T13:41:08.291Z] ============================================================
-[2025-09-21T13:41:08.292Z] 📤 MCP REQUEST:
-[2025-09-21T13:41:08.292Z] Tool: getPaymentInfo
-[2025-09-21T13:41:08.292Z] Arguments: {}
-[2025-09-21T13:41:08.294Z] 📥 MCP RESPONSE:
-[2025-09-21T13:41:08.294Z] Response: {
- "protocol": "x402-np",
- "currency": "NP",
- "scale": 0,
- "tools": {
- "getTimestamp": {
- "priceNP": 1,
- "recipient": "system",
- "description": "Get current server timestamp"
- }
- },
- "instructions": {
- "steps": [
- "To use a paid tool, first call it normally to get a 402 Payment Required response",
- "Use the initiateTransaction tool to pay the required amount to the specified recipient",
- "Include the transaction ID in the X-PAYMENT-TX-ID header",
- "Include your agent name in the X-PAYMENT-AGENT header",
- "Include the payment amount in the X-PAYMENT-AMOUNT header",
- "Retry the original tool call with these headers"
- ]
- }
-}
-[2025-09-21T13:41:08.294Z] Status: SUCCESS - Free tool worked
-[2025-09-21T13:41:08.294Z]
-[2025-09-21T13:41:08.294Z] ============================================================
-[2025-09-21T13:41:08.294Z] TEST: Call getBalance (now free)
-[2025-09-21T13:41:08.294Z] ============================================================
-[2025-09-21T13:41:08.294Z] 📤 MCP REQUEST:
-[2025-09-21T13:41:08.294Z] Tool: getBalance
-[2025-09-21T13:41:08.294Z] Arguments: {
- "agent_name": "claude-desktop"
-}
-[2025-09-21T13:41:08.300Z] 📥 MCP RESPONSE:
-[2025-09-21T13:41:08.301Z] Response: {
- "agent_name": "claude-desktop",
- "currency": "NP",
- "scale": 0,
- "balanceMinor": 1746,
- "balancePoints": 1746
-}
-[2025-09-21T13:41:08.301Z] ✅ SUCCESS: Free tool worked correctly
-[2025-09-21T13:41:08.301Z] Got balance: 1746 NP for claude-desktop
-[2025-09-21T13:41:08.301Z]
-[2025-09-21T13:41:08.301Z] ============================================================
-[2025-09-21T13:41:08.301Z] TEST: Call getReceipt (now free)
-[2025-09-21T13:41:08.301Z] ============================================================
-[2025-09-21T13:41:08.301Z] 📤 MCP REQUEST:
-[2025-09-21T13:41:08.301Z] Tool: getReceipt
-[2025-09-21T13:41:08.301Z] Arguments: {
- "txId": "test-receipt-id"
-}
-[2025-09-21T13:41:08.303Z] 📥 MCP RESPONSE:
-[2025-09-21T13:41:08.303Z] Response: {
- "error": "NOT_FOUND"
-}
-[2025-09-21T13:41:08.304Z] ✅ SUCCESS: Free tool worked correctly (receipt not found as expected)
-[2025-09-21T13:41:08.304Z]
-[2025-09-21T13:41:08.304Z] ============================================================
-[2025-09-21T13:41:08.304Z] TEST: Call getTimestamp without payment (should require payment)
-[2025-09-21T13:41:08.304Z] ============================================================
-[2025-09-21T13:41:08.304Z] 📤 MCP REQUEST:
-[2025-09-21T13:41:08.304Z] Tool: getTimestamp
-[2025-09-21T13:41:08.304Z] Arguments: {}
-[2025-09-21T13:41:08.305Z] 📥 MCP RESPONSE:
-[2025-09-21T13:41:08.306Z] Response: {
- "error": "PAYMENT_REQUIRED",
- "protocol": "x402-np",
- "tool": "getTimestamp",
- "price": {
- "amount": 1,
- "currency": "NP",
- "scale": 0,
- "recipient": "system"
- },
- "description": "Get current server timestamp",
- "instructions": {
- "steps": [
- "Use initiateTransaction tool to transfer 1 NP from your agent to system",
- "Include the payment details when calling this tool:",
- "- Add \"_paymentAgent\": \"your-agent-name\" to arguments",
- "- Add \"_paymentTxId\": \"transaction-id\" to arguments",
- "- Add \"_paymentAmount\": \"amount-paid\" to arguments",
- "Retry the tool call with payment arguments"
- ]
- }
-}
-[2025-09-21T13:41:08.306Z] ✅ EXPECTED: Payment required correctly detected
-[2025-09-21T13:41:08.306Z]
-[2025-09-21T13:41:08.306Z] ============================================================
-[2025-09-21T13:41:08.306Z] TEST: Make payment for getTimestamp access
-[2025-09-21T13:41:08.306Z] ============================================================
-[2025-09-21T13:41:08.306Z] 📤 MCP REQUEST:
-[2025-09-21T13:41:08.306Z] Tool: initiateTransaction
-[2025-09-21T13:41:08.306Z] Arguments: {
- "from": "claude-desktop",
- "to": "system",
- "amount": 1
-}
-[2025-09-21T13:41:08.315Z] 📥 MCP RESPONSE:
-[2025-09-21T13:41:08.315Z] Response: {
- "txId": "034ccc63-4319-4c23-9d18-ffea3d7ad6d2",
- "status": "completed",
- "amountPoints": 1,
- "currency": "NP",
- "scale": 0,
- "from": "claude-desktop",
- "to": "system",
- "createdAt": "2025-09-21T13:41:08.310Z",
- "receipt": {
- "txId": "034ccc63-4319-4c23-9d18-ffea3d7ad6d2",
- "issuedAt": "2025-09-21T13:41:08.313Z",
- "fromAgent": "claude-desktop",
- "toAgent": "system",
- "amountMinor": 1,
- "fromBalanceAfter": 1745,
- "toBalanceAfter": 1005,
- "_id": "68d000743b4cf18018400099"
- },
- "payload": {
- "txId": "034ccc63-4319-4c23-9d18-ffea3d7ad6d2",
- "issuedAt": "2025-09-21T13:41:08.313Z",
- "fromAgent": "claude-desktop",
- "toAgent": "system",
- "amountMinor": 1,
- "fromBalanceAfter": 1745,
- "toBalanceAfter": 1005,
- "_id": "68d000743b4cf18018400099"
- }
-}
-[2025-09-21T13:41:08.316Z] ✅ Payment successful! TxId: 034ccc63-4319-4c23-9d18-ffea3d7ad6d2
-[2025-09-21T13:41:08.316Z]
-[2025-09-21T13:41:08.316Z] ============================================================
-[2025-09-21T13:41:08.316Z] TEST: Access getTimestamp with payment proof
-[2025-09-21T13:41:08.316Z] ============================================================
-[2025-09-21T13:41:08.316Z] 📤 MCP REQUEST:
-[2025-09-21T13:41:08.316Z] Tool: getTimestamp
-[2025-09-21T13:41:08.316Z] Arguments: {
- "_paymentAgent": "claude-desktop",
- "_paymentTxId": "034ccc63-4319-4c23-9d18-ffea3d7ad6d2",
- "_paymentAmount": "1"
-}
-[2025-09-21T13:41:08.320Z] 📥 MCP RESPONSE:
-[2025-09-21T13:41:08.320Z] Response: {
- "timestamp": "2025-09-21T13:41:08.319Z",
- "unixTimestamp": 1758462068,
- "serverTime": "2025-09-21T13:41:08.319Z",
- "timezone": "UTC"
-}
-[2025-09-21T13:41:08.321Z] 🎉 SUCCESS! x402-NP payment flow completed for getTimestamp
-[2025-09-21T13:41:08.321Z] Server timestamp: 2025-09-21T13:41:08.319Z
-[2025-09-21T13:41:08.321Z]
-[2025-09-21T13:41:08.321Z] 📊 TEST SUMMARY
-[2025-09-21T13:41:08.321Z] ================
-[2025-09-21T13:41:08.321Z] ✅ MCP connection successful
-[2025-09-21T13:41:08.321Z] ✅ Tool listing successful
-[2025-09-21T13:41:08.321Z] ✅ Free tools (getBalance, getReceipt) working correctly
-[2025-09-21T13:41:08.321Z] ✅ Paid tool (getTimestamp) requiring payment correctly
-[2025-09-21T13:41:08.321Z] ✅ Payment flow working end-to-end
-[2025-09-21T13:41:08.321Z]
-[2025-09-21T13:41:08.326Z] ✅ Disconnected from server
-[2025-09-21T13:41:08.328Z]
-[2025-09-21T13:41:08.328Z] 🌐 Testing Direct HTTP Calls
-[2025-09-21T13:41:08.328Z] ==============================
-[2025-09-21T13:41:08.329Z]
-[2025-09-21T13:41:08.329Z] 📤 HTTP REQUEST: GET /health
-[2025-09-21T13:41:08.330Z] 📥 HTTP RESPONSE: 200 OK
-[2025-09-21T13:41:08.331Z] Response: {
- "status": "healthy",
- "server": "nanda-points-mcp",
- "version": "0.2.0"
-}
-[2025-09-21T13:41:08.331Z]
-[2025-09-21T13:41:08.331Z] 📤 HTTP REQUEST: POST /mcp
-[2025-09-21T13:41:08.331Z] Headers: Content-Type: application/json, Accept: application/json
-[2025-09-21T13:41:08.331Z] Body: {
- "jsonrpc": "2.0",
- "method": "tools/call",
- "params": {
- "name": "getBalance",
- "arguments": {
- "agent_name": "claude-desktop"
- }
- },
- "id": 1
-}
-[2025-09-21T13:41:08.333Z] 📥 HTTP RESPONSE: 400 Bad Request
-[2025-09-21T13:41:08.333Z] Headers: {
- "connection": "keep-alive",
- "content-length": "105",
- "content-type": "application/json; charset=utf-8",
- "date": "Sun, 21 Sep 2025 13:41:08 GMT",
- "etag": "W/\"69-znejF09uoTmzDVlRSJjg9S2smAo\"",
- "keep-alive": "timeout=5",
- "x-powered-by": "Express"
-}
-[2025-09-21T13:41:08.333Z] Error response: {"jsonrpc":"2.0","error":{"code":-32000,"message":"Bad Request: No valid session ID provided"},"id":null}
-[2025-09-21T13:41:08.333Z]
-[2025-09-21T13:41:08.333Z] 📋 Complete test log saved to: test.log
diff --git a/tsconfig.json b/tsconfig.json
index b79b398..2967b99 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,15 +1,43 @@
{
"compilerOptions": {
- "target": "ES2022",
- "module": "ES2022",
+ "target": "ES2020",
+ "module": "ES2020",
"moduleResolution": "bundler",
- "outDir": "dist",
- "rootDir": "src",
- "strict": true,
"esModuleInterop": true,
- "skipLibCheck": true
+ "allowSyntheticDefaultImports": true,
+ "forceConsistentCasingInFileNames": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noImplicitAny": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedIndexedAccess": true,
+ "exactOptionalPropertyTypes": true,
+ "resolveJsonModule": true,
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true,
+ "outDir": "./dist",
+ "baseUrl": ".",
+ "paths": {
+ "x402-nanda-shared": ["./packages/shared/src/index.ts"]
+ },
+ "types": ["node"]
},
"include": [
- "src/**/*"
+ "packages/*/src/**/*",
+ "packages/*/index.ts"
+ ],
+ "exclude": [
+ "node_modules",
+ "dist",
+ "**/*.test.ts",
+ "**/*.spec.ts"
+ ],
+ "references": [
+ { "path": "./packages/shared" },
+ { "path": "./packages/facilitator" },
+ { "path": "./packages/express-server" },
+ { "path": "./packages/advanced-server" }
]
}
\ No newline at end of file