@nextcloud/files 4.0.0-beta.4 → 4.0.0-beta.5
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.
- package/README.md +2 -2
- package/dist/chunks/{folder-QTYeAiOH.mjs → folder-Bf-tAYWu.mjs} +2 -3
- package/dist/chunks/folder-Bf-tAYWu.mjs.map +1 -0
- package/dist/dav/dav.d.ts +26 -9
- package/dist/dav.mjs +16 -23
- package/dist/dav.mjs.map +1 -1
- package/dist/fileListHeaders.d.ts +8 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +157 -1631
- package/dist/index.mjs.map +1 -1
- package/dist/navigation/column.d.ts +9 -9
- package/dist/navigation/navigation.d.ts +11 -8
- package/dist/navigation/view.d.ts +23 -11
- package/dist/sidebar/Sidebar.d.ts +33 -0
- package/dist/sidebar/SidebarTab.d.ts +78 -0
- package/dist/sidebar/index.d.ts +2 -0
- package/dist/types.d.ts +13 -13
- package/dist/utils/filename.d.ts +1 -1
- package/package.json +11 -16
- package/dist/chunks/folder-QTYeAiOH.mjs.map +0 -1
- package/dist/chunks/folder-dVU2u_me.cjs +0 -445
- package/dist/chunks/folder-dVU2u_me.cjs.map +0 -1
- package/dist/dav.cjs +0 -281
- package/dist/dav.cjs.map +0 -1
- package/dist/index.cjs +0 -3018
- package/dist/index.cjs.map +0 -1
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { INode } from '../node/node.ts';
|
|
2
|
+
import { IView } from './view.ts';
|
|
3
3
|
interface ColumnData {
|
|
4
4
|
/** Unique column ID */
|
|
5
5
|
id: string;
|
|
6
6
|
/** Translated column title */
|
|
7
7
|
title: string;
|
|
8
8
|
/** The content of the cell. The element will be appended within */
|
|
9
|
-
render: (node:
|
|
10
|
-
/** Function used to sort
|
|
11
|
-
sort?: (nodeA:
|
|
9
|
+
render: (node: INode, view: IView) => HTMLElement;
|
|
10
|
+
/** Function used to sort INodes between them */
|
|
11
|
+
sort?: (nodeA: INode, nodeB: INode) => number;
|
|
12
12
|
/**
|
|
13
13
|
* Custom summary of the column to display at the end of the list.
|
|
14
14
|
* Will not be displayed if nothing is provided
|
|
15
15
|
*/
|
|
16
|
-
summary?: (node:
|
|
16
|
+
summary?: (node: INode[], view: IView) => string;
|
|
17
17
|
}
|
|
18
18
|
export declare class Column implements ColumnData {
|
|
19
19
|
private _column;
|
|
20
20
|
constructor(column: ColumnData);
|
|
21
21
|
get id(): string;
|
|
22
22
|
get title(): string;
|
|
23
|
-
get render(): (node:
|
|
24
|
-
get sort(): ((nodeA:
|
|
25
|
-
get summary(): ((node:
|
|
23
|
+
get render(): (node: INode, view: IView) => HTMLElement;
|
|
24
|
+
get sort(): ((nodeA: INode, nodeB: INode) => number) | undefined;
|
|
25
|
+
get summary(): ((node: INode[], view: IView) => string) | undefined;
|
|
26
26
|
}
|
|
27
27
|
export {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IView } from './view';
|
|
2
2
|
import { TypedEventTarget } from 'typescript-event-target';
|
|
3
3
|
/**
|
|
4
4
|
* The event is emitted when the navigation view was updated.
|
|
5
5
|
* It contains the new active view in the `detail` attribute.
|
|
6
6
|
*/
|
|
7
|
-
interface UpdateActiveViewEvent extends CustomEvent<
|
|
7
|
+
interface UpdateActiveViewEvent extends CustomEvent<IView | null> {
|
|
8
8
|
type: 'updateActive';
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
@@ -43,9 +43,10 @@ export declare class Navigation extends TypedEventTarget<{
|
|
|
43
43
|
/**
|
|
44
44
|
* Register a new view on the navigation
|
|
45
45
|
* @param view The view to register
|
|
46
|
-
* @throws
|
|
46
|
+
* @throws {Error} if a view with the same id is already registered
|
|
47
|
+
* @throws {Error} if the registered view is invalid
|
|
47
48
|
*/
|
|
48
|
-
register(view:
|
|
49
|
+
register(view: IView): void;
|
|
49
50
|
/**
|
|
50
51
|
* Remove a registered view
|
|
51
52
|
* @param id The id of the view to remove
|
|
@@ -53,18 +54,20 @@ export declare class Navigation extends TypedEventTarget<{
|
|
|
53
54
|
remove(id: string): void;
|
|
54
55
|
/**
|
|
55
56
|
* Set the currently active view
|
|
57
|
+
*
|
|
58
|
+
* @param id - The id of the view to set as active
|
|
59
|
+
* @throws {Error} If no view with the given id was registered
|
|
56
60
|
* @fires UpdateActiveViewEvent
|
|
57
|
-
* @param view New active view
|
|
58
61
|
*/
|
|
59
|
-
setActive(
|
|
62
|
+
setActive(id: string | null): void;
|
|
60
63
|
/**
|
|
61
64
|
* The currently active files view
|
|
62
65
|
*/
|
|
63
|
-
get active():
|
|
66
|
+
get active(): IView | null;
|
|
64
67
|
/**
|
|
65
68
|
* All registered views
|
|
66
69
|
*/
|
|
67
|
-
get views():
|
|
70
|
+
get views(): IView[];
|
|
68
71
|
}
|
|
69
72
|
/**
|
|
70
73
|
* Get the current files navigation
|
|
@@ -5,7 +5,7 @@ export type ContentsWithRoot = {
|
|
|
5
5
|
folder: Folder;
|
|
6
6
|
contents: Node[];
|
|
7
7
|
};
|
|
8
|
-
interface
|
|
8
|
+
export interface IView {
|
|
9
9
|
/** Unique view ID */
|
|
10
10
|
id: string;
|
|
11
11
|
/** Translated view name */
|
|
@@ -26,14 +26,18 @@ interface ViewData {
|
|
|
26
26
|
*/
|
|
27
27
|
emptyView?: (div: HTMLDivElement) => void;
|
|
28
28
|
/**
|
|
29
|
-
* Method return the content of the
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* change and the promise is not resolved yet.
|
|
33
|
-
* You _must_ also return the current directory
|
|
29
|
+
* Method return the content of the provided path.
|
|
30
|
+
*
|
|
31
|
+
* This method _must_ also return the current directory
|
|
34
32
|
* information alongside with its content.
|
|
33
|
+
*
|
|
34
|
+
* Usually a abort signal is provided to be able to
|
|
35
|
+
* cancel the request if the user change directory
|
|
36
|
+
* {@see https://developer.mozilla.org/en-US/docs/Web/API/AbortController }.
|
|
35
37
|
*/
|
|
36
|
-
getContents
|
|
38
|
+
getContents(path: string, options: {
|
|
39
|
+
signal: AbortSignal;
|
|
40
|
+
}): Promise<ContentsWithRoot>;
|
|
37
41
|
/**
|
|
38
42
|
* If set then the view will be hidden from the navigation unless its the active view.
|
|
39
43
|
*/
|
|
@@ -75,15 +79,17 @@ interface ViewData {
|
|
|
75
79
|
*/
|
|
76
80
|
loadChildViews?: (view: View) => Promise<void>;
|
|
77
81
|
}
|
|
78
|
-
export declare class View implements
|
|
82
|
+
export declare class View implements IView {
|
|
79
83
|
private _view;
|
|
80
|
-
constructor(view:
|
|
84
|
+
constructor(view: IView);
|
|
81
85
|
get id(): string;
|
|
82
86
|
get name(): string;
|
|
83
87
|
get caption(): string | undefined;
|
|
84
88
|
get emptyTitle(): string | undefined;
|
|
85
89
|
get emptyCaption(): string | undefined;
|
|
86
|
-
get getContents(): (path: string
|
|
90
|
+
get getContents(): (path: string, options: {
|
|
91
|
+
signal: AbortSignal;
|
|
92
|
+
}) => Promise<ContentsWithRoot>;
|
|
87
93
|
get hidden(): true | undefined;
|
|
88
94
|
get icon(): string;
|
|
89
95
|
set icon(icon: string);
|
|
@@ -100,4 +106,10 @@ export declare class View implements ViewData {
|
|
|
100
106
|
get defaultSortKey(): string | undefined;
|
|
101
107
|
get loadChildViews(): ((view: View) => Promise<void>) | undefined;
|
|
102
108
|
}
|
|
103
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Validate a view interface to check all required properties are satisfied.
|
|
111
|
+
*
|
|
112
|
+
* @param view the view to check
|
|
113
|
+
* @throws {Error} if the view is not valid
|
|
114
|
+
*/
|
|
115
|
+
export declare function validateView(view: IView): void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ISidebarContext, ISidebarTab } from './SidebarTab.ts';
|
|
2
|
+
export interface ISidebar {
|
|
3
|
+
/**
|
|
4
|
+
* If the files sidebar can currently be accessed.
|
|
5
|
+
* Registering tabs also works if the sidebar is currently not available.
|
|
6
|
+
*/
|
|
7
|
+
readonly available: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* The current open state of the sidebar
|
|
10
|
+
*/
|
|
11
|
+
readonly open: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Open or close the sidebar
|
|
14
|
+
*
|
|
15
|
+
* @param open - The new open state
|
|
16
|
+
*/
|
|
17
|
+
setOpen(open: boolean): void;
|
|
18
|
+
/**
|
|
19
|
+
* Register a new sidebar tab
|
|
20
|
+
*
|
|
21
|
+
* @param tab - The sidebar tab to register
|
|
22
|
+
*/
|
|
23
|
+
registerTab(tab: ISidebarTab): void;
|
|
24
|
+
/**
|
|
25
|
+
* Get all registered sidebar tabs.
|
|
26
|
+
* If a node is passed only the enabled tabs are retrieved.
|
|
27
|
+
*/
|
|
28
|
+
getTabs(context?: ISidebarContext): ISidebarTab[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get a reference to the files sidebar.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getSidebar(): ISidebar;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { IView } from '../navigation/view.ts';
|
|
2
|
+
import { IFolder, INode } from '../node/index.ts';
|
|
3
|
+
export interface ISidebarContext {
|
|
4
|
+
/**
|
|
5
|
+
* The active node in the sidebar
|
|
6
|
+
*/
|
|
7
|
+
node: INode;
|
|
8
|
+
/**
|
|
9
|
+
* The current open folder in the files app
|
|
10
|
+
*/
|
|
11
|
+
folder: IFolder;
|
|
12
|
+
/**
|
|
13
|
+
* The currently active view
|
|
14
|
+
*/
|
|
15
|
+
view: IView;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* This component describes the custom web component that should be registered for a sidebar tab.
|
|
19
|
+
*
|
|
20
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Web_components
|
|
21
|
+
* @see https://vuejs.org/guide/extras/web-components#building-custom-elements-with-vue
|
|
22
|
+
*/
|
|
23
|
+
export interface SidebarComponent extends HTMLElement, ISidebarContext {
|
|
24
|
+
/**
|
|
25
|
+
* This method is called by the files app if the sidebar tab state changes.
|
|
26
|
+
*
|
|
27
|
+
* @param active - The new active state
|
|
28
|
+
*/
|
|
29
|
+
setActive(active: boolean): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Implementation of a custom sidebar tab within the files app.
|
|
33
|
+
*/
|
|
34
|
+
export interface ISidebarTab {
|
|
35
|
+
/**
|
|
36
|
+
* Unique id of the sidebar tab.
|
|
37
|
+
* This has to conform to the HTML id attribute specification.
|
|
38
|
+
*/
|
|
39
|
+
id: string;
|
|
40
|
+
/**
|
|
41
|
+
* The localized name of the sidebar tab.
|
|
42
|
+
*/
|
|
43
|
+
displayName: string;
|
|
44
|
+
/**
|
|
45
|
+
* The icon, as SVG, of the sidebar tab.
|
|
46
|
+
*/
|
|
47
|
+
iconSvgInline: string;
|
|
48
|
+
/**
|
|
49
|
+
* The order of this tab.
|
|
50
|
+
* Use a low number to make this tab ordered in front.
|
|
51
|
+
*/
|
|
52
|
+
order: number;
|
|
53
|
+
/**
|
|
54
|
+
* The tag name of the web component.
|
|
55
|
+
* The web component must already be registered under that tag name with `CustomElementRegistry.define()`.
|
|
56
|
+
*
|
|
57
|
+
* To avoid name clashes the name has to start with your appid (e.g. `your_app`).
|
|
58
|
+
* So in addition with the web component naming rules a good name would be `your_app-files-sidebar-tab`.
|
|
59
|
+
*/
|
|
60
|
+
tagName: string;
|
|
61
|
+
/**
|
|
62
|
+
* Callback to check if the sidebar tab should be shown for the selected node.
|
|
63
|
+
*
|
|
64
|
+
* @param context - The current context of the files app
|
|
65
|
+
*/
|
|
66
|
+
enabled: (context: ISidebarContext) => boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Register a new sidebar tab for the files app.
|
|
70
|
+
*
|
|
71
|
+
* @param tab - The sidebar tab to register
|
|
72
|
+
* @throws If the provided tab is not a valid sidebar tab and thus cannot be registered.
|
|
73
|
+
*/
|
|
74
|
+
export declare function registerSidebarTab(tab: ISidebarTab): void;
|
|
75
|
+
/**
|
|
76
|
+
* Get all currently registered sidebar tabs.
|
|
77
|
+
*/
|
|
78
|
+
export declare function getSidebarTabs(): ISidebarTab[];
|
package/dist/types.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { IFolder, INode } from './node/index.ts';
|
|
2
|
+
import { IView } from './navigation/index.ts';
|
|
3
3
|
export type ActionContextSingle = {
|
|
4
|
-
nodes: [
|
|
5
|
-
view:
|
|
6
|
-
folder:
|
|
7
|
-
contents:
|
|
4
|
+
nodes: [INode];
|
|
5
|
+
view: IView;
|
|
6
|
+
folder: IFolder;
|
|
7
|
+
contents: INode[];
|
|
8
8
|
};
|
|
9
9
|
export type ActionContext = {
|
|
10
|
-
nodes:
|
|
11
|
-
view:
|
|
12
|
-
folder:
|
|
13
|
-
contents:
|
|
10
|
+
nodes: INode[];
|
|
11
|
+
view: IView;
|
|
12
|
+
folder: IFolder;
|
|
13
|
+
contents: INode[];
|
|
14
14
|
};
|
|
15
15
|
export type ViewActionContext = {
|
|
16
|
-
view:
|
|
17
|
-
folder:
|
|
18
|
-
contents:
|
|
16
|
+
view: IView;
|
|
17
|
+
folder: IFolder;
|
|
18
|
+
contents: INode[];
|
|
19
19
|
};
|
package/dist/utils/filename.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextcloud/files",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.5",
|
|
4
4
|
"description": "Nextcloud files utils",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nextcloud",
|
|
@@ -21,18 +21,13 @@
|
|
|
21
21
|
"exports": {
|
|
22
22
|
".": {
|
|
23
23
|
"types": "./dist/index.d.ts",
|
|
24
|
-
"import": "./dist/index.mjs"
|
|
25
|
-
"require": "./dist/index.cjs"
|
|
24
|
+
"import": "./dist/index.mjs"
|
|
26
25
|
},
|
|
27
26
|
"./dav": {
|
|
28
27
|
"types": "./dist/dav/index.d.ts",
|
|
29
|
-
"import": "./dist/dav.mjs"
|
|
30
|
-
"require": "./dist/dav.cjs"
|
|
28
|
+
"import": "./dist/dav.mjs"
|
|
31
29
|
}
|
|
32
30
|
},
|
|
33
|
-
"main": "dist/index.cjs",
|
|
34
|
-
"module": "dist/index.mjs",
|
|
35
|
-
"types": "dist/index.d.ts",
|
|
36
31
|
"files": [
|
|
37
32
|
"dist"
|
|
38
33
|
],
|
|
@@ -56,11 +51,10 @@
|
|
|
56
51
|
"@nextcloud/auth": "^2.5.3",
|
|
57
52
|
"@nextcloud/capabilities": "^1.2.1",
|
|
58
53
|
"@nextcloud/l10n": "^3.4.1",
|
|
59
|
-
"@nextcloud/logger": "^3.0.
|
|
60
|
-
"@nextcloud/paths": "^
|
|
54
|
+
"@nextcloud/logger": "^3.0.3",
|
|
55
|
+
"@nextcloud/paths": "^3.0.0",
|
|
61
56
|
"@nextcloud/router": "^3.1.0",
|
|
62
57
|
"@nextcloud/sharing": "^0.3.0",
|
|
63
|
-
"cancelable-promise": "^4.3.1",
|
|
64
58
|
"is-svg": "^6.1.0",
|
|
65
59
|
"typescript-event-target": "^1.1.1",
|
|
66
60
|
"webdav": "^5.8.0"
|
|
@@ -71,19 +65,20 @@
|
|
|
71
65
|
"@nextcloud/event-bus": "^3.3.3",
|
|
72
66
|
"@nextcloud/typings": "^1.10.0",
|
|
73
67
|
"@nextcloud/vite-config": "^2.5.2",
|
|
74
|
-
"@types/node": "^
|
|
68
|
+
"@types/node": "^25.0.1",
|
|
75
69
|
"@vitest/coverage-istanbul": "^4.0.15",
|
|
76
|
-
"
|
|
77
|
-
"
|
|
70
|
+
"css.escape": "^1.5.1",
|
|
71
|
+
"fast-xml-parser": "^5.3.3",
|
|
72
|
+
"jsdom": "^27.3.0",
|
|
78
73
|
"tslib": "^2.8.1",
|
|
79
74
|
"typedoc": "^0.28.15",
|
|
80
75
|
"typedoc-plugin-missing-exports": "^4.1.2",
|
|
81
76
|
"typescript": "^5.9.3",
|
|
82
|
-
"vite": "^7.2.
|
|
77
|
+
"vite": "^7.2.7",
|
|
83
78
|
"vitest": "^4.0.14"
|
|
84
79
|
},
|
|
85
80
|
"engines": {
|
|
86
|
-
"node": "^
|
|
81
|
+
"node": "^24.0.0"
|
|
87
82
|
},
|
|
88
83
|
"devEngines": {
|
|
89
84
|
"packageManager": [
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"folder-QTYeAiOH.mjs","sources":["../../lib/utils/logger.ts","../../lib/node/fileType.ts","../../lib/permissions.ts","../../lib/node/nodeData.ts","../../lib/node/node.ts","../../lib/node/file.ts","../../lib/node/folder.ts"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { getLoggerBuilder } from '@nextcloud/logger'\n\nexport default getLoggerBuilder()\n\t.setApp('@nextcloud/files')\n\t.detectUser()\n\t.build()\n","/**\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nexport enum FileType {\n\tFolder = 'folder',\n\tFile = 'file',\n}\n","/**\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\n/**\n * Node permissions\n */\nexport enum Permission {\n\tNONE = 0,\n\tCREATE = 4,\n\tREAD = 1,\n\tUPDATE = 2,\n\tDELETE = 8,\n\tSHARE = 16,\n\tALL = 31,\n}\n","/**\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport { join } from 'path'\n\nimport { Permission } from '../permissions'\nimport { NodeStatus } from './node'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface Attribute { [key: string]: any }\n\nexport interface NodeData {\n\t/**\n\t * URL to the resource.\n\t * e.g. https://cloud.domain.com/remote.php/dav/files/emma/Photos/picture.jpg\n\t * or https://domain.com/Photos/picture.jpg\n\t */\n\tsource: string\n\n\t/**\n\t * The absolute root of the home relative to the service.\n\t * It is highly recommended to provide that information.\n\t * e.g. /files/emma\n\t */\n\troot: string\n\n\t/** Unique ID */\n\tid?: number\n\n\t/** Last modified time */\n\tmtime?: Date\n\n\t/** Creation time */\n\tcrtime?: Date\n\n\t/** The mime type Optional for folders only */\n\tmime?: string\n\n\t/** The node size type */\n\tsize?: number\n\n\t/** The node permissions */\n\tpermissions?: Permission\n\n\t/** The owner UID of this node */\n\towner: string|null\n\n\t/** Optional the displayname of this node */\n\tdisplayname?: string\n\n\t/** The node attributes */\n\tattributes?: Attribute\n\n\t/** The node status */\n\tstatus?: NodeStatus\n}\n\n/**\n * Check if a node source is from a specific DAV service\n *\n * @param source The source to check\n * @param davService Pattern to check if source is DAV resource\n */\nexport const isDavResource = function(source: string, davService: RegExp): boolean {\n\treturn source.match(davService) !== null\n}\n\n/**\n * Validate Node construct data\n *\n * @param data The node data\n * @param davService Pattern to check if source is DAV ressource\n */\nexport function validateData(data: NodeData, davService: RegExp) {\n\tif (data.id && typeof data.id !== 'number') {\n\t\tthrow new Error('Invalid id type of value')\n\t}\n\n\tif (!data.source) {\n\t\tthrow new Error('Missing mandatory source')\n\t}\n\n\ttry {\n\t\t// eslint-disable-next-line no-new\n\t\tnew URL(data.source)\n\t} catch (e) {\n\t\tthrow new Error('Invalid source format, source must be a valid URL')\n\t}\n\n\tif (!data.source.startsWith('http')) {\n\t\tthrow new Error('Invalid source format, only http(s) is supported')\n\t}\n\n\tif (!data.root) {\n\t\tthrow new Error('Missing mandatory root')\n\t}\n\n\tif (typeof data.root !== 'string') {\n\t\tthrow new Error('Invalid root type')\n\t}\n\n\tif (!data.root.startsWith('/')) {\n\t\tthrow new Error('Root must start with a leading slash')\n\t}\n\n\tif (!data.source.includes(data.root)) {\n\t\tthrow new Error('Root must be part of the source')\n\t}\n\n\tif (isDavResource(data.source, davService)) {\n\t\tconst service = data.source.match(davService)![0]\n\t\tif (!data.source.includes(join(service, data.root))) {\n\t\t\tthrow new Error('The root must be relative to the service. e.g /files/emma')\n\t\t}\n\t}\n\n\tif (data.displayname && typeof data.displayname !== 'string') {\n\t\tthrow new Error('Invalid displayname type')\n\t}\n\n\tif (data.mtime && !(data.mtime instanceof Date)) {\n\t\tthrow new Error('Invalid mtime type')\n\t}\n\n\tif (data.crtime && !(data.crtime instanceof Date)) {\n\t\tthrow new Error('Invalid crtime type')\n\t}\n\n\tif (!data.mime || typeof data.mime !== 'string'\n\t\t|| !data.mime.match(/^[-\\w.]+\\/[-+\\w.]+$/gi)) {\n\t\tthrow new Error('Missing or invalid mandatory mime')\n\t}\n\n\t// Allow size to be 0\n\tif ('size' in data && typeof data.size !== 'number' && data.size !== undefined) {\n\t\tthrow new Error('Invalid size type')\n\t}\n\n\t// Allow permissions to be 0\n\tif ('permissions' in data\n\t\t&& data.permissions !== undefined\n\t\t&& !(typeof data.permissions === 'number'\n\t\t\t&& data.permissions >= Permission.NONE\n\t\t\t&& data.permissions <= Permission.ALL\n\t\t)) {\n\t\tthrow new Error('Invalid permissions')\n\t}\n\n\tif (data.owner\n\t\t&& data.owner !== null\n\t\t&& typeof data.owner !== 'string') {\n\t\tthrow new Error('Invalid owner type')\n\t}\n\n\tif (data.attributes && typeof data.attributes !== 'object') {\n\t\tthrow new Error('Invalid attributes type')\n\t}\n\n\tif (data.status && !Object.values(NodeStatus).includes(data.status)) {\n\t\tthrow new Error('Status must be a valid NodeStatus')\n\t}\n}\n\n/**\n * In case we try to create a node from deserialized data,\n * we need to fix date types.\n *\n * @param data The internal node data\n */\nexport const fixDates = (data: NodeData) => {\n\tif (data.mtime && typeof data.mtime === 'string') {\n\t\tif (!isNaN(Date.parse(data.mtime))\n\t\t\t&& JSON.stringify(new Date(data.mtime)) === JSON.stringify(data.mtime)) {\n\t\t\tdata.mtime = new Date(data.mtime)\n\t\t}\n\t}\n\n\tif (data.crtime && typeof data.crtime === 'string') {\n\t\tif (!isNaN(Date.parse(data.crtime))\n\t\t\t&& JSON.stringify(new Date(data.crtime)) === JSON.stringify(data.crtime)) {\n\t\t\tdata.crtime = new Date(data.crtime)\n\t\t}\n\t}\n}\n\n/**\n * Fix a RegExp pattern from string or RegExp to RegExp\n *\n * @param pattern The pattern as string or RegExp\n */\nexport const fixRegExp = (pattern: string | RegExp): RegExp => {\n\tif (pattern instanceof RegExp) {\n\t\treturn pattern\n\t}\n\n\t// Extract the pattern and flags if it's a string\n\t// Pulled from https://www.npmjs.com/package/regex-parser\n\tconst matches = pattern.match(/(\\/?)(.+)\\1([a-z]*)/i)\n\n\t// If there's no match, throw an error\n\tif (!matches) {\n\t\tthrow new Error('Invalid regular expression format.')\n\t}\n\n\t// Filter valid flags: 'g', 'i', 'm', 's', 'u', and 'y'\n\tconst validFlags = Array.from(new Set(matches[3]))\n\t\t.filter((flag) => 'gimsuy'.includes(flag))\n\t\t.join('')\n\n\t// Create the regular expression\n\treturn new RegExp(matches[2], validFlags)\n}\n","/**\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { basename, extname, dirname } from 'path'\nimport { encodePath } from '@nextcloud/paths'\n\nimport { Permission } from '../permissions'\nimport { FileType } from './fileType'\nimport { Attribute, fixDates, fixRegExp, isDavResource, NodeData, validateData } from './nodeData'\n\nexport enum NodeStatus {\n\t/** This is a new node and it doesn't exists on the filesystem yet */\n\tNEW = 'new',\n\t/** This node has failed and is unavailable */\n\tFAILED = 'failed',\n\t/** This node is currently loading or have an operation in progress */\n\tLOADING = 'loading',\n\t/** This node is locked and cannot be modified */\n\tLOCKED = 'locked',\n}\n\nexport type NodeConstructorData = [NodeData, RegExp?]\n\nexport abstract class Node {\n\n\tprivate _attributes: Attribute\n\n\tprotected _data: NodeData\n\tprotected _knownDavService = /(remote|public)\\.php\\/(web)?dav/i\n\n\tprivate readonlyAttributes = Object.entries(Object.getOwnPropertyDescriptors(Node.prototype))\n\t\t.filter(e => typeof e[1].get === 'function' && e[0] !== '__proto__')\n\t\t.map(e => e[0])\n\n\tprivate handler = {\n\t\tset: (target: Attribute, prop: string, value: unknown): boolean => {\n\t\t\tif (this.readonlyAttributes.includes(prop)) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\t// Apply original changes\n\t\t\treturn Reflect.set(target, prop, value)\n\t\t},\n\t\tdeleteProperty: (target: Attribute, prop: string): boolean => {\n\t\t\tif (this.readonlyAttributes.includes(prop)) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\t// Apply original changes\n\t\t\treturn Reflect.deleteProperty(target, prop)\n\t\t},\n\t} as ProxyHandler<Attribute>\n\n\tprotected constructor(...[data, davService]: NodeConstructorData) {\n\t\tif (!data.mime) {\n\t\t\tdata.mime = 'application/octet-stream'\n\t\t}\n\n\t\t// Fix primitive types if needed\n\t\tfixDates(data)\n\t\tdavService = fixRegExp(davService || this._knownDavService)\n\n\t\t// Validate data\n\t\tvalidateData(data, davService)\n\n\t\tthis._data = {\n\t\t\t...data,\n\t\t\tattributes: {},\n\t\t}\n\n\t\t// Proxy the attributes to update the mtime on change\n\t\tthis._attributes = new Proxy(this._data.attributes!, this.handler)\n\n\t\t// Update attributes, this sanitizes the attributes to only contain valid attributes\n\t\tthis.update(data.attributes ?? {})\n\n\t\tif (davService) {\n\t\t\tthis._knownDavService = davService\n\t\t}\n\t}\n\n\t/**\n\t * Get the source url to this object\n\t * There is no setter as the source is not meant to be changed manually.\n\t * You can use the rename or move method to change the source.\n\t */\n\tget source(): string {\n\t\t// strip any ending slash\n\t\treturn this._data.source.replace(/\\/$/i, '')\n\t}\n\n\t/**\n\t * Get the encoded source url to this object for requests purposes\n\t */\n\tget encodedSource(): string {\n\t\tconst { origin } = new URL(this.source)\n\t\treturn origin + encodePath(this.source.slice(origin.length))\n\t}\n\n\t/**\n\t * Get this object name\n\t * There is no setter as the source is not meant to be changed manually.\n\t * You can use the rename or move method to change the source.\n\t */\n\tget basename(): string {\n\t\treturn basename(this.source)\n\t}\n\n\t/**\n\t * The nodes displayname\n\t * By default the display name and the `basename` are identical,\n\t * but it is possible to have a different name. This happens\n\t * on the files app for example for shared folders.\n\t */\n\tget displayname(): string {\n\t\treturn this._data.displayname || this.basename\n\t}\n\n\t/**\n\t * Set the displayname\n\t */\n\tset displayname(displayname: string) {\n\t\tvalidateData({ ...this._data, displayname }, this._knownDavService)\n\t\tthis._data.displayname = displayname\n\t}\n\n\t/**\n\t * Get this object's extension\n\t * There is no setter as the source is not meant to be changed manually.\n\t * You can use the rename or move method to change the source.\n\t */\n\tget extension(): string|null {\n\t\treturn extname(this.source)\n\t}\n\n\t/**\n\t * Get the directory path leading to this object\n\t * Will use the relative path to root if available\n\t *\n\t * There is no setter as the source is not meant to be changed manually.\n\t * You can use the rename or move method to change the source.\n\t */\n\tget dirname(): string {\n\t\treturn dirname(this.path)\n\t}\n\n\t/**\n\t * Is it a file or a folder ?\n\t */\n\tabstract get type(): FileType\n\n\t/**\n\t * Get the file mime\n\t */\n\tget mime(): string {\n\t\treturn this._data.mime || 'application/octet-stream'\n\t}\n\n\t/**\n\t * Set the file mime\n\t * Removing the mime type will set it to `application/octet-stream`\n\t */\n\tset mime(mime: string|undefined) {\n\t\tmime ??= 'application/octet-stream'\n\n\t\tvalidateData({ ...this._data, mime }, this._knownDavService)\n\t\tthis._data.mime = mime\n\t}\n\n\t/**\n\t * Get the file modification time\n\t */\n\tget mtime(): Date|undefined {\n\t\treturn this._data.mtime\n\t}\n\n\t/**\n\t * Set the file modification time\n\t */\n\tset mtime(mtime: Date|undefined) {\n\t\tvalidateData({ ...this._data, mtime }, this._knownDavService)\n\t\tthis._data.mtime = mtime\n\t}\n\n\t/**\n\t * Get the file creation time\n\t * There is no setter as the creation time is not meant to be changed\n\t */\n\tget crtime(): Date|undefined {\n\t\treturn this._data.crtime\n\t}\n\n\t/**\n\t * Get the file size\n\t */\n\tget size(): number|undefined {\n\t\treturn this._data.size\n\t}\n\n\t/**\n\t * Set the file size\n\t */\n\tset size(size: number|undefined) {\n\t\tvalidateData({ ...this._data, size }, this._knownDavService)\n\t\tthis.updateMtime()\n\t\tthis._data.size = size\n\t}\n\n\t/**\n\t * Get the file attribute\n\t * This contains all additional attributes not provided by the Node class\n\t */\n\tget attributes(): Attribute {\n\t\treturn this._attributes\n\t}\n\n\t/**\n\t * Get the file permissions\n\t */\n\tget permissions(): Permission {\n\t\t// If this is not a dav resource, we can only read it\n\t\tif (this.owner === null && !this.isDavResource) {\n\t\t\treturn Permission.READ\n\t\t}\n\n\t\t// If the permissions are not defined, we have none\n\t\treturn this._data.permissions !== undefined\n\t\t\t? this._data.permissions\n\t\t\t: Permission.NONE\n\t}\n\n\t/**\n\t * Set the file permissions\n\t */\n\tset permissions(permissions: Permission) {\n\t\tvalidateData({ ...this._data, permissions }, this._knownDavService)\n\t\tthis.updateMtime()\n\t\tthis._data.permissions = permissions\n\t}\n\n\t/**\n\t * Get the file owner\n\t * There is no setter as the owner is not meant to be changed\n\t */\n\tget owner(): string|null {\n\t\t// Remote resources have no owner\n\t\tif (!this.isDavResource) {\n\t\t\treturn null\n\t\t}\n\t\treturn this._data.owner\n\t}\n\n\t/**\n\t * Is this a dav-related resource ?\n\t */\n\tget isDavResource(): boolean {\n\t\treturn isDavResource(this.source, this._knownDavService)\n\t}\n\n\t/**\n\t * Get the dav root of this object\n\t * There is no setter as the root is not meant to be changed\n\t */\n\tget root(): string {\n\t\treturn this._data.root.replace(/^(.+)\\/$/, '$1')\n\t}\n\n\t/**\n\t * Get the absolute path of this object relative to the root\n\t */\n\tget path(): string {\n\t\t// Extract the path part from the source URL\n\t\t// e.g. https://cloud.domain.com/remote.php/dav/files/username/Path/To/File.txt\n\t\tconst idx = this.source.indexOf('://')\n\t\tconst protocol = this.source.slice(0, idx) // e.g. https\n\t\tconst remainder = this.source.slice(idx + 3) // e.g. cloud.domain.com/remote.php/dav/files/username/Path/To/File.txt\n\n\t\tconst slashIndex = remainder.indexOf('/')\n\t\tconst host = remainder.slice(0, slashIndex) // e.g. cloud.domain.com\n\t\tconst rawPath = remainder.slice(slashIndex) // e.g. /remote.php/dav/files/username/Path/To/File.txt\n\n\t\t// Rebuild a safe URL with encoded path\n\t\tconst safeUrl = `${protocol}://${host}${encodePath(rawPath)}`\n\t\tconst url = new URL(safeUrl)\n\n\t\tlet source = decodeURIComponent(url.pathname)\n\n\t\tif (this.isDavResource) {\n\t\t\t// ensure we only work on the real path in case root is not distinct\n\t\t\tsource = source.split(this._knownDavService).pop()!\n\t\t}\n\t\t// Using replace would remove all part matching root\n\t\tconst firstMatch = source.indexOf(this.root)\n\t\t// Ensure we do not remove the leading slash\n\t\tconst root = this.root.replace(/\\/$/, '')\n\t\treturn source.slice(firstMatch + root.length) || '/'\n\t}\n\n\t/**\n\t * Get the node id if defined.\n\t * There is no setter as the fileid is not meant to be changed\n\t */\n\tget fileid(): number|undefined {\n\t\treturn this._data?.id\n\t}\n\n\t/**\n\t * Get the node status.\n\t */\n\tget status(): NodeStatus|undefined {\n\t\treturn this._data?.status\n\t}\n\n\t/**\n\t * Set the node status.\n\t */\n\tset status(status: NodeStatus|undefined) {\n\t\tvalidateData({ ...this._data, status }, this._knownDavService)\n\t\tthis._data.status = status\n\t}\n\n\t/**\n\t * Move the node to a new destination\n\t *\n\t * @param {string} destination the new source.\n\t * e.g. https://cloud.domain.com/remote.php/dav/files/emma/Photos/picture.jpg\n\t */\n\tmove(destination: string) {\n\t\tvalidateData({ ...this._data, source: destination }, this._knownDavService)\n\t\tconst oldBasename = this.basename\n\n\t\tthis._data.source = destination\n\t\t// Check if the displayname and the (old) basename were the same\n\t\t// meaning no special displayname was set but just a fallback to the basename by Nextcloud's WebDAV server\n\t\tif (this.displayname === oldBasename\n\t\t\t&& this.basename !== oldBasename) {\n\t\t\t// We have to assume that the displayname was not set but just a copy of the basename\n\t\t\t// this can not be guaranteed, so to be sure users should better refetch the node\n\t\t\tthis.displayname = this.basename\n\t\t}\n\t}\n\n\t/**\n\t * Rename the node\n\t * This aliases the move method for easier usage\n\t *\n\t * @param basename The new name of the node\n\t */\n\trename(basename: string) {\n\t\tif (basename.includes('/')) {\n\t\t\tthrow new Error('Invalid basename')\n\t\t}\n\t\tthis.move(dirname(this.source) + '/' + basename)\n\t}\n\n\t/**\n\t * Update the mtime if exists\n\t */\n\tupdateMtime() {\n\t\tif (this._data.mtime) {\n\t\t\tthis._data.mtime = new Date()\n\t\t}\n\t}\n\n\t/**\n\t * Update the attributes of the node\n\t * Warning, updating attributes will NOT automatically update the mtime.\n\t *\n\t * @param attributes The new attributes to update on the Node attributes\n\t */\n\tupdate(attributes: Attribute) {\n\t\tfor (const [name, value] of Object.entries(attributes)) {\n\t\t\ttry {\n\t\t\t\tif (value === undefined) {\n\t\t\t\t\tdelete this.attributes[name]\n\t\t\t\t} else {\n\t\t\t\t\tthis.attributes[name] = value\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\t// Ignore readonly attributes\n\t\t\t\tif (e instanceof TypeError) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\t// Throw all other exceptions\n\t\t\t\tthrow e\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns a clone of the node\n\t */\n\tclone(): this {\n\t\t// @ts-expect-error -- this class is abstract and cannot be instantiated directly but all its children can\n\t\treturn new this.constructor(structuredClone(this._data), this._knownDavService)\n\t}\n\n\t/**\n\t * JSON representation of the node\n\t */\n\ttoJSON(): string {\n\t\treturn JSON.stringify([structuredClone(this._data), this._knownDavService.toString()])\n\t}\n\n}\n\n/**\n * Interface of the node class\n */\nexport type INode = Pick<Node, keyof Node>\n","/**\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport type { NodeConstructorData } from './node'\n\nimport { FileType } from './fileType'\nimport { Node } from './node'\n\nexport class File extends Node {\n\n\tpublic constructor(...[data, davService]: NodeConstructorData) {\n\t\tsuper(data, davService)\n\t}\n\n\tget type(): FileType.File {\n\t\treturn FileType.File\n\t}\n\n}\n\n/**\n * Interface of the File class\n */\nexport type IFile = Pick<File, keyof File>\n","/**\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport type { NodeConstructorData } from './node'\n\nimport { FileType } from './fileType'\nimport { Node } from './node'\n\nexport class Folder extends Node {\n\n\tconstructor(...[data, davService]: NodeConstructorData) {\n\t\t// enforcing mimes\n\t\tsuper({\n\t\t\t...data,\n\t\t\tmime: 'httpd/unix-directory',\n\t\t}, davService)\n\t}\n\n\tget type(): FileType.Folder {\n\t\treturn FileType.Folder\n\t}\n\n\tget extension(): null {\n\t\treturn null\n\t}\n\n\tget mime(): 'httpd/unix-directory' {\n\t\treturn 'httpd/unix-directory'\n\t}\n\n}\n\n/**\n * Interface of the folder class\n */\nexport type IFolder = Pick<Folder, keyof Folder>\n"],"names":["FileType","Permission","NodeStatus","basename"],"mappings":"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"}
|