(
path: string,
opts?: { recursive?: boolean; force?: boolean }
)
| 1162 | } |
| 1163 | |
| 1164 | async rm( |
| 1165 | path: string, |
| 1166 | opts?: { recursive?: boolean; force?: boolean } |
| 1167 | ): Promise<void> { |
| 1168 | await this.ensureInit(); |
| 1169 | const normalized = normalizePath(path); |
| 1170 | if (normalized === "/") |
| 1171 | throw new Error("EPERM: cannot remove root directory"); |
| 1172 | const T = this.tableName; |
| 1173 | |
| 1174 | const rows = await this.sql.query<{ type: string }>( |
| 1175 | `SELECT type FROM ${T} WHERE path = ?`, |
| 1176 | normalized |
| 1177 | ); |
| 1178 | |
| 1179 | if (!rows[0]) { |
| 1180 | if (opts?.force) return; |
| 1181 | throw new Error(`ENOENT: no such file or directory: ${path}`); |
| 1182 | } |
| 1183 | |
| 1184 | if (rows[0].type === "directory") { |
| 1185 | const children = await this.sql.query<{ cnt: number }>( |
| 1186 | `SELECT COUNT(*) AS cnt FROM ${T} WHERE parent_path = ?`, |
| 1187 | normalized |
| 1188 | ); |
| 1189 | if ((children[0]?.cnt ?? 0) > 0) { |
| 1190 | if (!opts?.recursive) { |
| 1191 | throw new Error(`ENOTEMPTY: directory not empty: ${path}`); |
| 1192 | } |
| 1193 | await this.deleteDescendants(normalized); |
| 1194 | } |
| 1195 | } else { |
| 1196 | const fileRow = ( |
| 1197 | await this.sql.query<{ |
| 1198 | storage_backend: string; |
| 1199 | r2_key: string | null; |
| 1200 | }>( |
| 1201 | `SELECT storage_backend, r2_key FROM ${T} WHERE path = ?`, |
| 1202 | normalized |
| 1203 | ) |
| 1204 | )[0]; |
| 1205 | if (fileRow?.storage_backend === "r2" && fileRow.r2_key) { |
| 1206 | const r2 = this.getR2(); |
| 1207 | if (r2) await r2.delete(fileRow.r2_key); |
| 1208 | } |
| 1209 | } |
| 1210 | |
| 1211 | await this.sql.run(`DELETE FROM ${T} WHERE path = ?`, normalized); |
| 1212 | this.emit("delete", normalized, rows[0].type as EntryType); |
| 1213 | this._observe("workspace:rm", { |
| 1214 | path: normalized, |
| 1215 | recursive: !!opts?.recursive |
| 1216 | }); |
| 1217 | } |
| 1218 | |
| 1219 | // ── Copy / Move ─────────────────────────────────────────────── |
| 1220 |
no test coverage detected