(
path: string,
content: string,
mimeType = "text/plain"
)
| 727 | } |
| 728 | |
| 729 | async writeFile( |
| 730 | path: string, |
| 731 | content: string, |
| 732 | mimeType = "text/plain" |
| 733 | ): Promise<void> { |
| 734 | await this.ensureInit(); |
| 735 | const normalized = await this.resolveSymlink(normalizePath(path)); |
| 736 | if (normalized === "/") |
| 737 | throw new Error("EISDIR: cannot write to root directory"); |
| 738 | |
| 739 | const parentPath = getParent(normalized); |
| 740 | const name = getBasename(normalized); |
| 741 | const bytes = TEXT_ENCODER.encode(content); |
| 742 | const size = bytes.byteLength; |
| 743 | const now = Math.floor(Date.now() / 1000); |
| 744 | const T = this.tableName; |
| 745 | |
| 746 | await this.ensureParentDir(parentPath); |
| 747 | |
| 748 | const existing = ( |
| 749 | await this.sql.query<{ |
| 750 | storage_backend: string; |
| 751 | r2_key: string | null; |
| 752 | }>(`SELECT storage_backend, r2_key FROM ${T} WHERE path = ?`, normalized) |
| 753 | )[0]; |
| 754 | |
| 755 | const r2 = this.getR2(); |
| 756 | |
| 757 | if (size >= this.threshold && r2) { |
| 758 | const key = this.r2Key(normalized); |
| 759 | |
| 760 | if (existing?.storage_backend === "r2" && existing.r2_key !== key) { |
| 761 | await r2.delete(existing.r2_key!); |
| 762 | } |
| 763 | |
| 764 | await r2.put(key, bytes, { |
| 765 | httpMetadata: { contentType: mimeType } |
| 766 | }); |
| 767 | |
| 768 | try { |
| 769 | await this.sql.run( |
| 770 | `INSERT INTO ${T} |
| 771 | (path, parent_path, name, type, mime_type, size, |
| 772 | storage_backend, r2_key, content_encoding, content, created_at, modified_at) |
| 773 | VALUES (?, ?, ?, 'file', ?, ?, 'r2', ?, 'utf8', NULL, ?, ?) |
| 774 | ON CONFLICT(path) DO UPDATE SET |
| 775 | mime_type = excluded.mime_type, |
| 776 | size = excluded.size, |
| 777 | storage_backend = 'r2', |
| 778 | r2_key = excluded.r2_key, |
| 779 | content_encoding = 'utf8', |
| 780 | content = NULL, |
| 781 | modified_at = excluded.modified_at`, |
| 782 | normalized, |
| 783 | parentPath, |
| 784 | name, |
| 785 | mimeType, |
| 786 | size, |
no test coverage detected