(
path: string,
content: string,
mimeType = "text/plain"
)
| 936 | } |
| 937 | |
| 938 | async appendFile( |
| 939 | path: string, |
| 940 | content: string, |
| 941 | mimeType = "text/plain" |
| 942 | ): Promise<void> { |
| 943 | await this.ensureInit(); |
| 944 | const normalized = await this.resolveSymlink(normalizePath(path)); |
| 945 | const T = this.tableName; |
| 946 | |
| 947 | const row = ( |
| 948 | await this.sql.query<{ |
| 949 | type: string; |
| 950 | storage_backend: string; |
| 951 | content_encoding: string; |
| 952 | }>( |
| 953 | `SELECT type, storage_backend, content_encoding |
| 954 | FROM ${T} WHERE path = ?`, |
| 955 | normalized |
| 956 | ) |
| 957 | )[0]; |
| 958 | |
| 959 | if (!row) { |
| 960 | await this.writeFile(path, content, mimeType); |
| 961 | return; |
| 962 | } |
| 963 | |
| 964 | if (row.type !== "file") { |
| 965 | throw new Error(`EISDIR: ${path} is a directory`); |
| 966 | } |
| 967 | |
| 968 | if (row.storage_backend === "inline" && row.content_encoding === "utf8") { |
| 969 | const appendSize = TEXT_ENCODER.encode(content).byteLength; |
| 970 | const now = Math.floor(Date.now() / 1000); |
| 971 | await this.sql.run( |
| 972 | `UPDATE ${T} SET |
| 973 | content = content || ?, |
| 974 | size = size + ?, |
| 975 | modified_at = ? |
| 976 | WHERE path = ?`, |
| 977 | content, |
| 978 | appendSize, |
| 979 | now, |
| 980 | normalized |
| 981 | ); |
| 982 | this.emit("update", normalized, "file"); |
| 983 | return; |
| 984 | } |
| 985 | |
| 986 | const existing = await this.readFile(path); |
| 987 | await this.writeFile(path, (existing ?? "") + content, mimeType); |
| 988 | } |
| 989 | |
| 990 | async deleteFile(path: string): Promise<boolean> { |
| 991 | await this.ensureInit(); |
nothing calls this directly
no test coverage detected