bookr-cli
Version:
A terminal-based CLI tool to book time in Jira using the Tempo plugin by parsing your current Git branch name
203 lines • 6.71 kB
JavaScript
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import envPaths from 'env-paths';
/**
* Get worklog storage file path
*/
export function getWorklogStoragePath() {
const paths = envPaths('bookr-cli', { suffix: '' });
return join(paths.data, 'worklogs.json');
}
/**
* Read stored worklogs
*/
export function readStoredWorklogs() {
try {
const storagePath = getWorklogStoragePath();
if (!existsSync(storagePath)) {
return { worklogs: [], lastWorklogId: undefined, lastCleanup: new Date().toISOString() };
}
const content = readFileSync(storagePath, 'utf-8');
const data = JSON.parse(content);
// Ensure we have the expected structure
if (!data.worklogs || !Array.isArray(data.worklogs)) {
return { worklogs: [], lastWorklogId: undefined, lastCleanup: new Date().toISOString() };
}
return data;
}
catch {
return { worklogs: [], lastWorklogId: undefined, lastCleanup: new Date().toISOString() };
}
}
/**
* Write stored worklogs
*/
export function writeStoredWorklogs(data) {
try {
const storagePath = getWorklogStoragePath();
const storageDir = dirname(storagePath);
// Ensure storage directory exists
if (!existsSync(storageDir)) {
mkdirSync(storageDir, { recursive: true });
}
writeFileSync(storagePath, JSON.stringify(data, null, 2));
}
catch {
// Silently fail storage writes
}
}
/**
* Store a worklog after creation
*/
export function storeWorklog(issue, worklog, originalComment) {
try {
if (!worklog.id || !worklog.author) {
return false;
}
const data = readStoredWorklogs();
const storedWorklog = {
id: worklog.id,
issueKey: issue.key,
issueId: issue.id,
issueSummary: issue.fields.summary,
timeSpent: worklog.timeSpent,
timeSpentSeconds: worklog.timeSpentSeconds || 0,
...(originalComment && { comment: originalComment }),
started: worklog.started || new Date().toISOString(),
createdAt: new Date().toISOString(),
author: worklog.author,
source: 'jira',
};
// Add to the beginning of the array (most recent first)
data.worklogs.unshift(storedWorklog);
// Track this as the last worklog
data.lastWorklogId = worklog.id;
// Keep only the last 100 worklogs to prevent unlimited growth
if (data.worklogs.length > 100) {
data.worklogs = data.worklogs.slice(0, 100);
}
writeStoredWorklogs(data);
return true;
}
catch {
return false;
}
}
/**
* Store a Tempo worklog after creation
*/
export function storeTempoWorklog(issue, tempoWorklog, originalComment) {
try {
if (!tempoWorklog.tempoWorklogId) {
return false;
}
const data = readStoredWorklogs();
const storedWorklog = {
id: String(tempoWorklog.tempoWorklogId),
tempoWorklogId: String(tempoWorklog.tempoWorklogId),
issueKey: issue.key,
issueId: issue.id,
issueSummary: issue.fields.summary,
timeSpent: tempoWorklog.timeSpent || '',
timeSpentSeconds: tempoWorklog.timeSpentSeconds || 0,
...(originalComment && { comment: originalComment }),
started: tempoWorklog.started || new Date().toISOString(),
createdAt: new Date().toISOString(),
author: {
name: 'Unknown',
displayName: 'Unknown',
},
source: 'tempo',
};
// Add to the beginning of the array (most recent first)
data.worklogs.unshift(storedWorklog);
// Track this as the last worklog
data.lastWorklogId = String(tempoWorklog.tempoWorklogId);
// Keep only the last 100 worklogs to prevent unlimited growth
if (data.worklogs.length > 100) {
data.worklogs = data.worklogs.slice(0, 100);
}
writeStoredWorklogs(data);
return true;
}
catch {
return false;
}
}
/**
* Get worklog by ID
*/
export function getStoredWorklogById(worklogId) {
const data = readStoredWorklogs();
return data.worklogs.find((w) => w.id === worklogId) || null;
}
/**
* Get the last worklog that was created
*/
export function getLastWorklog() {
const data = readStoredWorklogs();
if (!data.lastWorklogId) {
return null;
}
return data.worklogs.find((w) => w.id === data.lastWorklogId) || null;
}
/**
* Remove worklog from storage after deletion
*/
export function removeStoredWorklog(worklogId) {
try {
const data = readStoredWorklogs();
const originalLength = data.worklogs.length;
data.worklogs = data.worklogs.filter((w) => w.id !== worklogId);
// If we're removing the last worklog, clear the lastWorklogId
if (data.lastWorklogId === worklogId) {
data.lastWorklogId = undefined;
}
if (data.worklogs.length < originalLength) {
writeStoredWorklogs(data);
return true;
}
return false;
}
catch {
return false;
}
}
/**
* Get today's stored worklogs
*/
export function getTodaysStoredWorklogs() {
const data = readStoredWorklogs();
const today = new Date();
const startOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate());
const endOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59);
return data.worklogs.filter((worklog) => {
const worklogDate = new Date(worklog.started);
return worklogDate >= startOfDay && worklogDate <= endOfDay;
});
}
/**
* Clean up old worklogs (older than 30 days)
*/
export function cleanupOldWorklogs() {
try {
const data = readStoredWorklogs();
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - 30);
const originalLength = data.worklogs.length;
data.worklogs = data.worklogs.filter((worklog) => {
const worklogDate = new Date(worklog.createdAt);
return worklogDate >= cutoffDate;
});
const removedCount = originalLength - data.worklogs.length;
if (removedCount > 0) {
data.lastCleanup = new Date().toISOString();
writeStoredWorklogs(data);
}
return removedCount;
}
catch {
return 0;
}
}
//# sourceMappingURL=worklog-storage.js.map