{"version":3,"sources":["../../src/lib/index.ts","../../node_modules/tsup/assets/cjs_shims.js","../../src/commands/setup.ts","../../src/lib/config.ts","../../src/prisma/index.ts","../../src/lib/task.ts","../../src/commands/config.ts","../../src/lib/filewalker.ts","../../src/lib/line-parser.ts","../../src/commands/sync.ts","../../src/commands/clean.ts","../../src/commands/help.ts"],"sourcesContent":["import setupCommand from '../commands/setup.js';\nimport config from './config.js';\nimport configCommand from '../commands/config.js';\nimport prisma, { connect } from '../prisma/index.js';\nimport syncCommand  from '../commands/sync.js';\nimport cleanCommand from '../commands/clean.js';\nimport helpCommand from '../commands/help.js';\nimport Task, { TaskMessageLevel } from './task.js';\nimport { PrismaClient } from '@prisma/client';\n\nexport default async function fhemLog2Db (cmd: string | undefined, args: string[]) {\n    if(args.includes('-v')) {\n        Task.setLevel(TaskMessageLevel.Debug);\n    }\n    else if(cmd === 'cron') {\n        Task.setLevel(TaskMessageLevel.Error);\n    }\n\n    if(cmd === 'setup') {\n        await setupCommand();\n        return;\n    }\n\n    try {\n        await config.isValid();\n    }\n    catch(error) {\n        console.log(error);\n        console.log('');\n        console.log('Run setup command to update configuration:');\n        await setupCommand();\n    }\n\n    if(cmd === 'config') {\n        await configCommand();\n        return;\n    }\n\n    connect();\n\n    try {\n        await fhemLog2DbSyncAndClean(cmd, args);\n    }\n    finally {\n        prisma?.$disconnect();\n    }\n}\n\nasync function fhemLog2DbSyncAndClean (cmd: string | undefined, args: string[]) {\n    if (cmd === 'sync') {\n        await syncCommand(args);\n    }\n    else if (cmd === 'clean') {\n        await cleanCommand();\n    }\n    else if (cmd === 'cron') {\n        await syncCommand(args);\n        await cleanCommand();\n    }\n    else {\n        await helpCommand();\n    }\n}\n\nexport function isRunning(pid: number) {\n    try {\n        return process.kill(pid,0);\n    }\n    catch (e: unknown) {\n        return String(e).includes('EPERM');\n    }\n}\n\nexport async function checkRunningProcesses (prisma: PrismaClient) {\n    const runningExecution = await prisma.execution.findFirst({\n        where: {\n            completed: null\n        },\n        orderBy: [{\n            started: 'desc'\n        }]\n    });\n    if(runningExecution && runningExecution.pid && isRunning(runningExecution.pid)) {\n        throw new Error(`There's another ${runningExecution.type} process running, please wait till it's done (${runningExecution.pid}, running since ${runningExecution.started})`);\n    }\n    if(runningExecution && !runningExecution.pid) {\n        throw new Error(`There's another ${runningExecution.type} process running, please wait till it's done (running since ${runningExecution.started})`);\n    }\n}\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () =>\n  typeof document === 'undefined'\n    ? new URL(`file:${__filename}`).href\n    : (document.currentScript && document.currentScript.src) ||\n      new URL('main.js', document.baseURI).href\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import prompts from 'prompts';\nimport config from '../lib/config.js';\nimport { createTask } from '../lib/task.js';\n\nexport default async function setupCommand() {\n    const { defaultPath, database } = await prompts([\n        {\n            type: 'text',\n            name: 'defaultPath',\n            message: 'Where are the FHEM log files that are to be transferred?',\n            initial: config.defaultPath,\n            validate: async (value: string) => {\n                try {\n                    await config.isValidDefaultPath(value);\n                    return true;\n                }\n                catch(error) {\n                    return String(error);\n                }\n            }\n        },\n        {\n            type: 'text',\n            name: 'database',\n            message: 'To which database should the data be copied?',\n            initial: config.database,\n            validate: async (value: string) => {\n                try {\n                    await config.isValidDatabase(value);\n                    return true;\n                }\n                catch(error) {\n                    return String(error);\n                }\n            }\n        },\n        {\n            type: 'number',\n            name: 'period',\n            message: 'What is the maximum number of days to be synchronized.',\n            initial: Math.round(config.period / 60 / 60 / 24),\n            format: number => number * 60 * 60 * 24,\n            min: 0,\n            float: true,\n            validate: async (value: number) => {\n                try {\n                    await config.isValidPeriod(value);\n                    return true;\n                }\n                catch(error) {\n                    return String(error);\n                }\n            }\n        }\n    ]);\n    if(!defaultPath) {\n        throw new Error('Unable to update configuration: default path is not valid.');\n    }\n    if(!database) {\n        throw new Error('Unable to update configuration: database is not valid.');\n    }\n\n    config.defaultPath = defaultPath;\n    config.database = database;\n\n    await createTask(`Save settings in ${config.configFilePath}`, () => config.save());\n}\n","import { existsSync, readFileSync } from 'fs';\nimport { writeFile} from 'fs/promises';\nimport { join, resolve, dirname } from 'path';\nimport { validateDatabaseUri } from '../prisma/index.js';\nimport { cwd } from 'process';\nimport { fileURLToPath } from 'url';\n\nexport interface ConfigSchema {\n    path?: string;\n    database?: string;\n    period?: number;\n}\n\nexport class Config {\n    private readonly configPath: string;\n    private readonly configData: ConfigSchema = {};\n\n    constructor () {\n        let configPath: string | undefined;\n        if (process.env.FHEM_LOG2DB_CONFIG) {\n            configPath = process.env.FHEM_LOG2DB_CONFIG;\n        }\n        else if (process.env.HOME) {\n            configPath = join(process.env.HOME, 'fhem-log2db.config.json');\n        }\n        else {\n            throw new Error(\n                'Unable to load configuration: HOME environment variable is not set. Please set HOME or use '+\n                'FHEM_LOG2DB_CONFIG to set the path to the configuration file.'\n            );\n        }\n\n        this.configPath = resolve(cwd(), configPath);\n        if(existsSync(configPath)) {\n            this.configData = JSON.parse(readFileSync(this.configPath, 'utf8'));\n        }\n    }\n\n    get scriptPath(): string {\n        return resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');\n    }\n\n    get configFilePath(): string {\n        return this.configPath;\n    }\n\n    get defaultPath(): string {\n        return this.configData.path ?\n            resolve(dirname(this.configFilePath), this.configData.path) :\n            '/opt/fhem/log';\n    }\n\n    set defaultPath(path: string) {\n        this.configData.path = path;\n    }\n\n    get database(): string {\n        return this.configData.database || 'mysql://root@localhost';\n    }\n\n    set database(uri: string) {\n        this.configData.database = uri;\n    }\n\n    get period(): number {\n        return this.configData.period || 60 * 60 * 24 * 30;\n    }\n\n    set period(period: number) {\n        this.configData.period = period;\n    }\n\n    get periodStart(): Date | null {\n        return this.period > 0 ? new Date(new Date().getTime() - this.period * 1000) : null;\n    }\n\n    async isValid(): Promise<void> {\n        await Promise.all([\n            this.isValidDefaultPath(),\n            this.isValidDatabase(),\n            this.isValidPeriod()\n        ]);\n    }\n\n    async isValidDefaultPath(defaultPath: string = this.defaultPath): Promise<void> {\n        if(!existsSync(defaultPath)) {\n            throw new Error(`Logfile path ${defaultPath} does not exist.`);\n        }\n    }\n\n    async isValidDatabase(database: string = this.database): Promise<void> {\n        await validateDatabaseUri(database);\n    }\n\n    async isValidPeriod(period: number = this.period): Promise<void> {\n        if(period < 0) {\n            throw new Error('Period must be a positive number or 0 if everything has to be synced.');\n        }\n    }\n\n    async save() {\n        await writeFile(this.configPath, JSON.stringify(this.configData, null, '  '));\n    }\n}\n\nconst config = new Config;\nexport default config;\n","import { PrismaClient } from '@prisma/client';\nimport config from '../lib/config.js';\n\nlet prisma = null as PrismaClient | null;\n\nexport function connect(): void {\n    prisma = new PrismaClient({\n        datasources: {\n            db: {\n                url: config.database + (!config.database.includes('?') ? '?' : '&') + 'pool_timeout=120'\n            }\n        }\n    });\n}\n\nexport async function validateDatabaseUri (database: string): Promise<void> {\n    const prisma = new PrismaClient({\n        datasources: {\n            db: {\n                url: database\n            }\n        }\n    });\n\n    await prisma.$connect();\n    await prisma.$disconnect();\n}\n\nexport function getClient () {\n    return prisma;\n}\n\nexport default prisma;\n","export type CreateTaskFn<T> = (task: Task) => Promise<T>;\nexport enum TaskMessageLevel {\n    Debug,\n    Log,\n    Warning,\n    Error\n}\n\nexport type TaskMessageDebug = [TaskMessageLevel.Debug, string];\nexport type TaskMessageLog = [TaskMessageLevel.Log, string];\nexport type TaskMessageWarning = [TaskMessageLevel.Warning, string];\nexport type TaskMessageError = [TaskMessageLevel.Error, Error | unknown];\nexport type TaskMessage = TaskMessageDebug | TaskMessageLog | TaskMessageWarning | TaskMessageError;\n\nexport async function createTask<T>(name: string, fn: CreateTaskFn<T>): Promise<T> {\n    const task = new Task(name);\n\n    try {\n        return await fn(task);\n    }\n    catch(error) {\n        task.error(error);\n        throw error;\n    }\n    finally {\n        task.finally();\n    }\n}\n\nexport default class Task {\n    static level: TaskMessageLevel = TaskMessageLevel.Log;\n\n    private readonly name: string;\n    private readonly messages: TaskMessage[] = [];\n    private lastProgress: number | undefined;\n    private statusLength = 0;\n    private pending = true;\n\n    static setLevel(level: TaskMessageLevel) {\n        this.level = level;\n    }\n\n    constructor(name: string) {\n        this.name = name;\n\n        if (Task.level === TaskMessageLevel.Log) {\n            process.stdout.write(`${name}…`);\n        }\n    }\n\n    private status(message: string) {\n        if (Task.level !== TaskMessageLevel.Log) {\n            return;\n        }\n\n        this.statusLength = Math.max(this.statusLength, message.length);\n        process.stdout.write('\\r' + this.statusFiller(message));\n    }\n\n    private statusFiller(message: string): string {\n        const c = this.statusLength - message.length;\n        if(c <= 0) {\n            return message;\n        }\n\n        return message + (' '.repeat(c));\n    }\n\n    debug(message: string) {\n        this.messages.push([\n            TaskMessageLevel.Debug,\n            message\n        ]);\n    }\n\n    log(message: string) {\n        this.messages.push([\n            TaskMessageLevel.Log,\n            message\n        ]);\n    }\n\n    warn(message: string) {\n        this.messages.push([\n            TaskMessageLevel.Warning,\n            message\n        ]);\n    }\n\n    error(error: Error | unknown) {\n        this.messages.push([\n            TaskMessageLevel.Error,\n            error\n        ]);\n    }\n\n    progress(progress: number) {\n        if (this.pending && Task.level === TaskMessageLevel.Log && (!this.lastProgress || progress > this.lastProgress)) {\n            this.lastProgress = progress;\n            this.status(`${this.name}… (${(progress * 100).toFixed(1)}%)`);\n        }\n    }\n\n    finally() {\n        const relevantMessages = this.messages.filter(([level]) => level >= Task.level);\n        const hasFailed = !!this.messages.find(([level]) => level >= TaskMessageLevel.Error);\n        this.pending = false;\n\n        if (relevantMessages.length > 0 || Task.level === TaskMessageLevel.Log) {\n            const message = `\\r${this.name} [${hasFailed ? 'Failed' : 'Ok'}]`;\n            console.log(this.statusFiller(message) + ' ');\n        }\n        if (relevantMessages.length > 0) {\n            relevantMessages.forEach(message => {\n                if(message[0] === TaskMessageLevel.Debug) {\n                    console.log('  |- Debug:', message[1]);\n                }\n                else if(message[0] === TaskMessageLevel.Log) {\n                    console.log('  |-', message[1]);\n                }\n                else if(message[0] === TaskMessageLevel.Warning) {\n                    console.log('  |- Warning:', message[1]);\n                }\n                else if(message[0] === TaskMessageLevel.Error && message[1] instanceof Error && message[1].stack) {\n                    console.log('  |- Error:', message[1].stack.replace(/\\n/g, '\\n     '));\n                }\n                else if(message[0] === TaskMessageLevel.Error) {\n                    console.log('  |- Error:', message[1]);\n                }\n            });\n        }\n    }\n}\n","import config from '../lib/config.js';\n\nexport default async function configCommand() {\n    console.log(`fhem-log2db Path: ${config.scriptPath}`);\n    console.log(`     Config Path: ${config.configFilePath}`);\n    console.log(`        Log Path: ${config.defaultPath}`);\n    console.log(`        Database: ${config.database}`);\n    console.log(` Period duration: ${config.period} seconds`);\n    console.log('');\n}\n","import { lstat, mkdtemp, readdir, rm } from 'fs/promises';\nimport { createReadStream, Dirent, Stats } from 'node:fs';\nimport { join, extname } from 'path';\nimport { createInterface, Interface } from 'readline';\nimport extractZip from 'extract-zip';\nimport targz from 'targz';\nimport { tmpdir } from 'os';\nimport Task from './task.js';\nimport EventEmitter from 'events';\n\nconst { decompress: extractTarGz } = targz;\n\n\nexport interface FileWalkerOptions {\n    file: string;\n    callback: FileWalkerCallback;\n    batchSize?: number;\n}\n\nexport interface FileWalkerBaton {\n    internalPath: string;\n    externalPath: string;\n    options: FileWalkerOptions;\n    queue: FileWalkerQueue;\n}\n\ntype FileWalkerCallback = (line: string, file: string) => Promise<void>;\ntype FileWalkerUnarchiverCb = (archive: string, directory: string) => Promise<void>;\n\nclass FileWalkerBatchCounter {\n    private c = 0;\n    private paused = false;\n    private readonly rl: Interface;\n    private readonly batchSize: number;\n\n    constructor (rl: Interface, options: FileWalkerOptions) {\n        this.rl = rl;\n        this.batchSize = options.batchSize ? options.batchSize * 50 : 250;\n    }\n\n    get value () {\n        return this.c;\n    }\n\n    up () {\n        this.c++;\n\n        if (this.c >= this.batchSize && !this.paused) {\n            this.paused = true;\n            this.rl.pause();\n        }\n    }\n\n    down () {\n        this.c--;\n\n        if (this.c < this.batchSize * 0.8 && this.paused) {\n            this.paused = false;\n            this.rl.resume();\n        }\n    }\n}\n\nclass FileWalkerQueue {\n    private readonly batchSize;\n    private readonly events = new EventEmitter;\n    private readonly queue: Array<() => Promise<void>> = [];\n    private running = 0;\n\n    constructor (batchSize?: number) {\n        this.batchSize = batchSize || 20;\n    }\n\n    public add (fn: () => Promise<void>): Promise<void> {\n        return new Promise(cb => {\n            this.queue.push(() =>\n                fn().finally(() => cb())\n            );\n            this.check();\n        });\n    }\n\n    public check () {\n        if (this.running >= this.batchSize) {\n            return;\n        }\n\n        const task = this.queue.shift();\n        if (!task) {\n            this.events.emit('empty');\n            return;\n        }\n\n        this.running++;\n        task().finally(() => {\n            this.running--;\n            this.check();\n        });\n    }\n\n    public empty (): Promise<void> {\n        if(this.queue.length === 0) {\n            return Promise.resolve();\n        }\n\n        return new Promise(cb => {\n            this.events.once('empty', () => cb());\n        });\n    }\n}\n\nasync function createTemporaryFolder () {\n    return mkdtemp(join(tmpdir(), 'fhem-log2db–'));\n}\n\nasync function countLines (file: string): Promise<number> {\n    const rl = createInterface({\n        input: createReadStream(file)\n    });\n\n    let lines = 0;\n    rl.on('line', () => lines++);\n\n    return new Promise(cb =>\n        rl.on('close', () => cb(lines))\n    );\n}\n\nasync function onFolder (baton: FileWalkerBaton): Promise<void> {\n    const files = await readdir(baton.internalPath, { withFileTypes: true });\n    for (const file of files) {\n        const newBaton = Object.assign({}, baton, {\n            internalPath: join(baton.internalPath, file.name),\n            externalPath: join(baton.externalPath, file.name)\n        });\n\n        await runOnSomething(newBaton, file);\n    }\n}\n\nasync function onFile (baton: FileWalkerBaton): Promise<void> {\n    const ext = extname(baton.internalPath);\n\n    if (ext === '.log') {\n        await onLogFile(baton);\n    } else if (ext === '.zip') {\n        await onZipFile(baton);\n    } else if (ext === '.gz' && baton.internalPath.endsWith('.tar.gz')) {\n        await onTarGzFile(baton);\n    }\n}\n\nasync function onLogFile (baton: FileWalkerBaton): Promise<void> {\n    const task = new Task('Sync ' + baton.externalPath);\n    const lines = await countLines(baton.internalPath);\n    const rl = createInterface({\n        input: createReadStream(baton.internalPath)\n    });\n\n    const counter = new FileWalkerBatchCounter(rl, baton.options);\n\n    let lineNr = 0;\n    rl.on('line', (line: string) => {\n        const myLine = lineNr;\n\n        // Skip lines added after imports starts\n        if (myLine > lines) {\n            return;\n        }\n\n        onLine(Object.assign({}, baton, {\n            externalPath: baton.externalPath + ':' + ++lineNr\n        }), line, counter, task, baton.options.callback).then(() => {\n            task.progress(myLine / lines);\n        });\n    });\n\n    await new Promise(resolve => {\n        rl.on('close', () => resolve(null));\n    });\n\n    await baton.queue.empty();\n    task.finally();\n}\n\nasync function onZipFile (baton: FileWalkerBaton): Promise<void> {\n    await onArchive(baton, async (archive, dir) =>\n        extractZip(archive, { dir })\n    );\n}\n\nasync function onTarGzFile (baton: FileWalkerBaton): Promise<void> {\n    await onArchive(baton, async (src, dest) => new Promise((resolve, reject) => {\n        extractTarGz({ src, dest }, (error) => {\n            if (error) {\n                reject(error);\n            } else {\n                resolve();\n            }\n        });\n    }));\n}\n\nasync function onArchive (baton: FileWalkerBaton, extractor: FileWalkerUnarchiverCb): Promise<void> {\n    const dir = await createTemporaryFolder();\n\n    try {\n        await extractor(baton.internalPath, dir);\n        await onFolder(Object.assign({}, baton, {\n            internalPath: dir\n        }));\n    } finally {\n        await rm(dir, {\n            force: true,\n            maxRetries: 20,\n            recursive: true\n        });\n    }\n}\n\nasync function onLine (baton: FileWalkerBaton, line: string, counter: FileWalkerBatchCounter, task: Task, cb: FileWalkerCallback): Promise<void> {\n    counter.up();\n\n    return baton.queue.add(async () => {\n        try {\n            await cb(line, baton.externalPath);\n        }\n        catch (error) {\n            task.warn(`Unable to sync ${line}: ${error}`);\n        }\n        finally {\n            counter.down();\n        }\n    });\n}\n\nasync function runOnSomething (baton: FileWalkerBaton, something: Stats | Dirent): Promise<void> {\n    if (something.isDirectory()) {\n        await onFolder(baton);\n    }\n    if (something.isFile()) {\n        await onFile(baton);\n    }\n}\n\nexport default async function runFileWalker (options: FileWalkerOptions) {\n    const f = await lstat(options.file);\n    await runOnSomething({\n        internalPath: options.file,\n        externalPath: options.file,\n        queue: new FileWalkerQueue(options.batchSize),\n        options: options\n    }, f);\n}\n","export type ParsedLine = {\n    timestamp: Date\n    device: string\n    event: string\n    reading: string\n    value: string | null\n    unit: string | null\n}\n\nfunction checkForStringLength<T extends string | null = string>(str: T): string | T {\n    if (typeof str === 'string' && str.length > 191) {\n        return str.substr(0, 190) + '…';\n    }\n\n    return str;\n}\n\nexport function parseLine (line: string): ParsedLine | null {\n    const lineParts = line.trim().split(' ');\n    const timestamp = lineParts.shift()?.replace('_', ' ');\n    const device = String(lineParts.shift());\n    if(timestamp === undefined || device === undefined) {\n        return null;\n    }\n\n    const date = new Date(timestamp);\n    if(isNaN(date.getTime())) {\n        return null;\n    }\n\n    const event = lineParts.join(' ');\n    const eventParts = event.split(':');\n    const reading = eventParts.shift() || '';\n\n    const rawValue = eventParts.join(':').trim();\n    let value = rawValue || null;\n    let unit = null;\n\n    if(value !== null) {\n        const match = value.match(/^([\\d.]+)[\\s]?([^\\s\\d]{1,10})$/);\n        if(match !== null) {\n            value = match[1];\n            unit = match[2];\n        }\n    }\n\n    return {\n        timestamp: date,\n        device: checkForStringLength(device),\n        event: checkForStringLength(event),\n        reading: checkForStringLength(reading),\n        value: checkForStringLength(value),\n        unit: checkForStringLength(unit)\n    };\n}","import config from '../lib/config.js';\nimport { getClient } from '../prisma/index.js';\nimport runFileWalker  from '../lib/filewalker.js';\nimport { parseLine } from '../lib/line-parser.js';\nimport Task from '../lib/task.js';\nimport { checkRunningProcesses } from '../lib/index.js';\n\nasync function syncPath(path: string, syncFrom?: Date): Promise<void> {\n    await runFileWalker({\n        file: path,\n        callback: (line: string, file: string) => syncLine(line, file, syncFrom)\n    });\n}\n\n\nasync function syncLine(line: string, file: string, syncFrom?: Date): Promise<void> {\n    const prisma = getClient();\n    if (!prisma) {\n        throw new Error('Unable to sync: prisma is not ready');\n    }\n\n    const data = parseLine(line);\n    if (!data || (syncFrom && data.timestamp < syncFrom)) {\n        return;\n    }\n\n    try {\n        await prisma.history.upsert({\n            where: {\n                timestamp_device_reading: {\n                    timestamp: data.timestamp,\n                    device: data.device,\n                    reading: data.reading\n                }\n            },\n            update: {\n                event: data.event,\n                value: data.value,\n                unit: data.unit\n            },\n            create: data\n        });\n    }\n    catch(error) {\n        if(String(error).includes('Unique constraint failed on the constraint')) {\n            return;\n        }\n\n        console.log('----');\n        console.log(error);\n        console.log(data);\n        console.log('----');\n\n        throw error;\n    }\n}\n\nexport default async function syncCommand(args: string[] = []) {\n    const prisma = getClient();\n    if (!prisma) {\n        throw new Error('Unable to sync: prisma is not ready');\n    }\n\n    await checkRunningProcesses(prisma);\n    const thisExecution = await prisma.execution.create({\n        data: {\n            type: 'sync',\n            pid: process.pid,\n            started: new Date()\n        }\n    });\n\n    const paths = args.length > 0 ? args : [config.defaultPath];\n    for (const path of paths) {\n        let syncFrom: Date | undefined;\n\n        if (path === config.defaultPath) {\n            const prepareTask = new Task('Check what has to be synced in default path');\n            const lastExecution = await prisma.execution.findFirst({\n                where: {\n                    type: 'sync',\n                    completed: {\n                        not: null\n                    },\n                    started: {\n                        not: thisExecution.started\n                    }\n                },\n                orderBy: [{\n                    started: 'desc'\n                }]\n            });\n\n            syncFrom = lastExecution?.started;\n            prepareTask.log(`Last successfull sync at ${syncFrom || '-'}`);\n\n            const periodStart = config.periodStart;\n            if(config.period > 0 && periodStart !== null) {\n                prepareTask.log(`Configured period starts at ${periodStart}`);\n\n                if(!syncFrom || syncFrom < periodStart) {\n                    syncFrom = periodStart;\n                }\n            }\n\n            prepareTask.log(`Sync default path starting from ${syncFrom}`);\n            prepareTask.finally();\n        }\n\n        await syncPath(path, syncFrom);\n    }\n\n    await prisma.execution.update({\n        where: {\n            id: thisExecution.id\n        },\n        data: {\n            completed: new Date()\n        }\n    });\n}\n","import config from '../lib/config.js';\nimport { getClient } from '../prisma/index.js';\nimport { createTask } from '../lib/task.js';\nimport { checkRunningProcesses } from '../lib/index.js';\n\nexport default async function cleanCommand() {\n    const prisma = getClient();\n    if (!prisma) {\n        throw new Error('Unable to clean: prisma is not ready');\n    }\n\n    await checkRunningProcesses(prisma);\n    await createTask('Clean database', async (task) => {\n        const periodStart = config.periodStart;\n        if(periodStart === null) {\n            task.log('Period is set to 0 – skip cleaning.');\n            return;\n        }\n\n        task.log(`Remove items with timestamp < ${periodStart}`);\n        const thisExecution = await prisma.execution.create({\n            data: {\n                type: 'clean',\n                pid: process.pid,\n                started: new Date()\n            }\n        });\n\n        await prisma.history.deleteMany({\n            where: {\n                timestamp: {\n                    lt: periodStart\n                }\n            }\n        });\n\n        await prisma.execution.update({\n            where: {\n                id: thisExecution.id\n            },\n            data: {\n                completed: new Date()\n            }\n        });\n    });\n}\n","import { readFile } from 'fs/promises';\nimport { join } from 'path';\n\nexport default async function helpCommand() {\n    console.log('# fhem-log2db');\n\n    try {\n        const pkg = JSON.parse(await readFile(join(__dirname, '..', '..', 'package.json'), 'utf8'));\n        console.log(`  Version ${pkg.version}`);\n    }\n\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    catch(error) {\n        // ignore error\n    }\n\n    console.log('');\n\n    console.log('> fhemlog2db setup  →  Re-run setup script to write ~/fhem-log2db.config.json');\n    console.log('> fhemlog2db config →  Print current configuration');\n    console.log('> fhemlog2db sync   →  Sync files in default path to database');\n    console.log('> fhemlog2db clean  →  Delete old values in database');\n    console.log('> fhemlog2db cron   →  Run both sync and clean jobs');\n}"],"mappings":"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","names":["lib_exports","__export","checkRunningProcesses","fhemLog2Db","isRunning","__toCommonJS","getImportMetaUrl","importMetaUrl","import_prompts","import_fs","import_promises","import_path","import_client","prisma","connect","config_default","validateDatabaseUri","database","getClient","prisma_default","import_process","import_url","Config","configPath","importMetaUrl","path","uri","period","defaultPath","database","validateDatabaseUri","config","config_default","createTask","name","fn","task","Task","error","_Task","level","message","c","progress","relevantMessages","hasFailed","setupCommand","defaultPath","database","prompts","config_default","value","error","number","createTask","configCommand","config_default","import_promises","import_node_fs","import_path","import_readline","import_extract_zip","import_targz","import_os","import_events","extractTarGz","targz","FileWalkerBatchCounter","rl","options","FileWalkerQueue","EventEmitter","batchSize","fn","cb","task","createTemporaryFolder","countLines","file","lines","onFolder","baton","files","newBaton","runOnSomething","onFile","ext","onLogFile","onZipFile","onTarGzFile","Task","counter","lineNr","line","myLine","onLine","resolve","onArchive","archive","dir","extractZip","src","dest","reject","error","extractor","something","runFileWalker","f","checkForStringLength","str","parseLine","line","lineParts","timestamp","device","date","event","eventParts","reading","value","unit","match","syncPath","path","syncFrom","runFileWalker","line","file","syncLine","prisma","getClient","data","parseLine","error","syncCommand","args","checkRunningProcesses","thisExecution","paths","config_default","prepareTask","Task","periodStart","cleanCommand","prisma","getClient","checkRunningProcesses","createTask","task","periodStart","config_default","thisExecution","import_promises","import_path","helpCommand","pkg","fhemLog2Db","cmd","args","Task","setupCommand","config_default","error","configCommand","connect","fhemLog2DbSyncAndClean","prisma_default","syncCommand","cleanCommand","helpCommand","isRunning","pid","checkRunningProcesses","prisma","runningExecution"]}