trying to fix build

This commit is contained in:
Bojan Kucera 2025-06-09 20:00:08 -04:00
parent cc19f88ad2
commit 47109baff7
41 changed files with 315 additions and 415 deletions

View file

@ -2,27 +2,18 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"include": ["src/**/*"],
"references": [
{ "path": "../../libs/types" },
{ "path": "../../libs/config" },
{ "path": "../../libs/logger" },
{ "path": "../../libs/http" },
{ "path": "../../libs/types" },
{ "path": "../../libs/cache" },
{ "path": "../../libs/utils" },
{ "path": "../../libs/shutdown" },
{ "path": "../../libs/questdb-client" },
{ "path": "../../libs/mongodb-client" },
{ "path": "../../libs/event-bus" },
{ "path": "../../libs/shutdown" }
]
}

View file

@ -5,8 +5,6 @@
"name": "stock-bot",
"dependencies": {
"bullmq": "^5.53.2",
"envalid": "^8.0.0",
"valibot": "^1.1.0",
},
"devDependencies": {
"@testcontainers/mongodb": "^10.7.2",
@ -14,13 +12,14 @@
"@types/bun": "latest",
"@types/node": "^20.12.12",
"@types/supertest": "^6.0.2",
"@types/yup": "^0.32.0",
"bun-types": "^1.2.15",
"mongodb-memory-server": "^9.1.6",
"pg-mem": "^2.8.1",
"supertest": "^6.3.4",
"turbo": "^2.5.4",
"typescript": "^5.4.5",
"zod": "^3.25.56",
"typescript": "^5.8.3",
"yup": "^1.6.1",
},
},
"apps/dashboard": {
@ -170,7 +169,7 @@
"version": "1.0.0",
"dependencies": {
"dotenv": "^16.5.0",
"zod": "^3.25.56",
"yup": "^1.6.1",
},
"devDependencies": {
"@types/node": "^20.11.0",
@ -269,7 +268,7 @@
"@stock-bot/logger": "*",
"@stock-bot/types": "*",
"mongodb": "^6.3.0",
"zod": "^3.22.4",
"yup": "^1.6.1",
},
"devDependencies": {
"@types/node": "^20.11.0",
@ -288,7 +287,7 @@
"@stock-bot/logger": "*",
"@stock-bot/types": "*",
"pg": "^8.11.3",
"zod": "^3.22.4",
"yup": "^1.6.1",
},
"devDependencies": {
"@types/node": "^20.11.0",
@ -899,6 +898,8 @@
"@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
"@types/yup": ["@types/yup@0.32.0", "", { "dependencies": { "yup": "*" } }, "sha512-Gr2lllWTDxGVYHgWfL8szjdedERpNgm44L9BDL2cmcHG7Bfd6taEpiW3ayMFLaYvlJr/6bFXDJdh6L406AGlFg=="],
"@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=="],
"@typescript-eslint/parser": ["@typescript-eslint/parser@6.21.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", "@typescript-eslint/typescript-estree": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" } }, "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ=="],
@ -1201,8 +1202,6 @@
"env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="],
"envalid": ["envalid@8.0.0", "", { "dependencies": { "tslib": "2.6.2" } }, "sha512-PGeYJnJB5naN0ME6SH8nFcDj9HVbLpYIfg1p5lAyM9T4cH2lwtu2fLbozC/bq+HUUOIFxhX/LP0/GmlqPHT4tQ=="],
"environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="],
"err-code": ["err-code@2.0.3", "", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="],
@ -1803,6 +1802,8 @@
"properties-reader": ["properties-reader@2.3.0", "", { "dependencies": { "mkdirp": "^1.0.4" } }, "sha512-z597WicA7nDZxK12kZqHr2TcvwNU1GCfA5UwfDY/HDp3hXPoPlb5rlEx9bwGTiJnc0OqbBTkU975jDToth8Gxw=="],
"property-expr": ["property-expr@2.0.6", "", {}, "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA=="],
"protobufjs": ["protobufjs@7.5.3", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw=="],
"proxy-agent": ["proxy-agent@6.5.0", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.5" } }, "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A=="],
@ -2005,6 +2006,8 @@
"thread-stream": ["thread-stream@3.1.0", "", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A=="],
"tiny-case": ["tiny-case@1.0.3", "", {}, "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q=="],
"tinyglobby": ["tinyglobby@0.2.13", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw=="],
"tmp": ["tmp@0.2.3", "", {}, "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w=="],
@ -2013,6 +2016,8 @@
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
"toposort": ["toposort@2.0.2", "", {}, "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg=="],
"tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="],
"trading-dashboard": ["trading-dashboard@workspace:apps/dashboard"],
@ -2041,7 +2046,7 @@
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
"type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
"type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="],
"type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="],
@ -2071,8 +2076,6 @@
"uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
"valibot": ["valibot@1.1.0", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw=="],
"validate-npm-package-license": ["validate-npm-package-license@3.0.4", "", { "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="],
"validate-npm-package-name": ["validate-npm-package-name@6.0.1", "", {}, "sha512-OaI//3H0J7ZkR1OqlhGA8cA+Cbk/2xFOQpJOt5+s27/ta9eZwpeervh4Mxh4w0im/kdgktowaqVNR7QOrUd7Yg=="],
@ -2121,9 +2124,9 @@
"yoctocolors-cjs": ["yoctocolors-cjs@2.1.2", "", {}, "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA=="],
"zip-stream": ["zip-stream@6.0.1", "", { "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", "readable-stream": "^4.0.0" } }, "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA=="],
"yup": ["yup@1.6.1", "", { "dependencies": { "property-expr": "^2.0.5", "tiny-case": "^1.0.3", "toposort": "^2.0.2", "type-fest": "^2.19.0" } }, "sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA=="],
"zod": ["zod@3.25.56", "", {}, "sha512-rd6eEF3BTNvQnR2e2wwolfTmUTnp70aUTqr0oaGbHifzC3BKJsoV+Gat8vxUMR1hwOKBs6El+qWehrHbCpW6SQ=="],
"zip-stream": ["zip-stream@6.0.1", "", { "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", "readable-stream": "^4.0.0" } }, "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA=="],
"zone.js": ["zone.js@0.15.1", "", {}, "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w=="],
@ -2267,8 +2270,6 @@
"ent/punycode": ["punycode@1.4.1", "", {}, "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="],
"envalid/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="],
"external-editor/tmp": ["tmp@0.0.33", "", { "dependencies": { "os-tmpdir": "~1.0.2" } }, "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw=="],
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
@ -2285,6 +2286,8 @@
"globals/type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="],
"got/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
"hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
"http-proxy/eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="],

View file

@ -2,27 +2,12 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"include": ["src/**/*"],
"references": [
{ "path": "../types" },
{ "path": "../config" },
{ "path": "../logger" },
{ "path": "../utils" },
{ "path": "../postgres-client" },
{ "path": "../mongodb-client" },
{ "path": "../questdb-client" }
{ "path": "../logger" }
]
}

View file

@ -14,7 +14,7 @@
},
"dependencies": {
"dotenv": "^16.5.0",
"zod": "^3.25.56"
"yup": "^1.6.1"
},
"devDependencies": {
"@types/node": "^20.11.0",

View file

@ -1,5 +1,5 @@
/**
* Admin interfaces configuration using Zod
* Admin interfaces configuration using Yup
* PgAdmin, Mongo Express, Redis Insight for database management
*/
import { cleanEnv, envValidators } from './env-utils';

View file

@ -1,5 +1,5 @@
/**
* Core configuration module for the Stock Bot platform using Zod
* Core configuration module for the Stock Bot platform using Yup
*/
import { config as dotenvConfig } from 'dotenv';
import path from 'node:path';

View file

@ -1,5 +1,5 @@
/**
* Data provider configurations using Zod
* Data provider configurations using Yup
*/
import { cleanEnv, envValidators } from './env-utils';

View file

@ -1,5 +1,5 @@
/**
* Database configuration using Zod
* Database configuration using Yup
*/
import { cleanEnv, envValidators } from './env-utils.js';

View file

@ -1,5 +1,5 @@
/**
* Dragonfly (Redis replacement) configuration using Zod
* Dragonfly (Redis replacement) configuration using Yup
* High-performance caching and event streaming
*/
import { cleanEnv, envValidators } from './env-utils.js';

View file

@ -1,7 +1,7 @@
/**
* Environment validation utilities using Zod
* Environment validation utilities using Yup
*/
import { z } from 'zod';
import * as yup from 'yup';
import { config } from 'dotenv';
import { join } from 'path';
import { existsSync } from 'fs';
@ -50,30 +50,31 @@ function loadEnvFiles() {
loadEnvFiles();
/**
* Creates a Zod schema for environment variable validation
* Creates a Yup schema for environment variable validation
*/
export function createEnvSchema<T extends z.ZodRawShape>(shape: T) {
return z.object(shape);
export function createEnvSchema(shape: Record<string, any>) {
return yup.object(shape);
}
/**
* Validates environment variables against a Zod schema
* Validates environment variables against a Yup schema
*/
export function validateEnv<T extends z.ZodRawShape>(
schema: z.ZodObject<T>,
export function validateEnv(
schema: yup.ObjectSchema<any>,
env = process.env
): z.infer<z.ZodObject<T>> {
const result = schema.safeParse(env);
if (!result.success) {
console.error('❌ Invalid environment variables:');
result.error.issues.forEach((issue: any) => {
console.error(` ${issue.path.join('.')}: ${issue.message}`);
});
): any {
try {
const result = schema.validateSync(env, { abortEarly: false });
return result;
} catch (error) {
if (error instanceof yup.ValidationError) {
console.error('❌ Invalid environment variables:');
error.inner.forEach((err) => {
console.error(` ${err.path}: ${err.message}`);
});
}
throw new Error('Environment validation failed');
}
return result.data;
}
/**
@ -91,55 +92,71 @@ export function loadEnv(path?: string) {
/**
* Helper functions for common validation patterns
*/
export const envValidators = { // String with default
export const envValidators = {
// String with default
str: (defaultValue?: string, description?: string) =>
z.string().default(defaultValue || '').describe(description || ''),
yup.string().default(defaultValue || ''),
// String with choices (enum)
strWithChoices: (choices: string[], defaultValue?: string, description?: string) =>
z.enum(choices as [string, ...string[]])
.default((defaultValue || choices[0]) as any)
.describe(description || ''),
yup.string().oneOf(choices).default(defaultValue || choices[0]),
// Required string
requiredStr: (description?: string) =>
z.string().min(1, 'Required').describe(description || ''),
// Port number
yup.string().required('Required'),
// Port number
port: (defaultValue?: number, description?: string) =>
z.string().transform((val: string) => parseInt(val, 10))
.pipe(z.number().int().min(1).max(65535))
.default(defaultValue?.toString() || '3000')
.describe(description || ''),
yup.number()
.integer()
.min(1)
.max(65535)
.transform((val, originalVal) => {
if (typeof originalVal === 'string') {
return parseInt(originalVal, 10);
}
return val;
})
.default(defaultValue || 3000),
// Number with default
num: (defaultValue?: number, description?: string) =>
z.string().transform((val: string) => parseFloat(val))
.pipe(z.number())
.default(defaultValue?.toString() || '0')
.describe(description || ''),
yup.number()
.transform((val, originalVal) => {
if (typeof originalVal === 'string') {
return parseFloat(originalVal);
}
return val;
})
.default(defaultValue || 0),
// Boolean with default
bool: (defaultValue?: boolean, description?: string) =>
z.string().transform((val: string) => val === 'true' || val === '1')
.default(defaultValue?.toString() || 'false')
.describe(description || ''),
yup.boolean()
.transform((val, originalVal) => {
if (typeof originalVal === 'string') {
return originalVal === 'true' || originalVal === '1';
}
return val;
})
.default(defaultValue || false),
// URL validation
url: (defaultValue?: string, description?: string) =>
z.string().url().default(defaultValue || 'http://localhost')
.describe(description || ''),
yup.string().url().default(defaultValue || 'http://localhost'),
// Email validation
email: (description?: string) =>
z.string().email().describe(description || ''),
yup.string().email(),
};
/**
* Legacy compatibility - creates a cleanEnv-like function
*/
export function cleanEnv<T extends z.ZodRawShape>(
export function cleanEnv(
env: Record<string, string | undefined>,
validators: T
): z.infer<z.ZodObject<T>> {
validators: Record<string, any>
): any {
const schema = createEnvSchema(validators);
return validateEnv(schema, env);
}

View file

@ -1,7 +1,7 @@
/**
* @stock-bot/config
*
* Configuration management library for Stock Bot platform using Zod
* Configuration management library for Stock Bot platform using Yup
*/
// Re-export everything from all modules

View file

@ -1,5 +1,5 @@
/**
* Logging configuration using Zod
* Logging configuration using Yup
* Application logging settings without Loki (Loki config is in monitoring.ts)
*/
import { cleanEnv, envValidators } from './env-utils';

View file

@ -1,5 +1,5 @@
/**
* Loki log aggregation configuration using Zod
* Loki log aggregation configuration using Yup
* Centralized logging configuration for the Stock Bot platform
*/
import { cleanEnv, envValidators } from './env-utils';

View file

@ -1,5 +1,5 @@
/**
* MongoDB configuration using Zod
* MongoDB configuration using Yup
* Document storage for sentiment data, raw documents, and unstructured data
*/
import { cleanEnv, envValidators } from './env-utils';

View file

@ -1,5 +1,5 @@
/**
* Monitoring configuration using Zod
* Monitoring configuration using Yup
* Prometheus metrics, Grafana visualization, and Loki logging
*/
import { cleanEnv, envValidators } from './env-utils';

View file

@ -1,5 +1,5 @@
/**
* PostgreSQL configuration using Zod
* PostgreSQL configuration using Yup
*/
import { cleanEnv, envValidators } from './env-utils';

View file

@ -1,5 +1,5 @@
/**
* QuestDB configuration using Zod
* QuestDB configuration using Yup
* Time-series database for OHLCV data, indicators, and performance metrics
*/
import { cleanEnv, envValidators } from './env-utils';

View file

@ -1,5 +1,5 @@
/**
* Risk management configuration using Zod
* Risk management configuration using Yup
*/
import { cleanEnv, envValidators } from './env-utils';

View file

@ -2,20 +2,9 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"include": ["src/**/*"],
"references": [
{ "path": "../types" }
]

View file

@ -2,31 +2,12 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"include": ["src/**/*"],
"references": [
{ "path": "../types" },
{ "path": "../config" },
{ "path": "../logger" },
{ "path": "../utils" },
{ "path": "../postgres-client" },
{ "path": "../mongodb-client" },
{ "path": "../questdb-client" },
{ "path": "../cache" },
{ "path": "../http" },
{ "path": "../event-bus" },
{ "path": "../shutdown" }
{ "path": "../utils" }
]
}

View file

@ -2,29 +2,12 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"include": ["src/**/*"],
"references": [
{ "path": "../types" },
{ "path": "../config" },
{ "path": "../logger" },
{ "path": "../utils" },
{ "path": "../postgres-client" },
{ "path": "../mongodb-client" },
{ "path": "../questdb-client" },
{ "path": "../cache" },
{ "path": "../http" }
{ "path": "../logger" }
]
}

View file

@ -1,66 +0,0 @@
import axios, { AxiosRequestConfig, type AxiosInstance } from 'axios';
import { SocksProxyAgent } from 'socks-proxy-agent';
import { HttpsProxyAgent } from 'https-proxy-agent';
import { HttpProxyAgent } from 'http-proxy-agent';
import type { ProxyInfo } from './types.js';
export class ProxyManager {
/**
* Determine if we should use Bun fetch (HTTP/HTTPS) or Axios (SOCKS)
*/
static shouldUseBunFetch(proxy: ProxyInfo): boolean {
return proxy.protocol === 'http' || proxy.protocol === 'https';
}
/**
* Create proxy URL for both Bun fetch and Axios proxy agents
*/
static createProxyUrl(proxy: ProxyInfo): string {
const { protocol, host, port, username, password } = proxy;
if (username && password) {
return `${protocol}://${encodeURIComponent(username)}:${encodeURIComponent(password)}@${host}:${port}`;
}
return `${protocol}://${host}:${port}`;
}
/**
* Create appropriate agent for Axios based on proxy type
*/
static createProxyAgent(proxy: ProxyInfo) {
this.validateConfig(proxy);
const proxyUrl = this.createProxyUrl(proxy);
switch (proxy.protocol) {
case 'socks4':
case 'socks5':
// console.log(`Using SOCKS proxy: ${proxyUrl}`);
return new SocksProxyAgent(proxyUrl);
case 'http':
return new HttpProxyAgent(proxyUrl);
case 'https':
return new HttpsProxyAgent(proxyUrl);
default:
throw new Error(`Unsupported proxy protocol: ${proxy.protocol}`);
}
}
/**
* Create Axios instance with proxy configuration
*/
static createAxiosConfig(proxy: ProxyInfo): AxiosRequestConfig {
const agent = this.createProxyAgent(proxy);
return {
httpAgent: agent,
httpsAgent: agent,
};
}
/**
* Simple proxy config validation
*/
static validateConfig(proxy: ProxyInfo): void {
if (!proxy.host || !proxy.port) {
throw new Error('Proxy host and port are required');
}
if (!['http', 'https', 'socks4', 'socks5'].includes(proxy.protocol)) {
throw new Error(`Unsupported proxy protocol: ${proxy.protocol}`);
}
}
}

View file

@ -2,28 +2,11 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"include": ["src/**/*"],
"references": [
{ "path": "../types" },
{ "path": "../config" },
{ "path": "../logger" },
{ "path": "../utils" },
{ "path": "../postgres-client" },
{ "path": "../mongodb-client" },
{ "path": "../questdb-client" },
{ "path": "../cache" }
{ "path": "../logger" }
]
}

View file

@ -2,20 +2,9 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"include": ["src/**/*"],
"references": [
{ "path": "../types" },
{ "path": "../config" }

View file

@ -12,12 +12,11 @@
"type-check": "tsc --noEmit",
"clean": "rimraf dist"
},
"dependencies": {
"@stock-bot/config": "*",
"dependencies": { "@stock-bot/config": "*",
"@stock-bot/logger": "*",
"@stock-bot/types": "*",
"mongodb": "^6.3.0",
"zod": "^3.22.4"
"yup": "^1.6.1"
},
"devDependencies": {
"@types/node": "^20.11.0",

View file

@ -1,4 +1,4 @@
import { z } from 'zod';
import * as yup from 'yup';
/**
* Zod Schemas for MongoDB Document Validation

View file

@ -1,4 +1,4 @@
import { z } from 'zod';
import * as yup from 'yup';
import type { ObjectId } from 'mongodb';
/**

View file

@ -2,23 +2,12 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
], "references": [
"include": ["src/**/*"],
"references": [
{ "path": "../types" },
{ "path": "../config" },
{ "path": "../logger" },
{ "path": "../utils" }
{ "path": "../logger" }
]
}

View file

@ -12,12 +12,11 @@
"type-check": "tsc --noEmit",
"clean": "rimraf dist"
},
"dependencies": {
"@stock-bot/config": "*",
"dependencies": { "@stock-bot/config": "*",
"@stock-bot/logger": "*",
"@stock-bot/types": "*",
"pg": "^8.11.3",
"zod": "^3.22.4"
"yup": "^1.6.1"
},
"devDependencies": {
"@types/node": "^20.11.0",

View file

@ -2,23 +2,12 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
], "references": [
"include": ["src/**/*"],
"references": [
{ "path": "../types" },
{ "path": "../config" },
{ "path": "../logger" },
{ "path": "../utils" }
{ "path": "../logger" }
]
}

View file

@ -2,23 +2,12 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
], "references": [
"include": ["src/**/*"],
"references": [
{ "path": "../types" },
{ "path": "../config" },
{ "path": "../logger" },
{ "path": "../utils" }
{ "path": "../logger" }
]
}

View file

@ -2,30 +2,12 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"include": ["src/**/*"],
"references": [
{ "path": "../types" },
{ "path": "../config" },
{ "path": "../logger" },
{ "path": "../utils" },
{ "path": "../postgres-client" },
{ "path": "../mongodb-client" },
{ "path": "../questdb-client" },
{ "path": "../cache" },
{ "path": "../http" },
{ "path": "../event-bus" }
{ "path": "../logger" }
]
}

View file

@ -2,32 +2,13 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"references": [
"include": ["src/**/*"], "references": [
{ "path": "../types" },
{ "path": "../config" },
{ "path": "../logger" },
{ "path": "../utils" },
{ "path": "../postgres-client" },
{ "path": "../mongodb-client" },
{ "path": "../questdb-client" },
{ "path": "../cache" },
{ "path": "../http" },
{ "path": "../event-bus" },
{ "path": "../shutdown" },
{ "path": "../data-frame" },
{ "path": "../vector-engine" }
]

View file

@ -2,19 +2,8 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"include": ["src/**/*"],
"references": []
}

View file

@ -2,20 +2,9 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"include": ["src/**/*"],
"references": [
{ "path": "../types" },
{ "path": "../config" },

View file

@ -2,32 +2,13 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": false
"rootDir": "./src"
},
"include": [
"src/**/*"
],
"exclude": [
"dist",
"node_modules",
"**/*.test.ts",
"**/*.spec.ts"
],
"include": ["src/**/*"],
"references": [
{ "path": "../types" },
{ "path": "../config" },
{ "path": "../logger" },
{ "path": "../utils" },
{ "path": "../postgres-client" },
{ "path": "../mongodb-client" },
{ "path": "../questdb-client" },
{ "path": "../cache" },
{ "path": "../http" },
{ "path": "../event-bus" },
{ "path": "../shutdown" },
{ "path": "../data-frame" }
]
}

View file

@ -52,13 +52,14 @@
"@types/bun": "latest",
"@types/node": "^20.12.12",
"@types/supertest": "^6.0.2",
"@types/yup": "^0.32.0",
"bun-types": "^1.2.15",
"mongodb-memory-server": "^9.1.6",
"pg-mem": "^2.8.1",
"supertest": "^6.3.4",
"turbo": "^2.5.4",
"typescript": "^5.4.5",
"zod": "^3.25.56"
"typescript": "^5.8.3",
"yup": "^1.6.1"
},
"packageManager": "bun@1.1.12",
"engines": {
@ -66,9 +67,7 @@
"bun": ">=1.1.0"
},
"dependencies": {
"bullmq": "^5.53.2",
"envalid": "^8.0.0",
"valibot": "^1.1.0"
"bullmq": "^5.53.2"
},
"trustedDependencies": []
}

64
scripts/build-clean.ps1 Normal file
View file

@ -0,0 +1,64 @@
param(
[switch]$force
)
Write-Host "=== Clean Build Process ===" -ForegroundColor Green
# Step 1: Clean everything
Write-Host "Step 1: Cleaning build artifacts..." -ForegroundColor Yellow
& ".\scripts\clean.ps1" -dist -force
# Step 2: Install dependencies
Write-Host "Step 2: Installing dependencies..." -ForegroundColor Yellow
bun install
# Step 3: Build libraries in dependency order
Write-Host "Step 3: Building libraries..." -ForegroundColor Yellow
$libraries = @(
"types",
"config",
"logger",
"utils",
"postgres-client",
"mongodb-client",
"questdb-client",
"cache",
"http",
"event-bus",
"shutdown",
"data-frame",
"vector-engine",
"strategy-engine",
"data-adjustments"
)
foreach ($lib in $libraries) {
$libPath = "libs\$lib"
if (Test-Path $libPath) {
Write-Host "Building $lib..." -ForegroundColor Blue
Set-Location $libPath
bun run build
if ($LASTEXITCODE -ne 0) {
Write-Host "Failed to build $lib" -ForegroundColor Red
Set-Location "..\..\"
exit 1
}
Set-Location "..\..\"
Write-Host "$lib built successfully" -ForegroundColor Green
} else {
Write-Host "⚠ Library $lib not found, skipping..." -ForegroundColor Yellow
}
}
# Step 4: Build applications
Write-Host "Step 4: Building applications..." -ForegroundColor Yellow
turbo run build --filter='./apps/*'
if ($LASTEXITCODE -ne 0) {
Write-Host "Failed to build applications" -ForegroundColor Red
exit 1
}
Write-Host "=== Clean Build Complete! ===" -ForegroundColor Green
Write-Host "All packages built successfully" -ForegroundColor Blue

View file

@ -8,10 +8,9 @@ $libs = @(
"config", # Configuration - depends on types
"logger", # Logging utilities - depends on types
"utils", # Utilities - depends on types and config
# Database clients
# Database clients
"postgres-client", # PostgreSQL client - depends on types, config, logger
"mongodb-client", # MongoDB client - depends on types, config, logger
# "mongodb-client", # MongoDB client - depends on types, config, logger (temporarily disabled - needs zod->yup conversion)
"questdb-client", # QuestDB client - depends on types, config, logger
# Service libraries

94
scripts/verify-build.ps1 Normal file
View file

@ -0,0 +1,94 @@
param(
[switch]$verbose
)
Write-Host "=== Verifying Build Health ===" -ForegroundColor Green
$errors = @()
$warnings = @()
# Check for common build issues
Write-Host "Checking for common build issues..." -ForegroundColor Yellow
# Check for mismatched .d.ts files in source directories
Write-Host "Checking for .d.ts files in source directories..." -ForegroundColor Blue
$sourceDtsFiles = Get-ChildItem -Path ".\libs\*\src\**\*.d.ts" -Recurse -ErrorAction SilentlyContinue
if ($sourceDtsFiles.Count -gt 0) {
$warnings += "Found .d.ts files in source directories:"
foreach ($file in $sourceDtsFiles) {
$warnings += " - $($file.FullName)"
}
}
# Check for missing dist directories after build
Write-Host "Checking for missing dist directories..." -ForegroundColor Blue
$libraries = @("types", "config", "logger", "utils", "cache", "http")
foreach ($lib in $libraries) {
$distPath = "libs\$lib\dist"
if (-not (Test-Path $distPath)) {
$errors += "Missing dist directory for $lib"
} else {
$indexFile = "$distPath\index.js"
if (-not (Test-Path $indexFile)) {
$errors += "Missing index.js in $lib dist directory"
}
}
}
# Check for stale tsbuildinfo files
Write-Host "Checking for stale tsbuildinfo files..." -ForegroundColor Blue
$tsbuildFiles = Get-ChildItem -Path ".\**\*.tsbuildinfo" -Recurse -ErrorAction SilentlyContinue
if ($tsbuildFiles.Count -gt 0) {
$warnings += "Found stale .tsbuildinfo files:"
foreach ($file in $tsbuildFiles) {
$warnings += " - $($file.FullName)"
}
}
# Check package.json dependencies
Write-Host "Checking package.json files..." -ForegroundColor Blue
$packageFiles = Get-ChildItem -Path ".\**\package.json" -Recurse -ErrorAction SilentlyContinue
foreach ($packageFile in $packageFiles) {
try {
$packageContent = Get-Content $packageFile.FullName | ConvertFrom-Json
if (-not $packageContent.name) {
$errors += "Package.json missing name: $($packageFile.FullName)"
}
if (-not $packageContent.version) {
$warnings += "Package.json missing version: $($packageFile.FullName)"
}
} catch {
$errors += "Invalid package.json: $($packageFile.FullName)"
}
}
# Report results
Write-Host "`n=== Build Health Report ===" -ForegroundColor Green
if ($errors.Count -gt 0) {
Write-Host "❌ ERRORS FOUND:" -ForegroundColor Red
foreach ($error in $errors) {
Write-Host " $error" -ForegroundColor Red
}
}
if ($warnings.Count -gt 0) {
Write-Host "⚠ WARNINGS:" -ForegroundColor Yellow
foreach ($warning in $warnings) {
Write-Host " $warning" -ForegroundColor Yellow
}
}
if ($errors.Count -eq 0 -and $warnings.Count -eq 0) {
Write-Host "✅ No issues found - build environment is healthy!" -ForegroundColor Green
} elseif ($errors.Count -eq 0) {
Write-Host "✅ No critical errors found (only warnings)" -ForegroundColor Green
} else {
Write-Host "❌ Critical errors found - build may fail" -ForegroundColor Red
exit 1
}
Write-Host "`nRecommended commands:" -ForegroundColor Cyan
Write-Host " Clean build: bun run reset" -ForegroundColor Gray
Write-Host " Quick build: bun run build" -ForegroundColor Gray
Write-Host " Clean only: bun run clean:dist" -ForegroundColor Gray

View file

@ -1,17 +1,19 @@
{
"$schema": "https://turbo.build/schema.json",
"ui": "tui",
"globalDependencies": ["**/.env.*local"],
"tasks": {
"globalDependencies": ["**/.env.*local"], "tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"]
"outputs": ["dist/**", ".next/**", "!.next/cache/**"],
"inputs": ["src/**", "package.json", "tsconfig.json"]
},
"build:libs": {
"dependsOn": [],
"outputs": ["dist/**"]
"outputs": ["dist/**"],
"inputs": ["src/**", "package.json", "tsconfig.json"]
},
"dev": {
"dependsOn": ["^build"],
"cache": false,
"persistent": true
},