@lint-todo/utils
Version:
 [](https://badge.fury.io/js/%40lint-todo%2Futils) [](h
152 lines • 6.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateHash = exports.buildTodoDatum = exports.toOperation = exports.toTodoDatum = exports.buildTodoOperations = exports.buildFromTodoOperations = void 0;
const tslib_1 = require("tslib");
const upath_1 = require("upath");
const slash = require("slash");
const node_crypto_1 = require("node:crypto");
const date_utils_1 = require("./date-utils");
const todo_matcher_1 = tslib_1.__importDefault(require("./todo-matcher"));
const SEPARATOR = '|';
function buildFromTodoOperations(todoOperations, engine) {
const existingTodos = new Map();
for (const todoOperation of todoOperations) {
const [operation, todoDatum] = toTodoDatum(todoOperation);
if (engine !== 'all' && todoDatum.engine !== engine) {
continue;
}
if (!existingTodos.has(todoDatum.filePath)) {
existingTodos.set(todoDatum.filePath, new todo_matcher_1.default());
}
const matcher = existingTodos.get(todoDatum.filePath);
matcher === null || matcher === void 0 ? void 0 : matcher.addOrRemove(operation, todoDatum);
}
for (const [filePath, matcher] of existingTodos.entries()) {
if (matcher.unprocessed.size === 0) {
existingTodos.delete(filePath);
}
}
return existingTodos;
}
exports.buildFromTodoOperations = buildFromTodoOperations;
function buildTodoOperations(add, remove) {
if (add.size === 0 && remove.size === 0) {
return [];
}
const ops = [];
for (const todoDatum of add) {
ops.push(toOperation('add', todoDatum));
}
for (const todoDatum of remove) {
ops.push(toOperation('remove', todoDatum));
}
return ops;
}
exports.buildTodoOperations = buildTodoOperations;
function toTodoDatum(todoOperation) {
const [operation, engine, ruleId, line, column, endLine, endColumn, source, createdDate, warnDate, errorDate, ...filePathSegments] = todoOperation.split(SEPARATOR);
// The only case where we need to join back on the separator is when the filePath itself
// contains a pipe ('|') char. The vast majority of normal filePaths will simply join without
// the separator.
const filePath = filePathSegments.join(SEPARATOR);
return [
operation,
{
engine,
ruleId,
filePath,
range: {
start: {
line: Number.parseInt(line, 10),
column: Number.parseInt(column, 10),
},
end: {
line: Number.parseInt(endLine, 10),
column: Number.parseInt(endColumn, 10),
},
},
source,
createdDate: Number.parseInt(createdDate, 10),
warnDate: warnDate ? Number.parseInt(warnDate, 10) : undefined,
errorDate: errorDate ? Number.parseInt(errorDate, 10) : undefined,
},
];
}
exports.toTodoDatum = toTodoDatum;
function toOperation(operation, todoDatum) {
return [
operation,
todoDatum.engine,
todoDatum.ruleId,
todoDatum.range.start.line,
todoDatum.range.start.column,
todoDatum.range.end.line,
todoDatum.range.end.column,
todoDatum.source,
todoDatum.createdDate,
todoDatum.warnDate,
todoDatum.errorDate,
todoDatum.filePath,
].join(SEPARATOR);
}
exports.toOperation = toOperation;
/**
* Adapts a {@link https://github.com/lint-todo/utils/blob/master/src/types/lint.ts#L31|LintResult} to a {@link https://github.com/lint-todo/utils/blob/master/src/types/todo.ts#L61|TodoData}. FilePaths are absolute
* when received from a lint result, so they're converted to relative paths for stability in
* serializing the contents to disc.
*
* @param lintResult - The lint result object.
* @param lintMessage - A lint message object representing a specific violation for a file.
* @param todoConfig - An object containing the warn or error days, in integers.
* @returns - A {@link https://github.com/lint-todo/utils/blob/master/src/types/todo.ts#L61|TodoData} object.
*/
function buildTodoDatum(baseDir, genericLintData, todoConfig) {
const filePath = (0, upath_1.isAbsolute)(genericLintData.filePath)
? (0, upath_1.relative)(baseDir, genericLintData.filePath)
: (0, upath_1.normalize)(genericLintData.filePath);
const todoDatum = Object.assign(genericLintData, {
source: generateHash(genericLintData.source),
filePath: slash(filePath),
}, getTodoDates(genericLintData.ruleId, todoConfig));
return todoDatum;
}
exports.buildTodoDatum = buildTodoDatum;
function generateHash(input, algorithm = 'sha1') {
return (0, node_crypto_1.createHash)(algorithm).update(input).digest('hex');
}
exports.generateHash = generateHash;
function getTodoDates(ruleId, todoConfig) {
const createdDate = getCreatedDate();
const todoDates = {
createdDate: createdDate.getTime(),
};
const daysToDecay = getDaysToDecay(ruleId, todoConfig);
if (daysToDecay === null || daysToDecay === void 0 ? void 0 : daysToDecay.warn) {
todoDates.warnDate = addDays(createdDate, daysToDecay.warn).getTime();
}
if (daysToDecay === null || daysToDecay === void 0 ? void 0 : daysToDecay.error) {
todoDates.errorDate = addDays(createdDate, daysToDecay.error).getTime();
}
return todoDates;
}
function getDaysToDecay(ruleId, todoConfig) {
if (!todoConfig) {
return;
}
if ((todoConfig === null || todoConfig === void 0 ? void 0 : todoConfig.daysToDecayByRule) && todoConfig.daysToDecayByRule[ruleId]) {
return todoConfig.daysToDecayByRule[ruleId];
}
else if (todoConfig === null || todoConfig === void 0 ? void 0 : todoConfig.daysToDecay) {
return todoConfig.daysToDecay;
}
}
function getCreatedDate() {
const date = process.env.TODO_CREATED_DATE ? new Date(process.env.TODO_CREATED_DATE) : new Date();
return (0, date_utils_1.getDatePart)(date);
}
function addDays(createdDate, days) {
const datePlusDays = new Date(createdDate.valueOf());
datePlusDays.setDate(datePlusDays.getDate() + days);
return datePlusDays;
}
//# sourceMappingURL=builders.js.map