(content: string, isCompleted: boolean)
| 171 | } |
| 172 | |
| 173 | private static parseTaskContent(content: string, isCompleted: boolean): ParsedTaskData { |
| 174 | if (typeof content !== "string") { |
| 175 | throw new Error("Content must be a string"); |
| 176 | } |
| 177 | |
| 178 | if (content.length > 1000) { |
| 179 | throw new Error("Content too long to process safely"); |
| 180 | } |
| 181 | |
| 182 | try { |
| 183 | const state: ParsingState = { |
| 184 | line: content.trim(), |
| 185 | parsed: {}, |
| 186 | }; |
| 187 | |
| 188 | const blockLink = this.consumeBlockLink(state); |
| 189 | if (blockLink) { |
| 190 | state.parsed.blockLink = blockLink; |
| 191 | } |
| 192 | |
| 193 | this.consumeTrailingFields(state); |
| 194 | |
| 195 | const tags = this.extractTags(content); |
| 196 | const contexts = this.extractContexts(content); |
| 197 | const title = this.extractCleanTitle(state.line); |
| 198 | |
| 199 | let status: string | undefined = undefined; |
| 200 | if (isCompleted || state.parsed.doneDate) { |
| 201 | status = "done"; |
| 202 | } else if (state.parsed.startDate) { |
| 203 | try { |
| 204 | status = |
| 205 | !isPastDate(state.parsed.startDate) && !isToday(state.parsed.startDate) |
| 206 | ? "scheduled" |
| 207 | : "open"; |
| 208 | } catch { |
| 209 | // Invalid start date, ignore for status determination. |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | return { |
| 214 | title: title.trim() || "Untitled Task", |
| 215 | status, |
| 216 | priority: state.parsed.priority, |
| 217 | dueDate: state.parsed.dueDate, |
| 218 | scheduledDate: state.parsed.scheduledDate, |
| 219 | startDate: state.parsed.startDate, |
| 220 | createdDate: state.parsed.createdDate, |
| 221 | doneDate: state.parsed.doneDate, |
| 222 | recurrence: state.parsed.recurrence, |
| 223 | recurrenceAnchor: state.parsed.recurrenceAnchor, |
| 224 | recurrenceData: state.parsed.recurrenceData, |
| 225 | tags: tags.length > 0 ? tags : undefined, |
| 226 | contexts: contexts.length > 0 ? contexts : undefined, |
| 227 | projects: undefined, |
| 228 | isCompleted, |
| 229 | userFields: state.parsed.userFields, |
| 230 | customFrontmatter: state.parsed.customFrontmatter, |
no test coverage detected