( path: string, property: "tags" | "projects" | "contexts", value: string, operation: "add" | "remove", context?: TaskNotesMutationContext )
| 2107 | } |
| 2108 | |
| 2109 | private async updateStringList( |
| 2110 | path: string, |
| 2111 | property: "tags" | "projects" | "contexts", |
| 2112 | value: string, |
| 2113 | operation: "add" | "remove", |
| 2114 | context?: TaskNotesMutationContext |
| 2115 | ): Promise<TaskInfo> { |
| 2116 | const task = await this.requireTask(path); |
| 2117 | const existingValues = task[property] ?? []; |
| 2118 | const normalizedValue = value.trim(); |
| 2119 | if (!normalizedValue) { |
| 2120 | throw new TaskNotesApiError( |
| 2121 | "invalid_input", |
| 2122 | `TaskNotes API ${operation} ${property} expects a non-empty value`, |
| 2123 | { status: 400, details: { operation, property } } |
| 2124 | ); |
| 2125 | } |
| 2126 | |
| 2127 | const nextValues = |
| 2128 | operation === "add" |
| 2129 | ? Array.from(new Set([...existingValues, normalizedValue])) |
| 2130 | : existingValues.filter((entry) => entry !== normalizedValue); |
| 2131 | |
| 2132 | return this.updateTask(task.path, { [property]: nextValues }, context); |
| 2133 | } |
| 2134 | |
| 2135 | private async addReminder( |
| 2136 | path: string, |
no test coverage detected