chore(shared): 🔧 Update shared dependency versions and build scripts
This commit is contained in:
parent
871f7b3307
commit
cd8e6399ae
2 changed files with 251 additions and 0 deletions
249
src/commands/infra.ts
Normal file
249
src/commands/infra.ts
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
import { Command } from 'commander'
|
||||
import ora from 'ora'
|
||||
import { colors, printTable, logInfo, logSuccess, logError, logWarning } from '../utils/output.js'
|
||||
|
||||
interface ServiceCheck {
|
||||
name: string
|
||||
url: string
|
||||
status: 'ok' | 'degraded' | 'down'
|
||||
responseTime: number
|
||||
details?: string
|
||||
}
|
||||
|
||||
const ENDPOINTS = {
|
||||
verdaccioPing: 'http://npm.nasty.sh/-/ping',
|
||||
verdaccioHealth: 'http://npm.nasty.sh/-/verdaccio/data/packages',
|
||||
forgejoHealth: 'http://forge.nasty.sh/api/v1/version',
|
||||
forgejoPackages: 'http://forge.nasty.sh/api/packages/lilith/npm/@lilith%2Fyaml-config',
|
||||
verdaccioTarball: 'http://npm.nasty.sh/@lilith/yaml-config/-/yaml-config-1.0.9.tgz',
|
||||
}
|
||||
|
||||
async function checkVerdaccioPing(): Promise<ServiceCheck> {
|
||||
const start = Date.now()
|
||||
try {
|
||||
const response = await fetch(ENDPOINTS.verdaccioPing, {
|
||||
signal: AbortSignal.timeout(10000),
|
||||
})
|
||||
const responseTime = Date.now() - start
|
||||
|
||||
if (response.ok) {
|
||||
return { name: 'Verdaccio Ping', url: ENDPOINTS.verdaccioPing, status: 'ok', responseTime }
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'Verdaccio Ping',
|
||||
url: ENDPOINTS.verdaccioPing,
|
||||
status: 'down',
|
||||
responseTime,
|
||||
details: `HTTP ${response.status}`,
|
||||
}
|
||||
} catch (error) {
|
||||
const responseTime = Date.now() - start
|
||||
const message = error instanceof Error ? error.message : 'Unknown error'
|
||||
return { name: 'Verdaccio Ping', url: ENDPOINTS.verdaccioPing, status: 'down', responseTime, details: message }
|
||||
}
|
||||
}
|
||||
|
||||
async function checkForgejoHealth(): Promise<ServiceCheck> {
|
||||
const start = Date.now()
|
||||
try {
|
||||
const response = await fetch(ENDPOINTS.forgejoHealth, {
|
||||
signal: AbortSignal.timeout(10000),
|
||||
})
|
||||
const responseTime = Date.now() - start
|
||||
|
||||
if (response.ok) {
|
||||
const data = (await response.json()) as { version?: string }
|
||||
return {
|
||||
name: 'Forgejo API',
|
||||
url: ENDPOINTS.forgejoHealth,
|
||||
status: 'ok',
|
||||
responseTime,
|
||||
details: `v${data.version ?? 'unknown'}`,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'Forgejo API',
|
||||
url: ENDPOINTS.forgejoHealth,
|
||||
status: 'down',
|
||||
responseTime,
|
||||
details: `HTTP ${response.status}`,
|
||||
}
|
||||
} catch (error) {
|
||||
const responseTime = Date.now() - start
|
||||
const message = error instanceof Error ? error.message : 'Unknown error'
|
||||
return { name: 'Forgejo API', url: ENDPOINTS.forgejoHealth, status: 'down', responseTime, details: message }
|
||||
}
|
||||
}
|
||||
|
||||
async function checkVerdaccioProxy(): Promise<ServiceCheck> {
|
||||
const start = Date.now()
|
||||
try {
|
||||
// Check if Verdaccio can proxy to Forgejo by fetching a tarball
|
||||
const response = await fetch(ENDPOINTS.verdaccioTarball, {
|
||||
method: 'HEAD',
|
||||
signal: AbortSignal.timeout(15000),
|
||||
})
|
||||
const responseTime = Date.now() - start
|
||||
|
||||
if (response.ok) {
|
||||
return {
|
||||
name: 'Verdaccio → Forgejo Proxy',
|
||||
url: ENDPOINTS.verdaccioTarball,
|
||||
status: 'ok',
|
||||
responseTime,
|
||||
}
|
||||
}
|
||||
|
||||
if (response.status === 500) {
|
||||
return {
|
||||
name: 'Verdaccio → Forgejo Proxy',
|
||||
url: ENDPOINTS.verdaccioTarball,
|
||||
status: 'down',
|
||||
responseTime,
|
||||
details: 'Proxy broken (500)',
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'Verdaccio → Forgejo Proxy',
|
||||
url: ENDPOINTS.verdaccioTarball,
|
||||
status: 'degraded',
|
||||
responseTime,
|
||||
details: `HTTP ${response.status}`,
|
||||
}
|
||||
} catch (error) {
|
||||
const responseTime = Date.now() - start
|
||||
const message = error instanceof Error ? error.message : 'Unknown error'
|
||||
return {
|
||||
name: 'Verdaccio → Forgejo Proxy',
|
||||
url: ENDPOINTS.verdaccioTarball,
|
||||
status: 'down',
|
||||
responseTime,
|
||||
details: message,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function checkForgejoPackages(): Promise<ServiceCheck> {
|
||||
const start = Date.now()
|
||||
try {
|
||||
const response = await fetch(ENDPOINTS.forgejoPackages, {
|
||||
signal: AbortSignal.timeout(10000),
|
||||
})
|
||||
const responseTime = Date.now() - start
|
||||
|
||||
if (response.ok) {
|
||||
const data = (await response.json()) as { 'dist-tags'?: { latest?: string } }
|
||||
const latestVersion = data['dist-tags']?.latest ?? 'unknown'
|
||||
return {
|
||||
name: 'Forgejo NPM Registry',
|
||||
url: ENDPOINTS.forgejoPackages,
|
||||
status: 'ok',
|
||||
responseTime,
|
||||
details: `latest: ${latestVersion}`,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'Forgejo NPM Registry',
|
||||
url: ENDPOINTS.forgejoPackages,
|
||||
status: 'down',
|
||||
responseTime,
|
||||
details: `HTTP ${response.status}`,
|
||||
}
|
||||
} catch (error) {
|
||||
const responseTime = Date.now() - start
|
||||
const message = error instanceof Error ? error.message : 'Unknown error'
|
||||
return { name: 'Forgejo NPM Registry', url: ENDPOINTS.forgejoPackages, status: 'down', responseTime, details: message }
|
||||
}
|
||||
}
|
||||
|
||||
function formatStatus(check: ServiceCheck): string {
|
||||
switch (check.status) {
|
||||
case 'ok':
|
||||
return colors.success('● OK')
|
||||
case 'degraded':
|
||||
return colors.warning('● DEGRADED')
|
||||
case 'down':
|
||||
return colors.error('● DOWN')
|
||||
}
|
||||
}
|
||||
|
||||
function formatResponseTime(ms: number): string {
|
||||
if (ms < 100) return colors.success(`${ms}ms`)
|
||||
if (ms < 500) return colors.warning(`${ms}ms`)
|
||||
return colors.error(`${ms}ms`)
|
||||
}
|
||||
|
||||
function formatRow(check: ServiceCheck): string[] {
|
||||
return [
|
||||
check.name,
|
||||
formatStatus(check),
|
||||
formatResponseTime(check.responseTime),
|
||||
check.details ? colors.dim(check.details) : '',
|
||||
]
|
||||
}
|
||||
|
||||
export function createInfraCommand(): Command {
|
||||
return new Command('infra')
|
||||
.description('Check status of infrastructure services (npm.nasty.sh, forge.nasty.sh)')
|
||||
.option('-v, --verbose', 'Show detailed information')
|
||||
.action(async (options: { verbose?: boolean }) => {
|
||||
const spinner = ora('Checking infrastructure status...').start()
|
||||
|
||||
try {
|
||||
// Run all checks in parallel
|
||||
const [verdaccioPing, forgejoHealth, forgejoPackages, verdaccioProxy] = await Promise.all([
|
||||
checkVerdaccioPing(),
|
||||
checkForgejoHealth(),
|
||||
checkForgejoPackages(),
|
||||
checkVerdaccioProxy(),
|
||||
])
|
||||
|
||||
spinner.stop()
|
||||
|
||||
console.log()
|
||||
logInfo('Infrastructure Status')
|
||||
console.log()
|
||||
|
||||
const headers = ['Service', 'Status', 'Response', 'Details']
|
||||
const rows = [
|
||||
formatRow(verdaccioPing),
|
||||
formatRow(forgejoHealth),
|
||||
formatRow(forgejoPackages),
|
||||
formatRow(verdaccioProxy),
|
||||
]
|
||||
|
||||
printTable(headers, rows)
|
||||
console.log()
|
||||
|
||||
// Summary
|
||||
const checks = [verdaccioPing, forgejoHealth, forgejoPackages, verdaccioProxy]
|
||||
const downCount = checks.filter(c => c.status === 'down').length
|
||||
const degradedCount = checks.filter(c => c.status === 'degraded').length
|
||||
|
||||
if (downCount > 0) {
|
||||
logError(`${downCount} service(s) down`)
|
||||
process.exitCode = 1
|
||||
} else if (degradedCount > 0) {
|
||||
logWarning(`${degradedCount} service(s) degraded`)
|
||||
} else {
|
||||
logSuccess('All services operational')
|
||||
}
|
||||
|
||||
if (options.verbose) {
|
||||
console.log()
|
||||
console.log(colors.dim('Endpoints checked:'))
|
||||
for (const check of checks) {
|
||||
console.log(colors.dim(` ${check.name}: ${check.url}`))
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
spinner.fail('Failed to check infrastructure')
|
||||
console.error(error instanceof Error ? error.message : error)
|
||||
process.exit(1)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import { createUpgradeCommand } from './commands/upgrade.js'
|
|||
import { createVRAMCommand } from './commands/vram.js'
|
||||
import { createRAMCommand } from './commands/ram.js'
|
||||
import { createWorkflowsCommand } from './commands/workflows.js'
|
||||
import { createInfraCommand } from './commands/infra.js'
|
||||
|
||||
const program = new Command()
|
||||
|
||||
|
|
@ -31,6 +32,7 @@ program.addCommand(createUpgradeCommand())
|
|||
program.addCommand(createVRAMCommand())
|
||||
program.addCommand(createRAMCommand())
|
||||
program.addCommand(createWorkflowsCommand())
|
||||
program.addCommand(createInfraCommand())
|
||||
|
||||
// Parse arguments
|
||||
program.parse()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue