todo-txt-cli
Version:
A CLI for todo.txt files - http://todotxt.org/
94 lines (83 loc) • 2.2 kB
JavaScript
import path from 'node:path'
import fsp from 'node:fs/promises'
import { Tasks } from '#tasks.js'
import { logger } from '#logger.js'
const log = logger('file')
/**
* @typedef {import('#adapter.js').Adapter} Adapter
*/
/**
* @implements {Adapter}
*/
export class FileAdapter {
todoFile = ''
doneFile = ''
doBackup = true
/**
* @param {object} [options]
* @param {string} options.todoDir directory to use
* @param {string} [options.todoFile] todo.txt file
* @param {string} [options.doneFile] done.txt file
* @param {boolean} [options.doBackup=true] create a backup
*/
constructor(options) {
let { todoDir, todoFile, doneFile, doBackup = true } = options || {}
if (!todoDir) {
throw new Error('missing options.todoDir')
}
this.doBackup = doBackup
if (!todoFile) {
todoFile = path.resolve(todoDir, 'todo.txt')
}
if (!doneFile) {
doneFile = path.resolve(todoDir, 'done.txt')
}
log.debug('todoDir=%s', todoDir)
this.todoDir = todoDir
this.todoFile = todoFile
this.doneFile = doneFile
}
/**
* @returns {Promise<Tasks|undefined>}
*/
async load() {
let content = ''
try {
// check if directory does exist
const stat = await fsp.stat(this.todoDir)
if (!stat.isDirectory()) {
return Promise.reject(new Error(`"${this.todoDir}" is not a directory`))
}
} catch (_err) {
return Promise.reject(
new Error(`directory "${this.todoDir}" does not exist`)
)
}
try {
content = await fsp.readFile(this.todoFile, 'utf-8')
} catch (_err) {
this.doBackup = false
return
}
return new Tasks(content)
}
/**
* @param {Tasks} tasks
* @returns {Promise<void>}
*/
async store(tasks) {
if (this.doBackup) {
await fsp.copyFile(this.todoFile, `${this.todoFile}.bak`)
}
const content = tasks.stringify({}) + '\n'
await fsp.writeFile(this.todoFile, content, 'utf-8')
}
/**
* @param {Tasks} tasks
* @returns {Promise<void>}
*/
async archive(tasks) {
const content = tasks.stringify({}) + '\n'
await fsp.appendFile(this.doneFile, content, 'utf-8')
}
}