(path: string)
| 567 | } |
| 568 | |
| 569 | async readFileBytes(path: string): Promise<Uint8Array | null> { |
| 570 | await this.ensureInit(); |
| 571 | const normalized = normalizePath(path); |
| 572 | const resolved = await this.resolveSymlink(normalized); |
| 573 | const T = this.tableName; |
| 574 | const rows = await this.sql.query<{ |
| 575 | type: string; |
| 576 | storage_backend: string; |
| 577 | r2_key: string | null; |
| 578 | content: string | null; |
| 579 | content_encoding: string; |
| 580 | }>( |
| 581 | `SELECT type, storage_backend, r2_key, content, content_encoding |
| 582 | FROM ${T} WHERE path = ?`, |
| 583 | resolved |
| 584 | ); |
| 585 | const r = rows[0]; |
| 586 | if (!r) return null; |
| 587 | if (r.type !== "file") throw new Error(`EISDIR: ${path} is a directory`); |
| 588 | this._observe("workspace:read", { |
| 589 | path: resolved, |
| 590 | storage: r.storage_backend as "inline" | "r2" |
| 591 | }); |
| 592 | |
| 593 | if (r.storage_backend === "r2" && r.r2_key) { |
| 594 | const r2 = this.getR2(); |
| 595 | if (!r2) { |
| 596 | throw new Error( |
| 597 | `File ${path} is stored in R2 but no R2 bucket was provided` |
| 598 | ); |
| 599 | } |
| 600 | const obj = await r2.get(r.r2_key); |
| 601 | if (!obj) return new Uint8Array(0); |
| 602 | return new Uint8Array(await obj.arrayBuffer()); |
| 603 | } |
| 604 | |
| 605 | if (r.content_encoding === "base64" && r.content) { |
| 606 | return base64ToBytes(r.content); |
| 607 | } |
| 608 | return TEXT_ENCODER.encode(r.content ?? ""); |
| 609 | } |
| 610 | |
| 611 | async writeFileBytes( |
| 612 | path: string, |
no test coverage detected