@@ -7,25 +7,23 @@ import * as fs from 'fs';
77import * as path from 'path' ;
88import * as vscode from 'vscode' ;
99import type { WebDavConfigProvider } from './webdav-config.js' ;
10+ import { type WebDavFileSystemProvider , WEBDAV_SCHEME , webdavPathToUri } from './webdav-fs-provider.js' ;
1011import type { WebDavTreeDataProvider , WebDavTreeItem } from './webdav-tree-provider.js' ;
1112
1213export function registerWebDavCommands (
13- context : vscode . ExtensionContext ,
14+ _context : vscode . ExtensionContext ,
1415 configProvider : WebDavConfigProvider ,
1516 treeProvider : WebDavTreeDataProvider ,
17+ fsProvider : WebDavFileSystemProvider ,
1618) : vscode . Disposable [ ] {
1719 const refresh = vscode . commands . registerCommand ( 'b2c-dx.webdav.refresh' , ( ) => {
20+ fsProvider . clearCache ( ) ;
1821 configProvider . reset ( ) ;
1922 treeProvider . refresh ( ) ;
2023 } ) ;
2124
2225 const newFolder = vscode . commands . registerCommand ( 'b2c-dx.webdav.newFolder' , async ( node : WebDavTreeItem ) => {
2326 if ( ! node ) return ;
24- const instance = configProvider . getInstance ( ) ;
25- if ( ! instance ) {
26- vscode . window . showErrorMessage ( 'WebDAV: No B2C instance configured.' ) ;
27- return ;
28- }
2927
3028 const name = await vscode . window . showInputBox ( {
3129 title : 'New Folder' ,
@@ -45,8 +43,7 @@ export function registerWebDavCommands(
4543 { location : vscode . ProgressLocation . Notification , title : `Creating folder ${ name . trim ( ) } ...` } ,
4644 async ( ) => {
4745 try {
48- await instance . webdav . mkcol ( fullPath ) ;
49- treeProvider . refreshNode ( node ) ;
46+ await fsProvider . createDirectory ( webdavPathToUri ( fullPath ) ) ;
5047 } catch ( err ) {
5148 const message = err instanceof Error ? err . message : String ( err ) ;
5249 vscode . window . showErrorMessage ( `WebDAV: Failed to create folder: ${ message } ` ) ;
@@ -57,11 +54,6 @@ export function registerWebDavCommands(
5754
5855 const uploadFile = vscode . commands . registerCommand ( 'b2c-dx.webdav.uploadFile' , async ( node : WebDavTreeItem ) => {
5956 if ( ! node ) return ;
60- const instance = configProvider . getInstance ( ) ;
61- if ( ! instance ) {
62- vscode . window . showErrorMessage ( 'WebDAV: No B2C instance configured.' ) ;
63- return ;
64- }
6557
6658 const uris = await vscode . window . showOpenDialog ( {
6759 title : 'Select file to upload' ,
@@ -80,19 +72,10 @@ export function registerWebDavCommands(
8072 async ( ) => {
8173 try {
8274 const content = fs . readFileSync ( uri . fsPath ) ;
83- const ext = path . extname ( fileName ) . toLowerCase ( ) ;
84- const mime : Record < string , string > = {
85- '.json' : 'application/json' ,
86- '.xml' : 'application/xml' ,
87- '.zip' : 'application/zip' ,
88- '.js' : 'application/javascript' ,
89- '.ts' : 'application/typescript' ,
90- '.html' : 'text/html' ,
91- '.css' : 'text/css' ,
92- '.txt' : 'text/plain' ,
93- } ;
94- await instance . webdav . put ( fullPath , content , mime [ ext ] ) ;
95- treeProvider . refreshNode ( node ) ;
75+ await fsProvider . writeFile ( webdavPathToUri ( fullPath ) , new Uint8Array ( content ) , {
76+ create : true ,
77+ overwrite : true ,
78+ } ) ;
9679 } catch ( err ) {
9780 const message = err instanceof Error ? err . message : String ( err ) ;
9881 vscode . window . showErrorMessage ( `WebDAV: Upload failed: ${ message } ` ) ;
@@ -103,11 +86,6 @@ export function registerWebDavCommands(
10386
10487 const deleteItem = vscode . commands . registerCommand ( 'b2c-dx.webdav.delete' , async ( node : WebDavTreeItem ) => {
10588 if ( ! node ) return ;
106- const instance = configProvider . getInstance ( ) ;
107- if ( ! instance ) {
108- vscode . window . showErrorMessage ( 'WebDAV: No B2C instance configured.' ) ;
109- return ;
110- }
11189
11290 const detail = node . isCollection
11391 ? 'This directory and its contents will be deleted.'
@@ -124,10 +102,7 @@ export function registerWebDavCommands(
124102 { location : vscode . ProgressLocation . Notification , title : `Deleting ${ node . fileName } ...` } ,
125103 async ( ) => {
126104 try {
127- await instance . webdav . delete ( node . webdavPath ) ;
128- // Refresh parent by refreshing the whole tree — the parent node
129- // is not directly available from the child.
130- treeProvider . refresh ( ) ;
105+ await fsProvider . delete ( webdavPathToUri ( node . webdavPath ) ) ;
131106 } catch ( err ) {
132107 const message = err instanceof Error ? err . message : String ( err ) ;
133108 vscode . window . showErrorMessage ( `WebDAV: Delete failed: ${ message } ` ) ;
@@ -138,11 +113,6 @@ export function registerWebDavCommands(
138113
139114 const download = vscode . commands . registerCommand ( 'b2c-dx.webdav.download' , async ( node : WebDavTreeItem ) => {
140115 if ( ! node ) return ;
141- const instance = configProvider . getInstance ( ) ;
142- if ( ! instance ) {
143- vscode . window . showErrorMessage ( 'WebDAV: No B2C instance configured.' ) ;
144- return ;
145- }
146116
147117 const defaultUri = vscode . workspace . workspaceFolders ?. [ 0 ] ?. uri
148118 ? vscode . Uri . joinPath ( vscode . workspace . workspaceFolders [ 0 ] . uri , node . fileName )
@@ -157,8 +127,8 @@ export function registerWebDavCommands(
157127 { location : vscode . ProgressLocation . Notification , title : `Downloading ${ node . fileName } ...` } ,
158128 async ( ) => {
159129 try {
160- const buffer = await instance . webdav . get ( node . webdavPath ) ;
161- await vscode . workspace . fs . writeFile ( saveUri , new Uint8Array ( buffer ) ) ;
130+ const content = await fsProvider . readFile ( webdavPathToUri ( node . webdavPath ) ) ;
131+ await vscode . workspace . fs . writeFile ( saveUri , content ) ;
162132 vscode . window . showInformationMessage ( `Downloaded to ${ saveUri . fsPath } ` ) ;
163133 } catch ( err ) {
164134 const message = err instanceof Error ? err . message : String ( err ) ;
@@ -170,32 +140,56 @@ export function registerWebDavCommands(
170140
171141 const openFile = vscode . commands . registerCommand ( 'b2c-dx.webdav.openFile' , async ( node : WebDavTreeItem ) => {
172142 if ( ! node ) return ;
173- const instance = configProvider . getInstance ( ) ;
174- if ( ! instance ) {
175- vscode . window . showErrorMessage ( 'WebDAV: No B2C instance configured.' ) ;
176- return ;
177- }
143+ const uri = webdavPathToUri ( node . webdavPath ) ;
144+ await vscode . commands . executeCommand ( 'vscode.open' , uri ) ;
145+ } ) ;
178146
179- const previewDir = vscode . Uri . joinPath ( context . globalStorageUri , 'webdav-preview' ) ;
180- const tempFileUri = vscode . Uri . joinPath ( previewDir , node . webdavPath ) ;
147+ const newFile = vscode . commands . registerCommand ( 'b2c-dx.webdav.newFile' , async ( node : WebDavTreeItem ) => {
148+ if ( ! node ) return ;
181149
150+ const name = await vscode . window . showInputBox ( {
151+ title : 'New File' ,
152+ prompt : `Create file under ${ node . webdavPath } ` ,
153+ placeHolder : 'File name' ,
154+ validateInput : ( value : string ) => {
155+ const trimmed = value . trim ( ) ;
156+ if ( ! trimmed ) return 'Enter a file name' ;
157+ if ( / [ \\ / : * ? " < > | ] / . test ( trimmed ) ) return 'Name cannot contain \\ / : * ? " < > |' ;
158+ return null ;
159+ } ,
160+ } ) ;
161+ if ( ! name ) return ;
162+
163+ const fullPath = `${ node . webdavPath } /${ name . trim ( ) } ` ;
164+ const uri = webdavPathToUri ( fullPath ) ;
182165 await vscode . window . withProgress (
183- { location : vscode . ProgressLocation . Notification , title : `Opening ${ node . fileName } ...` } ,
166+ { location : vscode . ProgressLocation . Notification , title : `Creating file ${ name . trim ( ) } ...` } ,
184167 async ( ) => {
185168 try {
186- const buffer = await instance . webdav . get ( node . webdavPath ) ;
187- // Ensure parent directories exist
188- const parentDir = vscode . Uri . joinPath ( tempFileUri , '..' ) ;
189- await vscode . workspace . fs . createDirectory ( parentDir ) ;
190- await vscode . workspace . fs . writeFile ( tempFileUri , new Uint8Array ( buffer ) ) ;
191- await vscode . commands . executeCommand ( 'vscode.open' , tempFileUri ) ;
169+ await fsProvider . writeFile ( uri , new Uint8Array ( 0 ) , { create : true , overwrite : false } ) ;
170+ await vscode . commands . executeCommand ( 'vscode.open' , uri ) ;
192171 } catch ( err ) {
193172 const message = err instanceof Error ? err . message : String ( err ) ;
194- vscode . window . showErrorMessage ( `WebDAV: Failed to open file: ${ message } ` ) ;
173+ vscode . window . showErrorMessage ( `WebDAV: Failed to create file: ${ message } ` ) ;
195174 }
196175 } ,
197176 ) ;
198177 } ) ;
199178
200- return [ refresh , newFolder , uploadFile , deleteItem , download , openFile ] ;
179+ const mountWorkspace = vscode . commands . registerCommand ( 'b2c-dx.webdav.mountWorkspace' , ( ) => {
180+ vscode . workspace . updateWorkspaceFolders ( vscode . workspace . workspaceFolders ?. length ?? 0 , 0 , {
181+ uri : vscode . Uri . parse ( `${ WEBDAV_SCHEME } :/` ) ,
182+ name : 'B2C Commerce WebDAV' ,
183+ } ) ;
184+ } ) ;
185+
186+ const unmountWorkspace = vscode . commands . registerCommand ( 'b2c-dx.webdav.unmountWorkspace' , ( ) => {
187+ const folders = vscode . workspace . workspaceFolders ?? [ ] ;
188+ const idx = folders . findIndex ( ( f ) => f . uri . scheme === WEBDAV_SCHEME ) ;
189+ if ( idx >= 0 ) {
190+ vscode . workspace . updateWorkspaceFolders ( idx , 1 ) ;
191+ }
192+ } ) ;
193+
194+ return [ refresh , newFolder , newFile , uploadFile , deleteItem , download , openFile , mountWorkspace , unmountWorkspace ] ;
201195}
0 commit comments