import fs from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const rootDir = path.resolve(__dirname, '..', '..') const read = relativePath => fs.readFileSync(path.join(rootDir, relativePath), 'utf-8') const files = { manager: 'scripts/influxdb-process-manager.js', mysqlManager: 'scripts/mysql-process-manager.js', javaRunner: 'scripts/java-runner.js', lifecycle: 'electron/preload/lifecycle.js', configGenerator: 'scripts/config-generator.js', javaTemplate: 'build/extraResources/java/application.yml.template', influxdbBat: 'build/extraResources/influxdb-1.7.0/start-influxdb.bat', startup: 'scripts/startup-manager.js', builder: 'cmd/builder.json' } const failures = [] if (!fs.existsSync(path.join(rootDir, files.manager))) { failures.push('scripts/influxdb-process-manager.js should exist') } else { const source = read(files.manager) const checks = [ ['manager exports InfluxDBProcessManager', /module\.exports\s*=\s*InfluxDBProcessManager/.test(source)], ['manager starts InfluxDB through cmd.exe and start-influxdb.bat', /cmd\.exe/.test(source) && /start-influxdb\.bat/.test(source) && /spawn\(/.test(source)], ['manager records process ownership', /\.running-process\.json/.test(source)], ['manager can stop tracked process', /stopInfluxDBProcess/.test(source) && /terminateTrackedProcess/.test(source)] ] checks.forEach(([message, pass]) => { if (!pass) failures.push(message) }) } const lifecycleSource = read(files.lifecycle) const configGeneratorSource = read(files.configGenerator) const runtimePathSources = [ ['InfluxDB process manager', read(files.manager)], ['MySQL process manager', read(files.mysqlManager)], ['Java runner', read(files.javaRunner)], ['config generator', configGeneratorSource] ] const javaTemplateSource = read(files.javaTemplate) const startupSource = read(files.startup) const builderSource = read(files.builder) const influxdbBatSource = read(files.influxdbBat) const lifecycleChecks = [ ['lifecycle loads InfluxDBProcessManager', /InfluxDBProcessManager/.test(lifecycleSource)], ['lifecycle stores influxdbProcessManager', /this\.influxdbProcessManager/.test(lifecycleSource)], [ 'lifecycle starts InfluxDB after MySQL before Java port detection', /ensureServiceRunning\([\s\S]*?this\.influxdbPort\s*=\s*await\s*this\.influxdbProcessManager\.ensureServiceRunning[\s\S]*?findAvailablePort\(18093/.test( lifecycleSource ) ], ['lifecycle passes influxdbPort to config generator', /influxdbPort:\s*this\.influxdbPort/.test(lifecycleSource)], ['lifecycle stops InfluxDB during cleanup', /stopInfluxDBProcess/.test(lifecycleSource)] ] const startupChecks = [ ['startup has InfluxDB port step', /check-influxdb-port/.test(startupSource)], ['startup has InfluxDB wait step', /wait-influxdb/.test(startupSource)] ] const packageChecks = [ ['windows package includes InfluxDB resources', /build\/extraResources\/influxdb-1\.7\.0/.test(builderSource)] ] const configChecks = [ ['config generator replaces InfluxDB port placeholder', /INFLUXDB_PORT/.test(configGeneratorSource)], ['java template defines steady InfluxDB url placeholder', /steady:[\s\S]*influxdb:[\s\S]*url:\s*http:\/\/127\.0\.0\.1:\{\{INFLUXDB_PORT\}\}/.test(javaTemplateSource)], ['InfluxDB bat accepts runtime config path argument', /%~1/.test(influxdbBatSource) && /influxd\.exe\s+-config\s+/.test(influxdbBatSource)] ] const runtimePathChecks = runtimePathSources.map(([name, source]) => [ `${name} should not treat any process.resourcesPath as packaged runtime`, !/!\s*process\.resourcesPath/.test(source) ]) ;[...lifecycleChecks, ...startupChecks, ...configChecks, ...runtimePathChecks, ...packageChecks].forEach(([message, pass]) => { if (!pass) failures.push(message) }) if (failures.length > 0) { console.error(`InfluxDB startup contract failed:\n- ${failures.join('\n- ')}`) process.exit(1) } console.log('InfluxDB startup contract passed')