@eclipse-lyra/extension-webdav 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ declare const _default: {
2
+ "namespace": "extensions",
3
+ "en": {
4
+ "EXT_WEBDAV_NAME": "WebDAV Workspace",
5
+ "EXT_WEBDAV_DESC": "Connect to WebDAV servers (Nextcloud, ownCloud) as workspace folders for cloud storage integration"
6
+ },
7
+ "de": {
8
+ "EXT_WEBDAV_NAME": "WebDAV-Arbeitsbereich",
9
+ "EXT_WEBDAV_DESC": "Verbinden Sie sich mit WebDAV-Servern (Nextcloud, ownCloud) als Arbeitsbereichsordner für Cloud-Speicher-Integration"
10
+ }
11
+ };
12
+
13
+ export default _default;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ import { contributionRegistry, SYSTEM_LANGUAGE_BUNDLES, i18nLazy, extensionRegistry } from "@eclipse-lyra/core";
2
+ import pkg from "../package.json";
3
+ const namespace = "extensions";
4
+ const en = { "EXT_WEBDAV_NAME": "WebDAV Workspace", "EXT_WEBDAV_DESC": "Connect to WebDAV servers (Nextcloud, ownCloud) as workspace folders for cloud storage integration" };
5
+ const de = { "EXT_WEBDAV_NAME": "WebDAV-Arbeitsbereich", "EXT_WEBDAV_DESC": "Verbinden Sie sich mit WebDAV-Servern (Nextcloud, ownCloud) als Arbeitsbereichsordner für Cloud-Speicher-Integration" };
6
+ const bundle = {
7
+ namespace,
8
+ en,
9
+ de
10
+ };
11
+ contributionRegistry.registerContribution(SYSTEM_LANGUAGE_BUNDLES, bundle);
12
+ const t = i18nLazy("extensions");
13
+ extensionRegistry.registerExtension({
14
+ id: pkg.name,
15
+ name: t("EXT_WEBDAV_NAME"),
16
+ description: t("EXT_WEBDAV_DESC"),
17
+ loader: () => import("./webdav-extension-DhFP7zW5.js"),
18
+ icon: "cloud"
19
+ });
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { extensionRegistry, i18nLazy, contributionRegistry, SYSTEM_LANGUAGE_BUNDLES } from '@eclipse-lyra/core';\nimport bundle from './i18n.json';\nimport pkg from '../package.json';\n\ncontributionRegistry.registerContribution(SYSTEM_LANGUAGE_BUNDLES, bundle as any);\n\nconst t = i18nLazy('extensions');\n\nextensionRegistry.registerExtension({\n id: pkg.name,\n name: t('EXT_WEBDAV_NAME'),\n description: t('EXT_WEBDAV_DESC'),\n loader: () => import(\"./webdav-extension\"),\n icon: \"cloud\",\n \n \n});\n"],"names":[],"mappings":";;;;;;;;;;AAIA,qBAAqB,qBAAqB,yBAAyB,MAAa;AAEhF,MAAM,IAAI,SAAS,YAAY;AAE/B,kBAAkB,kBAAkB;AAAA,EAClC,IAAI,IAAI;AAAA,EACR,MAAM,EAAE,iBAAiB;AAAA,EACzB,aAAa,EAAE,iBAAiB;AAAA,EAChC,QAAQ,MAAM,OAAO,gCAAoB;AAAA,EACzC,MAAM;AAGR,CAAC;"}
@@ -0,0 +1,29 @@
1
+ export interface WebDAVConnectionInfo {
2
+ url: string;
3
+ username?: string;
4
+ password?: string;
5
+ }
6
+ export interface WebDAVResource {
7
+ href: string;
8
+ displayName: string;
9
+ isDirectory: boolean;
10
+ contentType?: string;
11
+ contentLength?: number;
12
+ lastModified?: Date;
13
+ etag?: string;
14
+ }
15
+ export declare class WebDAVClient {
16
+ private axios;
17
+ private baseUrl;
18
+ constructor(connectionInfo: WebDAVConnectionInfo);
19
+ propfind(path: string, depth?: number): Promise<WebDAVResource[]>;
20
+ getFile(path: string): Promise<ArrayBuffer>;
21
+ putFile(path: string, content: string | Blob | ArrayBuffer): Promise<void>;
22
+ deleteResource(path: string): Promise<void>;
23
+ createDirectory(path: string): Promise<void>;
24
+ moveResource(fromPath: string, toPath: string): Promise<void>;
25
+ copyResource(fromPath: string, toPath: string): Promise<void>;
26
+ private parseMultiStatus;
27
+ getBaseUrl(): string;
28
+ }
29
+ //# sourceMappingURL=webdav-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webdav-client.d.ts","sourceRoot":"","sources":["../src/webdav-client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,YAAY;IACrB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,OAAO,CAAS;gBAEZ,cAAc,EAAE,oBAAoB;IAsB1C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAyBpE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAO3C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1E,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5C,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7D,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnE,OAAO,CAAC,gBAAgB;IAgCxB,UAAU,IAAI,MAAM;CAGvB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Commands for WebDAV workspace integration
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=webdav-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webdav-commands.d.ts","sourceRoot":"","sources":["../src/webdav-commands.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,17 @@
1
+ import { LyraElement } from '@eclipse-lyra/core';
2
+ export declare class LyraWebDAVConnect extends LyraElement {
3
+ private url;
4
+ private username;
5
+ private password;
6
+ private connecting;
7
+ private showHelp;
8
+ private handleConnect;
9
+ private toggleHelp;
10
+ protected render(): import('lit-html').TemplateResult<1>;
11
+ }
12
+ declare global {
13
+ interface HTMLElementTagNameMap {
14
+ 'lyra-webdav-connect': LyraWebDAVConnect;
15
+ }
16
+ }
17
+ //# sourceMappingURL=webdav-connect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webdav-connect.d.ts","sourceRoot":"","sources":["../src/webdav-connect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQjD,qBACa,iBAAkB,SAAQ,WAAW;IAG9C,OAAO,CAAC,GAAG,CAAM;IAGjB,OAAO,CAAC,QAAQ,CAAM;IAGtB,OAAO,CAAC,QAAQ,CAAM;IAGtB,OAAO,CAAC,UAAU,CAAS;IAG3B,OAAO,CAAC,QAAQ,CAAS;YAEX,aAAa;IA4C3B,OAAO,CAAC,UAAU;IAIlB,SAAS,CAAC,MAAM;CAqJnB;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,qBAAqB,EAAE,iBAAiB,CAAC;KAC5C;CACJ"}
@@ -0,0 +1,753 @@
1
+ import { Directory, publish, TOPIC_WORKSPACE_CHANGED, File, FileContentType, createLogger, LyraElement, workspaceService, registerAll } from "@eclipse-lyra/core";
2
+ import axios from "axios";
3
+ import { state, customElement } from "lit/decorators.js";
4
+ import { html, render } from "lit";
5
+ class WebDAVClient {
6
+ constructor(connectionInfo) {
7
+ this.baseUrl = connectionInfo.url;
8
+ const config = {
9
+ baseURL: connectionInfo.url,
10
+ headers: {
11
+ "Content-Type": "application/xml"
12
+ },
13
+ maxRedirects: 5
14
+ // Follow redirects
15
+ };
16
+ if (connectionInfo.username !== void 0) {
17
+ config.auth = {
18
+ username: connectionInfo.username,
19
+ password: connectionInfo.password || ""
20
+ };
21
+ }
22
+ this.axios = axios.create(config);
23
+ }
24
+ async propfind(path, depth = 1) {
25
+ const requestBody = `<?xml version="1.0" encoding="UTF-8"?>
26
+ <d:propfind xmlns:d="DAV:">
27
+ <d:prop>
28
+ <d:displayname/>
29
+ <d:resourcetype/>
30
+ <d:getcontenttype/>
31
+ <d:getcontentlength/>
32
+ <d:getlastmodified/>
33
+ <d:getetag/>
34
+ </d:prop>
35
+ </d:propfind>`;
36
+ const response = await this.axios.request({
37
+ method: "PROPFIND",
38
+ url: path,
39
+ headers: {
40
+ "Depth": depth.toString()
41
+ },
42
+ data: requestBody
43
+ });
44
+ return this.parseMultiStatus(response.data);
45
+ }
46
+ async getFile(path) {
47
+ const response = await this.axios.get(path, {
48
+ responseType: "arraybuffer"
49
+ });
50
+ return response.data;
51
+ }
52
+ async putFile(path, content) {
53
+ await this.axios.put(path, content, {
54
+ headers: {
55
+ "Content-Type": "application/octet-stream"
56
+ }
57
+ });
58
+ }
59
+ async deleteResource(path) {
60
+ await this.axios.delete(path);
61
+ }
62
+ async createDirectory(path) {
63
+ await this.axios.request({
64
+ method: "MKCOL",
65
+ url: path
66
+ });
67
+ }
68
+ async moveResource(fromPath, toPath) {
69
+ const destination = new URL(toPath, this.baseUrl).href;
70
+ await this.axios.request({
71
+ method: "MOVE",
72
+ url: fromPath,
73
+ headers: {
74
+ "Destination": destination,
75
+ "Overwrite": "F"
76
+ }
77
+ });
78
+ }
79
+ async copyResource(fromPath, toPath) {
80
+ const destination = new URL(toPath, this.baseUrl).href;
81
+ await this.axios.request({
82
+ method: "COPY",
83
+ url: fromPath,
84
+ headers: {
85
+ "Destination": destination,
86
+ "Overwrite": "F"
87
+ }
88
+ });
89
+ }
90
+ parseMultiStatus(xml) {
91
+ const parser = new DOMParser();
92
+ const doc = parser.parseFromString(xml, "text/xml");
93
+ const responses = doc.querySelectorAll("response");
94
+ const resources = [];
95
+ responses.forEach((response) => {
96
+ const href = response.querySelector("href")?.textContent || "";
97
+ const displayName = response.querySelector("displayname")?.textContent || "";
98
+ const resourceType = response.querySelector("resourcetype");
99
+ const isDirectory = !!resourceType?.querySelector("collection");
100
+ const contentType = response.querySelector("getcontenttype")?.textContent || void 0;
101
+ const contentLengthStr = response.querySelector("getcontentlength")?.textContent;
102
+ const contentLength = contentLengthStr ? parseInt(contentLengthStr) : void 0;
103
+ const lastModifiedStr = response.querySelector("getlastmodified")?.textContent;
104
+ const lastModified = lastModifiedStr ? new Date(lastModifiedStr) : void 0;
105
+ const etag = response.querySelector("getetag")?.textContent || void 0;
106
+ resources.push({
107
+ href,
108
+ displayName: displayName || href.split("/").filter(Boolean).pop() || "",
109
+ isDirectory,
110
+ contentType,
111
+ contentLength,
112
+ lastModified,
113
+ etag
114
+ });
115
+ });
116
+ return resources;
117
+ }
118
+ getBaseUrl() {
119
+ return this.baseUrl;
120
+ }
121
+ }
122
+ class WebDAVFileResource extends File {
123
+ constructor(client, resource, parent) {
124
+ super();
125
+ this.client = client;
126
+ this.resource = resource;
127
+ this.parent = parent;
128
+ }
129
+ getName() {
130
+ return this.resource.displayName;
131
+ }
132
+ getParent() {
133
+ return this.parent;
134
+ }
135
+ async getContents(options) {
136
+ const buffer = await this.client.getFile(this.resource.href);
137
+ if (!options || options?.contentType === FileContentType.TEXT) {
138
+ const decoder = new TextDecoder();
139
+ return decoder.decode(buffer);
140
+ }
141
+ if (options?.blob) {
142
+ return new Blob([buffer]);
143
+ }
144
+ if (options?.uri) {
145
+ const blob = new Blob([buffer]);
146
+ return URL.createObjectURL(blob);
147
+ }
148
+ return buffer;
149
+ }
150
+ async saveContents(contents, _options) {
151
+ await this.client.putFile(this.resource.href, contents);
152
+ publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());
153
+ }
154
+ async size() {
155
+ return this.resource.contentLength ?? null;
156
+ }
157
+ async delete() {
158
+ await this.client.deleteResource(this.resource.href);
159
+ publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());
160
+ }
161
+ async copyTo(targetPath) {
162
+ const targetFile = await this.getWorkspace().getResource(targetPath, { create: true });
163
+ if (!targetFile) {
164
+ throw new Error(`Failed to create target file: ${targetPath}`);
165
+ }
166
+ const contents = await this.getContents({ blob: true });
167
+ await targetFile.saveContents(contents);
168
+ }
169
+ async rename(newName) {
170
+ if (this.getName() === newName) {
171
+ return;
172
+ }
173
+ const pathParts = this.resource.href.split("/");
174
+ pathParts[pathParts.length - 1] = newName;
175
+ const newPath = pathParts.join("/");
176
+ await this.client.moveResource(this.resource.href, newPath);
177
+ this.resource.href = newPath;
178
+ this.resource.displayName = newName;
179
+ publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());
180
+ }
181
+ }
182
+ class WebDAVDirectoryResource extends Directory {
183
+ constructor(client, resource, parent) {
184
+ super();
185
+ this.client = client;
186
+ this.resource = resource;
187
+ this.parent = parent;
188
+ }
189
+ getName() {
190
+ return this.resource.displayName;
191
+ }
192
+ getParent() {
193
+ return this.parent;
194
+ }
195
+ async listChildren(forceRefresh = false) {
196
+ if (forceRefresh || !this.children) {
197
+ const resources = await this.client.propfind(this.resource.href, 1);
198
+ this.children = /* @__PURE__ */ new Map();
199
+ for (let i = 1; i < resources.length; i++) {
200
+ const res = resources[i];
201
+ const child = res.isDirectory ? new WebDAVDirectoryResource(this.client, res, this) : new WebDAVFileResource(this.client, res, this);
202
+ this.children.set(res.displayName, child);
203
+ }
204
+ }
205
+ return Array.from(this.children.values());
206
+ }
207
+ async getResource(path, options) {
208
+ if (!path) {
209
+ throw new Error("No path provided");
210
+ }
211
+ const segments = path.split("/").filter((s) => s.trim());
212
+ let currentResource = this;
213
+ for (let i = 0; i < segments.length; i++) {
214
+ const segment = segments[i];
215
+ if (currentResource instanceof WebDAVDirectoryResource) {
216
+ await currentResource.listChildren();
217
+ if (!currentResource.children) {
218
+ return null;
219
+ }
220
+ let next = currentResource.children.get(segment);
221
+ if (!next && options?.create) {
222
+ const fullPath = this.buildPath(currentResource.resource.href, segment);
223
+ if (i < segments.length - 1) {
224
+ await this.client.createDirectory(fullPath);
225
+ const newResource = {
226
+ href: fullPath,
227
+ displayName: segment,
228
+ isDirectory: true
229
+ };
230
+ next = new WebDAVDirectoryResource(this.client, newResource, currentResource);
231
+ currentResource.children.set(segment, next);
232
+ } else {
233
+ await this.client.putFile(fullPath, "");
234
+ const newResource = {
235
+ href: fullPath,
236
+ displayName: segment,
237
+ isDirectory: false,
238
+ contentLength: 0
239
+ };
240
+ next = new WebDAVFileResource(this.client, newResource, currentResource);
241
+ currentResource.children.set(segment, next);
242
+ publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());
243
+ return next;
244
+ }
245
+ }
246
+ if (!next) {
247
+ return null;
248
+ }
249
+ currentResource = next;
250
+ }
251
+ }
252
+ return currentResource;
253
+ }
254
+ async delete(name, _recursive = true) {
255
+ if (!name) {
256
+ return this.getParent()?.delete(this.getName());
257
+ }
258
+ const fullPath = this.buildPath(this.resource.href, name);
259
+ await this.client.deleteResource(fullPath);
260
+ this.children?.delete(name);
261
+ publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());
262
+ }
263
+ async copyTo(targetPath) {
264
+ for (const resource of await this.listChildren()) {
265
+ const targetResourceName = [targetPath, resource.getName()].join("/");
266
+ await resource.copyTo(targetResourceName);
267
+ }
268
+ }
269
+ async rename(newName) {
270
+ if (this.getName() === newName) {
271
+ return;
272
+ }
273
+ const pathParts = this.resource.href.split("/").filter(Boolean);
274
+ pathParts[pathParts.length - 1] = newName;
275
+ const newPath = "/" + pathParts.join("/") + "/";
276
+ await this.client.moveResource(this.resource.href, newPath);
277
+ this.resource.href = newPath;
278
+ this.resource.displayName = newName;
279
+ publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());
280
+ }
281
+ touch() {
282
+ publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());
283
+ }
284
+ buildPath(basePath, segment) {
285
+ return basePath.endsWith("/") ? basePath + segment : basePath + "/" + segment;
286
+ }
287
+ getClient() {
288
+ return this.client;
289
+ }
290
+ }
291
+ var __defProp = Object.defineProperty;
292
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
293
+ var __decorateClass = (decorators, target, key, kind) => {
294
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
295
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
296
+ if (decorator = decorators[i])
297
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
298
+ if (kind && result) __defProp(target, key, result);
299
+ return result;
300
+ };
301
+ const logger$1 = createLogger("WebDAV");
302
+ let LyraWebDAVConnect = class extends LyraElement {
303
+ constructor() {
304
+ super(...arguments);
305
+ this.url = "";
306
+ this.username = "";
307
+ this.password = "";
308
+ this.connecting = false;
309
+ this.showHelp = false;
310
+ }
311
+ async handleConnect() {
312
+ if (!this.url) {
313
+ logger$1.error("Please provide a URL");
314
+ return;
315
+ }
316
+ try {
317
+ new URL(this.url);
318
+ } catch {
319
+ logger$1.error("Invalid URL format");
320
+ return;
321
+ }
322
+ this.connecting = true;
323
+ try {
324
+ const connectionInfo = {
325
+ url: this.url,
326
+ // Only include credentials if both are provided
327
+ ...this.username && this.password && {
328
+ username: this.username,
329
+ password: this.password
330
+ }
331
+ };
332
+ await workspaceService.connectWorkspace(connectionInfo);
333
+ logger$1.info("Successfully connected to WebDAV workspace");
334
+ this.dispatchEvent(new CustomEvent("connected", {
335
+ bubbles: true,
336
+ composed: true
337
+ }));
338
+ } catch (error) {
339
+ if (error instanceof Error) {
340
+ logger$1.error(`Connection failed: ${error.message}`);
341
+ } else {
342
+ logger$1.error("Failed to connect to WebDAV server");
343
+ }
344
+ } finally {
345
+ this.connecting = false;
346
+ }
347
+ }
348
+ toggleHelp() {
349
+ this.showHelp = !this.showHelp;
350
+ }
351
+ render() {
352
+ return html`
353
+ <style>
354
+ .webdav-connect-dialog {
355
+ display: flex;
356
+ flex-direction: column;
357
+ gap: 1rem;
358
+ max-width: 500px;
359
+ padding: 1.5rem;
360
+ }
361
+
362
+ .webdav-connect-dialog h2 {
363
+ margin: 0 0 1rem 0;
364
+ font-size: 1.5rem;
365
+ }
366
+
367
+ .form-buttons {
368
+ display: flex;
369
+ gap: 0.5rem;
370
+ justify-content: flex-end;
371
+ margin-top: 1rem;
372
+ }
373
+
374
+ .help-text {
375
+ background: var(--wa-color-neutral-50);
376
+ padding: 1rem;
377
+ border-radius: 4px;
378
+ font-size: 0.875rem;
379
+ margin-top: 1rem;
380
+ }
381
+
382
+ .help-text h3 {
383
+ margin-top: 0;
384
+ font-size: 1rem;
385
+ }
386
+
387
+ .help-text p {
388
+ margin: 0.5rem 0;
389
+ }
390
+
391
+ .help-text code {
392
+ display: block;
393
+ background: var(--wa-color-neutral-100);
394
+ padding: 0.5rem;
395
+ border-radius: 3px;
396
+ margin: 0.5rem 0;
397
+ font-family: monospace;
398
+ word-break: breaall;
399
+ }
400
+
401
+ .help-toggle {
402
+ cursor: pointer;
403
+ color: var(--wa-color-primary-600);
404
+ font-size: 0.875rem;
405
+ text-decoration: underline;
406
+ }
407
+ </style>
408
+
409
+ <div class="webdav-connect-dialog">
410
+ <h2>
411
+ <wa-icon name="cloud" label="WebDAV"></wa-icon>
412
+ Connect to WebDAV Folder
413
+ </h2>
414
+
415
+ <wa-input
416
+ label="WebDAV URL"
417
+ placeholder="https://cloud.example.com/remote.php/dav/files/username/"
418
+ .value=${this.url}
419
+ @input=${(e) => this.url = e.target.value}
420
+ required
421
+ help-text="The full WebDAV endpoint URL">
422
+ </wa-input>
423
+
424
+ <wa-input
425
+ label="Username (optional)"
426
+ placeholder="username"
427
+ .value=${this.username}
428
+ @input=${(e) => this.username = e.target.value}
429
+ help-text="Leave empty for public/shared folders">
430
+ </wa-input>
431
+
432
+ <wa-input
433
+ type="password"
434
+ label="Password (optional)"
435
+ placeholder="Password or App Password"
436
+ .value=${this.password}
437
+ @input=${(e) => this.password = e.target.value}
438
+ help-text="Leave empty for public/shared folders. Use an app password if 2FA is enabled">
439
+ </wa-input>
440
+
441
+ <div class="form-buttons">
442
+ <wa-button
443
+ appearance="outline"
444
+ @click=${this.toggleHelp}>
445
+ <wa-icon name="circle-info" slot="start"></wa-icon>
446
+ ${this.showHelp ? "Hide" : "Show"} Help
447
+ </wa-button>
448
+
449
+ <wa-button
450
+ appearance="primary"
451
+ @click=${this.handleConnect}
452
+ ?disabled=${this.connecting || !this.url}>
453
+ <wa-icon name="${this.connecting ? "spinner" : "plug"}" slot="start"></wa-icon>
454
+ ${this.connecting ? "Connecting..." : "Connect"}
455
+ </wa-button>
456
+ </div>
457
+
458
+ ${this.showHelp ? html`
459
+ <div class="help-text">
460
+ <h3>WebDAV Connection Help</h3>
461
+
462
+ <p><strong>Public/Shared Folders:</strong></p>
463
+ <p>For publicly shared WebDAV folders, just enter the URL and leave username/password empty.</p>
464
+
465
+ <p><strong>Nextcloud Public Shares:</strong></p>
466
+ <p>For Nextcloud public shares (e.g., https://cloud.example.com/s/TOKEN):</p>
467
+ <ul>
468
+ <li><strong>URL:</strong> https://your-cloud.com/public.php/webdav/</li>
469
+ <li><strong>Username:</strong> The share token (the part after /s/)</li>
470
+ <li><strong>Password:</strong> Leave empty (or enter share password if protected)</li>
471
+ </ul>
472
+ <p><em>Tip: Use the "Connect to Nextcloud Public Share" command for easier setup!</em></p>
473
+
474
+ <p><strong>Nextcloud Personal Files:</strong></p>
475
+ <p>Your WebDAV URL should look like:</p>
476
+ <code>https://your-cloud.com/remote.php/dav/files/USERNAME/</code>
477
+
478
+ <p><strong>ownCloud:</strong></p>
479
+ <code>https://your-owncloud.com/remote.php/dav/files/USERNAME/</code>
480
+
481
+ <p><strong>Two-Factor Authentication:</strong></p>
482
+ <p>If you have 2FA enabled:</p>
483
+ <ol>
484
+ <li>Go to your account settings</li>
485
+ <li>Find "Security" or "App passwords"</li>
486
+ <li>Generate a new app password</li>
487
+ <li>Use that password here instead of your regular password</li>
488
+ </ol>
489
+
490
+ <p><strong>CORS Issues:</strong></p>
491
+ <p>If connection fails, your WebDAV server may need CORS configuration.
492
+ Contact your administrator or check the server documentation.</p>
493
+
494
+ <p><strong>Note:</strong> Your credentials (if provided) will be stored securely in your browser's storage.</p>
495
+ </div>
496
+ ` : ""}
497
+ </div>
498
+ `;
499
+ }
500
+ };
501
+ __decorateClass([
502
+ state()
503
+ ], LyraWebDAVConnect.prototype, "url", 2);
504
+ __decorateClass([
505
+ state()
506
+ ], LyraWebDAVConnect.prototype, "username", 2);
507
+ __decorateClass([
508
+ state()
509
+ ], LyraWebDAVConnect.prototype, "password", 2);
510
+ __decorateClass([
511
+ state()
512
+ ], LyraWebDAVConnect.prototype, "connecting", 2);
513
+ __decorateClass([
514
+ state()
515
+ ], LyraWebDAVConnect.prototype, "showHelp", 2);
516
+ LyraWebDAVConnect = __decorateClass([
517
+ customElement("lyra-webdav-connect")
518
+ ], LyraWebDAVConnect);
519
+ const logger = createLogger("WebDAV");
520
+ let webdavDialog = null;
521
+ function getWebDAVDialog() {
522
+ if (!webdavDialog) {
523
+ const container = document.createElement("div");
524
+ const handleConnect = async () => {
525
+ const dialog = container.querySelector("wa-dialog");
526
+ const urlInput = container.querySelector("#webdav-url");
527
+ const passwordInput = container.querySelector("#webdav-password");
528
+ const url = urlInput?.value;
529
+ if (!url) {
530
+ logger.error("Please provide a URL");
531
+ return;
532
+ }
533
+ const password = passwordInput?.value;
534
+ try {
535
+ let connectionInfo;
536
+ const shareMatch = url.match(/^(https?:\/\/[^\/]+)\/(?:index\.php\/)?s\/([A-Za-z0-9]+)/);
537
+ if (shareMatch) {
538
+ const server = shareMatch[1];
539
+ const token = shareMatch[2];
540
+ connectionInfo = {
541
+ url: `${server}/public.php/webdav/`,
542
+ username: token,
543
+ password: password || ""
544
+ };
545
+ } else {
546
+ connectionInfo = {
547
+ url,
548
+ ...password && {
549
+ username: "",
550
+ password
551
+ }
552
+ };
553
+ }
554
+ await workspaceService.connectWorkspace(connectionInfo);
555
+ logger.info("Connected to WebDAV workspace");
556
+ dialog.open = false;
557
+ urlInput.value = "";
558
+ passwordInput.value = "";
559
+ } catch (error) {
560
+ if (error instanceof Error) {
561
+ logger.error(`Failed to connect: ${error.message}`);
562
+ } else {
563
+ logger.error("Failed to connect to WebDAV workspace");
564
+ }
565
+ }
566
+ };
567
+ const template = html`
568
+ <wa-dialog label="Connect to WebDAV / Cloud Storage">
569
+ <style>
570
+ .webdav-dialog {
571
+ display: flex;
572
+ flex-direction: column;
573
+ gap: 1rem;
574
+ padding: 1.5rem;
575
+ max-width: 500px;
576
+ }
577
+
578
+ .form-buttons {
579
+ display: flex;
580
+ gap: 0.5rem;
581
+ justify-content: flex-end;
582
+ margin-top: 1rem;
583
+ }
584
+ </style>
585
+
586
+ <div class="webdav-dialog">
587
+ <wa-input
588
+ id="webdav-url"
589
+ label="URL"
590
+ placeholder="https://my-nextcloud.de/s/<share-token>"
591
+ required
592
+ help-text="Nextcloud share link or WebDAV endpoint URL">
593
+ </wa-input>
594
+
595
+ <wa-input
596
+ id="webdav-password"
597
+ type="password"
598
+ label="Password (optional)"
599
+ placeholder="Leave empty if not required">
600
+ </wa-input>
601
+
602
+ <div class="form-buttons">
603
+ <wa-button
604
+ appearance="outline"
605
+ @click=${() => container.querySelector("wa-dialog").open = false}>
606
+ Cancel
607
+ </wa-button>
608
+
609
+ <wa-button
610
+ appearance="primary"
611
+ @click=${handleConnect}>
612
+ <wa-icon name="plug" slot="start"></wa-icon>
613
+ Connect
614
+ </wa-button>
615
+ </div>
616
+ </div>
617
+ </wa-dialog>
618
+ `;
619
+ render(template, container);
620
+ document.body.appendChild(container);
621
+ webdavDialog = container.querySelector("wa-dialog");
622
+ }
623
+ return webdavDialog;
624
+ }
625
+ registerAll({
626
+ command: {
627
+ "id": "workspace.connect.webdav",
628
+ "name": "WebDAV / Cloud Storage",
629
+ "description": "Connect to WebDAV servers, Nextcloud shares, ownCloud, and other cloud storage",
630
+ "parameters": [
631
+ {
632
+ "name": "url",
633
+ "type": "string",
634
+ "description": "WebDAV URL: share link (https://cloud.example.com/s/TOKEN) or direct endpoint",
635
+ "required": false
636
+ },
637
+ {
638
+ "name": "password",
639
+ "type": "string",
640
+ "description": "Password (if required)",
641
+ "required": false
642
+ }
643
+ ]
644
+ },
645
+ handler: {
646
+ execute: async (context) => {
647
+ const url = context.parameters?.url;
648
+ const password = context.parameters?.password;
649
+ if (!url) {
650
+ const dialog = getWebDAVDialog();
651
+ dialog.open = true;
652
+ return;
653
+ }
654
+ try {
655
+ let connectionInfo;
656
+ const shareMatch = url.match(/^(https?:\/\/[^\/]+)\/(?:index\.php\/)?s\/([A-Za-z0-9]+)/);
657
+ if (shareMatch) {
658
+ const server = shareMatch[1];
659
+ const token = shareMatch[2];
660
+ connectionInfo = {
661
+ url: `${server}/public.php/webdav/`,
662
+ username: token,
663
+ password: password || ""
664
+ };
665
+ } else {
666
+ connectionInfo = {
667
+ url,
668
+ ...password && {
669
+ username: "",
670
+ password
671
+ }
672
+ };
673
+ }
674
+ await workspaceService.connectWorkspace(connectionInfo);
675
+ logger.info("Connected to WebDAV workspace");
676
+ } catch (error) {
677
+ if (error instanceof Error) {
678
+ logger.error(`Failed to connect: ${error.message}`);
679
+ } else {
680
+ logger.error("Failed to connect to WebDAV workspace");
681
+ }
682
+ }
683
+ }
684
+ },
685
+ contribution: {
686
+ target: "filebrowser.connections",
687
+ label: "WebDAV / Cloud Storage",
688
+ icon: "cloud"
689
+ }
690
+ });
691
+ workspaceService.registerContribution({
692
+ type: "webdav",
693
+ name: "WebDAV (Cloud Storage)",
694
+ canHandle(input) {
695
+ return input && typeof input === "object" && "url" in input && typeof input.url === "string";
696
+ },
697
+ async connect(input) {
698
+ const client = new WebDAVClient(input);
699
+ const rootResource = {
700
+ href: input.url,
701
+ displayName: extractWorkspaceNameFromUrl(input.url),
702
+ isDirectory: true
703
+ };
704
+ return new WebDAVDirectoryResource(client, rootResource);
705
+ },
706
+ async restore(data) {
707
+ if (!data || !data.url) {
708
+ return void 0;
709
+ }
710
+ try {
711
+ const client = new WebDAVClient(data);
712
+ const rootResource = {
713
+ href: data.url,
714
+ displayName: extractWorkspaceNameFromUrl(data.url),
715
+ isDirectory: true
716
+ };
717
+ return new WebDAVDirectoryResource(client, rootResource);
718
+ } catch (error) {
719
+ console.error("Failed to restore WebDAV workspace:", error);
720
+ return void 0;
721
+ }
722
+ },
723
+ async persist(workspace) {
724
+ if (workspace instanceof WebDAVDirectoryResource) {
725
+ const client = workspace.getClient();
726
+ const baseUrl = client.getBaseUrl();
727
+ return {
728
+ url: baseUrl,
729
+ username: "",
730
+ // Will need re-authentication
731
+ password: ""
732
+ // Will need re-authentication
733
+ };
734
+ }
735
+ return null;
736
+ }
737
+ });
738
+ function extractWorkspaceNameFromUrl(url) {
739
+ try {
740
+ const urlObj = new URL(url);
741
+ const pathParts = urlObj.pathname.split("/").filter(Boolean);
742
+ return pathParts[pathParts.length - 1] || "workspace";
743
+ } catch {
744
+ return "workspace";
745
+ }
746
+ }
747
+ console.log("WebDAV Extension loaded");
748
+ export {
749
+ WebDAVClient,
750
+ WebDAVDirectoryResource,
751
+ WebDAVFileResource
752
+ };
753
+ //# sourceMappingURL=webdav-extension-DhFP7zW5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webdav-extension-DhFP7zW5.js","sources":["../src/webdav-client.ts","../src/webdav-filesys.ts","../src/webdav-connect.ts","../src/webdav-commands.ts","../src/webdav-extension.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios';\n\nexport interface WebDAVConnectionInfo {\n url: string;\n username?: string;\n password?: string;\n}\n\nexport interface WebDAVResource {\n href: string;\n displayName: string;\n isDirectory: boolean;\n contentType?: string;\n contentLength?: number;\n lastModified?: Date;\n etag?: string;\n}\n\nexport class WebDAVClient {\n private axios: AxiosInstance;\n private baseUrl: string;\n\n constructor(connectionInfo: WebDAVConnectionInfo) {\n this.baseUrl = connectionInfo.url;\n \n const config: any = {\n baseURL: connectionInfo.url,\n headers: {\n 'Content-Type': 'application/xml',\n },\n maxRedirects: 5 // Follow redirects\n };\n \n // Include auth if username is provided (password can be empty for public shares)\n if (connectionInfo.username !== undefined) {\n config.auth = {\n username: connectionInfo.username,\n password: connectionInfo.password || ''\n };\n }\n \n this.axios = axios.create(config);\n }\n\n async propfind(path: string, depth: number = 1): Promise<WebDAVResource[]> {\n const requestBody = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <d:propfind xmlns:d=\"DAV:\">\n <d:prop>\n <d:displayname/>\n <d:resourcetype/>\n <d:getcontenttype/>\n <d:getcontentlength/>\n <d:getlastmodified/>\n <d:getetag/>\n </d:prop>\n </d:propfind>`;\n\n const response = await this.axios.request({\n method: 'PROPFIND',\n url: path,\n headers: {\n 'Depth': depth.toString()\n },\n data: requestBody\n });\n\n return this.parseMultiStatus(response.data);\n }\n\n async getFile(path: string): Promise<ArrayBuffer> {\n const response = await this.axios.get(path, {\n responseType: 'arraybuffer'\n });\n return response.data;\n }\n\n async putFile(path: string, content: string | Blob | ArrayBuffer): Promise<void> {\n await this.axios.put(path, content, {\n headers: {\n 'Content-Type': 'application/octet-stream'\n }\n });\n }\n\n async deleteResource(path: string): Promise<void> {\n await this.axios.delete(path);\n }\n\n async createDirectory(path: string): Promise<void> {\n await this.axios.request({\n method: 'MKCOL',\n url: path\n });\n }\n\n async moveResource(fromPath: string, toPath: string): Promise<void> {\n const destination = new URL(toPath, this.baseUrl).href;\n await this.axios.request({\n method: 'MOVE',\n url: fromPath,\n headers: {\n 'Destination': destination,\n 'Overwrite': 'F'\n }\n });\n }\n\n async copyResource(fromPath: string, toPath: string): Promise<void> {\n const destination = new URL(toPath, this.baseUrl).href;\n await this.axios.request({\n method: 'COPY',\n url: fromPath,\n headers: {\n 'Destination': destination,\n 'Overwrite': 'F'\n }\n });\n }\n\n private parseMultiStatus(xml: string): WebDAVResource[] {\n const parser = new DOMParser();\n const doc = parser.parseFromString(xml, 'text/xml');\n const responses = doc.querySelectorAll('response');\n \n const resources: WebDAVResource[] = [];\n responses.forEach(response => {\n const href = response.querySelector('href')?.textContent || '';\n const displayName = response.querySelector('displayname')?.textContent || '';\n const resourceType = response.querySelector('resourcetype');\n const isDirectory = !!resourceType?.querySelector('collection');\n const contentType = response.querySelector('getcontenttype')?.textContent || undefined;\n const contentLengthStr = response.querySelector('getcontentlength')?.textContent;\n const contentLength = contentLengthStr ? parseInt(contentLengthStr) : undefined;\n const lastModifiedStr = response.querySelector('getlastmodified')?.textContent;\n const lastModified = lastModifiedStr ? new Date(lastModifiedStr) : undefined;\n const etag = response.querySelector('getetag')?.textContent || undefined;\n\n resources.push({\n href,\n displayName: displayName || href.split('/').filter(Boolean).pop() || '',\n isDirectory,\n contentType,\n contentLength,\n lastModified,\n etag\n });\n });\n\n return resources;\n }\n\n getBaseUrl(): string {\n return this.baseUrl;\n }\n}\n\n\n","import { \n File, \n Directory, \n Resource, \n GetResourceOptions, \n FileContentsOptions, \n FileContentType,\n TOPIC_WORKSPACE_CHANGED \n} from '@eclipse-lyra/core';\nimport { WebDAVClient, WebDAVResource } from './webdav-client';\nimport { publish } from '@eclipse-lyra/core';\n\nexport class WebDAVFileResource extends File {\n private client: WebDAVClient;\n private resource: WebDAVResource;\n private parent: Directory;\n\n constructor(client: WebDAVClient, resource: WebDAVResource, parent: Directory) {\n super();\n this.client = client;\n this.resource = resource;\n this.parent = parent;\n }\n\n getName(): string {\n return this.resource.displayName;\n }\n\n getParent(): Directory {\n return this.parent;\n }\n\n async getContents(options?: FileContentsOptions): Promise<any> {\n const buffer = await this.client.getFile(this.resource.href);\n \n if (!options || options?.contentType === FileContentType.TEXT) {\n const decoder = new TextDecoder();\n return decoder.decode(buffer);\n }\n\n if (options?.blob) {\n return new Blob([buffer]);\n }\n\n if (options?.uri) {\n const blob = new Blob([buffer]);\n return URL.createObjectURL(blob);\n }\n\n return buffer;\n }\n\n async saveContents(contents: any, _options?: FileContentsOptions): Promise<void> {\n await this.client.putFile(this.resource.href, contents);\n publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());\n }\n\n async size(): Promise<number | null> {\n return this.resource.contentLength ?? null;\n }\n\n async delete(): Promise<void> {\n await this.client.deleteResource(this.resource.href);\n publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());\n }\n\n async copyTo(targetPath: string): Promise<void> {\n const targetFile = await this.getWorkspace().getResource(targetPath, { create: true }) as File;\n if (!targetFile) {\n throw new Error(`Failed to create target file: ${targetPath}`);\n }\n const contents = await this.getContents({ blob: true });\n await targetFile.saveContents(contents);\n }\n\n async rename(newName: string): Promise<void> {\n if (this.getName() === newName) {\n return;\n }\n\n const pathParts = this.resource.href.split('/');\n pathParts[pathParts.length - 1] = newName;\n const newPath = pathParts.join('/');\n \n await this.client.moveResource(this.resource.href, newPath);\n this.resource.href = newPath;\n this.resource.displayName = newName;\n \n publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());\n }\n}\n\nexport class WebDAVDirectoryResource extends Directory {\n private client: WebDAVClient;\n private resource: WebDAVResource;\n private parent?: Directory;\n private children?: Map<string, Resource>;\n\n constructor(client: WebDAVClient, resource: WebDAVResource, parent?: Directory) {\n super();\n this.client = client;\n this.resource = resource;\n this.parent = parent;\n }\n\n getName(): string {\n return this.resource.displayName;\n }\n\n getParent(): Directory | undefined {\n return this.parent;\n }\n\n async listChildren(forceRefresh: boolean = false): Promise<Resource[]> {\n if (forceRefresh || !this.children) {\n const resources = await this.client.propfind(this.resource.href, 1);\n this.children = new Map();\n\n // Skip first entry (it's the directory itself)\n for (let i = 1; i < resources.length; i++) {\n const res = resources[i];\n const child = res.isDirectory\n ? new WebDAVDirectoryResource(this.client, res, this)\n : new WebDAVFileResource(this.client, res, this);\n this.children.set(res.displayName, child);\n }\n }\n\n return Array.from(this.children.values());\n }\n\n async getResource(path: string, options?: GetResourceOptions): Promise<Resource | null> {\n if (!path) {\n throw new Error(\"No path provided\");\n }\n\n const segments = path.split(\"/\").filter(s => s.trim());\n let currentResource: Resource = this;\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n \n if (currentResource instanceof WebDAVDirectoryResource) {\n await currentResource.listChildren();\n \n if (!currentResource.children) {\n return null;\n }\n\n let next = currentResource.children.get(segment);\n\n if (!next && options?.create) {\n const fullPath = this.buildPath(currentResource.resource.href, segment);\n \n // If not the last segment, create directory\n if (i < segments.length - 1) {\n await this.client.createDirectory(fullPath);\n const newResource: WebDAVResource = {\n href: fullPath,\n displayName: segment,\n isDirectory: true\n };\n next = new WebDAVDirectoryResource(this.client, newResource, currentResource);\n currentResource.children.set(segment, next);\n } else {\n // Last segment - create file\n await this.client.putFile(fullPath, '');\n const newResource: WebDAVResource = {\n href: fullPath,\n displayName: segment,\n isDirectory: false,\n contentLength: 0\n };\n next = new WebDAVFileResource(this.client, newResource, currentResource);\n currentResource.children.set(segment, next);\n publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());\n return next;\n }\n }\n\n if (!next) {\n return null;\n }\n\n currentResource = next;\n }\n }\n\n return currentResource;\n }\n\n async delete(name?: string, _recursive: boolean = true): Promise<void> {\n if (!name) {\n return this.getParent()?.delete(this.getName());\n }\n\n const fullPath = this.buildPath(this.resource.href, name);\n await this.client.deleteResource(fullPath);\n this.children?.delete(name);\n publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());\n }\n\n async copyTo(targetPath: string): Promise<void> {\n for (const resource of await this.listChildren()) {\n const targetResourceName = [targetPath, resource.getName()].join(\"/\");\n await resource.copyTo(targetResourceName);\n }\n }\n\n async rename(newName: string): Promise<void> {\n if (this.getName() === newName) {\n return;\n }\n\n const pathParts = this.resource.href.split('/').filter(Boolean);\n pathParts[pathParts.length - 1] = newName;\n const newPath = '/' + pathParts.join('/') + '/';\n \n await this.client.moveResource(this.resource.href, newPath);\n this.resource.href = newPath;\n this.resource.displayName = newName;\n \n publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());\n }\n\n touch(): void {\n publish(TOPIC_WORKSPACE_CHANGED, this.getWorkspace());\n }\n\n private buildPath(basePath: string, segment: string): string {\n return basePath.endsWith('/') \n ? basePath + segment \n : basePath + '/' + segment;\n }\n\n getClient(): WebDAVClient {\n return this.client;\n }\n}\n\n","import { customElement, state } from \"lit/decorators.js\";\nimport { LyraElement } from \"@eclipse-lyra/core\";\nimport { html } from \"lit\";\nimport { workspaceService } from \"@eclipse-lyra/core\";\nimport type { WebDAVConnectionInfo } from \"./webdav-client\";\nimport { createLogger } from \"@eclipse-lyra/core\";\n\nconst logger = createLogger('WebDAV');\n\n@customElement('lyra-webdav-connect')\nexport class LyraWebDAVConnect extends LyraElement {\n \n @state()\n private url = '';\n \n @state()\n private username = '';\n \n @state()\n private password = '';\n \n @state()\n private connecting = false;\n\n @state()\n private showHelp = false;\n\n private async handleConnect() {\n if (!this.url) {\n logger.error('Please provide a URL');\n return;\n }\n\n // Validate URL format\n try {\n new URL(this.url);\n } catch {\n logger.error('Invalid URL format');\n return;\n }\n\n this.connecting = true;\n \n try {\n const connectionInfo: WebDAVConnectionInfo = {\n url: this.url,\n // Only include credentials if both are provided\n ...(this.username && this.password && {\n username: this.username,\n password: this.password\n })\n };\n \n await workspaceService.connectWorkspace(connectionInfo);\n logger.info('Successfully connected to WebDAV workspace');\n \n this.dispatchEvent(new CustomEvent('connected', {\n bubbles: true,\n composed: true\n }));\n } catch (error) {\n if (error instanceof Error) {\n logger.error(`Connection failed: ${error.message}`);\n } else {\n logger.error('Failed to connect to WebDAV server');\n }\n } finally {\n this.connecting = false;\n }\n }\n\n private toggleHelp() {\n this.showHelp = !this.showHelp;\n }\n\n protected render() {\n return html`\n <style>\n .webdav-connect-dialog {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n max-width: 500px;\n padding: 1.5rem;\n }\n \n .webdav-connect-dialog h2 {\n margin: 0 0 1rem 0;\n font-size: 1.5rem;\n }\n \n .form-buttons {\n display: flex;\n gap: 0.5rem;\n justify-content: flex-end;\n margin-top: 1rem;\n }\n \n .help-text {\n background: var(--wa-color-neutral-50);\n padding: 1rem;\n border-radius: 4px;\n font-size: 0.875rem;\n margin-top: 1rem;\n }\n \n .help-text h3 {\n margin-top: 0;\n font-size: 1rem;\n }\n \n .help-text p {\n margin: 0.5rem 0;\n }\n \n .help-text code {\n display: block;\n background: var(--wa-color-neutral-100);\n padding: 0.5rem;\n border-radius: 3px;\n margin: 0.5rem 0;\n font-family: monospace;\n word-break: breaall;\n }\n \n .help-toggle {\n cursor: pointer;\n color: var(--wa-color-primary-600);\n font-size: 0.875rem;\n text-decoration: underline;\n }\n </style>\n \n <div class=\"webdav-connect-dialog\">\n <h2>\n <wa-icon name=\"cloud\" label=\"WebDAV\"></wa-icon>\n Connect to WebDAV Folder\n </h2>\n \n <wa-input\n label=\"WebDAV URL\"\n placeholder=\"https://cloud.example.com/remote.php/dav/files/username/\"\n .value=${this.url}\n @input=${(e: Event) => this.url = (e.target as any).value}\n required\n help-text=\"The full WebDAV endpoint URL\">\n </wa-input>\n \n <wa-input\n label=\"Username (optional)\"\n placeholder=\"username\"\n .value=${this.username}\n @input=${(e: Event) => this.username = (e.target as any).value}\n help-text=\"Leave empty for public/shared folders\">\n </wa-input>\n \n <wa-input\n type=\"password\"\n label=\"Password (optional)\"\n placeholder=\"Password or App Password\"\n .value=${this.password}\n @input=${(e: Event) => this.password = (e.target as any).value}\n help-text=\"Leave empty for public/shared folders. Use an app password if 2FA is enabled\">\n </wa-input>\n \n <div class=\"form-buttons\">\n <wa-button\n appearance=\"outline\"\n @click=${this.toggleHelp}>\n <wa-icon name=\"circle-info\" slot=\"start\"></wa-icon>\n ${this.showHelp ? 'Hide' : 'Show'} Help\n </wa-button>\n \n <wa-button\n appearance=\"primary\"\n @click=${this.handleConnect}\n ?disabled=${this.connecting || !this.url}>\n <wa-icon name=\"${this.connecting ? 'spinner' : 'plug'}\" slot=\"start\"></wa-icon>\n ${this.connecting ? 'Connecting...' : 'Connect'}\n </wa-button>\n </div>\n \n ${this.showHelp ? html`\n <div class=\"help-text\">\n <h3>WebDAV Connection Help</h3>\n \n <p><strong>Public/Shared Folders:</strong></p>\n <p>For publicly shared WebDAV folders, just enter the URL and leave username/password empty.</p>\n \n <p><strong>Nextcloud Public Shares:</strong></p>\n <p>For Nextcloud public shares (e.g., https://cloud.example.com/s/TOKEN):</p>\n <ul>\n <li><strong>URL:</strong> https://your-cloud.com/public.php/webdav/</li>\n <li><strong>Username:</strong> The share token (the part after /s/)</li>\n <li><strong>Password:</strong> Leave empty (or enter share password if protected)</li>\n </ul>\n <p><em>Tip: Use the \"Connect to Nextcloud Public Share\" command for easier setup!</em></p>\n \n <p><strong>Nextcloud Personal Files:</strong></p>\n <p>Your WebDAV URL should look like:</p>\n <code>https://your-cloud.com/remote.php/dav/files/USERNAME/</code>\n \n <p><strong>ownCloud:</strong></p>\n <code>https://your-owncloud.com/remote.php/dav/files/USERNAME/</code>\n \n <p><strong>Two-Factor Authentication:</strong></p>\n <p>If you have 2FA enabled:</p>\n <ol>\n <li>Go to your account settings</li>\n <li>Find \"Security\" or \"App passwords\"</li>\n <li>Generate a new app password</li>\n <li>Use that password here instead of your regular password</li>\n </ol>\n \n <p><strong>CORS Issues:</strong></p>\n <p>If connection fails, your WebDAV server may need CORS configuration. \n Contact your administrator or check the server documentation.</p>\n \n <p><strong>Note:</strong> Your credentials (if provided) will be stored securely in your browser's storage.</p>\n </div>\n ` : ''}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-webdav-connect': LyraWebDAVConnect;\n }\n}\n\n","/**\n * Commands for WebDAV workspace integration\n */\n\nimport { registerAll } from \"@eclipse-lyra/core\";\nimport { workspaceService } from \"@eclipse-lyra/core\";\nimport { createLogger } from \"@eclipse-lyra/core\";\nimport type { WebDAVConnectionInfo } from \"./webdav-client\";\nimport { html, render } from \"lit\";\n\nconst logger = createLogger('WebDAV');\n\n// Singleton dialog instance to prevent DOM memory leaks\nlet webdavDialog: HTMLElement | null = null;\n\nfunction getWebDAVDialog(): HTMLElement {\n if (!webdavDialog) {\n const container = document.createElement('div');\n \n const handleConnect = async () => {\n const dialog = container.querySelector('wa-dialog') as any;\n const urlInput = container.querySelector('#webdav-url') as any;\n const passwordInput = container.querySelector('#webdav-password') as any;\n \n const url = urlInput?.value;\n if (!url) {\n logger.error('Please provide a URL');\n return;\n }\n \n const password = passwordInput?.value;\n \n try {\n let connectionInfo: WebDAVConnectionInfo;\n \n // Check if it's a Nextcloud/ownCloud share URL format\n const shareMatch = url.match(/^(https?:\\/\\/[^\\/]+)\\/(?:index\\.php\\/)?s\\/([A-Za-z0-9]+)/);\n \n if (shareMatch) {\n // It's a share URL - convert to WebDAV endpoint\n const server = shareMatch[1];\n const token = shareMatch[2];\n \n connectionInfo = {\n url: `${server}/public.php/webdav/`,\n username: token,\n password: password || ''\n };\n } else {\n // It's a direct WebDAV URL - use as-is\n connectionInfo = {\n url,\n ...(password && {\n username: '',\n password\n })\n };\n }\n\n await workspaceService.connectWorkspace(connectionInfo);\n logger.info('Connected to WebDAV workspace');\n \n dialog.open = false;\n urlInput.value = '';\n passwordInput.value = '';\n } catch (error) {\n if (error instanceof Error) {\n logger.error(`Failed to connect: ${error.message}`);\n } else {\n logger.error('Failed to connect to WebDAV workspace');\n }\n }\n };\n \n const template = html`\n <wa-dialog label=\"Connect to WebDAV / Cloud Storage\">\n <style>\n .webdav-dialog {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n padding: 1.5rem;\n max-width: 500px;\n }\n \n .form-buttons {\n display: flex;\n gap: 0.5rem;\n justify-content: flex-end;\n margin-top: 1rem;\n }\n </style>\n \n <div class=\"webdav-dialog\">\n <wa-input\n id=\"webdav-url\"\n label=\"URL\"\n placeholder=\"https://my-nextcloud.de/s/<share-token>\"\n required\n help-text=\"Nextcloud share link or WebDAV endpoint URL\">\n </wa-input>\n \n <wa-input\n id=\"webdav-password\"\n type=\"password\"\n label=\"Password (optional)\"\n placeholder=\"Leave empty if not required\">\n </wa-input>\n \n <div class=\"form-buttons\">\n <wa-button\n appearance=\"outline\"\n @click=${() => (container.querySelector('wa-dialog') as any).open = false}>\n Cancel\n </wa-button>\n \n <wa-button\n appearance=\"primary\"\n @click=${handleConnect}>\n <wa-icon name=\"plug\" slot=\"start\"></wa-icon>\n Connect\n </wa-button>\n </div>\n </div>\n </wa-dialog>\n `;\n \n render(template, container);\n document.body.appendChild(container);\n webdavDialog = container.querySelector('wa-dialog') as HTMLElement;\n }\n return webdavDialog;\n}\n\n/**\n * Universal WebDAV connection command\n * Handles Nextcloud shares, direct WebDAV URLs, and more\n */\nregisterAll({\n command: {\n \"id\": \"workspace.connect.webdav\",\n \"name\": \"WebDAV / Cloud Storage\",\n \"description\": \"Connect to WebDAV servers, Nextcloud shares, ownCloud, and other cloud storage\",\n \"parameters\": [\n {\n \"name\": \"url\",\n \"type\": \"string\",\n \"description\": \"WebDAV URL: share link (https://cloud.example.com/s/TOKEN) or direct endpoint\",\n \"required\": false\n },\n {\n \"name\": \"password\",\n \"type\": \"string\",\n \"description\": \"Password (if required)\",\n \"required\": false\n }\n ]\n },\n handler: {\n execute: async (context) => {\n const url = context.parameters?.url as string;\n const password = context.parameters?.password as string;\n\n // If no parameters provided, show the dialog\n if (!url) {\n const dialog = getWebDAVDialog();\n (dialog as any).open = true;\n return;\n }\n\n try {\n let connectionInfo: WebDAVConnectionInfo;\n \n // Check if it's a Nextcloud/ownCloud share URL format\n const shareMatch = url.match(/^(https?:\\/\\/[^\\/]+)\\/(?:index\\.php\\/)?s\\/([A-Za-z0-9]+)/);\n \n if (shareMatch) {\n // It's a share URL - convert to WebDAV endpoint\n const server = shareMatch[1];\n const token = shareMatch[2];\n \n connectionInfo = {\n url: `${server}/public.php/webdav/`,\n username: token,\n password: password || ''\n };\n } else {\n // It's a direct WebDAV URL - use as-is\n connectionInfo = {\n url,\n ...(password && {\n username: '',\n password\n })\n };\n }\n\n await workspaceService.connectWorkspace(connectionInfo);\n logger.info('Connected to WebDAV workspace');\n } catch (error) {\n if (error instanceof Error) {\n logger.error(`Failed to connect: ${error.message}`);\n } else {\n logger.error('Failed to connect to WebDAV workspace');\n }\n }\n }\n },\n contribution: {\n target: \"filebrowser.connections\",\n label: \"WebDAV / Cloud Storage\",\n icon: \"cloud\"\n }\n});\n","/**\n * WebDAV Extension for geo!space\n * \n * This extension enables connecting to WebDAV servers (Nextcloud, ownCloud, etc.)\n * as workspace folders, providing cloud storage integration.\n * \n * Features:\n * - Connect to WebDAV servers\n * - Full file/directory operations\n * - Nextcloud and ownCloud support\n * - Seamless integration with existing workspace API\n * \n * Usage:\n * Import this file to register the WebDAV extension and its commands.\n */\n\nimport { workspaceService } from '@eclipse-lyra/core';\nimport { WebDAVClient, type WebDAVConnectionInfo } from './webdav-client';\nimport { WebDAVDirectoryResource } from './webdav-filesys';\nimport type { WebDAVResource } from './webdav-client';\n\n// Export all WebDAV types and classes\nexport { WebDAVClient, type WebDAVConnectionInfo, type WebDAVResource } from './webdav-client';\nexport { WebDAVFileResource, WebDAVDirectoryResource } from './webdav-filesys';\n\n// Import UI component (registers itself)\nimport './webdav-connect';\n\n// Import commands (registers themselves)\nimport './webdav-commands';\n\n// Register WebDAV as a workspace contribution\nworkspaceService.registerContribution({\n type: 'webdav',\n name: 'WebDAV (Cloud Storage)',\n \n canHandle(input: any): boolean {\n // Accept any connection info with a URL (credentials are optional for public/shared folders)\n return input && typeof input === 'object' && 'url' in input && typeof input.url === 'string';\n },\n \n async connect(input: WebDAVConnectionInfo) {\n const client = new WebDAVClient(input);\n const rootResource: WebDAVResource = {\n href: input.url,\n displayName: extractWorkspaceNameFromUrl(input.url),\n isDirectory: true\n };\n return new WebDAVDirectoryResource(client, rootResource);\n },\n \n async restore(data: WebDAVConnectionInfo) {\n if (!data || !data.url) {\n return undefined;\n }\n \n try {\n const client = new WebDAVClient(data);\n const rootResource: WebDAVResource = {\n href: data.url,\n displayName: extractWorkspaceNameFromUrl(data.url),\n isDirectory: true\n };\n return new WebDAVDirectoryResource(client, rootResource);\n } catch (error) {\n console.error('Failed to restore WebDAV workspace:', error);\n return undefined;\n }\n },\n \n async persist(workspace) {\n // Extract connection info from the workspace\n if (workspace instanceof WebDAVDirectoryResource) {\n const client = workspace.getClient();\n const baseUrl = client.getBaseUrl();\n \n // Note: We can't extract username/password from the client after creation\n // This is a security limitation - credentials should be re-requested on restore\n // For now, we'll store a placeholder that will require re-authentication\n return {\n url: baseUrl,\n username: '', // Will need re-authentication\n password: '' // Will need re-authentication\n };\n }\n return null;\n }\n});\n\nfunction extractWorkspaceNameFromUrl(url: string): string {\n try {\n const urlObj = new URL(url);\n const pathParts = urlObj.pathname.split('/').filter(Boolean);\n return pathParts[pathParts.length - 1] || 'workspace';\n } catch {\n return 'workspace';\n }\n}\n\nconsole.log('WebDAV Extension loaded');\n\n"],"names":["logger"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * WebDAV Extension for geo!space
3
+ *
4
+ * This extension enables connecting to WebDAV servers (Nextcloud, ownCloud, etc.)
5
+ * as workspace folders, providing cloud storage integration.
6
+ *
7
+ * Features:
8
+ * - Connect to WebDAV servers
9
+ * - Full file/directory operations
10
+ * - Nextcloud and ownCloud support
11
+ * - Seamless integration with existing workspace API
12
+ *
13
+ * Usage:
14
+ * Import this file to register the WebDAV extension and its commands.
15
+ */
16
+ export { WebDAVClient, type WebDAVConnectionInfo, type WebDAVResource } from './webdav-client';
17
+ export { WebDAVFileResource, WebDAVDirectoryResource } from './webdav-filesys';
18
+ //# sourceMappingURL=webdav-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webdav-extension.d.ts","sourceRoot":"","sources":["../src/webdav-extension.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,OAAO,EAAE,YAAY,EAAE,KAAK,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAG/E,OAAO,kBAAkB,CAAC;AAG1B,OAAO,mBAAmB,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { File, Directory, Resource, GetResourceOptions, FileContentsOptions } from '@eclipse-lyra/core';
2
+ import { WebDAVClient, WebDAVResource } from './webdav-client';
3
+ export declare class WebDAVFileResource extends File {
4
+ private client;
5
+ private resource;
6
+ private parent;
7
+ constructor(client: WebDAVClient, resource: WebDAVResource, parent: Directory);
8
+ getName(): string;
9
+ getParent(): Directory;
10
+ getContents(options?: FileContentsOptions): Promise<any>;
11
+ saveContents(contents: any, _options?: FileContentsOptions): Promise<void>;
12
+ size(): Promise<number | null>;
13
+ delete(): Promise<void>;
14
+ copyTo(targetPath: string): Promise<void>;
15
+ rename(newName: string): Promise<void>;
16
+ }
17
+ export declare class WebDAVDirectoryResource extends Directory {
18
+ private client;
19
+ private resource;
20
+ private parent?;
21
+ private children?;
22
+ constructor(client: WebDAVClient, resource: WebDAVResource, parent?: Directory);
23
+ getName(): string;
24
+ getParent(): Directory | undefined;
25
+ listChildren(forceRefresh?: boolean): Promise<Resource[]>;
26
+ getResource(path: string, options?: GetResourceOptions): Promise<Resource | null>;
27
+ delete(name?: string, _recursive?: boolean): Promise<void>;
28
+ copyTo(targetPath: string): Promise<void>;
29
+ rename(newName: string): Promise<void>;
30
+ touch(): void;
31
+ private buildPath;
32
+ getClient(): WebDAVClient;
33
+ }
34
+ //# sourceMappingURL=webdav-filesys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webdav-filesys.d.ts","sourceRoot":"","sources":["../src/webdav-filesys.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,kBAAkB,EAClB,mBAAmB,EAGtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAG/D,qBAAa,kBAAmB,SAAQ,IAAI;IACxC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,MAAM,CAAY;gBAEd,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS;IAO7E,OAAO,IAAI,MAAM;IAIjB,SAAS,IAAI,SAAS;IAIhB,WAAW,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC;IAoBxD,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1E,IAAI,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAI9B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAKvB,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASzC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAe/C;AAED,qBAAa,uBAAwB,SAAQ,SAAS;IAClD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,MAAM,CAAC,CAAY;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAwB;gBAE7B,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,SAAS;IAO9E,OAAO,IAAI,MAAM;IAIjB,SAAS,IAAI,SAAS,GAAG,SAAS;IAI5B,YAAY,CAAC,YAAY,GAAE,OAAe,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAkBhE,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA4DjF,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,GAAE,OAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAWhE,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOzC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB5C,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,SAAS;IAMjB,SAAS,IAAI,YAAY;CAG5B"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@eclipse-lyra/extension-webdav",
3
+ "version": "0.0.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ }
11
+ },
12
+ "dependencies": {
13
+ "@eclipse-lyra/core": "*",
14
+ "axios": "^1.13.1"
15
+ },
16
+ "devDependencies": {
17
+ "typescript": "^5.9.3",
18
+ "vite": "^7.1.12",
19
+ "vite-plugin-dts": "^4.5.4"
20
+ },
21
+ "module": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "scripts": {
27
+ "build": "vite build"
28
+ }
29
+ }