1- import { exists , readdir , stat , Stats , mkdir , rmdir , open , close } from "fs" ;
1+ import { exists , readdir , stat , Stats , mkdir , rmdir , open , close , access } from "fs" ;
22import { IFolder } from "ithit.webdav.server/Class1/IFolder" ;
33import { IHierarchyItem } from "ithit.webdav.server/IHierarchyItem" ;
44import { IItemCollection } from "ithit.webdav.server/IItemCollection" ;
@@ -11,6 +11,7 @@ import { DavHierarchyItem } from "./DavHierarchyItem";
1111import { DavException } from "ithit.webdav.server/DavException" ;
1212import { DavStatus } from "ithit.webdav.server/DavStatus" ;
1313import { EncodeUtil } from "ithit.webdav.server/EncodeUtil" ;
14+ import { F_OK } from "constants" ;
1415
1516/**
1617 * Folder in WebDAV repository.
@@ -23,9 +24,10 @@ export class DavFolder extends DavHierarchyItem implements IFolder {
2324 * @returns Folder instance or null if physical folder not found in file system.
2425 */
2526 public static async getFolder ( context : DavContext , path : string ) : Promise < DavFolder | null > {
26- const folderPath : string = context . mapPath ( path ) + sep + path ;
27- const existFolder = await promisify ( exists ) ( folderPath ) ;
28- if ( ! existFolder ) {
27+ const folderPath : string = EncodeUtil . decodeUrlPart ( context . mapPath ( path ) + sep + path ) ;
28+ try {
29+ await promisify ( access ) ( folderPath , F_OK ) ;
30+ } catch ( err ) {
2931 return null ;
3032 }
3133
@@ -170,7 +172,51 @@ export class DavFolder extends DavHierarchyItem implements IFolder {
170172 * @param destName New name of this folder.
171173 * @param multistatus Information about child items that failed to move.
172174 */
173- public moveTo ( destFolder : IItemCollection , destName : string , multistatus : MultistatusException ) : void {
175+ public async moveTo ( destFolder : IItemCollection , destName : string , multistatus : MultistatusException ) : Promise < void > {
176+ await this . requireHasToken ( ) ;
177+ const targetFolder = destFolder as DavFolder ;
178+ if ( targetFolder == null ) {
179+ throw new DavException ( "Target folder doesn't exist" , undefined , DavStatus . CONFLICT ) ;
180+ }
181+
182+ if ( this . isRecursive ( targetFolder ) ) {
183+ throw new DavException ( "Cannot move folder to its subtree." , undefined , DavStatus . FORBIDDEN ) ;
184+ }
185+
186+ const targetPath = ( targetFolder . path + EncodeUtil . encodeUrlPart ( destName ) ) ;
187+ try {
188+ // Remove item with the same name at destination if it exists.
189+ const item = await this . context . getHierarchyItem ( targetPath ) ;
190+ if ( item !== null ) {
191+ await item . delete ( multistatus ) ;
192+ }
193+
194+ await targetFolder . createFolder ( destName ) ;
195+ } catch ( err ) {
196+ // Continue the operation but report error with destination path to client.
197+ multistatus . addInnerException ( targetPath , undefined , err ) ;
198+ return ;
199+ }
200+
201+ // Move child items.
202+ let movedSuccessfully = true ;
203+ const createdFolder = await this . context . getHierarchyItem ( targetPath ) ;
204+ const children = await this . getChildren ( [ new PropertyName ( ) ] ) ;
205+ for ( let i = 0 ; i < children . length ; i ++ ) {
206+ const item = children [ i ] ;
207+
208+ try {
209+ await item . moveTo ( createdFolder as IItemCollection , item . name , multistatus ) ;
210+ } catch ( err ) {
211+ // If a child item failed to copy we continue but report error to client.
212+ multistatus . addInnerException ( item . path , undefined , err ) ;
213+ movedSuccessfully = false ;
214+ }
215+ }
216+
217+ if ( movedSuccessfully ) {
218+ await this . delete ( multistatus ) ;
219+ }
174220 }
175221
176222 /**
@@ -208,6 +254,7 @@ export class DavFolder extends DavHierarchyItem implements IFolder {
208254 * @returns List of @see IHierarchyItemAsync satisfying search request.
209255 */
210256 public search ( searchString : string , options : any , propNames : PropertyName [ ] ) : void {
257+ // Not implemented currently.
211258 }
212259 //$>
213260
0 commit comments