refactor: js output
This commit is contained in:
parent
1aa28c2a34
commit
c6704c3a04
96 changed files with 3816 additions and 147 deletions
89
src/issue.js
Normal file
89
src/issue.js
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
// mime-todo/lib/issue.ts
|
||||
// Valid status transitions
|
||||
const VALID_TRANSITIONS = {
|
||||
"open": ["in-progress", "hold", "cancelled"],
|
||||
"in-progress": ["done", "hold", "open", "cancelled"],
|
||||
"hold": ["open", "in-progress", "cancelled"],
|
||||
"done": ["open"],
|
||||
"cancelled": ["open"],
|
||||
};
|
||||
export function validateStatusTransition(from, to) {
|
||||
if (from === to)
|
||||
return null; // no-op is fine
|
||||
const allowed = VALID_TRANSITIONS[from];
|
||||
if (!allowed?.includes(to)) {
|
||||
return `Invalid status transition: ${from} → ${to}. Allowed from ${from}: ${allowed?.join(", ") ?? "none"}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
export function parseRelationships(text) {
|
||||
const relationships = {};
|
||||
// Handle empty relationships
|
||||
if (!text || text.trim() === "") {
|
||||
return relationships;
|
||||
}
|
||||
// Simple parsing for format like "dependsOn:3"
|
||||
const parts = text.split(/,\s*/).filter(p => p.trim() !== "");
|
||||
for (const part of parts) {
|
||||
const [key, value] = part.split(":").map(s => s.trim());
|
||||
if (key && value) {
|
||||
relationships[key] = value.split(/[\s]+/).map(Number).filter(n => !isNaN(n));
|
||||
}
|
||||
}
|
||||
return relationships;
|
||||
}
|
||||
export function parseIssue(text) {
|
||||
const lines = text.split(/\r?\n/);
|
||||
const issue = {};
|
||||
let inDescription = false;
|
||||
const descLines = [];
|
||||
const bodyLines = [];
|
||||
for (const line of lines) {
|
||||
if (!inDescription) {
|
||||
if (line.startsWith("ID:"))
|
||||
issue.id = Number(line.slice(3).trim());
|
||||
else if (line.startsWith("Type:"))
|
||||
issue.type = line.slice(5).trim();
|
||||
else if (line.startsWith("Title:"))
|
||||
issue.title = line.slice(6).trim();
|
||||
else if (line.startsWith("Status:"))
|
||||
issue.status = line.slice(7).trim();
|
||||
else if (line.startsWith("Priority:"))
|
||||
issue.priority = line.slice(9).trim();
|
||||
else if (line.startsWith("Created:"))
|
||||
issue.created = line.slice(8).trim();
|
||||
else if (line.startsWith("DueStart:"))
|
||||
issue.dueStart = line.slice(9).trim();
|
||||
else if (line.startsWith("DueEnd:"))
|
||||
issue.dueEnd = line.slice(7).trim();
|
||||
else if (line.startsWith("Module:"))
|
||||
issue.module = line.slice("Module:".length).trim();
|
||||
else if (line.startsWith("Relationships:")) {
|
||||
const rel = line.slice("Relationships:".length).trim();
|
||||
issue.relationships = parseRelationships(rel);
|
||||
}
|
||||
else if (line.startsWith("Description:")) {
|
||||
inDescription = true;
|
||||
descLines.push(line.slice("Description:".length).trim());
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Description continuation
|
||||
if (line.trim() === "") {
|
||||
// blank line ends description
|
||||
inDescription = false;
|
||||
continue;
|
||||
}
|
||||
if (/^\s+/.test(line)) {
|
||||
descLines.push(line.trim());
|
||||
continue;
|
||||
}
|
||||
// first non-indented line ends description
|
||||
inDescription = false;
|
||||
bodyLines.push(line);
|
||||
}
|
||||
}
|
||||
issue.description = descLines.join("\n");
|
||||
issue.body = bodyLines.join("\n");
|
||||
return issue;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue