diff --git a/apps/data-ingestion/config/default.json b/apps/data-ingestion/config/default.json deleted file mode 100644 index a919adc..0000000 --- a/apps/data-ingestion/config/default.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "service": { - "name": "data-ingestion", - "port": 2001, - "host": "0.0.0.0", - "healthCheckPath": "/health", - "metricsPath": "/metrics", - "shutdownTimeout": 30000, - "cors": { - "enabled": true, - "origin": "*", - "credentials": false - } - }, - "log": { - "level": "info", - "format": "json", - "hideObject": false, - "loki": { - "enabled": false, - "host": "localhost", - "port": 3100, - "labels": {} - } - }, - "database": { - "postgres": { - "host": "localhost", - "port": 5432, - "database": "trading_bot", - "user": "trading_user", - "password": "trading_pass_dev", - "ssl": false, - "poolSize": 20, - "connectionTimeout": 30000, - "idleTimeout": 10000 - }, - "questdb": { - "host": "localhost", - "ilpPort": 9009, - "httpPort": 9000, - "pgPort": 8812, - "database": "questdb", - "user": "admin", - "password": "quest", - "bufferSize": 65536, - "flushInterval": 1000 - }, - "mongodb": { - "host": "localhost", - "port": 27017, - "database": "stock", - "user": "trading_admin", - "password": "trading_mongo_dev", - "authSource": "admin", - "poolSize": 20 - }, - "dragonfly": { - "host": "localhost", - "port": 6379, - "db": 0, - "maxRetries": 3, - "retryDelay": 100 - } - }, - "queue": { - "redis": { - "host": "localhost", - "port": 6379, - "db": 0 - }, - "defaultJobOptions": { - "attempts": 3, - "backoff": { - "type": "exponential", - "delay": 1000 - }, - "removeOnComplete": 100, - "removeOnFail": 50 - } - }, - "webshare": { - "apiKey": "", - "apiUrl": "https://proxy.webshare.io/api/v2/" - }, - "http": { - "timeout": 30000, - "retries": 3, - "retryDelay": 1000, - "userAgent": "StockBot/1.0", - "rateLimit": { - "enabled": false, - "requestsPerSecond": 10, - "burstSize": 20 - } - } -} diff --git a/apps/data-pipeline/config/default.json b/apps/data-pipeline/config/default.json deleted file mode 100644 index a7893f4..0000000 --- a/apps/data-pipeline/config/default.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "service": { - "name": "data-pipeline", - "port": 3005, - "host": "0.0.0.0", - "healthCheckPath": "/health", - "metricsPath": "/metrics", - "shutdownTimeout": 30000, - "cors": { - "enabled": true, - "origin": "*", - "credentials": false - } - } -} diff --git a/apps/stock/README.md b/apps/stock/README.md new file mode 100644 index 0000000..a82978b --- /dev/null +++ b/apps/stock/README.md @@ -0,0 +1,124 @@ +# Stock Trading Bot Application + +A comprehensive stock trading bot application with multiple microservices for data ingestion, processing, and API access. + +## Architecture + +The stock bot consists of the following services: + +- **Config**: Centralized configuration management +- **Data Ingestion**: Handles real-time and historical data collection +- **Data Pipeline**: Processes and transforms market data +- **Web API**: RESTful API for accessing stock data +- **Web App**: Frontend user interface + +## Quick Start + +### Prerequisites + +- Node.js >= 18.0.0 +- Bun >= 1.1.0 +- Turbo +- PostgreSQL, MongoDB, QuestDB, and Redis/Dragonfly running locally + +### Installation + +```bash +# Install all dependencies +bun install + +# Build the configuration package first +bun run build:config +``` + +### Development + +```bash +# Run all services in development mode (using Turbo) +bun run dev + +# Run only backend services +bun run dev:backend + +# Run only frontend +bun run dev:frontend + +# Run specific service +bun run dev:ingestion +bun run dev:pipeline +bun run dev:api +bun run dev:web +``` + +### Production + +```bash +# Build all services (using Turbo) +bun run build + +# Start with PM2 +bun run pm2:start + +# Check status +bun run pm2:status + +# View logs +bun run pm2:logs +``` + +### Configuration + +Configuration is managed centrally in the `config` package. + +- Default config: `config/config/default.json` +- Environment-specific: `config/config/[environment].json` +- Environment variables: Can override any config value + +### Health Checks + +```bash +# Check all services health +bun run health:check +``` + +### Database Management + +```bash +# Run migrations +bun run db:migrate + +# Seed database +bun run db:seed +``` + +## Available Scripts + +| Script | Description | +|--------|-------------| +| `dev` | Run all services in development mode | +| `build` | Build all services | +| `start` | Start all backend services | +| `test` | Run tests for all services | +| `lint` | Lint all services | +| `clean` | Clean build artifacts and dependencies | +| `docker:build` | Build Docker images | +| `pm2:start` | Start services with PM2 | +| `health:check` | Check health of all services | + +## Service Ports + +- Data Ingestion: 2001 +- Data Pipeline: 2002 +- Web API: 2003 +- Web App: 3000 (or next available) + +## Environment Variables + +Key environment variables: + +- `NODE_ENV`: development, test, or production +- `PORT`: Override default service port +- Database connection strings +- API keys for data providers + +See `config/config/default.json` for full configuration options. \ No newline at end of file diff --git a/apps/stock/config/config/default.json b/apps/stock/config/config/default.json new file mode 100644 index 0000000..b70a370 --- /dev/null +++ b/apps/stock/config/config/default.json @@ -0,0 +1,223 @@ +{ + "name": "stock-bot", + "version": "1.0.0", + "environment": "development", + "service": { + "name": "stock-bot", + "port": 3000, + "host": "0.0.0.0", + "healthCheckPath": "/health", + "metricsPath": "/metrics", + "shutdownTimeout": 30000, + "cors": { + "enabled": true, + "origin": "*", + "credentials": true + } + }, + "database": { + "postgres": { + "enabled": true, + "host": "localhost", + "port": 5432, + "database": "trading_bot", + "user": "trading_user", + "password": "trading_pass_dev", + "ssl": false, + "poolSize": 20, + "connectionTimeout": 30000, + "idleTimeout": 10000 + }, + "questdb": { + "host": "localhost", + "ilpPort": 9009, + "httpPort": 9000, + "pgPort": 8812, + "database": "questdb", + "user": "admin", + "password": "quest", + "bufferSize": 65536, + "flushInterval": 1000 + }, + "mongodb": { + "uri": "mongodb://trading_admin:trading_mongo_dev@localhost:27017/stock?authSource=admin", + "database": "stock", + "poolSize": 20 + }, + "dragonfly": { + "host": "localhost", + "port": 6379, + "db": 0, + "keyPrefix": "stock-bot:", + "maxRetries": 3, + "retryDelay": 100 + } + }, + "log": { + "level": "info", + "format": "json", + "hideObject": false, + "loki": { + "enabled": false, + "host": "localhost", + "port": 3100, + "labels": {} + } + }, + "redis": { + "enabled": true, + "host": "localhost", + "port": 6379, + "db": 0 + }, + "queue": { + "enabled": true, + "redis": { + "host": "localhost", + "port": 6379, + "db": 1 + }, + "workers": 5, + "concurrency": 2, + "enableScheduledJobs": true, + "delayWorkerStart": false, + "defaultJobOptions": { + "attempts": 3, + "backoff": { + "type": "exponential", + "delay": 1000 + }, + "removeOnComplete": 100, + "removeOnFail": 50, + "timeout": 300000 + } + }, + "http": { + "timeout": 30000, + "retries": 3, + "retryDelay": 1000, + "userAgent": "StockBot/1.0", + "proxy": { + "enabled": false + } + }, + "webshare": { + "apiKey": "", + "apiUrl": "https://proxy.webshare.io/api/v2/", + "enabled": true + }, + "browser": { + "headless": true, + "timeout": 30000 + }, + "proxy": { + "cachePrefix": "proxy:", + "ttl": 3600 + }, + "providers": { + "yahoo": { + "name": "yahoo", + "enabled": true, + "priority": 1, + "rateLimit": { + "maxRequests": 5, + "windowMs": 60000 + }, + "timeout": 30000, + "baseUrl": "https://query1.finance.yahoo.com" + }, + "qm": { + "name": "qm", + "enabled": false, + "priority": 2, + "username": "", + "password": "", + "baseUrl": "https://app.quotemedia.com/quotetools", + "webmasterId": "" + }, + "ib": { + "name": "ib", + "enabled": false, + "priority": 3, + "gateway": { + "host": "localhost", + "port": 5000, + "clientId": 1 + }, + "marketDataType": "delayed" + }, + "eod": { + "name": "eod", + "enabled": false, + "priority": 4, + "apiKey": "", + "baseUrl": "https://eodhistoricaldata.com/api", + "tier": "free" + } + }, + "features": { + "realtime": true, + "backtesting": true, + "paperTrading": true, + "autoTrading": false, + "historicalData": true, + "realtimeData": true, + "fundamentalData": true, + "newsAnalysis": false, + "notifications": false, + "emailAlerts": false, + "smsAlerts": false, + "webhookAlerts": false, + "technicalAnalysis": true, + "sentimentAnalysis": false, + "patternRecognition": false, + "riskManagement": true, + "positionSizing": true, + "stopLoss": true, + "takeProfit": true + }, + "services": { + "dataIngestion": { + "port": 2001, + "workers": 4, + "queues": { + "ceo": { "concurrency": 2 }, + "webshare": { "concurrency": 1 }, + "qm": { "concurrency": 2 }, + "ib": { "concurrency": 1 }, + "proxy": { "concurrency": 1 } + }, + "rateLimit": { + "enabled": true, + "requestsPerSecond": 10 + } + }, + "dataPipeline": { + "port": 2002, + "workers": 2, + "batchSize": 1000, + "processingInterval": 60000, + "queues": { + "exchanges": { "concurrency": 1 }, + "symbols": { "concurrency": 2 } + }, + "syncOptions": { + "maxRetries": 3, + "retryDelay": 5000, + "timeout": 300000 + } + }, + "webApi": { + "port": 2003, + "rateLimitPerMinute": 60, + "cache": { + "ttl": 300, + "checkPeriod": 60 + }, + "cors": { + "origins": ["http://localhost:3000", "http://localhost:4200"], + "credentials": true + } + } + } +} \ No newline at end of file diff --git a/apps/stock/config/config/development.json b/apps/stock/config/config/development.json new file mode 100644 index 0000000..06bd8e9 --- /dev/null +++ b/apps/stock/config/config/development.json @@ -0,0 +1,11 @@ +{ + "environment": "development", + "log": { + "level": "debug", + "format": "pretty" + }, + "features": { + "autoTrading": false, + "paperTrading": true + } +} \ No newline at end of file diff --git a/apps/stock/config/config/production.json b/apps/stock/config/config/production.json new file mode 100644 index 0000000..dd7806e --- /dev/null +++ b/apps/stock/config/config/production.json @@ -0,0 +1,42 @@ +{ + "environment": "production", + "log": { + "level": "warn", + "format": "json", + "loki": { + "enabled": true, + "host": "loki.production.example.com", + "port": 3100 + } + }, + "database": { + "postgres": { + "host": "postgres.production.example.com", + "ssl": true, + "poolSize": 50 + }, + "questdb": { + "host": "questdb.production.example.com" + }, + "mongodb": { + "uri": "mongodb+srv://prod_user:prod_pass@cluster.mongodb.net/stock?retryWrites=true&w=majority", + "poolSize": 50 + }, + "dragonfly": { + "host": "redis.production.example.com", + "password": "production_redis_password" + } + }, + "queue": { + "redis": { + "host": "redis.production.example.com", + "password": "production_redis_password" + } + }, + "features": { + "autoTrading": true, + "notifications": true, + "emailAlerts": true, + "webhookAlerts": true + } +} \ No newline at end of file diff --git a/apps/stock/config/package.json b/apps/stock/config/package.json new file mode 100644 index 0000000..00abb97 --- /dev/null +++ b/apps/stock/config/package.json @@ -0,0 +1,22 @@ +{ + "name": "@stock-bot/stock-config", + "version": "1.0.0", + "description": "Stock trading bot configuration", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc", + "clean": "rm -rf dist", + "dev": "tsc --watch", + "test": "jest", + "lint": "eslint src --ext .ts" + }, + "dependencies": { + "@stock-bot/config": "*", + "zod": "^3.22.4" + }, + "devDependencies": { + "@types/node": "^20.11.0", + "typescript": "^5.3.3" + } +} \ No newline at end of file diff --git a/apps/stock/config/src/config-instance.ts b/apps/stock/config/src/config-instance.ts new file mode 100644 index 0000000..487969f --- /dev/null +++ b/apps/stock/config/src/config-instance.ts @@ -0,0 +1,83 @@ +import { ConfigManager, createAppConfig } from '@stock-bot/config'; +import { stockAppSchema, type StockAppConfig } from './schemas'; +import * as path from 'path'; + +let configInstance: ConfigManager | null = null; + +/** + * Initialize the stock application configuration + * @param serviceName - Optional service name to override port configuration + */ +export function initializeStockConfig(serviceName?: 'dataIngestion' | 'dataPipeline' | 'webApi'): StockAppConfig { + try { + if (!configInstance) { + configInstance = createAppConfig(stockAppSchema, { + configPath: path.join(__dirname, '../config'), + }); + } + + const config = configInstance.initialize(stockAppSchema); + + // If a service name is provided, override the service port + if (serviceName && config.services?.[serviceName]) { + return { + ...config, + service: { + ...config.service, + port: config.services[serviceName].port, + name: serviceName.replace(/([A-Z])/g, '-$1').toLowerCase() // Convert camelCase to kebab-case + } + }; + } + + return config; + } catch (error: any) { + console.error('Failed to initialize stock configuration:', error.message); + if (error.errors) { + console.error('Validation errors:', JSON.stringify(error.errors, null, 2)); + } + throw error; + } +} + +/** + * Get the current stock configuration + */ +export function getStockConfig(): StockAppConfig { + if (!configInstance) { + // Auto-initialize if not already done + return initializeStockConfig(); + } + return configInstance.get(); +} + +/** + * Get configuration for a specific service + */ +export function getServiceConfig(service: 'dataIngestion' | 'dataPipeline' | 'webApi') { + const config = getStockConfig(); + return config.services?.[service]; +} + +/** + * Get configuration for a specific provider + */ +export function getProviderConfig(provider: 'eod' | 'ib' | 'qm' | 'yahoo') { + const config = getStockConfig(); + return config.providers[provider]; +} + +/** + * Check if a feature is enabled + */ +export function isFeatureEnabled(feature: keyof StockAppConfig['features']): boolean { + const config = getStockConfig(); + return config.features[feature]; +} + +/** + * Reset configuration (useful for testing) + */ +export function resetStockConfig(): void { + configInstance = null; +} \ No newline at end of file diff --git a/apps/stock/config/src/index.ts b/apps/stock/config/src/index.ts new file mode 100644 index 0000000..2197dde --- /dev/null +++ b/apps/stock/config/src/index.ts @@ -0,0 +1,15 @@ +// Export schemas +export * from './schemas'; + +// Export config instance functions +export { + initializeStockConfig, + getStockConfig, + getServiceConfig, + getProviderConfig, + isFeatureEnabled, + resetStockConfig, +} from './config-instance'; + +// Re-export type for convenience +export type { StockAppConfig } from './schemas/stock-app.schema'; \ No newline at end of file diff --git a/apps/stock/config/src/schemas/features.schema.ts b/apps/stock/config/src/schemas/features.schema.ts new file mode 100644 index 0000000..5946029 --- /dev/null +++ b/apps/stock/config/src/schemas/features.schema.ts @@ -0,0 +1,35 @@ +import { z } from 'zod'; + +/** + * Feature flags for the stock trading application + */ +export const featuresSchema = z.object({ + // Trading features + realtime: z.boolean().default(true), + backtesting: z.boolean().default(true), + paperTrading: z.boolean().default(true), + autoTrading: z.boolean().default(false), + + // Data features + historicalData: z.boolean().default(true), + realtimeData: z.boolean().default(true), + fundamentalData: z.boolean().default(true), + newsAnalysis: z.boolean().default(false), + + // Notification features + notifications: z.boolean().default(false), + emailAlerts: z.boolean().default(false), + smsAlerts: z.boolean().default(false), + webhookAlerts: z.boolean().default(false), + + // Analysis features + technicalAnalysis: z.boolean().default(true), + sentimentAnalysis: z.boolean().default(false), + patternRecognition: z.boolean().default(false), + + // Risk management + riskManagement: z.boolean().default(true), + positionSizing: z.boolean().default(true), + stopLoss: z.boolean().default(true), + takeProfit: z.boolean().default(true), +}); \ No newline at end of file diff --git a/apps/stock/config/src/schemas/index.ts b/apps/stock/config/src/schemas/index.ts new file mode 100644 index 0000000..6ab54d6 --- /dev/null +++ b/apps/stock/config/src/schemas/index.ts @@ -0,0 +1,3 @@ +export * from './stock-app.schema'; +export * from './providers.schema'; +export * from './features.schema'; \ No newline at end of file diff --git a/apps/stock/config/src/schemas/providers.schema.ts b/apps/stock/config/src/schemas/providers.schema.ts new file mode 100644 index 0000000..992da6a --- /dev/null +++ b/apps/stock/config/src/schemas/providers.schema.ts @@ -0,0 +1,67 @@ +import { z } from 'zod'; + +// Base provider configuration +export const baseProviderConfigSchema = z.object({ + name: z.string(), + enabled: z.boolean().default(true), + priority: z.number().default(0), + rateLimit: z + .object({ + maxRequests: z.number().default(100), + windowMs: z.number().default(60000), + }) + .optional(), + timeout: z.number().default(30000), + retries: z.number().default(3), +}); + +// EOD Historical Data provider +export const eodProviderConfigSchema = baseProviderConfigSchema.extend({ + apiKey: z.string(), + baseUrl: z.string().default('https://eodhistoricaldata.com/api'), + tier: z.enum(['free', 'fundamentals', 'all-in-one']).default('free'), +}); + +// Interactive Brokers provider +export const ibProviderConfigSchema = baseProviderConfigSchema.extend({ + gateway: z.object({ + host: z.string().default('localhost'), + port: z.number().default(5000), + clientId: z.number().default(1), + }), + account: z.string().optional(), + marketDataType: z.enum(['live', 'delayed', 'frozen']).default('delayed'), +}); + +// QuoteMedia provider +export const qmProviderConfigSchema = baseProviderConfigSchema.extend({ + username: z.string(), + password: z.string(), + baseUrl: z.string().default('https://app.quotemedia.com/quotetools'), + webmasterId: z.string(), +}); + +// Yahoo Finance provider +export const yahooProviderConfigSchema = baseProviderConfigSchema.extend({ + baseUrl: z.string().default('https://query1.finance.yahoo.com'), + cookieJar: z.boolean().default(true), + crumb: z.string().optional(), +}); + +// Combined provider configuration +export const providersSchema = z.object({ + eod: eodProviderConfigSchema.optional(), + ib: ibProviderConfigSchema.optional(), + qm: qmProviderConfigSchema.optional(), + yahoo: yahooProviderConfigSchema.optional(), +}); + +// Dynamic provider configuration type +export type ProviderName = 'eod' | 'ib' | 'qm' | 'yahoo'; + +export const providerSchemas = { + eod: eodProviderConfigSchema, + ib: ibProviderConfigSchema, + qm: qmProviderConfigSchema, + yahoo: yahooProviderConfigSchema, +} as const; \ No newline at end of file diff --git a/apps/stock/config/src/schemas/stock-app.schema.ts b/apps/stock/config/src/schemas/stock-app.schema.ts new file mode 100644 index 0000000..570971b --- /dev/null +++ b/apps/stock/config/src/schemas/stock-app.schema.ts @@ -0,0 +1,72 @@ +import { z } from 'zod'; +import { + baseAppSchema, + postgresConfigSchema, + mongodbConfigSchema, + questdbConfigSchema, + dragonflyConfigSchema +} from '@stock-bot/config'; +import { providersSchema } from './providers.schema'; +import { featuresSchema } from './features.schema'; + +/** + * Stock trading application configuration schema + */ +export const stockAppSchema = baseAppSchema.extend({ + // Stock app uses all databases + database: z.object({ + postgres: postgresConfigSchema, + mongodb: mongodbConfigSchema, + questdb: questdbConfigSchema, + dragonfly: dragonflyConfigSchema, + }), + + // Stock-specific providers + providers: providersSchema, + + // Feature flags + features: featuresSchema, + + // Service-specific configurations + services: z.object({ + dataIngestion: z.object({ + port: z.number().default(2001), + workers: z.number().default(4), + queues: z.record(z.object({ + concurrency: z.number().default(1), + })).optional(), + rateLimit: z.object({ + enabled: z.boolean().default(true), + requestsPerSecond: z.number().default(10), + }).optional(), + }).optional(), + dataPipeline: z.object({ + port: z.number().default(2002), + workers: z.number().default(2), + batchSize: z.number().default(1000), + processingInterval: z.number().default(60000), + queues: z.record(z.object({ + concurrency: z.number().default(1), + })).optional(), + syncOptions: z.object({ + maxRetries: z.number().default(3), + retryDelay: z.number().default(5000), + timeout: z.number().default(300000), + }).optional(), + }).optional(), + webApi: z.object({ + port: z.number().default(2003), + rateLimitPerMinute: z.number().default(60), + cache: z.object({ + ttl: z.number().default(300), + checkPeriod: z.number().default(60), + }).optional(), + cors: z.object({ + origins: z.array(z.string()).default(['http://localhost:3000']), + credentials: z.boolean().default(true), + }).optional(), + }).optional(), + }).optional(), +}); + +export type StockAppConfig = z.infer; \ No newline at end of file diff --git a/apps/stock/config/tsconfig.json b/apps/stock/config/tsconfig.json new file mode 100644 index 0000000..59ed31f --- /dev/null +++ b/apps/stock/config/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "composite": true, + "declaration": true, + "declarationMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "**/*.test.ts"], + "references": [ + { "path": "../../../libs/core/config" } + ] +} \ No newline at end of file diff --git a/apps/data-ingestion/AWILIX-MIGRATION.md b/apps/stock/data-ingestion/AWILIX-MIGRATION.md similarity index 100% rename from apps/data-ingestion/AWILIX-MIGRATION.md rename to apps/stock/data-ingestion/AWILIX-MIGRATION.md diff --git a/apps/data-ingestion/package.json b/apps/stock/data-ingestion/package.json similarity index 96% rename from apps/data-ingestion/package.json rename to apps/stock/data-ingestion/package.json index 8072ed6..fd5e902 100644 --- a/apps/data-ingestion/package.json +++ b/apps/stock/data-ingestion/package.json @@ -14,6 +14,7 @@ "dependencies": { "@stock-bot/cache": "*", "@stock-bot/config": "*", + "@stock-bot/stock-config": "*", "@stock-bot/di": "*", "@stock-bot/handlers": "*", "@stock-bot/logger": "*", diff --git a/apps/data-ingestion/src/handlers/ceo/actions/index.ts b/apps/stock/data-ingestion/src/handlers/ceo/actions/index.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ceo/actions/index.ts rename to apps/stock/data-ingestion/src/handlers/ceo/actions/index.ts diff --git a/apps/data-ingestion/src/handlers/ceo/actions/process-individual-symbol.action.ts b/apps/stock/data-ingestion/src/handlers/ceo/actions/process-individual-symbol.action.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ceo/actions/process-individual-symbol.action.ts rename to apps/stock/data-ingestion/src/handlers/ceo/actions/process-individual-symbol.action.ts diff --git a/apps/data-ingestion/src/handlers/ceo/actions/update-ceo-channels.action.ts b/apps/stock/data-ingestion/src/handlers/ceo/actions/update-ceo-channels.action.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ceo/actions/update-ceo-channels.action.ts rename to apps/stock/data-ingestion/src/handlers/ceo/actions/update-ceo-channels.action.ts diff --git a/apps/data-ingestion/src/handlers/ceo/actions/update-unique-symbols.action.ts b/apps/stock/data-ingestion/src/handlers/ceo/actions/update-unique-symbols.action.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ceo/actions/update-unique-symbols.action.ts rename to apps/stock/data-ingestion/src/handlers/ceo/actions/update-unique-symbols.action.ts diff --git a/apps/data-ingestion/src/handlers/ceo/ceo.handler.ts b/apps/stock/data-ingestion/src/handlers/ceo/ceo.handler.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ceo/ceo.handler.ts rename to apps/stock/data-ingestion/src/handlers/ceo/ceo.handler.ts diff --git a/apps/data-ingestion/src/handlers/example/example.handler.ts b/apps/stock/data-ingestion/src/handlers/example/example.handler.ts similarity index 100% rename from apps/data-ingestion/src/handlers/example/example.handler.ts rename to apps/stock/data-ingestion/src/handlers/example/example.handler.ts diff --git a/apps/data-ingestion/src/handlers/ib/actions/fetch-exchanges-and-symbols.action.ts b/apps/stock/data-ingestion/src/handlers/ib/actions/fetch-exchanges-and-symbols.action.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ib/actions/fetch-exchanges-and-symbols.action.ts rename to apps/stock/data-ingestion/src/handlers/ib/actions/fetch-exchanges-and-symbols.action.ts diff --git a/apps/data-ingestion/src/handlers/ib/actions/fetch-exchanges.action.ts b/apps/stock/data-ingestion/src/handlers/ib/actions/fetch-exchanges.action.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ib/actions/fetch-exchanges.action.ts rename to apps/stock/data-ingestion/src/handlers/ib/actions/fetch-exchanges.action.ts diff --git a/apps/data-ingestion/src/handlers/ib/actions/fetch-session.action.ts b/apps/stock/data-ingestion/src/handlers/ib/actions/fetch-session.action.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ib/actions/fetch-session.action.ts rename to apps/stock/data-ingestion/src/handlers/ib/actions/fetch-session.action.ts diff --git a/apps/data-ingestion/src/handlers/ib/actions/fetch-symbols.action.ts b/apps/stock/data-ingestion/src/handlers/ib/actions/fetch-symbols.action.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ib/actions/fetch-symbols.action.ts rename to apps/stock/data-ingestion/src/handlers/ib/actions/fetch-symbols.action.ts diff --git a/apps/data-ingestion/src/handlers/ib/actions/index.ts b/apps/stock/data-ingestion/src/handlers/ib/actions/index.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ib/actions/index.ts rename to apps/stock/data-ingestion/src/handlers/ib/actions/index.ts diff --git a/apps/data-ingestion/src/handlers/ib/ib.handler.ts b/apps/stock/data-ingestion/src/handlers/ib/ib.handler.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ib/ib.handler.ts rename to apps/stock/data-ingestion/src/handlers/ib/ib.handler.ts diff --git a/apps/data-ingestion/src/handlers/ib/shared/config.ts b/apps/stock/data-ingestion/src/handlers/ib/shared/config.ts similarity index 100% rename from apps/data-ingestion/src/handlers/ib/shared/config.ts rename to apps/stock/data-ingestion/src/handlers/ib/shared/config.ts diff --git a/apps/data-ingestion/src/handlers/index.ts b/apps/stock/data-ingestion/src/handlers/index.ts similarity index 100% rename from apps/data-ingestion/src/handlers/index.ts rename to apps/stock/data-ingestion/src/handlers/index.ts diff --git a/apps/data-ingestion/src/handlers/proxy/operations/check.operations.ts b/apps/stock/data-ingestion/src/handlers/proxy/operations/check.operations.ts similarity index 100% rename from apps/data-ingestion/src/handlers/proxy/operations/check.operations.ts rename to apps/stock/data-ingestion/src/handlers/proxy/operations/check.operations.ts diff --git a/apps/data-ingestion/src/handlers/proxy/operations/fetch.operations.ts b/apps/stock/data-ingestion/src/handlers/proxy/operations/fetch.operations.ts similarity index 100% rename from apps/data-ingestion/src/handlers/proxy/operations/fetch.operations.ts rename to apps/stock/data-ingestion/src/handlers/proxy/operations/fetch.operations.ts diff --git a/apps/data-ingestion/src/handlers/proxy/operations/query.operations.ts b/apps/stock/data-ingestion/src/handlers/proxy/operations/query.operations.ts similarity index 100% rename from apps/data-ingestion/src/handlers/proxy/operations/query.operations.ts rename to apps/stock/data-ingestion/src/handlers/proxy/operations/query.operations.ts diff --git a/apps/data-ingestion/src/handlers/proxy/operations/queue.operations.ts b/apps/stock/data-ingestion/src/handlers/proxy/operations/queue.operations.ts similarity index 100% rename from apps/data-ingestion/src/handlers/proxy/operations/queue.operations.ts rename to apps/stock/data-ingestion/src/handlers/proxy/operations/queue.operations.ts diff --git a/apps/data-ingestion/src/handlers/proxy/proxy.handler.ts b/apps/stock/data-ingestion/src/handlers/proxy/proxy.handler.ts similarity index 100% rename from apps/data-ingestion/src/handlers/proxy/proxy.handler.ts rename to apps/stock/data-ingestion/src/handlers/proxy/proxy.handler.ts diff --git a/apps/data-ingestion/src/handlers/proxy/shared/config.ts b/apps/stock/data-ingestion/src/handlers/proxy/shared/config.ts similarity index 100% rename from apps/data-ingestion/src/handlers/proxy/shared/config.ts rename to apps/stock/data-ingestion/src/handlers/proxy/shared/config.ts diff --git a/apps/data-ingestion/src/handlers/proxy/shared/types.ts b/apps/stock/data-ingestion/src/handlers/proxy/shared/types.ts similarity index 100% rename from apps/data-ingestion/src/handlers/proxy/shared/types.ts rename to apps/stock/data-ingestion/src/handlers/proxy/shared/types.ts diff --git a/apps/data-ingestion/src/handlers/qm/actions/exchanges.action.ts b/apps/stock/data-ingestion/src/handlers/qm/actions/exchanges.action.ts similarity index 100% rename from apps/data-ingestion/src/handlers/qm/actions/exchanges.action.ts rename to apps/stock/data-ingestion/src/handlers/qm/actions/exchanges.action.ts diff --git a/apps/data-ingestion/src/handlers/qm/actions/session.action.ts b/apps/stock/data-ingestion/src/handlers/qm/actions/session.action.ts similarity index 100% rename from apps/data-ingestion/src/handlers/qm/actions/session.action.ts rename to apps/stock/data-ingestion/src/handlers/qm/actions/session.action.ts diff --git a/apps/data-ingestion/src/handlers/qm/actions/spider.action.ts b/apps/stock/data-ingestion/src/handlers/qm/actions/spider.action.ts similarity index 100% rename from apps/data-ingestion/src/handlers/qm/actions/spider.action.ts rename to apps/stock/data-ingestion/src/handlers/qm/actions/spider.action.ts diff --git a/apps/data-ingestion/src/handlers/qm/actions/symbols.action.ts b/apps/stock/data-ingestion/src/handlers/qm/actions/symbols.action.ts similarity index 100% rename from apps/data-ingestion/src/handlers/qm/actions/symbols.action.ts rename to apps/stock/data-ingestion/src/handlers/qm/actions/symbols.action.ts diff --git a/apps/data-ingestion/src/handlers/qm/qm.handler.ts b/apps/stock/data-ingestion/src/handlers/qm/qm.handler.ts similarity index 100% rename from apps/data-ingestion/src/handlers/qm/qm.handler.ts rename to apps/stock/data-ingestion/src/handlers/qm/qm.handler.ts diff --git a/apps/data-ingestion/src/handlers/qm/shared/config.ts b/apps/stock/data-ingestion/src/handlers/qm/shared/config.ts similarity index 100% rename from apps/data-ingestion/src/handlers/qm/shared/config.ts rename to apps/stock/data-ingestion/src/handlers/qm/shared/config.ts diff --git a/apps/data-ingestion/src/handlers/qm/shared/session-manager.ts b/apps/stock/data-ingestion/src/handlers/qm/shared/session-manager.ts similarity index 100% rename from apps/data-ingestion/src/handlers/qm/shared/session-manager.ts rename to apps/stock/data-ingestion/src/handlers/qm/shared/session-manager.ts diff --git a/apps/data-ingestion/src/handlers/qm/shared/types.ts b/apps/stock/data-ingestion/src/handlers/qm/shared/types.ts similarity index 100% rename from apps/data-ingestion/src/handlers/qm/shared/types.ts rename to apps/stock/data-ingestion/src/handlers/qm/shared/types.ts diff --git a/apps/data-ingestion/src/handlers/webshare/operations/fetch.operations.ts b/apps/stock/data-ingestion/src/handlers/webshare/operations/fetch.operations.ts similarity index 74% rename from apps/data-ingestion/src/handlers/webshare/operations/fetch.operations.ts rename to apps/stock/data-ingestion/src/handlers/webshare/operations/fetch.operations.ts index aca7037..6c14688 100644 --- a/apps/data-ingestion/src/handlers/webshare/operations/fetch.operations.ts +++ b/apps/stock/data-ingestion/src/handlers/webshare/operations/fetch.operations.ts @@ -12,17 +12,35 @@ export async function fetchWebShareProxies(): Promise { const ctx = OperationContext.create('webshare', 'fetch-proxies'); try { - // Get configuration from config system - const { getConfig } = await import('@stock-bot/config'); - const config = getConfig(); + // Get configuration from stock config system - ensure it's initialized + const { getStockConfig, initializeStockConfig } = await import('@stock-bot/stock-config'); + + // Try to get existing config, or initialize if needed + let config; + try { + config = getStockConfig(); + } catch (error) { + // Config not initialized yet, initialize it + config = initializeStockConfig('dataIngestion'); + } const apiKey = config.webshare?.apiKey; const apiUrl = config.webshare?.apiUrl; + + ctx.logger.debug('WebShare config loaded', { + hasConfig: !!config, + hasWebshare: !!config.webshare, + webshareConfig: config.webshare, + apiKeyLength: apiKey?.length || 0, + apiUrl: apiUrl, + envApiKey: process.env.WEBSHARE_API_KEY ? 'SET' : 'NOT_SET', + }); if (!apiKey || !apiUrl) { ctx.logger.error('Missing WebShare configuration', { hasApiKey: !!apiKey, hasApiUrl: !!apiUrl, + apiKeyValue: apiKey ? `${apiKey.substring(0, 5)}...` : 'NOT_SET', }); return []; } diff --git a/apps/data-ingestion/src/handlers/webshare/shared/config.ts b/apps/stock/data-ingestion/src/handlers/webshare/shared/config.ts similarity index 100% rename from apps/data-ingestion/src/handlers/webshare/shared/config.ts rename to apps/stock/data-ingestion/src/handlers/webshare/shared/config.ts diff --git a/apps/data-ingestion/src/handlers/webshare/webshare.handler.ts b/apps/stock/data-ingestion/src/handlers/webshare/webshare.handler.ts similarity index 100% rename from apps/data-ingestion/src/handlers/webshare/webshare.handler.ts rename to apps/stock/data-ingestion/src/handlers/webshare/webshare.handler.ts diff --git a/apps/data-ingestion/src/index.ts b/apps/stock/data-ingestion/src/index.ts similarity index 85% rename from apps/data-ingestion/src/index.ts rename to apps/stock/data-ingestion/src/index.ts index d814152..45aeeea 100644 --- a/apps/data-ingestion/src/index.ts +++ b/apps/stock/data-ingestion/src/index.ts @@ -3,7 +3,7 @@ * Simplified entry point using ServiceApplication framework */ -import { initializeServiceConfig } from '@stock-bot/config'; +import { initializeStockConfig } from '@stock-bot/stock-config'; import { ServiceApplication, } from '@stock-bot/di'; @@ -13,9 +13,9 @@ import { getLogger } from '@stock-bot/logger'; import { initializeAllHandlers } from './handlers'; import { createRoutes } from './routes/create-routes'; -// Initialize configuration -const config = initializeServiceConfig(); -console.log('Data Service Configuration:', JSON.stringify(config, null, 2)); +// Initialize configuration with service-specific overrides +const config = initializeStockConfig('dataIngestion'); +console.log('Data Ingestion Service Configuration:', JSON.stringify(config, null, 2)); // Create service application const app = new ServiceApplication( @@ -57,7 +57,7 @@ async function createContainer(config: any) { .withOptions({ enableQuestDB: false, // Data ingestion doesn't need QuestDB yet enableMongoDB: true, - enablePostgres: true, + enablePostgres: config.database?.postgres?.enabled ?? false, enableCache: true, enableQueue: true, enableBrowser: true, // Data ingestion needs browser for web scraping diff --git a/apps/data-ingestion/src/routes/create-routes.ts b/apps/stock/data-ingestion/src/routes/create-routes.ts similarity index 100% rename from apps/data-ingestion/src/routes/create-routes.ts rename to apps/stock/data-ingestion/src/routes/create-routes.ts diff --git a/apps/data-ingestion/src/routes/exchange.routes.ts b/apps/stock/data-ingestion/src/routes/exchange.routes.ts similarity index 100% rename from apps/data-ingestion/src/routes/exchange.routes.ts rename to apps/stock/data-ingestion/src/routes/exchange.routes.ts diff --git a/apps/data-ingestion/src/routes/health.routes.ts b/apps/stock/data-ingestion/src/routes/health.routes.ts similarity index 100% rename from apps/data-ingestion/src/routes/health.routes.ts rename to apps/stock/data-ingestion/src/routes/health.routes.ts diff --git a/apps/data-ingestion/src/routes/index.ts b/apps/stock/data-ingestion/src/routes/index.ts similarity index 100% rename from apps/data-ingestion/src/routes/index.ts rename to apps/stock/data-ingestion/src/routes/index.ts diff --git a/apps/data-ingestion/src/routes/market-data.routes.ts b/apps/stock/data-ingestion/src/routes/market-data.routes.ts similarity index 100% rename from apps/data-ingestion/src/routes/market-data.routes.ts rename to apps/stock/data-ingestion/src/routes/market-data.routes.ts diff --git a/apps/data-ingestion/src/routes/queue.routes.ts b/apps/stock/data-ingestion/src/routes/queue.routes.ts similarity index 100% rename from apps/data-ingestion/src/routes/queue.routes.ts rename to apps/stock/data-ingestion/src/routes/queue.routes.ts diff --git a/apps/data-ingestion/src/types/exchange.types.ts b/apps/stock/data-ingestion/src/types/exchange.types.ts similarity index 100% rename from apps/data-ingestion/src/types/exchange.types.ts rename to apps/stock/data-ingestion/src/types/exchange.types.ts diff --git a/apps/data-ingestion/src/types/job-payloads.ts b/apps/stock/data-ingestion/src/types/job-payloads.ts similarity index 100% rename from apps/data-ingestion/src/types/job-payloads.ts rename to apps/stock/data-ingestion/src/types/job-payloads.ts diff --git a/apps/data-ingestion/src/utils/symbol-search.util.ts b/apps/stock/data-ingestion/src/utils/symbol-search.util.ts similarity index 100% rename from apps/data-ingestion/src/utils/symbol-search.util.ts rename to apps/stock/data-ingestion/src/utils/symbol-search.util.ts diff --git a/apps/data-ingestion/test-ceo-operations.ts b/apps/stock/data-ingestion/test-ceo-operations.ts similarity index 100% rename from apps/data-ingestion/test-ceo-operations.ts rename to apps/stock/data-ingestion/test-ceo-operations.ts diff --git a/apps/data-ingestion/tsconfig.json b/apps/stock/data-ingestion/tsconfig.json similarity index 89% rename from apps/data-ingestion/tsconfig.json rename to apps/stock/data-ingestion/tsconfig.json index 32948f6..0ac761f 100644 --- a/apps/data-ingestion/tsconfig.json +++ b/apps/stock/data-ingestion/tsconfig.json @@ -12,6 +12,7 @@ { "path": "../../libs/data/questdb" }, { "path": "../../libs/services/queue" }, { "path": "../../libs/services/shutdown" }, - { "path": "../../libs/utils" } + { "path": "../../libs/utils" }, + { "path": "../config" } ] } diff --git a/apps/data-pipeline/README.md b/apps/stock/data-pipeline/README.md similarity index 100% rename from apps/data-pipeline/README.md rename to apps/stock/data-pipeline/README.md diff --git a/apps/data-pipeline/package.json b/apps/stock/data-pipeline/package.json similarity index 96% rename from apps/data-pipeline/package.json rename to apps/stock/data-pipeline/package.json index 9b381f4..c10b086 100644 --- a/apps/data-pipeline/package.json +++ b/apps/stock/data-pipeline/package.json @@ -14,6 +14,7 @@ "dependencies": { "@stock-bot/cache": "*", "@stock-bot/config": "*", + "@stock-bot/stock-config": "*", "@stock-bot/logger": "*", "@stock-bot/mongodb": "*", "@stock-bot/postgres": "*", diff --git a/apps/data-pipeline/src/container-setup.ts b/apps/stock/data-pipeline/src/container-setup.ts similarity index 100% rename from apps/data-pipeline/src/container-setup.ts rename to apps/stock/data-pipeline/src/container-setup.ts diff --git a/apps/data-pipeline/src/handlers/exchanges/exchanges.handler.ts b/apps/stock/data-pipeline/src/handlers/exchanges/exchanges.handler.ts similarity index 100% rename from apps/data-pipeline/src/handlers/exchanges/exchanges.handler.ts rename to apps/stock/data-pipeline/src/handlers/exchanges/exchanges.handler.ts diff --git a/apps/data-pipeline/src/handlers/exchanges/operations/clear-postgresql-data.operations.ts b/apps/stock/data-pipeline/src/handlers/exchanges/operations/clear-postgresql-data.operations.ts similarity index 100% rename from apps/data-pipeline/src/handlers/exchanges/operations/clear-postgresql-data.operations.ts rename to apps/stock/data-pipeline/src/handlers/exchanges/operations/clear-postgresql-data.operations.ts diff --git a/apps/data-pipeline/src/handlers/exchanges/operations/enhanced-sync-status.operations.ts b/apps/stock/data-pipeline/src/handlers/exchanges/operations/enhanced-sync-status.operations.ts similarity index 100% rename from apps/data-pipeline/src/handlers/exchanges/operations/enhanced-sync-status.operations.ts rename to apps/stock/data-pipeline/src/handlers/exchanges/operations/enhanced-sync-status.operations.ts diff --git a/apps/data-pipeline/src/handlers/exchanges/operations/exchange-stats.operations.ts b/apps/stock/data-pipeline/src/handlers/exchanges/operations/exchange-stats.operations.ts similarity index 100% rename from apps/data-pipeline/src/handlers/exchanges/operations/exchange-stats.operations.ts rename to apps/stock/data-pipeline/src/handlers/exchanges/operations/exchange-stats.operations.ts diff --git a/apps/data-pipeline/src/handlers/exchanges/operations/index.ts b/apps/stock/data-pipeline/src/handlers/exchanges/operations/index.ts similarity index 100% rename from apps/data-pipeline/src/handlers/exchanges/operations/index.ts rename to apps/stock/data-pipeline/src/handlers/exchanges/operations/index.ts diff --git a/apps/data-pipeline/src/handlers/exchanges/operations/provider-mapping-stats.operations.ts b/apps/stock/data-pipeline/src/handlers/exchanges/operations/provider-mapping-stats.operations.ts similarity index 100% rename from apps/data-pipeline/src/handlers/exchanges/operations/provider-mapping-stats.operations.ts rename to apps/stock/data-pipeline/src/handlers/exchanges/operations/provider-mapping-stats.operations.ts diff --git a/apps/data-pipeline/src/handlers/exchanges/operations/qm-exchanges.operations.ts b/apps/stock/data-pipeline/src/handlers/exchanges/operations/qm-exchanges.operations.ts similarity index 100% rename from apps/data-pipeline/src/handlers/exchanges/operations/qm-exchanges.operations.ts rename to apps/stock/data-pipeline/src/handlers/exchanges/operations/qm-exchanges.operations.ts diff --git a/apps/data-pipeline/src/handlers/exchanges/operations/sync-all-exchanges.operations.ts b/apps/stock/data-pipeline/src/handlers/exchanges/operations/sync-all-exchanges.operations.ts similarity index 100% rename from apps/data-pipeline/src/handlers/exchanges/operations/sync-all-exchanges.operations.ts rename to apps/stock/data-pipeline/src/handlers/exchanges/operations/sync-all-exchanges.operations.ts diff --git a/apps/data-pipeline/src/handlers/exchanges/operations/sync-ib-exchanges.operations.ts b/apps/stock/data-pipeline/src/handlers/exchanges/operations/sync-ib-exchanges.operations.ts similarity index 100% rename from apps/data-pipeline/src/handlers/exchanges/operations/sync-ib-exchanges.operations.ts rename to apps/stock/data-pipeline/src/handlers/exchanges/operations/sync-ib-exchanges.operations.ts diff --git a/apps/data-pipeline/src/handlers/exchanges/operations/sync-qm-provider-mappings.operations.ts b/apps/stock/data-pipeline/src/handlers/exchanges/operations/sync-qm-provider-mappings.operations.ts similarity index 100% rename from apps/data-pipeline/src/handlers/exchanges/operations/sync-qm-provider-mappings.operations.ts rename to apps/stock/data-pipeline/src/handlers/exchanges/operations/sync-qm-provider-mappings.operations.ts diff --git a/apps/data-pipeline/src/handlers/index.ts b/apps/stock/data-pipeline/src/handlers/index.ts similarity index 100% rename from apps/data-pipeline/src/handlers/index.ts rename to apps/stock/data-pipeline/src/handlers/index.ts diff --git a/apps/data-pipeline/src/handlers/symbols/operations/index.ts b/apps/stock/data-pipeline/src/handlers/symbols/operations/index.ts similarity index 100% rename from apps/data-pipeline/src/handlers/symbols/operations/index.ts rename to apps/stock/data-pipeline/src/handlers/symbols/operations/index.ts diff --git a/apps/data-pipeline/src/handlers/symbols/operations/qm-symbols.operations.ts b/apps/stock/data-pipeline/src/handlers/symbols/operations/qm-symbols.operations.ts similarity index 100% rename from apps/data-pipeline/src/handlers/symbols/operations/qm-symbols.operations.ts rename to apps/stock/data-pipeline/src/handlers/symbols/operations/qm-symbols.operations.ts diff --git a/apps/data-pipeline/src/handlers/symbols/operations/sync-status.operations.ts b/apps/stock/data-pipeline/src/handlers/symbols/operations/sync-status.operations.ts similarity index 100% rename from apps/data-pipeline/src/handlers/symbols/operations/sync-status.operations.ts rename to apps/stock/data-pipeline/src/handlers/symbols/operations/sync-status.operations.ts diff --git a/apps/data-pipeline/src/handlers/symbols/operations/sync-symbols-from-provider.operations.ts b/apps/stock/data-pipeline/src/handlers/symbols/operations/sync-symbols-from-provider.operations.ts similarity index 100% rename from apps/data-pipeline/src/handlers/symbols/operations/sync-symbols-from-provider.operations.ts rename to apps/stock/data-pipeline/src/handlers/symbols/operations/sync-symbols-from-provider.operations.ts diff --git a/apps/data-pipeline/src/handlers/symbols/symbols.handler.ts b/apps/stock/data-pipeline/src/handlers/symbols/symbols.handler.ts similarity index 100% rename from apps/data-pipeline/src/handlers/symbols/symbols.handler.ts rename to apps/stock/data-pipeline/src/handlers/symbols/symbols.handler.ts diff --git a/apps/data-pipeline/src/index.ts b/apps/stock/data-pipeline/src/index.ts similarity index 92% rename from apps/data-pipeline/src/index.ts rename to apps/stock/data-pipeline/src/index.ts index 7f1be83..b6fe633 100644 --- a/apps/data-pipeline/src/index.ts +++ b/apps/stock/data-pipeline/src/index.ts @@ -3,7 +3,7 @@ * Simplified entry point using ServiceApplication framework */ -import { initializeServiceConfig } from '@stock-bot/config'; +import { initializeStockConfig } from '@stock-bot/stock-config'; import { ServiceApplication, createServiceContainerFromConfig, @@ -16,8 +16,8 @@ import { initializeAllHandlers } from './handlers'; import { createRoutes } from './routes/create-routes'; import { setupServiceContainer } from './container-setup'; -// Initialize configuration -const config = initializeServiceConfig(); +// Initialize configuration with service-specific overrides +const config = initializeStockConfig('dataPipeline'); console.log('Data Pipeline Service Configuration:', JSON.stringify(config, null, 2)); // Create service application diff --git a/apps/data-pipeline/src/routes/create-routes.ts b/apps/stock/data-pipeline/src/routes/create-routes.ts similarity index 100% rename from apps/data-pipeline/src/routes/create-routes.ts rename to apps/stock/data-pipeline/src/routes/create-routes.ts diff --git a/apps/data-pipeline/src/routes/enhanced-sync.routes.ts b/apps/stock/data-pipeline/src/routes/enhanced-sync.routes.ts similarity index 100% rename from apps/data-pipeline/src/routes/enhanced-sync.routes.ts rename to apps/stock/data-pipeline/src/routes/enhanced-sync.routes.ts diff --git a/apps/data-pipeline/src/routes/health.routes.ts b/apps/stock/data-pipeline/src/routes/health.routes.ts similarity index 100% rename from apps/data-pipeline/src/routes/health.routes.ts rename to apps/stock/data-pipeline/src/routes/health.routes.ts diff --git a/apps/data-pipeline/src/routes/index.ts b/apps/stock/data-pipeline/src/routes/index.ts similarity index 100% rename from apps/data-pipeline/src/routes/index.ts rename to apps/stock/data-pipeline/src/routes/index.ts diff --git a/apps/data-pipeline/src/routes/stats.routes.ts b/apps/stock/data-pipeline/src/routes/stats.routes.ts similarity index 100% rename from apps/data-pipeline/src/routes/stats.routes.ts rename to apps/stock/data-pipeline/src/routes/stats.routes.ts diff --git a/apps/data-pipeline/src/routes/sync.routes.ts b/apps/stock/data-pipeline/src/routes/sync.routes.ts similarity index 100% rename from apps/data-pipeline/src/routes/sync.routes.ts rename to apps/stock/data-pipeline/src/routes/sync.routes.ts diff --git a/apps/data-pipeline/src/types/job-payloads.ts b/apps/stock/data-pipeline/src/types/job-payloads.ts similarity index 100% rename from apps/data-pipeline/src/types/job-payloads.ts rename to apps/stock/data-pipeline/src/types/job-payloads.ts diff --git a/apps/data-pipeline/tsconfig.json b/apps/stock/data-pipeline/tsconfig.json similarity index 100% rename from apps/data-pipeline/tsconfig.json rename to apps/stock/data-pipeline/tsconfig.json diff --git a/apps/stock/ecosystem.config.js b/apps/stock/ecosystem.config.js new file mode 100644 index 0000000..a94d2a4 --- /dev/null +++ b/apps/stock/ecosystem.config.js @@ -0,0 +1,72 @@ +module.exports = { + apps: [ + { + name: 'stock-ingestion', + script: './data-ingestion/dist/index.js', + instances: 1, + autorestart: true, + watch: false, + max_memory_restart: '1G', + env: { + NODE_ENV: 'production', + PORT: 2001 + }, + env_development: { + NODE_ENV: 'development', + PORT: 2001 + } + }, + { + name: 'stock-pipeline', + script: './data-pipeline/dist/index.js', + instances: 1, + autorestart: true, + watch: false, + max_memory_restart: '1G', + env: { + NODE_ENV: 'production', + PORT: 2002 + }, + env_development: { + NODE_ENV: 'development', + PORT: 2002 + } + }, + { + name: 'stock-api', + script: './web-api/dist/index.js', + instances: 2, + autorestart: true, + watch: false, + max_memory_restart: '1G', + exec_mode: 'cluster', + env: { + NODE_ENV: 'production', + PORT: 2003 + }, + env_development: { + NODE_ENV: 'development', + PORT: 2003 + } + } + ], + + deploy: { + production: { + user: 'deploy', + host: 'production-server', + ref: 'origin/master', + repo: 'git@github.com:username/stock-bot.git', + path: '/var/www/stock-bot', + 'post-deploy': 'cd apps/stock && npm install && npm run build && pm2 reload ecosystem.config.js --env production' + }, + staging: { + user: 'deploy', + host: 'staging-server', + ref: 'origin/develop', + repo: 'git@github.com:username/stock-bot.git', + path: '/var/www/stock-bot-staging', + 'post-deploy': 'cd apps/stock && npm install && npm run build && pm2 reload ecosystem.config.js --env development' + } + } +}; \ No newline at end of file diff --git a/apps/stock/package.json b/apps/stock/package.json new file mode 100644 index 0000000..cd8c82c --- /dev/null +++ b/apps/stock/package.json @@ -0,0 +1,91 @@ +{ + "name": "@stock-bot/stock-app", + "version": "1.0.0", + "private": true, + "description": "Stock trading bot application", + "scripts": { + "dev": "turbo run dev", + "dev:ingestion": "cd data-ingestion && bun run dev", + "dev:pipeline": "cd data-pipeline && bun run dev", + "dev:api": "cd web-api && bun run dev", + "dev:web": "cd web-app && bun run dev", + "dev:backend": "turbo run dev --filter=\"@stock-bot/data-*\" --filter=\"@stock-bot/web-api\"", + "dev:frontend": "turbo run dev --filter=\"@stock-bot/web-app\"", + + "build": "turbo run build", + "build:config": "cd config && bun run build", + "build:services": "turbo run build --filter=\"@stock-bot/data-*\" --filter=\"@stock-bot/web-*\"", + "build:ingestion": "cd data-ingestion && bun run build", + "build:pipeline": "cd data-pipeline && bun run build", + "build:api": "cd web-api && bun run build", + "build:web": "cd web-app && bun run build", + + "start": "turbo run start --filter=\"@stock-bot/data-*\" --filter=\"@stock-bot/web-api\"", + "start:all": "turbo run start", + "start:ingestion": "cd data-ingestion && bun start", + "start:pipeline": "cd data-pipeline && bun start", + "start:api": "cd web-api && bun start", + + "clean": "turbo run clean", + "clean:all": "turbo run clean && rm -rf node_modules", + "clean:ingestion": "cd data-ingestion && rm -rf dist node_modules", + "clean:pipeline": "cd data-pipeline && rm -rf dist node_modules", + "clean:api": "cd web-api && rm -rf dist node_modules", + "clean:web": "cd web-app && rm -rf dist node_modules", + "clean:config": "cd config && rm -rf dist node_modules", + + "test": "turbo run test", + "test:all": "turbo run test", + "test:config": "cd config && bun test", + "test:services": "turbo run test --filter=\"@stock-bot/data-*\" --filter=\"@stock-bot/web-*\"", + "test:ingestion": "cd data-ingestion && bun test", + "test:pipeline": "cd data-pipeline && bun test", + "test:api": "cd web-api && bun test", + + "lint": "turbo run lint", + "lint:all": "turbo run lint", + "lint:config": "cd config && bun run lint", + "lint:services": "turbo run lint --filter=\"@stock-bot/data-*\" --filter=\"@stock-bot/web-*\"", + "lint:ingestion": "cd data-ingestion && bun run lint", + "lint:pipeline": "cd data-pipeline && bun run lint", + "lint:api": "cd web-api && bun run lint", + "lint:web": "cd web-app && bun run lint", + + "install:all": "bun install", + + "docker:build": "docker-compose build", + "docker:up": "docker-compose up", + "docker:down": "docker-compose down", + + "pm2:start": "pm2 start ecosystem.config.js", + "pm2:stop": "pm2 stop all", + "pm2:restart": "pm2 restart all", + "pm2:logs": "pm2 logs", + "pm2:status": "pm2 status", + + "db:migrate": "cd data-ingestion && bun run db:migrate", + "db:seed": "cd data-ingestion && bun run db:seed", + + "health:check": "bun scripts/health-check.js", + "monitor": "bun run pm2:logs", + "status": "bun run pm2:status" + }, + "devDependencies": { + "pm2": "^5.3.0", + "@types/node": "^20.11.0", + "typescript": "^5.3.3", + "turbo": "^2.5.4" + }, + "workspaces": [ + "config", + "data-ingestion", + "data-pipeline", + "web-api", + "web-app" + ], + "engines": { + "node": ">=18.0.0", + "bun": ">=1.1.0" + }, + "packageManager": "bun@1.1.12" +} \ No newline at end of file diff --git a/apps/stock/scripts/health-check.js b/apps/stock/scripts/health-check.js new file mode 100755 index 0000000..62c05e9 --- /dev/null +++ b/apps/stock/scripts/health-check.js @@ -0,0 +1,60 @@ +#!/usr/bin/env node + +const http = require('http'); +const services = [ + { name: 'Data Ingestion', port: 2001 }, + { name: 'Data Pipeline', port: 2002 }, + { name: 'Web API', port: 2003 }, +]; + +console.log('🏥 Stock Bot Health Check\n'); + +async function checkService(service) { + return new Promise((resolve) => { + const options = { + hostname: 'localhost', + port: service.port, + path: '/health', + method: 'GET', + timeout: 5000, + }; + + const req = http.request(options, (res) => { + if (res.statusCode === 200) { + resolve({ ...service, status: '✅ Healthy', code: res.statusCode }); + } else { + resolve({ ...service, status: '⚠️ Unhealthy', code: res.statusCode }); + } + }); + + req.on('error', (err) => { + resolve({ ...service, status: '❌ Offline', error: err.message }); + }); + + req.on('timeout', () => { + req.destroy(); + resolve({ ...service, status: '⏱️ Timeout', error: 'Request timed out' }); + }); + + req.end(); + }); +} + +async function checkAllServices() { + const results = await Promise.all(services.map(checkService)); + + results.forEach((result) => { + console.log(`${result.name.padEnd(15)} ${result.status}`); + if (result.error) { + console.log(` ${result.error}`); + } + }); + + const allHealthy = results.every(r => r.status === '✅ Healthy'); + + console.log('\n' + (allHealthy ? '✅ All services are healthy!' : '⚠️ Some services need attention')); + + process.exit(allHealthy ? 0 : 1); +} + +checkAllServices(); \ No newline at end of file diff --git a/apps/stock/tsconfig.json b/apps/stock/tsconfig.json new file mode 100644 index 0000000..5d62c04 --- /dev/null +++ b/apps/stock/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "baseUrl": "../..", + "paths": { + "@stock-bot/*": ["libs/*/src"], + "@stock-bot/stock-config": ["apps/stock/config/src"], + "@stock-bot/stock-config/*": ["apps/stock/config/src/*"] + } + }, + "references": [ + { "path": "./config" }, + { "path": "./data-ingestion" }, + { "path": "./data-pipeline" }, + { "path": "./web-api" }, + { "path": "./web-app" } + ] +} \ No newline at end of file diff --git a/apps/web-api/package.json b/apps/stock/web-api/package.json similarity index 95% rename from apps/web-api/package.json rename to apps/stock/web-api/package.json index 1f260ec..28e3701 100644 --- a/apps/web-api/package.json +++ b/apps/stock/web-api/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "@stock-bot/config": "*", + "@stock-bot/stock-config": "*", "@stock-bot/logger": "*", "@stock-bot/mongodb": "*", "@stock-bot/postgres": "*", diff --git a/apps/web-api/src/container-setup.ts b/apps/stock/web-api/src/container-setup.ts similarity index 100% rename from apps/web-api/src/container-setup.ts rename to apps/stock/web-api/src/container-setup.ts diff --git a/apps/web-api/src/index.ts b/apps/stock/web-api/src/index.ts similarity index 93% rename from apps/web-api/src/index.ts rename to apps/stock/web-api/src/index.ts index aee4d32..ffb7d2b 100644 --- a/apps/web-api/src/index.ts +++ b/apps/stock/web-api/src/index.ts @@ -3,7 +3,7 @@ * Simplified entry point using ServiceApplication framework */ -import { initializeServiceConfig } from '@stock-bot/config'; +import { initializeStockConfig } from '@stock-bot/stock-config'; import { ServiceApplication, createServiceContainerFromConfig, @@ -15,8 +15,8 @@ import { getLogger } from '@stock-bot/logger'; import { createRoutes } from './routes/create-routes'; import { setupServiceContainer } from './container-setup'; -// Initialize configuration -const config = initializeServiceConfig(); +// Initialize configuration with service-specific overrides +const config = initializeStockConfig('webApi'); console.log('Web API Service Configuration:', JSON.stringify(config, null, 2)); // Create service application diff --git a/apps/web-api/src/routes/create-routes.ts b/apps/stock/web-api/src/routes/create-routes.ts similarity index 100% rename from apps/web-api/src/routes/create-routes.ts rename to apps/stock/web-api/src/routes/create-routes.ts diff --git a/apps/web-api/src/routes/exchange.routes.ts b/apps/stock/web-api/src/routes/exchange.routes.ts similarity index 100% rename from apps/web-api/src/routes/exchange.routes.ts rename to apps/stock/web-api/src/routes/exchange.routes.ts diff --git a/apps/web-api/src/routes/health.routes.ts b/apps/stock/web-api/src/routes/health.routes.ts similarity index 100% rename from apps/web-api/src/routes/health.routes.ts rename to apps/stock/web-api/src/routes/health.routes.ts diff --git a/apps/web-api/src/routes/index.ts b/apps/stock/web-api/src/routes/index.ts similarity index 100% rename from apps/web-api/src/routes/index.ts rename to apps/stock/web-api/src/routes/index.ts diff --git a/apps/web-api/src/services/exchange.service.ts b/apps/stock/web-api/src/services/exchange.service.ts similarity index 100% rename from apps/web-api/src/services/exchange.service.ts rename to apps/stock/web-api/src/services/exchange.service.ts diff --git a/apps/web-api/src/types/exchange.types.ts b/apps/stock/web-api/src/types/exchange.types.ts similarity index 100% rename from apps/web-api/src/types/exchange.types.ts rename to apps/stock/web-api/src/types/exchange.types.ts diff --git a/apps/web-api/src/utils/error-handler.ts b/apps/stock/web-api/src/utils/error-handler.ts similarity index 100% rename from apps/web-api/src/utils/error-handler.ts rename to apps/stock/web-api/src/utils/error-handler.ts diff --git a/apps/web-api/src/utils/validation.ts b/apps/stock/web-api/src/utils/validation.ts similarity index 100% rename from apps/web-api/src/utils/validation.ts rename to apps/stock/web-api/src/utils/validation.ts diff --git a/apps/web-api/tsconfig.json b/apps/stock/web-api/tsconfig.json similarity index 100% rename from apps/web-api/tsconfig.json rename to apps/stock/web-api/tsconfig.json diff --git a/apps/web-app/.env b/apps/stock/web-app/.env similarity index 100% rename from apps/web-app/.env rename to apps/stock/web-app/.env diff --git a/apps/web-app/.env.example b/apps/stock/web-app/.env.example similarity index 100% rename from apps/web-app/.env.example rename to apps/stock/web-app/.env.example diff --git a/apps/web-app/README.md b/apps/stock/web-app/README.md similarity index 100% rename from apps/web-app/README.md rename to apps/stock/web-app/README.md diff --git a/apps/web-app/eslint.config.js b/apps/stock/web-app/eslint.config.js similarity index 100% rename from apps/web-app/eslint.config.js rename to apps/stock/web-app/eslint.config.js diff --git a/apps/web-app/index.html b/apps/stock/web-app/index.html similarity index 100% rename from apps/web-app/index.html rename to apps/stock/web-app/index.html diff --git a/apps/web-app/package.json b/apps/stock/web-app/package.json similarity index 100% rename from apps/web-app/package.json rename to apps/stock/web-app/package.json diff --git a/apps/web-app/postcss.config.js b/apps/stock/web-app/postcss.config.js similarity index 100% rename from apps/web-app/postcss.config.js rename to apps/stock/web-app/postcss.config.js diff --git a/apps/web-app/public/vite.svg b/apps/stock/web-app/public/vite.svg similarity index 100% rename from apps/web-app/public/vite.svg rename to apps/stock/web-app/public/vite.svg diff --git a/apps/web-app/src/App.tsx b/apps/stock/web-app/src/App.tsx similarity index 100% rename from apps/web-app/src/App.tsx rename to apps/stock/web-app/src/App.tsx diff --git a/apps/web-app/src/app/App.tsx b/apps/stock/web-app/src/app/App.tsx similarity index 100% rename from apps/web-app/src/app/App.tsx rename to apps/stock/web-app/src/app/App.tsx diff --git a/apps/web-app/src/app/index.ts b/apps/stock/web-app/src/app/index.ts similarity index 100% rename from apps/web-app/src/app/index.ts rename to apps/stock/web-app/src/app/index.ts diff --git a/apps/web-app/src/components/index.ts b/apps/stock/web-app/src/components/index.ts similarity index 100% rename from apps/web-app/src/components/index.ts rename to apps/stock/web-app/src/components/index.ts diff --git a/apps/web-app/src/components/layout/Header.tsx b/apps/stock/web-app/src/components/layout/Header.tsx similarity index 100% rename from apps/web-app/src/components/layout/Header.tsx rename to apps/stock/web-app/src/components/layout/Header.tsx diff --git a/apps/web-app/src/components/layout/Layout.tsx b/apps/stock/web-app/src/components/layout/Layout.tsx similarity index 100% rename from apps/web-app/src/components/layout/Layout.tsx rename to apps/stock/web-app/src/components/layout/Layout.tsx diff --git a/apps/web-app/src/components/layout/Sidebar.tsx b/apps/stock/web-app/src/components/layout/Sidebar.tsx similarity index 100% rename from apps/web-app/src/components/layout/Sidebar.tsx rename to apps/stock/web-app/src/components/layout/Sidebar.tsx diff --git a/apps/web-app/src/components/layout/index.ts b/apps/stock/web-app/src/components/layout/index.ts similarity index 100% rename from apps/web-app/src/components/layout/index.ts rename to apps/stock/web-app/src/components/layout/index.ts diff --git a/apps/web-app/src/components/ui/Card.tsx b/apps/stock/web-app/src/components/ui/Card.tsx similarity index 100% rename from apps/web-app/src/components/ui/Card.tsx rename to apps/stock/web-app/src/components/ui/Card.tsx diff --git a/apps/web-app/src/components/ui/DataTable/DataTable.tsx b/apps/stock/web-app/src/components/ui/DataTable/DataTable.tsx similarity index 100% rename from apps/web-app/src/components/ui/DataTable/DataTable.tsx rename to apps/stock/web-app/src/components/ui/DataTable/DataTable.tsx diff --git a/apps/web-app/src/components/ui/DataTable/index.ts b/apps/stock/web-app/src/components/ui/DataTable/index.ts similarity index 100% rename from apps/web-app/src/components/ui/DataTable/index.ts rename to apps/stock/web-app/src/components/ui/DataTable/index.ts diff --git a/apps/web-app/src/components/ui/DataTable/types.ts b/apps/stock/web-app/src/components/ui/DataTable/types.ts similarity index 100% rename from apps/web-app/src/components/ui/DataTable/types.ts rename to apps/stock/web-app/src/components/ui/DataTable/types.ts diff --git a/apps/web-app/src/components/ui/StatCard.tsx b/apps/stock/web-app/src/components/ui/StatCard.tsx similarity index 100% rename from apps/web-app/src/components/ui/StatCard.tsx rename to apps/stock/web-app/src/components/ui/StatCard.tsx diff --git a/apps/web-app/src/components/ui/button.tsx b/apps/stock/web-app/src/components/ui/button.tsx similarity index 100% rename from apps/web-app/src/components/ui/button.tsx rename to apps/stock/web-app/src/components/ui/button.tsx diff --git a/apps/web-app/src/components/ui/dialog.tsx b/apps/stock/web-app/src/components/ui/dialog.tsx similarity index 100% rename from apps/web-app/src/components/ui/dialog.tsx rename to apps/stock/web-app/src/components/ui/dialog.tsx diff --git a/apps/web-app/src/components/ui/index.ts b/apps/stock/web-app/src/components/ui/index.ts similarity index 100% rename from apps/web-app/src/components/ui/index.ts rename to apps/stock/web-app/src/components/ui/index.ts diff --git a/apps/web-app/src/features/dashboard/DashboardPage.tsx b/apps/stock/web-app/src/features/dashboard/DashboardPage.tsx similarity index 100% rename from apps/web-app/src/features/dashboard/DashboardPage.tsx rename to apps/stock/web-app/src/features/dashboard/DashboardPage.tsx diff --git a/apps/web-app/src/features/dashboard/components/DashboardActivity.tsx b/apps/stock/web-app/src/features/dashboard/components/DashboardActivity.tsx similarity index 100% rename from apps/web-app/src/features/dashboard/components/DashboardActivity.tsx rename to apps/stock/web-app/src/features/dashboard/components/DashboardActivity.tsx diff --git a/apps/web-app/src/features/dashboard/components/DashboardStats.tsx b/apps/stock/web-app/src/features/dashboard/components/DashboardStats.tsx similarity index 100% rename from apps/web-app/src/features/dashboard/components/DashboardStats.tsx rename to apps/stock/web-app/src/features/dashboard/components/DashboardStats.tsx diff --git a/apps/web-app/src/features/dashboard/components/PortfolioTable.tsx b/apps/stock/web-app/src/features/dashboard/components/PortfolioTable.tsx similarity index 100% rename from apps/web-app/src/features/dashboard/components/PortfolioTable.tsx rename to apps/stock/web-app/src/features/dashboard/components/PortfolioTable.tsx diff --git a/apps/web-app/src/features/dashboard/components/index.ts b/apps/stock/web-app/src/features/dashboard/components/index.ts similarity index 100% rename from apps/web-app/src/features/dashboard/components/index.ts rename to apps/stock/web-app/src/features/dashboard/components/index.ts diff --git a/apps/web-app/src/features/dashboard/index.ts b/apps/stock/web-app/src/features/dashboard/index.ts similarity index 100% rename from apps/web-app/src/features/dashboard/index.ts rename to apps/stock/web-app/src/features/dashboard/index.ts diff --git a/apps/web-app/src/features/exchanges/ExchangesPage.tsx b/apps/stock/web-app/src/features/exchanges/ExchangesPage.tsx similarity index 100% rename from apps/web-app/src/features/exchanges/ExchangesPage.tsx rename to apps/stock/web-app/src/features/exchanges/ExchangesPage.tsx diff --git a/apps/web-app/src/features/exchanges/components/AddExchangeDialog.tsx b/apps/stock/web-app/src/features/exchanges/components/AddExchangeDialog.tsx similarity index 100% rename from apps/web-app/src/features/exchanges/components/AddExchangeDialog.tsx rename to apps/stock/web-app/src/features/exchanges/components/AddExchangeDialog.tsx diff --git a/apps/web-app/src/features/exchanges/components/AddProviderMappingDialog.tsx b/apps/stock/web-app/src/features/exchanges/components/AddProviderMappingDialog.tsx similarity index 100% rename from apps/web-app/src/features/exchanges/components/AddProviderMappingDialog.tsx rename to apps/stock/web-app/src/features/exchanges/components/AddProviderMappingDialog.tsx diff --git a/apps/web-app/src/features/exchanges/components/AddSourceDialog.tsx b/apps/stock/web-app/src/features/exchanges/components/AddSourceDialog.tsx similarity index 100% rename from apps/web-app/src/features/exchanges/components/AddSourceDialog.tsx rename to apps/stock/web-app/src/features/exchanges/components/AddSourceDialog.tsx diff --git a/apps/web-app/src/features/exchanges/components/DeleteExchangeDialog.tsx b/apps/stock/web-app/src/features/exchanges/components/DeleteExchangeDialog.tsx similarity index 100% rename from apps/web-app/src/features/exchanges/components/DeleteExchangeDialog.tsx rename to apps/stock/web-app/src/features/exchanges/components/DeleteExchangeDialog.tsx diff --git a/apps/web-app/src/features/exchanges/components/ExchangesTable.tsx b/apps/stock/web-app/src/features/exchanges/components/ExchangesTable.tsx similarity index 100% rename from apps/web-app/src/features/exchanges/components/ExchangesTable.tsx rename to apps/stock/web-app/src/features/exchanges/components/ExchangesTable.tsx diff --git a/apps/web-app/src/features/exchanges/components/index.ts b/apps/stock/web-app/src/features/exchanges/components/index.ts similarity index 100% rename from apps/web-app/src/features/exchanges/components/index.ts rename to apps/stock/web-app/src/features/exchanges/components/index.ts diff --git a/apps/web-app/src/features/exchanges/hooks/index.ts b/apps/stock/web-app/src/features/exchanges/hooks/index.ts similarity index 100% rename from apps/web-app/src/features/exchanges/hooks/index.ts rename to apps/stock/web-app/src/features/exchanges/hooks/index.ts diff --git a/apps/web-app/src/features/exchanges/hooks/useExchanges.ts b/apps/stock/web-app/src/features/exchanges/hooks/useExchanges.ts similarity index 100% rename from apps/web-app/src/features/exchanges/hooks/useExchanges.ts rename to apps/stock/web-app/src/features/exchanges/hooks/useExchanges.ts diff --git a/apps/web-app/src/features/exchanges/hooks/useFormValidation.ts b/apps/stock/web-app/src/features/exchanges/hooks/useFormValidation.ts similarity index 100% rename from apps/web-app/src/features/exchanges/hooks/useFormValidation.ts rename to apps/stock/web-app/src/features/exchanges/hooks/useFormValidation.ts diff --git a/apps/web-app/src/features/exchanges/index.ts b/apps/stock/web-app/src/features/exchanges/index.ts similarity index 100% rename from apps/web-app/src/features/exchanges/index.ts rename to apps/stock/web-app/src/features/exchanges/index.ts diff --git a/apps/web-app/src/features/exchanges/services/exchangeApi.ts b/apps/stock/web-app/src/features/exchanges/services/exchangeApi.ts similarity index 100% rename from apps/web-app/src/features/exchanges/services/exchangeApi.ts rename to apps/stock/web-app/src/features/exchanges/services/exchangeApi.ts diff --git a/apps/web-app/src/features/exchanges/types/api.types.ts b/apps/stock/web-app/src/features/exchanges/types/api.types.ts similarity index 100% rename from apps/web-app/src/features/exchanges/types/api.types.ts rename to apps/stock/web-app/src/features/exchanges/types/api.types.ts diff --git a/apps/web-app/src/features/exchanges/types/component.types.ts b/apps/stock/web-app/src/features/exchanges/types/component.types.ts similarity index 100% rename from apps/web-app/src/features/exchanges/types/component.types.ts rename to apps/stock/web-app/src/features/exchanges/types/component.types.ts diff --git a/apps/web-app/src/features/exchanges/types/index.ts b/apps/stock/web-app/src/features/exchanges/types/index.ts similarity index 100% rename from apps/web-app/src/features/exchanges/types/index.ts rename to apps/stock/web-app/src/features/exchanges/types/index.ts diff --git a/apps/web-app/src/features/exchanges/types/request.types.ts b/apps/stock/web-app/src/features/exchanges/types/request.types.ts similarity index 100% rename from apps/web-app/src/features/exchanges/types/request.types.ts rename to apps/stock/web-app/src/features/exchanges/types/request.types.ts diff --git a/apps/web-app/src/features/exchanges/utils/formatters.ts b/apps/stock/web-app/src/features/exchanges/utils/formatters.ts similarity index 100% rename from apps/web-app/src/features/exchanges/utils/formatters.ts rename to apps/stock/web-app/src/features/exchanges/utils/formatters.ts diff --git a/apps/web-app/src/features/exchanges/utils/validation.ts b/apps/stock/web-app/src/features/exchanges/utils/validation.ts similarity index 100% rename from apps/web-app/src/features/exchanges/utils/validation.ts rename to apps/stock/web-app/src/features/exchanges/utils/validation.ts diff --git a/apps/web-app/src/index.css b/apps/stock/web-app/src/index.css similarity index 100% rename from apps/web-app/src/index.css rename to apps/stock/web-app/src/index.css diff --git a/apps/web-app/src/lib/constants.ts b/apps/stock/web-app/src/lib/constants.ts similarity index 100% rename from apps/web-app/src/lib/constants.ts rename to apps/stock/web-app/src/lib/constants.ts diff --git a/apps/web-app/src/lib/constants/index.ts b/apps/stock/web-app/src/lib/constants/index.ts similarity index 100% rename from apps/web-app/src/lib/constants/index.ts rename to apps/stock/web-app/src/lib/constants/index.ts diff --git a/apps/web-app/src/lib/constants/navigation.ts b/apps/stock/web-app/src/lib/constants/navigation.ts similarity index 100% rename from apps/web-app/src/lib/constants/navigation.ts rename to apps/stock/web-app/src/lib/constants/navigation.ts diff --git a/apps/web-app/src/lib/utils.ts b/apps/stock/web-app/src/lib/utils.ts similarity index 100% rename from apps/web-app/src/lib/utils.ts rename to apps/stock/web-app/src/lib/utils.ts diff --git a/apps/web-app/src/lib/utils/cn.ts b/apps/stock/web-app/src/lib/utils/cn.ts similarity index 100% rename from apps/web-app/src/lib/utils/cn.ts rename to apps/stock/web-app/src/lib/utils/cn.ts diff --git a/apps/web-app/src/lib/utils/index.ts b/apps/stock/web-app/src/lib/utils/index.ts similarity index 100% rename from apps/web-app/src/lib/utils/index.ts rename to apps/stock/web-app/src/lib/utils/index.ts diff --git a/apps/web-app/src/main.tsx b/apps/stock/web-app/src/main.tsx similarity index 100% rename from apps/web-app/src/main.tsx rename to apps/stock/web-app/src/main.tsx diff --git a/apps/web-app/tailwind.config.js b/apps/stock/web-app/tailwind.config.js similarity index 100% rename from apps/web-app/tailwind.config.js rename to apps/stock/web-app/tailwind.config.js diff --git a/apps/web-app/tsconfig.json b/apps/stock/web-app/tsconfig.json similarity index 100% rename from apps/web-app/tsconfig.json rename to apps/stock/web-app/tsconfig.json diff --git a/apps/web-app/tsconfig.node.json b/apps/stock/web-app/tsconfig.node.json similarity index 100% rename from apps/web-app/tsconfig.node.json rename to apps/stock/web-app/tsconfig.node.json diff --git a/apps/web-app/vite.config.ts b/apps/stock/web-app/vite.config.ts similarity index 100% rename from apps/web-app/vite.config.ts rename to apps/stock/web-app/vite.config.ts diff --git a/apps/web-api/config/default.json b/apps/web-api/config/default.json deleted file mode 100644 index 4770e43..0000000 --- a/apps/web-api/config/default.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "service": { - "name": "web-api", - "port": 4000, - "host": "0.0.0.0", - "healthCheckPath": "/health", - "metricsPath": "/metrics", - "shutdownTimeout": 30000, - "cors": { - "enabled": true, - "origin": ["http://localhost:4200", "http://localhost:3000", "http://localhost:3002"], - "credentials": true - } - } -} diff --git a/bun.lock b/bun.lock index ddbabeb..88d73de 100644 --- a/bun.lock +++ b/bun.lock @@ -41,7 +41,29 @@ "yup": "^1.6.1", }, }, - "apps/data-ingestion": { + "apps/stock": { + "name": "@stock-bot/stock-app", + "version": "1.0.0", + "devDependencies": { + "@types/node": "^20.11.0", + "pm2": "^5.3.0", + "turbo": "^2.5.4", + "typescript": "^5.3.3", + }, + }, + "apps/stock/config": { + "name": "@stock-bot/stock-config", + "version": "1.0.0", + "dependencies": { + "@stock-bot/config": "*", + "zod": "^3.22.4", + }, + "devDependencies": { + "@types/node": "^20.11.0", + "typescript": "^5.3.3", + }, + }, + "apps/stock/data-ingestion": { "name": "@stock-bot/data-ingestion", "version": "1.0.0", "dependencies": { @@ -55,6 +77,7 @@ "@stock-bot/questdb": "*", "@stock-bot/queue": "*", "@stock-bot/shutdown": "*", + "@stock-bot/stock-config": "*", "@stock-bot/utils": "*", "hono": "^4.0.0", }, @@ -62,7 +85,7 @@ "typescript": "^5.0.0", }, }, - "apps/data-pipeline": { + "apps/stock/data-pipeline": { "name": "@stock-bot/data-pipeline", "version": "1.0.0", "dependencies": { @@ -74,13 +97,14 @@ "@stock-bot/questdb": "*", "@stock-bot/queue": "*", "@stock-bot/shutdown": "*", + "@stock-bot/stock-config": "*", "hono": "^4.0.0", }, "devDependencies": { "typescript": "^5.0.0", }, }, - "apps/web-api": { + "apps/stock/web-api": { "name": "@stock-bot/web-api", "version": "1.0.0", "dependencies": { @@ -89,13 +113,14 @@ "@stock-bot/mongodb": "*", "@stock-bot/postgres": "*", "@stock-bot/shutdown": "*", + "@stock-bot/stock-config": "*", "hono": "^4.0.0", }, "devDependencies": { "typescript": "^5.0.0", }, }, - "apps/web-app": { + "apps/stock/web-app": { "name": "@stock-bot/web-app", "version": "0.1.0", "dependencies": { @@ -627,6 +652,14 @@ "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], + "@pm2/agent": ["@pm2/agent@2.0.4", "", { "dependencies": { "async": "~3.2.0", "chalk": "~3.0.0", "dayjs": "~1.8.24", "debug": "~4.3.1", "eventemitter2": "~5.0.1", "fast-json-patch": "^3.0.0-1", "fclone": "~1.0.11", "nssocket": "0.6.0", "pm2-axon": "~4.0.1", "pm2-axon-rpc": "~0.7.0", "proxy-agent": "~6.3.0", "semver": "~7.5.0", "ws": "~7.5.10" } }, "sha512-n7WYvvTJhHLS2oBb1PjOtgLpMhgImOq8sXkPBw6smeg9LJBWZjiEgPKOpR8mn9UJZsB5P3W4V/MyvNnp31LKeA=="], + + "@pm2/io": ["@pm2/io@6.0.1", "", { "dependencies": { "async": "~2.6.1", "debug": "~4.3.1", "eventemitter2": "^6.3.1", "require-in-the-middle": "^5.0.0", "semver": "~7.5.4", "shimmer": "^1.2.0", "signal-exit": "^3.0.3", "tslib": "1.9.3" } }, "sha512-KiA+shC6sULQAr9mGZ1pg+6KVW9MF8NpG99x26Lf/082/Qy8qsTCtnJy+HQReW1A9Rdf0C/404cz0RZGZro+IA=="], + + "@pm2/js-api": ["@pm2/js-api@0.8.0", "", { "dependencies": { "async": "^2.6.3", "debug": "~4.3.1", "eventemitter2": "^6.3.1", "extrareqp2": "^1.0.0", "ws": "^7.0.0" } }, "sha512-nmWzrA/BQZik3VBz+npRcNIu01kdBhWL0mxKmP1ciF/gTcujPTQqt027N9fc1pK9ERM8RipFhymw7RcmCyOEYA=="], + + "@pm2/pm2-version-check": ["@pm2/pm2-version-check@1.0.4", "", { "dependencies": { "debug": "^4.3.1" } }, "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA=="], + "@primeng/themes": ["@primeng/themes@19.1.3", "", { "dependencies": { "@primeuix/styled": "^0.3.2" } }, "sha512-y4VryHHUTPWlmfR56NBANC0QPIxEngTUE/J3pGs4SJquq1n5EE/U16dxa1qW/wXqLF3jn3l/AO/4KZqGj5UuAA=="], "@primeuix/styled": ["@primeuix/styled@0.3.2", "", { "dependencies": { "@primeuix/utils": "^0.3.2" } }, "sha512-ColZes0+/WKqH4ob2x8DyNYf1NENpe5ZguOvx5yCLxaP8EIMVhLjWLO/3umJiDnQU4XXMLkn2mMHHw+fhTX/mw=="], @@ -751,9 +784,9 @@ "@stock-bot/config": ["@stock-bot/config@workspace:libs/core/config"], - "@stock-bot/data-ingestion": ["@stock-bot/data-ingestion@workspace:apps/data-ingestion"], + "@stock-bot/data-ingestion": ["@stock-bot/data-ingestion@workspace:apps/stock/data-ingestion"], - "@stock-bot/data-pipeline": ["@stock-bot/data-pipeline@workspace:apps/data-pipeline"], + "@stock-bot/data-pipeline": ["@stock-bot/data-pipeline@workspace:apps/stock/data-pipeline"], "@stock-bot/di": ["@stock-bot/di@workspace:libs/core/di"], @@ -775,13 +808,17 @@ "@stock-bot/shutdown": ["@stock-bot/shutdown@workspace:libs/services/shutdown"], + "@stock-bot/stock-app": ["@stock-bot/stock-app@workspace:apps/stock"], + + "@stock-bot/stock-config": ["@stock-bot/stock-config@workspace:apps/stock/config"], + "@stock-bot/types": ["@stock-bot/types@workspace:libs/core/types"], "@stock-bot/utils": ["@stock-bot/utils@workspace:libs/utils"], - "@stock-bot/web-api": ["@stock-bot/web-api@workspace:apps/web-api"], + "@stock-bot/web-api": ["@stock-bot/web-api@workspace:apps/stock/web-api"], - "@stock-bot/web-app": ["@stock-bot/web-app@workspace:apps/web-app"], + "@stock-bot/web-app": ["@stock-bot/web-app@workspace:apps/stock/web-app"], "@szmarczak/http-timer": ["@szmarczak/http-timer@5.0.1", "", { "dependencies": { "defer-to-connect": "^2.0.1" } }, "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw=="], @@ -899,6 +936,12 @@ "ajv": ["ajv@6.12.6", "", { "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" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], + "amp": ["amp@0.3.1", "", {}, "sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw=="], + + "amp-message": ["amp-message@0.1.2", "", { "dependencies": { "amp": "0.3.1" } }, "sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg=="], + + "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], + "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], @@ -989,6 +1032,10 @@ "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], + "blessed": ["blessed@0.1.81", "", { "bin": { "blessed": "./bin/tput.js" } }, "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ=="], + + "bodec": ["bodec@0.1.0", "", {}, "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ=="], + "body-parser": ["body-parser@2.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" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="], "bowser": ["bowser@2.11.0", "", {}, "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA=="], @@ -1007,6 +1054,8 @@ "buffer-crc32": ["buffer-crc32@1.0.0", "", {}, "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w=="], + "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], + "buildcheck": ["buildcheck@0.0.6", "", {}, "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A=="], "bullmq": ["bullmq@5.55.0", "", { "dependencies": { "cron-parser": "^4.9.0", "ioredis": "^5.4.1", "msgpackr": "^1.11.2", "node-abort-controller": "^3.1.1", "semver": "^7.5.4", "tslib": "^2.0.0", "uuid": "^9.0.0" } }, "sha512-LKaQZroyXBYSQd/SNP9EcmCZgiZjIImtQHBlnupUvhX1GmmJfIXjn0bf8lek3bvajMUbvVf8FrYdFD0ajAuy0g=="], @@ -1041,12 +1090,16 @@ "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "charm": ["charm@0.1.2", "", {}, "sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ=="], + "chokidar": ["chokidar@3.6.0", "", { "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" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], "cli-table": ["cli-table@0.3.11", "", { "dependencies": { "colors": "1.0.3" } }, "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ=="], + "cli-tableau": ["cli-tableau@2.0.1", "", { "dependencies": { "chalk": "3.0.0" } }, "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ=="], + "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], @@ -1065,7 +1118,7 @@ "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], - "commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], + "commander": ["commander@2.15.1", "", {}, "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag=="], "commondir": ["commondir@1.0.1", "", {}, "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="], @@ -1099,12 +1152,16 @@ "cron-parser": ["cron-parser@4.9.0", "", { "dependencies": { "luxon": "^3.2.1" } }, "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q=="], + "croner": ["croner@4.1.97", "", {}, "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ=="], + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + "culvert": ["culvert@0.1.2", "", {}, "sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg=="], + "data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="], "data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="], @@ -1115,6 +1172,8 @@ "dateformat": ["dateformat@4.6.3", "", {}, "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA=="], + "dayjs": ["dayjs@1.11.13", "", {}, "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="], + "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], @@ -1179,6 +1238,8 @@ "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], + "enquirer": ["enquirer@2.3.6", "", { "dependencies": { "ansi-colors": "^4.1.1" } }, "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg=="], + "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], "es-abstract": ["es-abstract@1.24.0", "", { "dependencies": { "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" } }, "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg=="], @@ -1249,6 +1310,8 @@ "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], + "eventemitter2": ["eventemitter2@5.0.1", "", {}, "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg=="], + "eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], "events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="], @@ -1265,6 +1328,8 @@ "express-rate-limit": ["express-rate-limit@7.5.1", "", { "peerDependencies": { "express": ">= 4.11" } }, "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw=="], + "extrareqp2": ["extrareqp2@1.0.0", "", { "dependencies": { "follow-redirects": "^1.14.0" } }, "sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA=="], + "fast-copy": ["fast-copy@3.0.2", "", {}, "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ=="], "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], @@ -1273,6 +1338,8 @@ "fast-glob": ["fast-glob@3.3.3", "", { "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" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + "fast-json-patch": ["fast-json-patch@3.1.1", "", {}, "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ=="], + "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], @@ -1285,6 +1352,8 @@ "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], + "fclone": ["fclone@1.0.11", "", {}, "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw=="], + "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="], "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], @@ -1353,6 +1422,10 @@ "get-uri": ["get-uri@6.0.4", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4" } }, "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ=="], + "git-node-fs": ["git-node-fs@1.0.0", "", {}, "sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ=="], + + "git-sha1": ["git-sha1@0.1.2", "", {}, "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg=="], + "github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="], "glob": ["glob@10.4.5", "", { "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" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], @@ -1405,7 +1478,7 @@ "human-signals": ["human-signals@4.3.1", "", {}, "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ=="], - "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], @@ -1517,6 +1590,8 @@ "joycon": ["joycon@3.1.1", "", {}, "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw=="], + "js-git": ["js-git@0.7.8", "", { "dependencies": { "bodec": "^0.1.0", "culvert": "^0.1.2", "git-sha1": "^0.1.2", "pako": "^0.2.5" } }, "sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA=="], + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], @@ -1533,6 +1608,8 @@ "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], + "json-stringify-safe": ["json-stringify-safe@5.0.1", "", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="], + "json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="], "jsonify": ["jsonify@0.0.1", "", {}, "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg=="], @@ -1543,6 +1620,8 @@ "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], + "lazy": ["lazy@1.0.11", "", {}, "sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA=="], + "lazystream": ["lazystream@1.0.1", "", { "dependencies": { "readable-stream": "^2.0.5" } }, "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw=="], "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], @@ -1617,6 +1696,8 @@ "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="], + "module-details-from-path": ["module-details-from-path@1.0.4", "", {}, "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w=="], + "moment": ["moment@2.30.1", "", {}, "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how=="], "mongodb": ["mongodb@6.17.0", "", { "dependencies": { "@mongodb-js/saslprep": "^1.1.9", "bson": "^6.10.4", "mongodb-connection-string-url": "^3.0.0" }, "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.2.2", "socks": "^2.7.1" }, "optionalPeers": ["@aws-sdk/credential-providers", "@mongodb-js/zstd", "gcp-metadata", "kerberos", "mongodb-client-encryption", "snappy", "socks"] }, "sha512-neerUzg/8U26cgruLysKEjJvoNSXhyID3RvzvdcpsIi2COYM3FS3o9nlH7fxFtefTb942dX3W9i37oPfCVj4wA=="], @@ -1649,6 +1730,8 @@ "msgpackr-extract": ["msgpackr-extract@3.0.3", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA=="], + "mute-stream": ["mute-stream@0.0.8", "", {}, "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="], + "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], "nan": ["nan@2.22.2", "", {}, "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ=="], @@ -1661,6 +1744,8 @@ "nearley": ["nearley@2.20.1", "", { "dependencies": { "commander": "^2.19.0", "moo": "^0.5.0", "railroad-diagrams": "^1.0.0", "randexp": "0.4.6" }, "bin": { "nearleyc": "bin/nearleyc.js", "nearley-test": "bin/nearley-test.js", "nearley-unparse": "bin/nearley-unparse.js", "nearley-railroad": "bin/nearley-railroad.js" } }, "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ=="], + "needle": ["needle@2.4.0", "", { "dependencies": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", "sax": "^1.2.4" }, "bin": { "needle": "./bin/needle" } }, "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg=="], + "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], "netmask": ["netmask@2.0.2", "", {}, "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="], @@ -1693,6 +1778,8 @@ "npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="], + "nssocket": ["nssocket@0.6.0", "", { "dependencies": { "eventemitter2": "~0.4.14", "lazy": "~1.0.11" } }, "sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w=="], + "numeral": ["numeral@2.0.6", "", {}, "sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA=="], "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], @@ -1751,6 +1838,8 @@ "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], + "pako": ["pako@0.2.9", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="], + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], @@ -1799,6 +1888,8 @@ "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "pidusage": ["pidusage@3.0.2", "", { "dependencies": { "safe-buffer": "^5.2.1" } }, "sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w=="], + "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], "pino": ["pino@9.7.0", "", { "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^3.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg=="], @@ -1821,6 +1912,18 @@ "playwright-core": ["playwright-core@1.53.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-Z46Oq7tLAyT0lGoFx4DOuB1IA9D1TPj0QkYxpPVUnGDqHHvDpCftu1J2hM2PiWsNMoZh8+LQaarAWcDfPBc6zg=="], + "pm2": ["pm2@5.4.3", "", { "dependencies": { "@pm2/agent": "~2.0.0", "@pm2/io": "~6.0.1", "@pm2/js-api": "~0.8.0", "@pm2/pm2-version-check": "latest", "async": "~3.2.0", "blessed": "0.1.81", "chalk": "3.0.0", "chokidar": "^3.5.3", "cli-tableau": "^2.0.0", "commander": "2.15.1", "croner": "~4.1.92", "dayjs": "~1.11.5", "debug": "^4.3.1", "enquirer": "2.3.6", "eventemitter2": "5.0.1", "fclone": "1.0.11", "js-yaml": "~4.1.0", "mkdirp": "1.0.4", "needle": "2.4.0", "pidusage": "~3.0", "pm2-axon": "~4.0.1", "pm2-axon-rpc": "~0.7.1", "pm2-deploy": "~1.0.2", "pm2-multimeter": "^0.1.2", "promptly": "^2", "semver": "^7.2", "source-map-support": "0.5.21", "sprintf-js": "1.1.2", "vizion": "~2.2.1" }, "optionalDependencies": { "pm2-sysmonit": "^1.2.8" }, "bin": { "pm2": "bin/pm2", "pm2-dev": "bin/pm2-dev", "pm2-docker": "bin/pm2-docker", "pm2-runtime": "bin/pm2-runtime" } }, "sha512-4/I1htIHzZk1Y67UgOCo4F1cJtas1kSds31N8zN0PybO230id1nigyjGuGFzUnGmUFPmrJ0On22fO1ChFlp7VQ=="], + + "pm2-axon": ["pm2-axon@4.0.1", "", { "dependencies": { "amp": "~0.3.1", "amp-message": "~0.1.1", "debug": "^4.3.1", "escape-string-regexp": "^4.0.0" } }, "sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg=="], + + "pm2-axon-rpc": ["pm2-axon-rpc@0.7.1", "", { "dependencies": { "debug": "^4.3.1" } }, "sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw=="], + + "pm2-deploy": ["pm2-deploy@1.0.2", "", { "dependencies": { "run-series": "^1.1.8", "tv4": "^1.3.0" } }, "sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg=="], + + "pm2-multimeter": ["pm2-multimeter@0.1.2", "", { "dependencies": { "charm": "~0.1.1" } }, "sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA=="], + + "pm2-sysmonit": ["pm2-sysmonit@1.2.8", "", { "dependencies": { "async": "^3.2.0", "debug": "^4.3.1", "pidusage": "^2.0.21", "systeminformation": "^5.7", "tx2": "~1.0.4" } }, "sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA=="], + "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], @@ -1863,6 +1966,8 @@ "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], + "promptly": ["promptly@2.2.0", "", { "dependencies": { "read": "^1.0.4" } }, "sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA=="], + "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], "proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="], @@ -1875,6 +1980,10 @@ "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], + "proxy-agent": ["proxy-agent@6.3.1", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.0.1", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.2" } }, "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ=="], + + "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + "pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="], "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], @@ -1919,6 +2028,8 @@ "react-window-infinite-loader": ["react-window-infinite-loader@1.0.10", "", { "peerDependencies": { "react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-NO/csdHlxjWqA2RJZfzQgagAjGHspbO2ik9GtWZb0BY1Nnapq0auG8ErI+OhGCzpjYJsCYerqUlK6hkq9dfAAA=="], + "read": ["read@1.0.7", "", { "dependencies": { "mute-stream": "~0.0.4" } }, "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ=="], + "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], "readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], @@ -1941,6 +2052,8 @@ "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + "require-in-the-middle": ["require-in-the-middle@5.2.0", "", { "dependencies": { "debug": "^4.1.1", "module-details-from-path": "^1.0.3", "resolve": "^1.22.1" } }, "sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg=="], + "reservoir": ["reservoir@0.1.2", "", {}, "sha512-ysyw95gLBhMAzqIVrOHJ2yMrRQHAS+h97bS9r89Z7Ou10Jhl2k5KOsyjPqrxL+WfEanov0o5bAMVzQ7AKyENHA=="], "resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="], @@ -1969,6 +2082,8 @@ "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + "run-series": ["run-series@1.1.9", "", {}, "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g=="], + "rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="], "safe-array-concat": ["safe-array-concat@1.1.3", "", { "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" } }, "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q=="], @@ -1983,6 +2098,8 @@ "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + "sax": ["sax@1.4.1", "", {}, "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="], + "scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], "secure-json-parse": ["secure-json-parse@2.7.0", "", {}, "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="], @@ -2007,6 +2124,8 @@ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + "shimmer": ["shimmer@1.2.1", "", {}, "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw=="], + "side-channel": ["side-channel@1.1.0", "", { "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" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], @@ -2037,13 +2156,15 @@ "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], + "sparse-bitfield": ["sparse-bitfield@3.0.3", "", { "dependencies": { "memory-pager": "^1.0.2" } }, "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ=="], "split-ca": ["split-ca@1.0.1", "", {}, "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ=="], "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], - "sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], + "sprintf-js": ["sprintf-js@1.1.2", "", {}, "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="], "ssh-remote-port-forward": ["ssh-remote-port-forward@1.0.4", "", { "dependencies": { "@types/ssh2": "^0.5.48", "ssh2": "^1.4.0" } }, "sha512-x0LV1eVDwjf1gmG7TTnfqIzf+3VPRz7vrNIjX6oYLbeCrf/PeVY6hkT68Mg+q02qXxQhrLjB0jfgvhevoCRmLQ=="], @@ -2099,6 +2220,8 @@ "system-ca": ["system-ca@2.0.1", "", { "optionalDependencies": { "macos-export-certificate-and-key": "^1.2.0", "win-export-certificate-and-key": "^2.1.0" } }, "sha512-9ZDV9yl8ph6Op67wDGPr4LykX86usE9x3le+XZSHfVMiiVJ5IRgmCWjLgxyz35ju9H3GDIJJZm4ogAeIfN5cQQ=="], + "systeminformation": ["systeminformation@5.27.6", "", { "os": "!aix", "bin": { "systeminformation": "lib/cli.js" } }, "sha512-9gmEXEtFp8vkewF8MLo69OmYBf0UpvGnqfAQs0kO+dgJRyFuCDxBwX53NQj4p/aV4fFmJQry+K1LLxPadAgmFQ=="], + "tailwind-merge": ["tailwind-merge@3.3.1", "", {}, "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g=="], "tailwindcss": ["tailwindcss@3.4.17", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.6", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og=="], @@ -2157,8 +2280,12 @@ "turbo-windows-arm64": ["turbo-windows-arm64@2.5.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-oQ8RrK1VS8lrxkLriotFq+PiF7iiGgkZtfLKF4DDKsmdbPo0O9R2mQxm7jHLuXraRCuIQDWMIw6dpcr7Iykf4A=="], + "tv4": ["tv4@1.3.0", "", {}, "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw=="], + "tweetnacl": ["tweetnacl@0.14.5", "", {}, "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="], + "tx2": ["tx2@1.0.5", "", { "dependencies": { "json-stringify-safe": "^5.0.1" } }, "sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg=="], + "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], "type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], @@ -2199,6 +2326,8 @@ "vite": ["vite@4.5.14", "", { "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", "rollup": "^3.27.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@types/node": ">= 14", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g=="], + "vizion": ["vizion@2.2.1", "", { "dependencies": { "async": "^2.6.3", "git-node-fs": "^1.0.0", "ini": "^1.3.5", "js-git": "^0.7.8" } }, "sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww=="], + "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], "webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="], @@ -2225,6 +2354,8 @@ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + "ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], + "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], @@ -2285,6 +2416,30 @@ "@mongodb-js/oidc-plugin/express": ["express@4.21.2", "", { "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" } }, "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA=="], + "@pm2/agent/chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="], + + "@pm2/agent/dayjs": ["dayjs@1.8.36", "", {}, "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw=="], + + "@pm2/agent/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="], + + "@pm2/agent/semver": ["semver@7.5.4", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" } }, "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA=="], + + "@pm2/io/async": ["async@2.6.4", "", { "dependencies": { "lodash": "^4.17.14" } }, "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA=="], + + "@pm2/io/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="], + + "@pm2/io/eventemitter2": ["eventemitter2@6.4.9", "", {}, "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg=="], + + "@pm2/io/semver": ["semver@7.5.4", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" } }, "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA=="], + + "@pm2/io/tslib": ["tslib@1.9.3", "", {}, "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="], + + "@pm2/js-api/async": ["async@2.6.4", "", { "dependencies": { "lodash": "^4.17.14" } }, "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA=="], + + "@pm2/js-api/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="], + + "@pm2/js-api/eventemitter2": ["eventemitter2@6.4.9", "", {}, "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg=="], + "@sideway/address/@hapi/hoek": ["@hapi/hoek@9.3.0", "", {}, "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="], "@stock-bot/mongodb/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@6.21.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/type-utils": "6.21.0", "@typescript-eslint/utils": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", "eslint": "^7.0.0 || ^8.0.0" } }, "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA=="], @@ -2333,10 +2488,14 @@ "bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "body-parser/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "bun-types/@types/node": ["@types/node@22.15.32", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-3jigKqgSjsH6gYZv2nEsqdXfZqIFGAV36XYYjf9KGZ3PSG+IhLecqPnI310RvjutyMwifE2hhhNEklOUrvx/wA=="], "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + "cli-tableau/chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="], + "compress-commons/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], "decompress-response/mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], @@ -2391,6 +2550,8 @@ "http-errors/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], + "ip-address/sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], + "is-wsl/is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], "joi/@hapi/hoek": ["@hapi/hoek@9.3.0", "", {}, "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="], @@ -2411,8 +2572,12 @@ "nearley/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + "needle/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], + "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], + "nssocket/eventemitter2": ["eventemitter2@0.4.14", "", {}, "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ=="], + "openid-client/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], "os-dns-native/node-addon-api": ["node-addon-api@4.3.0", "", {}, "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="], @@ -2423,10 +2588,18 @@ "pkg-dir/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + "pm2/chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="], + + "pm2-sysmonit/pidusage": ["pidusage@2.0.21", "", { "dependencies": { "safe-buffer": "^5.2.1" } }, "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA=="], + "prebuild-install/tar-fs": ["tar-fs@2.1.3", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg=="], "protobufjs/@types/node": ["@types/node@22.15.32", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-3jigKqgSjsH6gYZv2nEsqdXfZqIFGAV36XYYjf9KGZ3PSG+IhLecqPnI310RvjutyMwifE2hhhNEklOUrvx/wA=="], + "proxy-agent/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], + + "raw-body/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], "readdir-glob/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], @@ -2437,10 +2610,14 @@ "send/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="], + "sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], + "tailwindcss/object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], "type-is/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="], + "vizion/async": ["async@2.6.4", "", { "dependencies": { "lodash": "^4.17.14" } }, "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA=="], + "win-export-certificate-and-key/node-addon-api": ["node-addon-api@3.2.1", "", {}, "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A=="], "yauzl/buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="], @@ -2487,6 +2664,10 @@ "@mongodb-js/oidc-plugin/express/type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="], + "@pm2/agent/semver/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], + + "@pm2/io/semver/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], + "@stock-bot/mongodb/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@6.21.0", "", { "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0" } }, "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg=="], "@stock-bot/mongodb/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@6.21.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "6.21.0", "@typescript-eslint/utils": "6.21.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" } }, "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag=="], @@ -2683,8 +2864,6 @@ "@mongodb-js/oidc-plugin/express/accepts/negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="], - "@mongodb-js/oidc-plugin/express/body-parser/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], - "@mongodb-js/oidc-plugin/express/body-parser/raw-body": ["raw-body@2.5.2", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA=="], "@mongodb-js/oidc-plugin/express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], diff --git a/config/default.json b/config/default.json deleted file mode 100644 index 1e26b67..0000000 --- a/config/default.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "name": "stock-bot", - "version": "1.0.0", - "environment": "development", - "service": { - "name": "default-service", - "port": 3000, - "host": "0.0.0.0", - "healthCheckPath": "/health", - "metricsPath": "/metrics", - "shutdownTimeout": 30000, - "cors": { - "enabled": true, - "origin": "*", - "credentials": true - } - }, - "database": { - "postgres": { - "host": "localhost", - "port": 5432, - "database": "trading_bot", - "user": "trading_user", - "password": "trading_pass_dev", - "ssl": false, - "poolSize": 10, - "connectionTimeout": 30000, - "idleTimeout": 10000 - }, - "questdb": { - "host": "localhost", - "ilpPort": 9009, - "httpPort": 9000, - "pgPort": 8812, - "database": "questdb", - "user": "admin", - "password": "quest", - "bufferSize": 65536, - "flushInterval": 1000 - }, - "mongodb": { - "uri": "mongodb://trading_admin:trading_mongo_dev@localhost:27017/stock?authSource=admin", - "host": "localhost", - "port": 27017, - "database": "stock", - "user": "trading_admin", - "password": "trading_mongo_dev", - "authSource": "admin", - "poolSize": 10 - }, - "dragonfly": { - "host": "localhost", - "port": 6379, - "db": 0, - "keyPrefix": "stock-bot:", - "maxRetries": 3, - "retryDelay": 100 - } - }, - "log": { - "level": "info", - "format": "json" - }, - "providers": { - "yahoo": { - "name": "yahoo", - "enabled": true, - "rateLimit": { - "maxRequests": 5, - "windowMs": 60000 - }, - "timeout": 30000, - "baseUrl": "https://query1.finance.yahoo.com" - } - }, - "queue": { - "redis": { - "host": "localhost", - "port": 6379, - "db": 1 - }, - "defaultJobOptions": { - "attempts": 3, - "backoff": { - "type": "exponential", - "delay": 1000 - }, - "removeOnComplete": 100, - "removeOnFail": 50 - } - }, - "features": { - "realtime": true, - "backtesting": true, - "paperTrading": true, - "notifications": false - } -} \ No newline at end of file diff --git a/libs/core/config/src/config-manager.ts b/libs/core/config/src/config-manager.ts index ed30d3d..8dc2dde 100644 --- a/libs/core/config/src/config-manager.ts +++ b/libs/core/config/src/config-manager.ts @@ -73,6 +73,17 @@ export class ConfigManager> { this.config = this.schema.parse(mergedConfig) as T; } catch (error) { if (error instanceof z.ZodError) { + const errorDetails = error.errors.map(err => ({ + path: err.path.join('.'), + message: err.message, + code: err.code, + expected: (err as any).expected, + received: (err as any).received, + })); + + console.error('Configuration validation failed:'); + console.error(JSON.stringify(errorDetails, null, 2)); + throw new ConfigValidationError('Configuration validation failed', error.errors); } throw error; diff --git a/libs/core/config/src/index.ts b/libs/core/config/src/index.ts index 25594d3..7856072 100644 --- a/libs/core/config/src/index.ts +++ b/libs/core/config/src/index.ts @@ -1,11 +1,12 @@ -// Import necessary types for singleton +// Import necessary types import { EnvLoader } from './loaders/env.loader'; import { FileLoader } from './loaders/file.loader'; import { ConfigManager } from './config-manager'; import type { AppConfig } from './schemas'; import { appConfigSchema } from './schemas'; +import { z } from 'zod'; -// Create singleton instance +// Legacy singleton instance for backward compatibility let configInstance: ConfigManager | null = null; // Synchronously load critical env vars for early initialization @@ -57,6 +58,7 @@ loadCriticalEnvVarsSync(); /** * Initialize the global configuration synchronously. + * @deprecated Use initializeAppConfig with your own schema instead * * This loads configuration from all sources in the correct hierarchy: * 1. Schema defaults (lowest priority) @@ -143,8 +145,11 @@ export function getLoggingConfig() { return getConfig().log; } +// Deprecated - provider configs should be app-specific +// @deprecated Move provider configs to your app-specific config export function getProviderConfig(provider: string) { - const providers = getConfig().providers; + const config = getConfig() as any; + const providers = config.providers; if (!providers || !(provider in providers)) { throw new Error(`Provider configuration not found: ${provider}`); } @@ -168,6 +173,39 @@ export function isTest(): boolean { return getConfig().environment === 'test'; } +/** + * Generic config builder for creating app-specific configurations + * @param schema - Zod schema for your app config + * @param options - Config manager options + * @returns Initialized config manager instance + */ +export function createAppConfig( + schema: T, + options?: { + configPath?: string; + environment?: 'development' | 'test' | 'production'; + loaders?: any[]; + } +): ConfigManager> { + const manager = new ConfigManager>(options); + return manager; +} + +/** + * Create and initialize app config in one step + */ +export function initializeAppConfig( + schema: T, + options?: { + configPath?: string; + environment?: 'development' | 'test' | 'production'; + loaders?: any[]; + } +): z.infer { + const manager = createAppConfig(schema, options); + return manager.initialize(schema); +} + // Export all schemas export * from './schemas'; diff --git a/libs/core/config/src/loaders/env.loader.ts b/libs/core/config/src/loaders/env.loader.ts index 2da2cb1..ac6a0ee 100644 --- a/libs/core/config/src/loaders/env.loader.ts +++ b/libs/core/config/src/loaders/env.loader.ts @@ -28,7 +28,7 @@ export class EnvLoader implements ConfigLoader { load(): Record { try { // Load root .env file - try multiple possible locations - const possiblePaths = ['./.env', '../.env', '../../.env']; + const possiblePaths = ['./.env', '../.env', '../../.env', '../../../.env']; for (const path of possiblePaths) { this.loadEnvFile(path); } diff --git a/libs/core/config/src/schemas/base-app.schema.ts b/libs/core/config/src/schemas/base-app.schema.ts new file mode 100644 index 0000000..130bded --- /dev/null +++ b/libs/core/config/src/schemas/base-app.schema.ts @@ -0,0 +1,61 @@ +import { z } from 'zod'; +import { baseConfigSchema, environmentSchema } from './base.schema'; +import { + postgresConfigSchema, + mongodbConfigSchema, + questdbConfigSchema, + dragonflyConfigSchema +} from './database.schema'; +import { + serviceConfigSchema, + loggingConfigSchema, + queueConfigSchema, + httpConfigSchema, + webshareConfigSchema, + browserConfigSchema, + proxyConfigSchema +} from './service.schema'; + +/** + * Generic base application schema that can be extended by specific apps + */ +export const baseAppSchema = z.object({ + // Basic app info + name: z.string(), + version: z.string(), + environment: environmentSchema.default('development'), + + // Service configuration + service: serviceConfigSchema, + + // Logging configuration + log: loggingConfigSchema, + + // Database configuration - apps can choose which databases they need + database: z.object({ + postgres: postgresConfigSchema.optional(), + mongodb: mongodbConfigSchema.optional(), + questdb: questdbConfigSchema.optional(), + dragonfly: dragonflyConfigSchema.optional(), + }).optional(), + + // Redis configuration (used for cache and queue) + redis: dragonflyConfigSchema.optional(), + + // Queue configuration + queue: queueConfigSchema.optional(), + + // HTTP client configuration + http: httpConfigSchema.optional(), + + // WebShare proxy configuration + webshare: webshareConfigSchema.optional(), + + // Browser configuration + browser: browserConfigSchema.optional(), + + // Proxy manager configuration + proxy: proxyConfigSchema.optional(), +}); + +export type BaseAppConfig = z.infer; \ No newline at end of file diff --git a/libs/core/config/src/schemas/database.schema.ts b/libs/core/config/src/schemas/database.schema.ts index c2c0c78..47fd1fd 100644 --- a/libs/core/config/src/schemas/database.schema.ts +++ b/libs/core/config/src/schemas/database.schema.ts @@ -31,15 +31,16 @@ export const questdbConfigSchema = z.object({ // MongoDB configuration export const mongodbConfigSchema = z.object({ enabled: z.boolean().default(true), - uri: z.string().url().optional(), - host: z.string().default('localhost'), - port: z.number().default(27017), - database: z.string(), + uri: z.string().url(), // URI is required and contains all connection info + database: z.string(), // Database name for reference + poolSize: z.number().min(1).max(100).default(10), + // Optional fields for cases where URI parsing might fail + host: z.string().default('localhost').optional(), + port: z.number().default(27017).optional(), user: z.string().optional(), password: z.string().optional(), - authSource: z.string().default('admin'), + authSource: z.string().default('admin').optional(), replicaSet: z.string().optional(), - poolSize: z.number().min(1).max(100).default(10), }); // Dragonfly/Redis configuration diff --git a/libs/core/config/src/schemas/index.ts b/libs/core/config/src/schemas/index.ts index 0ea6635..d1b5467 100644 --- a/libs/core/config/src/schemas/index.ts +++ b/libs/core/config/src/schemas/index.ts @@ -1,116 +1,25 @@ -import { z } from 'zod'; -import { baseConfigSchema, environmentSchema } from './base.schema'; -import { providerConfigSchema, webshareProviderConfigSchema } from './provider.schema'; -import { httpConfigSchema, queueConfigSchema } from './service.schema'; - +// Export all schema modules export * from './base.schema'; export * from './database.schema'; -export * from './provider.schema'; export * from './service.schema'; +export * from './base-app.schema'; -// Flexible service schema with defaults -const flexibleServiceConfigSchema = z - .object({ - name: z.string().default('default-service'), - port: z.number().min(1).max(65535).default(3000), - host: z.string().default('0.0.0.0'), - healthCheckPath: z.string().default('/health'), - metricsPath: z.string().default('/metrics'), - shutdownTimeout: z.number().default(30000), - cors: z - .object({ - enabled: z.boolean().default(true), - origin: z.union([z.string(), z.array(z.string())]).default('*'), - credentials: z.boolean().default(true), - }) - .default({}), - }) - .default({}); +// Export provider schemas temporarily for backward compatibility +// These will be moved to stock-specific config +export * from './provider.schema'; -// Flexible database schema with defaults -const flexibleDatabaseConfigSchema = z - .object({ - postgres: z - .object({ - host: z.string().default('localhost'), - port: z.number().default(5432), - database: z.string().default('test_db'), - user: z.string().default('test_user'), - password: z.string().default('test_pass'), - ssl: z.boolean().default(false), - poolSize: z.number().min(1).max(100).default(10), - connectionTimeout: z.number().default(30000), - idleTimeout: z.number().default(10000), - }) - .default({}), - questdb: z - .object({ - host: z.string().default('localhost'), - ilpPort: z.number().default(9009), - httpPort: z.number().default(9000), - pgPort: z.number().default(8812), - database: z.string().default('questdb'), - user: z.string().default('admin'), - password: z.string().default('quest'), - bufferSize: z.number().default(65536), - flushInterval: z.number().default(1000), - }) - .default({}), - mongodb: z - .object({ - uri: z.string().url().optional(), - host: z.string().default('localhost'), - port: z.number().default(27017), - database: z.string().default('test_mongo'), - user: z.string().optional(), - password: z.string().optional(), - authSource: z.string().default('admin'), - replicaSet: z.string().optional(), - poolSize: z.number().min(1).max(100).default(10), - }) - .default({}), - dragonfly: z - .object({ - host: z.string().default('localhost'), - port: z.number().default(6379), - password: z.string().optional(), - db: z.number().min(0).max(15).default(0), - keyPrefix: z.string().optional(), - ttl: z.number().optional(), - maxRetries: z.number().default(3), - retryDelay: z.number().default(100), - }) - .default({}), - }) - .default({}); +// Re-export commonly used schemas for convenience +export { baseAppSchema } from './base-app.schema'; +export type { BaseAppConfig } from './base-app.schema'; -// Flexible log schema with defaults (renamed from logging) -const flexibleLogConfigSchema = z - .object({ - level: z.enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal']).default('info'), - format: z.enum(['json', 'pretty']).default('json'), - hideObject: z.boolean().default(false), - loki: z - .object({ - enabled: z.boolean().default(false), - host: z.string().default('localhost'), - port: z.number().default(3100), - labels: z.record(z.string()).default({}), - }) - .optional(), - }) - .default({}); +// Keep AppConfig for backward compatibility (deprecated) +// @deprecated Use baseAppSchema and extend it for your specific app +import { z } from 'zod'; +import { baseAppSchema } from './base-app.schema'; +import { providerConfigSchema } from './provider.schema'; -// Complete application configuration schema -export const appConfigSchema = baseConfigSchema.extend({ - environment: environmentSchema.default('development'), - service: flexibleServiceConfigSchema, - log: flexibleLogConfigSchema, - database: flexibleDatabaseConfigSchema, - queue: queueConfigSchema.optional(), - http: httpConfigSchema.optional(), +export const appConfigSchema = baseAppSchema.extend({ providers: providerConfigSchema.optional(), - webshare: webshareProviderConfigSchema.optional(), }); export type AppConfig = z.infer; diff --git a/libs/core/config/src/schemas/service.schema.ts b/libs/core/config/src/schemas/service.schema.ts index d0c0c89..1427fb8 100644 --- a/libs/core/config/src/schemas/service.schema.ts +++ b/libs/core/config/src/schemas/service.schema.ts @@ -21,6 +21,7 @@ export const serviceConfigSchema = z.object({ export const loggingConfigSchema = z.object({ level: z.enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal']).default('info'), format: z.enum(['json', 'pretty']).default('json'), + hideObject: z.boolean().default(false), loki: z .object({ enabled: z.boolean().default(false), @@ -33,12 +34,17 @@ export const loggingConfigSchema = z.object({ // Queue configuration export const queueConfigSchema = z.object({ + enabled: z.boolean().default(true), redis: z.object({ host: z.string().default('localhost'), port: z.number().default(6379), password: z.string().optional(), db: z.number().default(1), }), + workers: z.number().default(1), + concurrency: z.number().default(1), + enableScheduledJobs: z.boolean().default(true), + delayWorkerStart: z.boolean().default(false), defaultJobOptions: z .object({ attempts: z.number().default(3), @@ -48,8 +54,9 @@ export const queueConfigSchema = z.object({ delay: z.number().default(1000), }) .default({}), - removeOnComplete: z.number().default(10), - removeOnFail: z.number().default(5), + removeOnComplete: z.number().default(100), + removeOnFail: z.number().default(50), + timeout: z.number().optional(), }) .default({}), }); @@ -73,3 +80,22 @@ export const httpConfigSchema = z.object({ }) .optional(), }); + +// WebShare proxy service configuration +export const webshareConfigSchema = z.object({ + apiKey: z.string().optional(), + apiUrl: z.string().default('https://proxy.webshare.io/api/v2/'), + enabled: z.boolean().default(true), +}); + +// Browser configuration +export const browserConfigSchema = z.object({ + headless: z.boolean().default(true), + timeout: z.number().default(30000), +}); + +// Proxy manager configuration +export const proxyConfigSchema = z.object({ + cachePrefix: z.string().default('proxy:'), + ttl: z.number().default(3600), +}); diff --git a/libs/core/di/src/config/schemas/service.schema.ts b/libs/core/di/src/config/schemas/service.schema.ts index 2a76d26..40f955f 100644 --- a/libs/core/di/src/config/schemas/service.schema.ts +++ b/libs/core/di/src/config/schemas/service.schema.ts @@ -12,6 +12,20 @@ export const browserConfigSchema = z.object({ export const queueConfigSchema = z.object({ enabled: z.boolean().optional().default(true), + workers: z.number().optional().default(1), + concurrency: z.number().optional().default(1), + enableScheduledJobs: z.boolean().optional().default(true), + delayWorkerStart: z.boolean().optional().default(false), + defaultJobOptions: z.object({ + attempts: z.number().default(3), + backoff: z.object({ + type: z.enum(['exponential', 'fixed']).default('exponential'), + delay: z.number().default(1000), + }).default({}), + removeOnComplete: z.number().default(100), + removeOnFail: z.number().default(50), + timeout: z.number().optional(), + }).optional().default({}), }); export type ProxyConfig = z.infer; diff --git a/libs/core/di/src/container/builder.ts b/libs/core/di/src/container/builder.ts index 8376979..42cd419 100644 --- a/libs/core/di/src/container/builder.ts +++ b/libs/core/di/src/container/builder.ts @@ -73,26 +73,24 @@ export class ServiceContainerBuilder { private applyServiceOptions(config: Partial): AppConfig { return { - redis: { + redis: config.redis || { enabled: this.options.enableCache ?? true, - host: config.redis?.host || 'localhost', - port: config.redis?.port || 6379, - password: config.redis?.password, - username: config.redis?.username, - db: config.redis?.db || 0, + host: 'localhost', + port: 6379, + db: 0, }, - mongodb: { + mongodb: config.mongodb || { enabled: this.options.enableMongoDB ?? true, - uri: config.mongodb?.uri || '', - database: config.mongodb?.database || '', + uri: '', + database: '', }, - postgres: { + postgres: config.postgres || { enabled: this.options.enablePostgres ?? true, - host: config.postgres?.host || 'localhost', - port: config.postgres?.port || 5432, - database: config.postgres?.database || '', - user: config.postgres?.user || '', - password: config.postgres?.password || '', + host: 'localhost', + port: 5432, + database: 'postgres', + user: 'postgres', + password: 'postgres', }, questdb: this.options.enableQuestDB ? (config.questdb || { enabled: true, @@ -104,7 +102,19 @@ export class ServiceContainerBuilder { }) : undefined, proxy: this.options.enableProxy ? (config.proxy || { cachePrefix: 'proxy:', ttl: 3600 }) : undefined, browser: this.options.enableBrowser ? (config.browser || { headless: true, timeout: 30000 }) : undefined, - queue: this.options.enableQueue ? { enabled: this.options.enableQueue } : undefined, + queue: this.options.enableQueue ? (config.queue || { + enabled: true, + workers: 1, + concurrency: 1, + enableScheduledJobs: true, + delayWorkerStart: false, + defaultJobOptions: { + attempts: 3, + backoff: { type: 'exponential' as const, delay: 1000 }, + removeOnComplete: 100, + removeOnFail: 50, + } + }) : undefined, }; } @@ -133,8 +143,8 @@ export class ServiceContainerBuilder { } private transformStockBotConfig(config: AppConfig | StockBotAppConfig): Partial { - // If it's already in the new format, return as is - if ('redis' in config) { + // If it's already in the new format (has redis AND postgres at top level), return as is + if ('redis' in config && 'postgres' in config && 'mongodb' in config) { return config as AppConfig; } @@ -149,18 +159,17 @@ export class ServiceContainerBuilder { db: stockBotConfig.database.dragonfly.db || 0, } : undefined, mongodb: stockBotConfig.database?.mongodb ? { - enabled: true, - uri: stockBotConfig.database.mongodb.uri || - `mongodb://${stockBotConfig.database.mongodb.user || ''}:${stockBotConfig.database.mongodb.password || ''}@${stockBotConfig.database.mongodb.host || 'localhost'}:${stockBotConfig.database.mongodb.port || 27017}/${stockBotConfig.database.mongodb.database || 'test'}?authSource=${stockBotConfig.database.mongodb.authSource || 'admin'}`, - database: stockBotConfig.database.mongodb.database || 'test', + enabled: stockBotConfig.database.mongodb.enabled ?? true, + uri: stockBotConfig.database.mongodb.uri, + database: stockBotConfig.database.mongodb.database, } : undefined, postgres: stockBotConfig.database?.postgres ? { - enabled: true, - host: stockBotConfig.database.postgres.host || 'localhost', - port: stockBotConfig.database.postgres.port || 5432, - database: stockBotConfig.database.postgres.database || 'test', - user: stockBotConfig.database.postgres.user || 'test', - password: stockBotConfig.database.postgres.password || 'test', + enabled: stockBotConfig.database.postgres.enabled ?? true, + host: stockBotConfig.database.postgres.host, + port: stockBotConfig.database.postgres.port, + database: stockBotConfig.database.postgres.database, + user: stockBotConfig.database.postgres.user, + password: stockBotConfig.database.postgres.password, } : undefined, questdb: stockBotConfig.database?.questdb ? { enabled: true, @@ -170,6 +179,9 @@ export class ServiceContainerBuilder { influxPort: stockBotConfig.database.questdb.ilpPort || 9009, database: stockBotConfig.database.questdb.database || 'questdb', } : undefined, + queue: stockBotConfig.queue, + browser: stockBotConfig.browser, + proxy: stockBotConfig.proxy, }; } } diff --git a/libs/core/di/src/registrations/database.registration.ts b/libs/core/di/src/registrations/database.registration.ts index 5e900ab..e479213 100644 --- a/libs/core/di/src/registrations/database.registration.ts +++ b/libs/core/di/src/registrations/database.registration.ts @@ -20,7 +20,7 @@ export function registerDatabaseServices( port: parseInt(uriMatch?.[4] || '27017'), database: config.mongodb.database, username: uriMatch?.[1], - password: uriMatch?.[2], + password: uriMatch?.[2] ? String(uriMatch?.[2]) : undefined, authSource: uriMatch?.[6] || 'admin', uri: config.mongodb.uri, }; @@ -37,16 +37,19 @@ export function registerDatabaseServices( if (config.postgres.enabled) { container.register({ postgresClient: asFunction(({ logger }) => { - return new PostgreSQLClient( - { - host: config.postgres.host, - port: config.postgres.port, - database: config.postgres.database, - username: config.postgres.user, - password: config.postgres.password, - }, - logger - ); + const pgConfig = { + host: config.postgres.host, + port: config.postgres.port, + database: config.postgres.database, + username: config.postgres.user, + password: String(config.postgres.password), // Ensure password is a string + }; + + logger.debug('PostgreSQL config:', { + ...pgConfig, + password: pgConfig.password ? '***' : 'NO_PASSWORD', + }); + return new PostgreSQLClient(pgConfig, logger); }).singleton(), }); } else { diff --git a/libs/core/di/src/registrations/service.registration.ts b/libs/core/di/src/registrations/service.registration.ts index 734c8fe..d239d55 100644 --- a/libs/core/di/src/registrations/service.registration.ts +++ b/libs/core/di/src/registrations/service.registration.ts @@ -56,19 +56,12 @@ export function registerApplicationServices( db: config.redis.db, }, defaultQueueOptions: { - workers: 1, - concurrency: 1, - defaultJobOptions: { - removeOnComplete: 100, - removeOnFail: 50, - attempts: 3, - backoff: { - type: 'exponential', - delay: 1000, - }, - }, + workers: config.queue!.workers || 1, + concurrency: config.queue!.concurrency || 1, + defaultJobOptions: config.queue!.defaultJobOptions, }, - enableScheduledJobs: true, + enableScheduledJobs: config.queue!.enableScheduledJobs ?? true, + delayWorkerStart: config.queue!.delayWorkerStart ?? false, }; return new QueueManager(queueConfig, logger); }).singleton(), diff --git a/libs/data/postgres/src/client.ts b/libs/data/postgres/src/client.ts index a2037c5..c54df1c 100644 --- a/libs/data/postgres/src/client.ts +++ b/libs/data/postgres/src/client.ts @@ -435,12 +435,22 @@ export class PostgreSQLClient { } private buildPoolConfig(): any { - return { + this.logger.debug('Building PostgreSQL pool config:', { host: this.config.host, port: this.config.port, database: this.config.database, user: this.config.username, - password: this.config.password, + passwordLength: this.config.password?.length, + passwordType: typeof this.config.password, + passwordValue: this.config.password ? `${this.config.password.substring(0, 3)}***` : 'NO_PASSWORD', + }); + + const poolConfig = { + host: this.config.host, + port: this.config.port, + database: this.config.database, + user: this.config.username, + password: typeof this.config.password === 'string' ? this.config.password : String(this.config.password || ''), min: this.config.poolSettings?.min, max: this.config.poolSettings?.max, idleTimeoutMillis: this.config.poolSettings?.idleTimeoutMillis, @@ -455,6 +465,8 @@ export class PostgreSQLClient { } : false, }; + + return poolConfig; } private setupErrorHandlers(): void { diff --git a/package.json b/package.json index 77aa5c3..84be0f5 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,12 @@ "libs/core/*", "libs/data/*", "libs/services/*", - "apps/*" + "apps/stock", + "apps/stock/config", + "apps/stock/data-ingestion", + "apps/stock/data-pipeline", + "apps/stock/web-api", + "apps/stock/web-app" ], "devDependencies": { "@eslint/js": "^9.28.0",