bananareporter
Version:
Easily generate a report from multiple sources
95 lines (94 loc) • 4.32 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TodoTxtIntegration = exports.TodoTxtConfig = void 0;
const base_1 = require("./base");
// import {Axios} from 'axios'
const common_1 = require("../util/common");
const zod_1 = require("zod");
const dayjs = require("dayjs");
const logger_1 = require("../util/logger");
const objectPath = require("object-path");
const node_fs_1 = require("node:fs");
const todo_txt_parser_1 = require("@lggruspe/todo-txt-parser");
const path = require("path");
exports.TodoTxtConfig = zod_1.z.object({
// TODO support wildcard
file: zod_1.z.string().min(1).default('./todo.txt').refine(s => {
return path.resolve(s);
}),
filters: zod_1.z.array(zod_1.z.object({
on: zod_1.z.string().min(1),
regex: zod_1.z.string().min(1),
})).nonempty().optional(),
from: common_1.zIsoString.optional(),
to: common_1.zIsoString.optional(),
});
class TodoTxtIntegration extends base_1.IntegrationBase {
constructor(_rawConfig, bananaReporterConfig) {
var _a, _b;
super(_rawConfig, bananaReporterConfig);
logger_1.logger.debug('todo.txt integration');
this.config = exports.TodoTxtConfig.parse(_rawConfig);
logger_1.logger.debug('todo.txt integration config', this.config);
this.bananaReporterConfig = bananaReporterConfig;
this.dateRange = {
from: (_a = this.config.from) !== null && _a !== void 0 ? _a : this.bananaReporterConfig.from,
to: (_b = this.config.to) !== null && _b !== void 0 ? _b : this.bananaReporterConfig.to,
};
logger_1.logger.debug('todo.txt integration dateRange', this.dateRange);
if (!(0, node_fs_1.existsSync)(this.config.file)) {
const errorMsg = `Unable to find file ${this.config.file}`;
logger_1.logger.error(errorMsg);
throw new Error(errorMsg);
}
logger_1.logger.debug(`todo.txt file ${this.config.file} exists`);
}
async fetchData() {
// parse
const rawTodoTxt = (0, node_fs_1.readFileSync)(this.config.file).toString();
const parsedTodoTxtFile = (0, todo_txt_parser_1.parse)(rawTodoTxt);
const fromDate = dayjs(this.dateRange.from).subtract(1, 'minute');
const toDate = dayjs(this.dateRange.to).add(1, 'minute');
let filteredTasks = parsedTodoTxtFile.filter(t => {
const rawTaskDate = t.completion || t.creation;
// unknown task date, don't include it
if (typeof rawTaskDate === 'undefined') {
return false;
}
const taskDateObj = dayjs(rawTaskDate);
return (taskDateObj.isAfter(fromDate) &&
taskDateObj.isBefore(toDate));
});
// format data to common obj
for (const filter of this.config.filters || []) {
const targetKey = filter.on;
filteredTasks = filteredTasks.filter(t => {
const regex = new RegExp(filter.regex);
const value = objectPath.get(t, targetKey);
if (typeof value === 'undefined') {
const errorMsg = `while filtering "${t.description}" unable to find the key ${targetKey} in the task's object (available keys: ${Object.keys(t).join(',')})`;
logger_1.logger.error(errorMsg);
throw new Error(errorMsg);
}
return regex.test(value);
});
}
const formattedData = filteredTasks.map((e, i) => this.toBananaReporterObj(e, i));
return formattedData;
}
toBananaReporterObj(rawData, index) {
var _a;
const projectName = (_a = rawData.projects) === null || _a === void 0 ? void 0 : _a.map(p => p.replace('+', '')).join(',');
const description = `${rawData.description}`;
return {
id: `${this.config.file}_${index}`,
date: rawData.completion || rawData.creation || '',
description,
projectName,
type: TodoTxtIntegration.type,
__raw: this.bananaReporterConfig.includeRawObject ? rawData : undefined,
};
}
}
exports.TodoTxtIntegration = TodoTxtIntegration;
TodoTxtIntegration.type = base_1.SourceType.Enum['todo.txt'];