(
path: string
)
| 849 | } |
| 850 | |
| 851 | async readFileStream( |
| 852 | path: string |
| 853 | ): Promise<ReadableStream<Uint8Array> | null> { |
| 854 | await this.ensureInit(); |
| 855 | const normalized = normalizePath(path); |
| 856 | const resolved = await this.resolveSymlink(normalized); |
| 857 | const T = this.tableName; |
| 858 | const rows = await this.sql.query<{ |
| 859 | type: string; |
| 860 | storage_backend: string; |
| 861 | r2_key: string | null; |
| 862 | content: string | null; |
| 863 | content_encoding: string; |
| 864 | }>( |
| 865 | `SELECT type, storage_backend, r2_key, content, content_encoding |
| 866 | FROM ${T} WHERE path = ?`, |
| 867 | resolved |
| 868 | ); |
| 869 | const r = rows[0]; |
| 870 | if (!r) return null; |
| 871 | if (r.type !== "file") throw new Error(`EISDIR: ${path} is a directory`); |
| 872 | this._observe("workspace:read", { |
| 873 | path: resolved, |
| 874 | storage: r.storage_backend as "inline" | "r2" |
| 875 | }); |
| 876 | |
| 877 | if (r.storage_backend === "r2" && r.r2_key) { |
| 878 | const r2 = this.getR2(); |
| 879 | if (!r2) { |
| 880 | throw new Error( |
| 881 | `File ${path} is stored in R2 but no R2 bucket was provided` |
| 882 | ); |
| 883 | } |
| 884 | const obj = await r2.get(r.r2_key); |
| 885 | if (!obj) { |
| 886 | return new ReadableStream({ |
| 887 | start(c) { |
| 888 | c.close(); |
| 889 | } |
| 890 | }); |
| 891 | } |
| 892 | return obj.body; |
| 893 | } |
| 894 | |
| 895 | const bytes = |
| 896 | r.content_encoding === "base64" && r.content |
| 897 | ? base64ToBytes(r.content) |
| 898 | : TEXT_ENCODER.encode(r.content ?? ""); |
| 899 | return new ReadableStream({ |
| 900 | start(controller) { |
| 901 | controller.enqueue(bytes); |
| 902 | controller.close(); |
| 903 | } |
| 904 | }); |
| 905 | } |
| 906 | |
| 907 | async writeFileStream( |
| 908 | path: string, |
no test coverage detected