Preview: Builds ueber den Runner
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
40a8aad3f9
commit
4258b5b9f1
7 files changed
+526
-5
No files matched your search
@@ -0,0 +1,55 @@
|
||||
// Build-Protokolle je Projekt: upload-data/preview-logs/<projectId>/<runFile>, maskiert, letzte 5
|
||||
import crypto from 'node:crypto'
|
||||
import fs from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import { config } from '../config.js'
|
||||
import { maskLog } from './previewEnv.js'
|
||||
|
||||
const KEEP = 5
|
||||
const MAX_LINES = 300
|
||||
const PROJECT_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,35}$/
|
||||
const FILE_RE = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z-[0-9a-f]{6}\.log$/
|
||||
|
||||
const projectDir = (projectId) => {
|
||||
if (!PROJECT_RE.test(String(projectId || '')) || String(projectId).includes('..')) {
|
||||
throw new Error('Ungültige Projekt-ID')
|
||||
}
|
||||
return path.join(config.previewRunner.logDir, projectId)
|
||||
}
|
||||
|
||||
export async function saveRunLog(projectId, lines, env) {
|
||||
const dir = projectDir(projectId)
|
||||
await fs.mkdir(dir, { recursive: true })
|
||||
const stamp = new Date().toISOString().replace(/[:.]/g, '-')
|
||||
const runFile = `${stamp}-${crypto.randomBytes(3).toString('hex')}.log`
|
||||
const text = maskLog((Array.isArray(lines) ? lines : []).slice(-MAX_LINES).join('\n'), env)
|
||||
await fs.writeFile(path.join(dir, runFile), text + '\n', 'utf8')
|
||||
const all = (await fs.readdir(dir)).filter((f) => FILE_RE.test(f)).sort()
|
||||
for (const old of all.slice(0, Math.max(0, all.length - KEEP))) {
|
||||
await fs.rm(path.join(dir, old), { force: true })
|
||||
}
|
||||
return runFile
|
||||
}
|
||||
|
||||
// Neueste zuerst
|
||||
export async function listRunLogs(projectId) {
|
||||
let files
|
||||
try { files = await fs.readdir(projectDir(projectId)) } catch { return [] }
|
||||
return files
|
||||
.filter((f) => FILE_RE.test(f))
|
||||
.sort()
|
||||
.reverse()
|
||||
.map((runFile) => ({
|
||||
runFile,
|
||||
at: runFile.slice(0, 24).replace(/^(.{13})-(.{2})-(.{2})-/, '$1:$2:$3.'),
|
||||
}))
|
||||
}
|
||||
|
||||
export async function readRunLog(projectId, runFile) {
|
||||
if (!FILE_RE.test(String(runFile || ''))) return null
|
||||
try {
|
||||
return await fs.readFile(path.join(projectDir(projectId), runFile), 'utf8')
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user