1+ import { FileSystemError } from "../error" ;
12import type { FileInfo , FileReader , FileWriter } from "../filesystem" ;
3+ import type { FileCreateOptions } from "../filesystem" ;
24import { joinPath } from "../utils" ;
35import type DropboxFileSystem from "./dropbox" ;
46
@@ -53,12 +55,30 @@ export class DropboxFileWriter implements FileWriter {
5355
5456 fs : DropboxFileSystem ;
5557
56- constructor ( fs : DropboxFileSystem , path : string ) {
58+ opts ?: FileCreateOptions ;
59+
60+ constructor ( fs : DropboxFileSystem , path : string , opts ?: FileCreateOptions ) {
5761 this . fs = fs ;
5862 this . path = path ;
63+ this . opts = opts ;
5964 }
6065
6166 async write ( content : string | Blob ) : Promise < void > {
67+ if ( this . opts ?. expectedDigest && ! this . opts . expectedVersion ) {
68+ throw new FileSystemError ( {
69+ provider : "dropbox" ,
70+ message : "Dropbox conditional writes require expectedVersion (rev), not expectedDigest" ,
71+ code : "unsupported_conditional_write" ,
72+ unsupported : true ,
73+ } ) ;
74+ }
75+ if ( this . opts ?. createOnly || this . opts ?. overwrite === false ) {
76+ return this . createNewFile ( content ) ;
77+ }
78+ if ( this . opts ?. expectedVersion ) {
79+ return this . updateFile ( content , this . opts . expectedVersion ) ;
80+ }
81+
6282 // 检查文件是否存在
6383 const exists = await this . fs . exists ( this . path ) ;
6484
@@ -71,23 +91,19 @@ export class DropboxFileWriter implements FileWriter {
7191 }
7292 }
7393
74- private async updateFile ( content : string | Blob ) : Promise < void > {
94+ private async updateFile ( content : string | Blob , rev ?: string ) : Promise < void > {
7595 const myHeaders = new Headers ( ) ;
7696 myHeaders . append ( "Content-Type" , "application/octet-stream" ) ;
7797 myHeaders . append (
7898 "Dropbox-API-Arg" ,
7999 JSON . stringify ( {
80100 path : this . path ,
81- mode : "overwrite" ,
101+ mode : rev ? { ".tag" : "update" , update : rev } : "overwrite" ,
82102 autorename : false ,
83103 } )
84104 ) ;
85105
86- await this . fs . request ( "https://content.dropboxapi.com/2/files/upload" , {
87- method : "POST" ,
88- headers : myHeaders ,
89- body : content instanceof Blob ? content : new Blob ( [ content ] ) ,
90- } ) ;
106+ await this . upload ( myHeaders , content ) ;
91107
92108 return Promise . resolve ( ) ;
93109 }
@@ -104,12 +120,30 @@ export class DropboxFileWriter implements FileWriter {
104120 } )
105121 ) ;
106122
107- await this . fs . request ( "https://content.dropboxapi.com/2/files/upload" , {
108- method : "POST" ,
109- headers : myHeaders ,
110- body : content instanceof Blob ? content : new Blob ( [ content ] ) ,
111- } ) ;
123+ await this . upload ( myHeaders , content ) ;
112124
113125 return Promise . resolve ( ) ;
114126 }
127+
128+ private async upload ( headers : Headers , content : string | Blob ) : Promise < void > {
129+ try {
130+ await this . fs . request ( "https://content.dropboxapi.com/2/files/upload" , {
131+ method : "POST" ,
132+ headers,
133+ body : content instanceof Blob ? content : new Blob ( [ content ] ) ,
134+ } ) ;
135+ } catch ( error ) {
136+ const message = error instanceof Error ? error . message : String ( error ) ;
137+ if ( message . includes ( "409" ) || message . includes ( "conflict" ) || message . includes ( "incorrect_offset" ) ) {
138+ throw new FileSystemError ( {
139+ provider : "dropbox" ,
140+ message,
141+ status : message . includes ( "409" ) ? 409 : undefined ,
142+ conflict : true ,
143+ raw : error ,
144+ } ) ;
145+ }
146+ throw error ;
147+ }
148+ }
115149}
0 commit comments