diff --git a/database/package.json b/database/package.json index 47af20975..ed4115b78 100644 --- a/database/package.json +++ b/database/package.json @@ -13,10 +13,14 @@ "up": "cross-env TZ=UTC node build/src/index.js up", "down": "cross-env TZ=UTC node build/src/index.js down", "reset": "cross-env TZ=UTC node build/src/index.js reset", - "dev_up": "cross-env TZ=UTC ts-node src/index.ts up", - "dev_down": "cross-env TZ=UTC ts-node src/index.ts down", - "dev_reset": "cross-env TZ=UTC ts-node src/index.ts reset", - "lint": "eslint --max-warnings=0 --ext .js,.ts ." + "clear": "cross-env TZ=UTC tsx src/index.ts clear", + "dev_up": "cross-env TZ=UTC tsx src/index.ts up", + "dev_down": "cross-env TZ=UTC tsx src/index.ts down", + "dev_reset": "cross-env TZ=UTC tsx src/index.ts reset", + "lint": "eslint --max-warnings=0 --ext .js,.ts .", + "up:backend_test": "cross-env TZ=UTC DB_DATABASE=gradido_test_backend tsx src/index.ts up", + "up:federation_test": "cross-env TZ=UTC DB_DATABASE=gradido_test_federation tsx src/index.ts up", + "up:dht_test": "cross-env TZ=UTC DB_DATABASE=gradido_test_dht tsx src/index.ts up" }, "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "^3.2.1", @@ -38,6 +42,7 @@ "ncp": "^2.0.0", "prettier": "^2.8.7", "ts-node": "^10.9.2", + "tsx": "^4.19.3", "typescript": "^4.9.5" }, "dependencies": { diff --git a/database/src/clear.ts b/database/src/clear.ts new file mode 100644 index 000000000..67b456c98 --- /dev/null +++ b/database/src/clear.ts @@ -0,0 +1,55 @@ +/* eslint-disable no-console */ +import { Connection, createConnection } from 'mysql2/promise' +import { CONFIG } from './config' + +export async function truncateTables(connection: Connection) { + const [tables] = await connection.query('SHOW TABLES') + const tableNames = (tables as any[]).map((table) => Object.values(table)[0]) + + if (tableNames.length === 0) { + // No tables found in database. + return + } + + // Disabling foreign key checks... + await connection.query('SET FOREIGN_KEY_CHECKS = 0') + + // Truncating all tables... + for (const tableName of tableNames) { + if (tableName === CONFIG.MIGRATIONS_TABLE) { + continue + } + await connection.query(`TRUNCATE TABLE \`${tableName}\``) + } + + // Re-enabling foreign key checks... + await connection.query('SET FOREIGN_KEY_CHECKS = 1') +} + +export async function clearDatabase() { + const connection = await createConnection({ + host: CONFIG.DB_HOST, + port: CONFIG.DB_PORT, + user: CONFIG.DB_USER, + password: CONFIG.DB_PASSWORD, + database: CONFIG.DB_DATABASE, + }) + + await truncateTables(connection) + + // Database cleared successfully. + await connection.end() +} + +// Execute if this file is run directly +if (require.main === module) { + clearDatabase() + .then(() => { + // Database clear operation completed. + process.exit(0) + }) + .catch((error) => { + console.error('Failed to clear database:', error) + process.exit(1) + }) +} diff --git a/database/src/config/index.ts b/database/src/config/index.ts index 0fc8cf9c5..1a5fb08ed 100644 --- a/database/src/config/index.ts +++ b/database/src/config/index.ts @@ -24,6 +24,8 @@ const migrations = { MIGRATIONS_TABLE: process.env.MIGRATIONS_TABLE || 'migrations', } +const nodeEnv = process.env.NODE_ENV || 'development' + // Check config version constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION || constants.CONFIG_VERSION.DEFAULT if ( @@ -36,4 +38,4 @@ if ( ) } -export const CONFIG = { ...constants, ...database, ...migrations } +export const CONFIG = { ...constants, ...database, ...migrations, NODE_ENV: nodeEnv } diff --git a/database/src/index.ts b/database/src/index.ts index 96785a721..86ac05c79 100644 --- a/database/src/index.ts +++ b/database/src/index.ts @@ -1,14 +1,43 @@ -import { createDatabase } from './prepare' +import { DatabaseState, getDatabaseState } from './prepare' import { CONFIG } from './config' import { createPool } from 'mysql' import { Migration } from 'ts-mysql-migrate' +import { clearDatabase } from './clear' +import { latestDbVersion } from './config/detectLastDBVersion' import path from 'path' const run = async (command: string) => { + if (command === 'clear') { + if (CONFIG.NODE_ENV === 'production') { + throw new Error('Clearing database in production is not allowed') + } + await clearDatabase() + return + } // Database actions not supported by our migration library - await createDatabase() - + // await createDatabase() + const state = await getDatabaseState() + if (state === DatabaseState.NOT_CONNECTED) { + throw new Error( + `Database not connected, is database server running? + host: ${CONFIG.DB_HOST} + port: ${CONFIG.DB_PORT} + user: ${CONFIG.DB_USER} + password: ${CONFIG.DB_PASSWORD.slice(-2)} + database: ${CONFIG.DB_DATABASE}`, + ) + } + if (state === DatabaseState.HIGHER_VERSION) { + throw new Error('Database version is higher than required, please switch to the correct branch') + } + if (state === DatabaseState.SAME_VERSION) { + if (command === 'up') { + // eslint-disable-next-line no-console + console.log('Database is up to date') + return + } + } // Initialize Migrations const pool = createPool({ host: CONFIG.DB_HOST, @@ -34,12 +63,29 @@ const run = async (command: string) => { await migration.down() // use for downgrade script break case 'reset': - // TODO protect from production + if (CONFIG.NODE_ENV === 'production') { + throw new Error('Resetting database in production is not allowed') + } await migration.reset() break default: throw new Error(`Unsupported command ${command}`) } + if (command === 'reset') { + // eslint-disable-next-line no-console + console.log('Database was reset') + } else { + const currentDbVersion = await migration.getLastVersion() + // eslint-disable-next-line no-console + console.log(`Database was ${command} migrated to version: ${currentDbVersion.fileName}`) + if (latestDbVersion === currentDbVersion.fileName.split('.')[0]) { + // eslint-disable-next-line no-console + console.log('Database is now up to date') + } else { + // eslint-disable-next-line no-console + console.log('The latest database version is: ', latestDbVersion) + } + } // Terminate connections gracefully pool.end() diff --git a/database/src/prepare.ts b/database/src/prepare.ts index 2ecbb4c42..ee60fc496 100644 --- a/database/src/prepare.ts +++ b/database/src/prepare.ts @@ -1,38 +1,64 @@ -import { createConnection } from 'mysql2/promise' +/* eslint-disable no-unused-vars */ +import { Connection, createConnection, ResultSetHeader, RowDataPacket } from 'mysql2/promise' import { CONFIG } from './config' +import { latestDbVersion } from './config/detectLastDBVersion' -export const createDatabase = async (): Promise => { - const con = await createConnection({ - host: CONFIG.DB_HOST, - port: CONFIG.DB_PORT, - user: CONFIG.DB_USER, - password: CONFIG.DB_PASSWORD, - }) +export enum DatabaseState { + NOT_CONNECTED = 'NOT_CONNECTED', + LOWER_VERSION = 'LOWER_VERSION', + HIGHER_VERSION = 'HIGHER_VERSION', + SAME_VERSION = 'SAME_VERSION', +} - await con.connect() +async function connectToDatabaseServer(): Promise { + try { + return await createConnection({ + host: CONFIG.DB_HOST, + port: CONFIG.DB_PORT, + user: CONFIG.DB_USER, + password: CONFIG.DB_PASSWORD, + }) + } catch (error) { + return null + } +} - // Create Database `gradido_community` - await con.query(` - CREATE DATABASE IF NOT EXISTS ${CONFIG.DB_DATABASE} +export const getDatabaseState = async (): Promise => { + const connection = await connectToDatabaseServer() + if (!connection) { + return DatabaseState.NOT_CONNECTED + } + + // make sure the database exists + const [result] = await connection.query(` + CREATE DATABASE IF NOT EXISTS ${CONFIG.DB_DATABASE} DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci;`) - /* LEGACY CODE - import { RowDataPacket } from 'mysql2/promise' - // Check if old migration table is present, delete if needed - const [rows] = await con.query(`SHOW TABLES FROM \`${CONFIG.DB_DATABASE}\` LIKE 'migrations';`) - if ((rows).length > 0) { - const [rows] = await con.query( - `SHOW COLUMNS FROM \`${CONFIG.DB_DATABASE}\`.\`migrations\` LIKE 'db_version';`, - ) - if ((rows).length > 0) { - await con.query(`DROP TABLE \`${CONFIG.DB_DATABASE}\`.\`migrations\``) - // eslint-disable-next-line no-console - console.log('Found and dropped old migrations table') - } + if (result.affectedRows === 1) { + // eslint-disable-next-line no-console + console.log(`Database ${CONFIG.DB_DATABASE} created`) + return DatabaseState.LOWER_VERSION } - */ - await con.end() + await connection.query(`USE ${CONFIG.DB_DATABASE}`) + try { + // check if the database is up to date + const [rows] = await connection.query( + `SELECT * FROM ${CONFIG.MIGRATIONS_TABLE} ORDER BY version DESC LIMIT 1`, + ) + if (rows.length === 0) { + return DatabaseState.LOWER_VERSION + } + connection.destroy() + const dbVersion = rows[0].fileName.split('.')[0] + return dbVersion === latestDbVersion + ? DatabaseState.SAME_VERSION + : dbVersion < latestDbVersion + ? DatabaseState.LOWER_VERSION + : DatabaseState.HIGHER_VERSION + } catch (error) { + return DatabaseState.LOWER_VERSION + } } diff --git a/database/yarn.lock b/database/yarn.lock index 491470016..c07fbe5a1 100644 --- a/database/yarn.lock +++ b/database/yarn.lock @@ -16,6 +16,131 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@esbuild/aix-ppc64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz#014180d9a149cffd95aaeead37179433f5ea5437" + integrity sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ== + +"@esbuild/android-arm64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.3.tgz#649e47e04ddb24a27dc05c395724bc5f4c55cbfe" + integrity sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ== + +"@esbuild/android-arm@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.3.tgz#8a0f719c8dc28a4a6567ef7328c36ea85f568ff4" + integrity sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A== + +"@esbuild/android-x64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.3.tgz#e2ab182d1fd06da9bef0784a13c28a7602d78009" + integrity sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ== + +"@esbuild/darwin-arm64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.3.tgz#c7f3166fcece4d158a73dcfe71b2672ca0b1668b" + integrity sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w== + +"@esbuild/darwin-x64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.3.tgz#d8c5342ec1a4bf4b1915643dfe031ba4b173a87a" + integrity sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A== + +"@esbuild/freebsd-arm64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.3.tgz#9f7d789e2eb7747d4868817417cc968ffa84f35b" + integrity sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw== + +"@esbuild/freebsd-x64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.3.tgz#8ad35c51d084184a8e9e76bb4356e95350a64709" + integrity sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q== + +"@esbuild/linux-arm64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.3.tgz#3af0da3d9186092a9edd4e28fa342f57d9e3cd30" + integrity sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A== + +"@esbuild/linux-arm@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.3.tgz#e91cafa95e4474b3ae3d54da12e006b782e57225" + integrity sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ== + +"@esbuild/linux-ia32@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.3.tgz#81025732d85b68ee510161b94acdf7e3007ea177" + integrity sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw== + +"@esbuild/linux-loong64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.3.tgz#3c744e4c8d5e1148cbe60a71a11b58ed8ee5deb8" + integrity sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g== + +"@esbuild/linux-mips64el@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.3.tgz#1dfe2a5d63702db9034cc6b10b3087cc0424ec26" + integrity sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag== + +"@esbuild/linux-ppc64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.3.tgz#2e85d9764c04a1ebb346dc0813ea05952c9a5c56" + integrity sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg== + +"@esbuild/linux-riscv64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.3.tgz#a9ea3334556b09f85ccbfead58c803d305092415" + integrity sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA== + +"@esbuild/linux-s390x@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.3.tgz#f6a7cb67969222b200974de58f105dfe8e99448d" + integrity sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ== + +"@esbuild/linux-x64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.3.tgz#a237d3578ecdd184a3066b1f425e314ade0f8033" + integrity sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA== + +"@esbuild/netbsd-arm64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.3.tgz#4c15c68d8149614ddb6a56f9c85ae62ccca08259" + integrity sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA== + +"@esbuild/netbsd-x64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.3.tgz#12f6856f8c54c2d7d0a8a64a9711c01a743878d5" + integrity sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g== + +"@esbuild/openbsd-arm64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.3.tgz#ca078dad4a34df192c60233b058db2ca3d94bc5c" + integrity sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ== + +"@esbuild/openbsd-x64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.3.tgz#c9178adb60e140e03a881d0791248489c79f95b2" + integrity sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w== + +"@esbuild/sunos-x64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.3.tgz#03765eb6d4214ff27e5230af779e80790d1ee09f" + integrity sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA== + +"@esbuild/win32-arm64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.3.tgz#f1c867bd1730a9b8dfc461785ec6462e349411ea" + integrity sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ== + +"@esbuild/win32-ia32@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.3.tgz#77491f59ef6c9ddf41df70670d5678beb3acc322" + integrity sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew== + +"@esbuild/win32-x64@0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz#b17a2171f9074df9e91bfb07ef99a892ac06412a" + integrity sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg== + "@eslint-community/eslint-plugin-eslint-comments@^3.2.1": version "3.2.1" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.1.tgz#3c65061e27f155eae3744c3b30c5a8253a959040" @@ -763,6 +888,37 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +esbuild@~0.25.0: + version "0.25.3" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.3.tgz#371f7cb41283e5b2191a96047a7a89562965a285" + integrity sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q== + optionalDependencies: + "@esbuild/aix-ppc64" "0.25.3" + "@esbuild/android-arm" "0.25.3" + "@esbuild/android-arm64" "0.25.3" + "@esbuild/android-x64" "0.25.3" + "@esbuild/darwin-arm64" "0.25.3" + "@esbuild/darwin-x64" "0.25.3" + "@esbuild/freebsd-arm64" "0.25.3" + "@esbuild/freebsd-x64" "0.25.3" + "@esbuild/linux-arm" "0.25.3" + "@esbuild/linux-arm64" "0.25.3" + "@esbuild/linux-ia32" "0.25.3" + "@esbuild/linux-loong64" "0.25.3" + "@esbuild/linux-mips64el" "0.25.3" + "@esbuild/linux-ppc64" "0.25.3" + "@esbuild/linux-riscv64" "0.25.3" + "@esbuild/linux-s390x" "0.25.3" + "@esbuild/linux-x64" "0.25.3" + "@esbuild/netbsd-arm64" "0.25.3" + "@esbuild/netbsd-x64" "0.25.3" + "@esbuild/openbsd-arm64" "0.25.3" + "@esbuild/openbsd-x64" "0.25.3" + "@esbuild/sunos-x64" "0.25.3" + "@esbuild/win32-arm64" "0.25.3" + "@esbuild/win32-ia32" "0.25.3" + "@esbuild/win32-x64" "0.25.3" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -1123,6 +1279,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -1199,6 +1360,13 @@ get-tsconfig@^4.5.0: dependencies: resolve-pkg-maps "^1.0.0" +get-tsconfig@^4.7.5: + version "4.10.0" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.10.0.tgz#403a682b373a823612475a4c2928c7326fc0f6bb" + integrity sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A== + dependencies: + resolve-pkg-maps "^1.0.0" + glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -2412,6 +2580,16 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tsx@^4.19.3: + version "4.19.3" + resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.19.3.tgz#2bdbcb87089374d933596f8645615142ed727666" + integrity sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ== + dependencies: + esbuild "~0.25.0" + get-tsconfig "^4.7.5" + optionalDependencies: + fsevents "~2.3.3" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"