@nextcloud/files 3.10.0 → 3.10.2
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/dist/chunks/{dav-DxfiR0wZ.mjs → dav-Co9y-hkg.mjs} +15 -9
- package/dist/chunks/dav-Co9y-hkg.mjs.map +1 -0
- package/dist/chunks/{dav-BBwoJ8WE.cjs → dav-CtqjqS4O.cjs} +15 -9
- package/dist/chunks/dav-CtqjqS4O.cjs.map +1 -0
- package/dist/dav/dav.d.ts +55 -0
- package/dist/dav/davPermissions.d.ts +6 -0
- package/dist/dav/davProperties.d.ts +57 -0
- package/dist/dav/index.d.ts +13 -0
- package/dist/dav.cjs +1 -1
- package/dist/dav.mjs +1 -1
- package/dist/fileAction.d.ts +83 -0
- package/dist/fileListAction.d.ts +41 -0
- package/dist/fileListFilters.d.ts +100 -0
- package/dist/fileListHeaders.d.ts +26 -0
- package/dist/files/file.d.ts +13 -0
- package/dist/files/fileType.d.ts +8 -0
- package/dist/files/folder.d.ts +17 -0
- package/dist/files/node.d.ts +177 -0
- package/dist/files/nodeData.d.ts +53 -0
- package/dist/index.cjs +1956 -1805
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +118 -1099
- package/dist/index.mjs +1957 -1806
- package/dist/index.mjs.map +1 -1
- package/dist/navigation/column.d.ts +27 -0
- package/dist/navigation/index.d.ts +7 -0
- package/dist/navigation/navigation.d.ts +73 -0
- package/dist/navigation/view.d.ts +91 -0
- package/dist/newFileMenu.d.ts +65 -0
- package/dist/permissions.d.ts +16 -0
- package/dist/utils/fileSize.d.ts +25 -0
- package/dist/utils/fileSorting.d.ts +34 -0
- package/dist/utils/filename-validation.d.ts +51 -0
- package/dist/utils/filename.d.ts +24 -0
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/sorting.d.ts +12 -0
- package/dist/vendor.LICENSE.txt +1 -1
- package/package.json +14 -14
- package/dist/chunks/dav-BBwoJ8WE.cjs.map +0 -1
- package/dist/chunks/dav-DxfiR0wZ.mjs.map +0 -1
- package/dist/dav.d.ts +0 -370
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Node } from '../files/node';
|
|
2
|
+
import { View } from './view';
|
|
3
|
+
interface ColumnData {
|
|
4
|
+
/** Unique column ID */
|
|
5
|
+
id: string;
|
|
6
|
+
/** Translated column title */
|
|
7
|
+
title: string;
|
|
8
|
+
/** The content of the cell. The element will be appended within */
|
|
9
|
+
render: (node: Node, view: View) => HTMLElement;
|
|
10
|
+
/** Function used to sort Nodes between them */
|
|
11
|
+
sort?: (nodeA: Node, nodeB: Node) => number;
|
|
12
|
+
/**
|
|
13
|
+
* Custom summary of the column to display at the end of the list.
|
|
14
|
+
* Will not be displayed if nothing is provided
|
|
15
|
+
*/
|
|
16
|
+
summary?: (node: Node[], view: View) => string;
|
|
17
|
+
}
|
|
18
|
+
export declare class Column implements ColumnData {
|
|
19
|
+
private _column;
|
|
20
|
+
constructor(column: ColumnData);
|
|
21
|
+
get id(): string;
|
|
22
|
+
get title(): string;
|
|
23
|
+
get render(): (node: Node, view: View) => HTMLElement;
|
|
24
|
+
get sort(): ((nodeA: Node, nodeB: Node) => number) | undefined;
|
|
25
|
+
get summary(): ((node: Node[], view: View) => string) | undefined;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { View } from './view';
|
|
2
|
+
import { TypedEventTarget } from 'typescript-event-target';
|
|
3
|
+
/**
|
|
4
|
+
* The event is emitted when the navigation view was updated.
|
|
5
|
+
* It contains the new active view in the `detail` attribute.
|
|
6
|
+
*/
|
|
7
|
+
interface UpdateActiveViewEvent extends CustomEvent<View | null> {
|
|
8
|
+
type: 'updateActive';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* This event is emitted when the list of registered views is changed
|
|
12
|
+
*/
|
|
13
|
+
interface UpdateViewsEvent extends CustomEvent<never> {
|
|
14
|
+
type: 'update';
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The files navigation manages the available and active views
|
|
18
|
+
*
|
|
19
|
+
* Custom views for the files app can be registered (examples are the favorites views or the shared-with-you view).
|
|
20
|
+
* It is also possible to listen on changes of the registered views or when the current active view is changed.
|
|
21
|
+
* @example
|
|
22
|
+
* ```js
|
|
23
|
+
* const navigation = getNavigation()
|
|
24
|
+
* navigation.addEventListener('update', () => {
|
|
25
|
+
* // This will be called whenever a new view is registered or a view is removed
|
|
26
|
+
* const viewNames = navigation.views.map((view) => view.name)
|
|
27
|
+
* console.warn('Registered views changed', viewNames)
|
|
28
|
+
* })
|
|
29
|
+
* // Or you can react to changes of the current active view
|
|
30
|
+
* navigation.addEventListener('updateActive', (event) => {
|
|
31
|
+
* // This will be called whenever the active view changed
|
|
32
|
+
* const newView = event.detail // you could also use `navigation.active`
|
|
33
|
+
* console.warn('Active view changed to ' + newView.name)
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare class Navigation extends TypedEventTarget<{
|
|
38
|
+
updateActive: UpdateActiveViewEvent;
|
|
39
|
+
update: UpdateViewsEvent;
|
|
40
|
+
}> {
|
|
41
|
+
private _views;
|
|
42
|
+
private _currentView;
|
|
43
|
+
/**
|
|
44
|
+
* Register a new view on the navigation
|
|
45
|
+
* @param view The view to register
|
|
46
|
+
* @throws `Error` is thrown if a view with the same id is already registered
|
|
47
|
+
*/
|
|
48
|
+
register(view: View): void;
|
|
49
|
+
/**
|
|
50
|
+
* Remove a registered view
|
|
51
|
+
* @param id The id of the view to remove
|
|
52
|
+
*/
|
|
53
|
+
remove(id: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Set the currently active view
|
|
56
|
+
* @fires UpdateActiveViewEvent
|
|
57
|
+
* @param view New active view
|
|
58
|
+
*/
|
|
59
|
+
setActive(view: View | null): void;
|
|
60
|
+
/**
|
|
61
|
+
* The currently active files view
|
|
62
|
+
*/
|
|
63
|
+
get active(): View | null;
|
|
64
|
+
/**
|
|
65
|
+
* All registered views
|
|
66
|
+
*/
|
|
67
|
+
get views(): View[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get the current files navigation
|
|
71
|
+
*/
|
|
72
|
+
export declare const getNavigation: () => Navigation;
|
|
73
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Folder } from '../files/folder';
|
|
2
|
+
import { Node } from '../files/node';
|
|
3
|
+
import { Column } from './column.js';
|
|
4
|
+
export type ContentsWithRoot = {
|
|
5
|
+
folder: Folder;
|
|
6
|
+
contents: Node[];
|
|
7
|
+
};
|
|
8
|
+
interface ViewData {
|
|
9
|
+
/** Unique view ID */
|
|
10
|
+
id: string;
|
|
11
|
+
/** Translated view name */
|
|
12
|
+
name: string;
|
|
13
|
+
/** Translated accessible description of the view */
|
|
14
|
+
caption?: string;
|
|
15
|
+
/** Translated title of the empty view */
|
|
16
|
+
emptyTitle?: string;
|
|
17
|
+
/** Translated description of the empty view */
|
|
18
|
+
emptyCaption?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Method return the content of the provided path
|
|
21
|
+
* This ideally should be a cancellable promise.
|
|
22
|
+
* promise.cancel(reason) will be called when the directory
|
|
23
|
+
* change and the promise is not resolved yet.
|
|
24
|
+
* You _must_ also return the current directory
|
|
25
|
+
* information alongside with its content.
|
|
26
|
+
*/
|
|
27
|
+
getContents: (path: string) => Promise<ContentsWithRoot>;
|
|
28
|
+
/** The view icon as an inline svg */
|
|
29
|
+
icon: string;
|
|
30
|
+
/**
|
|
31
|
+
* The view order.
|
|
32
|
+
* If not set will be natural sorted by view name.
|
|
33
|
+
*/
|
|
34
|
+
order?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Custom params to give to the router on click
|
|
37
|
+
* If defined, will be treated as a dummy view and
|
|
38
|
+
* will just redirect and not fetch any contents.
|
|
39
|
+
*/
|
|
40
|
+
params?: Record<string, string>;
|
|
41
|
+
/**
|
|
42
|
+
* This view column(s). Name and actions are
|
|
43
|
+
* by default always included
|
|
44
|
+
*/
|
|
45
|
+
columns?: Column[];
|
|
46
|
+
/** The empty view element to render your empty content into */
|
|
47
|
+
emptyView?: (div: HTMLDivElement) => void;
|
|
48
|
+
/** The parent unique ID */
|
|
49
|
+
parent?: string;
|
|
50
|
+
/** This view is sticky (sent at the bottom) */
|
|
51
|
+
sticky?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* This view has children and is expanded (by default)
|
|
54
|
+
* or not. This will be overridden by user config.
|
|
55
|
+
*/
|
|
56
|
+
expanded?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Will be used as default if the user
|
|
59
|
+
* haven't customized their sorting column
|
|
60
|
+
*/
|
|
61
|
+
defaultSortKey?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Method called to load child views if any
|
|
64
|
+
*/
|
|
65
|
+
loadChildViews?: (view: View) => Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
export declare class View implements ViewData {
|
|
68
|
+
private _view;
|
|
69
|
+
constructor(view: ViewData);
|
|
70
|
+
get id(): string;
|
|
71
|
+
get name(): string;
|
|
72
|
+
get caption(): string | undefined;
|
|
73
|
+
get emptyTitle(): string | undefined;
|
|
74
|
+
get emptyCaption(): string | undefined;
|
|
75
|
+
get getContents(): (path: string) => Promise<ContentsWithRoot>;
|
|
76
|
+
get icon(): string;
|
|
77
|
+
set icon(icon: string);
|
|
78
|
+
get order(): number | undefined;
|
|
79
|
+
set order(order: number | undefined);
|
|
80
|
+
get params(): Record<string, string> | undefined;
|
|
81
|
+
set params(params: Record<string, string> | undefined);
|
|
82
|
+
get columns(): Column[] | undefined;
|
|
83
|
+
get emptyView(): ((div: HTMLDivElement) => void) | undefined;
|
|
84
|
+
get parent(): string | undefined;
|
|
85
|
+
get sticky(): boolean | undefined;
|
|
86
|
+
get expanded(): boolean | undefined;
|
|
87
|
+
set expanded(expanded: boolean | undefined);
|
|
88
|
+
get defaultSortKey(): string | undefined;
|
|
89
|
+
get loadChildViews(): ((view: View) => Promise<void>) | undefined;
|
|
90
|
+
}
|
|
91
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Folder, Node } from './index';
|
|
2
|
+
export declare enum NewMenuEntryCategory {
|
|
3
|
+
/**
|
|
4
|
+
* For actions where the user is intended to upload from their device
|
|
5
|
+
*/
|
|
6
|
+
UploadFromDevice = 0,
|
|
7
|
+
/**
|
|
8
|
+
* For actions that create new nodes on the server without uploading
|
|
9
|
+
*/
|
|
10
|
+
CreateNew = 1,
|
|
11
|
+
/**
|
|
12
|
+
* For everything not matching the other categories
|
|
13
|
+
*/
|
|
14
|
+
Other = 2
|
|
15
|
+
}
|
|
16
|
+
export interface Entry {
|
|
17
|
+
/** Unique ID */
|
|
18
|
+
id: string;
|
|
19
|
+
/**
|
|
20
|
+
* Category to put this entry in
|
|
21
|
+
* (supported since Nextcloud 30)
|
|
22
|
+
* @since 3.3.0
|
|
23
|
+
* @default NewMenuEntryCategory.CreateNew
|
|
24
|
+
*/
|
|
25
|
+
category?: NewMenuEntryCategory;
|
|
26
|
+
/** Translatable string displayed in the menu */
|
|
27
|
+
displayName: string;
|
|
28
|
+
/**
|
|
29
|
+
* Condition wether this entry is shown or not
|
|
30
|
+
* @param context the creation context. Usually the current folder
|
|
31
|
+
*/
|
|
32
|
+
enabled?: (context: Folder) => boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Either iconSvgInline or iconClass must be defined
|
|
35
|
+
* Svg as inline string. <svg><path fill="..." /></svg>
|
|
36
|
+
*/
|
|
37
|
+
iconSvgInline?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Existing icon css class
|
|
40
|
+
* @deprecated use iconSvgInline instead
|
|
41
|
+
*/
|
|
42
|
+
iconClass?: string;
|
|
43
|
+
/** Order of the entry in the menu */
|
|
44
|
+
order?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Function to be run after creation
|
|
47
|
+
* @param context the creation context. Usually the current folder
|
|
48
|
+
* @param content list of file/folders present in the context folder
|
|
49
|
+
*/
|
|
50
|
+
handler: (context: Folder, content: Node[]) => void;
|
|
51
|
+
}
|
|
52
|
+
export declare class NewFileMenu {
|
|
53
|
+
private _entries;
|
|
54
|
+
registerEntry(entry: Entry): void;
|
|
55
|
+
unregisterEntry(entry: Entry | string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Get the list of registered entries
|
|
58
|
+
*
|
|
59
|
+
* @param {Folder} context the creation context. Usually the current folder
|
|
60
|
+
*/
|
|
61
|
+
getEntries(context?: Folder): Array<Entry>;
|
|
62
|
+
private getEntryIndex;
|
|
63
|
+
private validateEntry;
|
|
64
|
+
}
|
|
65
|
+
export declare const getNewFileMenu: () => NewFileMenu;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
|
|
3
|
+
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Node permissions
|
|
7
|
+
*/
|
|
8
|
+
export declare enum Permission {
|
|
9
|
+
NONE = 0,
|
|
10
|
+
CREATE = 4,
|
|
11
|
+
READ = 1,
|
|
12
|
+
UPDATE = 2,
|
|
13
|
+
DELETE = 8,
|
|
14
|
+
SHARE = 16,
|
|
15
|
+
ALL = 31
|
|
16
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
|
|
3
|
+
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Format a file size in a human-like format. e.g. 42GB
|
|
7
|
+
*
|
|
8
|
+
* The default for Nextcloud is like Windows using binary sizes but showing decimal units,
|
|
9
|
+
* meaning 1024 bytes will show as 1KB instead of 1KiB or like on Apple 1.02 KB
|
|
10
|
+
*
|
|
11
|
+
* @param size in bytes
|
|
12
|
+
* @param skipSmallSizes avoid rendering tiny sizes and return '< 1 KB' instead
|
|
13
|
+
* @param binaryPrefixes True if size binary prefixes like `KiB` should be used as per IEC 80000-13
|
|
14
|
+
* @param base1000 Set to true to use base 1000 as per SI or used by Apple (default is base 1024 like Linux or Windows)
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatFileSize(size: number | string, skipSmallSizes?: boolean, binaryPrefixes?: boolean, base1000?: boolean): string;
|
|
17
|
+
/**
|
|
18
|
+
* Returns a file size in bytes from a humanly readable string
|
|
19
|
+
* Note: `b` and `B` are both parsed as bytes and not as bit or byte.
|
|
20
|
+
*
|
|
21
|
+
* @param {string} value file size in human-readable format
|
|
22
|
+
* @param {boolean} forceBinary for backwards compatibility this allows values to be base 2 (so 2KB means 2048 bytes instead of 2000 bytes)
|
|
23
|
+
* @return {number} or null if string could not be parsed
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseFileSize(value: string, forceBinary?: boolean): number | null;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { INode } from '../files/node';
|
|
2
|
+
import { SortingOrder } from './sorting';
|
|
3
|
+
export declare enum FilesSortingMode {
|
|
4
|
+
Name = "basename",
|
|
5
|
+
Modified = "mtime",
|
|
6
|
+
Size = "size"
|
|
7
|
+
}
|
|
8
|
+
export interface FilesSortingOptions {
|
|
9
|
+
/**
|
|
10
|
+
* They key to order the files by
|
|
11
|
+
* @default FilesSortingMode.Name
|
|
12
|
+
*/
|
|
13
|
+
sortingMode?: FilesSortingMode;
|
|
14
|
+
/**
|
|
15
|
+
* @default 'asc'
|
|
16
|
+
*/
|
|
17
|
+
sortingOrder?: SortingOrder;
|
|
18
|
+
/**
|
|
19
|
+
* If set to true nodes marked as favorites are ordered on top of all other nodes
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
sortFavoritesFirst?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* If set to true folders are ordered on top of files
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
sortFoldersFirst?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Sort files and folders according to the sorting options
|
|
31
|
+
* @param nodes Nodes to sort
|
|
32
|
+
* @param options Sorting options
|
|
33
|
+
*/
|
|
34
|
+
export declare function sortNodes(nodes: readonly INode[], options?: FilesSortingOptions): INode[];
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
|
|
3
|
+
* SPDX-License-Identifier: AGPL-3.0-or-later or LGPL-3.0-or-later
|
|
4
|
+
*/
|
|
5
|
+
export declare enum InvalidFilenameErrorReason {
|
|
6
|
+
ReservedName = "reserved name",
|
|
7
|
+
Character = "character",
|
|
8
|
+
Extension = "extension"
|
|
9
|
+
}
|
|
10
|
+
interface InvalidFilenameErrorOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The filename that was validated
|
|
13
|
+
*/
|
|
14
|
+
filename: string;
|
|
15
|
+
/**
|
|
16
|
+
* Reason why the validation failed
|
|
17
|
+
*/
|
|
18
|
+
reason: InvalidFilenameErrorReason;
|
|
19
|
+
/**
|
|
20
|
+
* Part of the filename that caused this error
|
|
21
|
+
*/
|
|
22
|
+
segment: string;
|
|
23
|
+
}
|
|
24
|
+
export declare class InvalidFilenameError extends Error {
|
|
25
|
+
constructor(options: InvalidFilenameErrorOptions);
|
|
26
|
+
/**
|
|
27
|
+
* The filename that was validated
|
|
28
|
+
*/
|
|
29
|
+
get filename(): string;
|
|
30
|
+
/**
|
|
31
|
+
* Reason why the validation failed
|
|
32
|
+
*/
|
|
33
|
+
get reason(): InvalidFilenameErrorReason;
|
|
34
|
+
/**
|
|
35
|
+
* Part of the filename that caused this error
|
|
36
|
+
*/
|
|
37
|
+
get segment(): string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validate a given filename
|
|
41
|
+
* @param filename The filename to check
|
|
42
|
+
* @throws {InvalidFilenameError}
|
|
43
|
+
*/
|
|
44
|
+
export declare function validateFilename(filename: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Check the validity of a filename
|
|
47
|
+
* This is a convinient wrapper for `checkFilenameValidity` to only return a boolean for the valid
|
|
48
|
+
* @param filename Filename to check validity
|
|
49
|
+
*/
|
|
50
|
+
export declare function isFilenameValid(filename: string): boolean;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: Ferdinand Thiessen <opensource@fthiessen.de>
|
|
3
|
+
* SPDX-License-Identifier: AGPL-3.0-or-later or LGPL-3.0-or-later
|
|
4
|
+
*/
|
|
5
|
+
interface UniqueNameOptions {
|
|
6
|
+
/**
|
|
7
|
+
* A function that takes an index and returns a suffix to add to the file name, defaults to '(index)'
|
|
8
|
+
* @param index The current index to add
|
|
9
|
+
*/
|
|
10
|
+
suffix?: (index: number) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Set to true to ignore the file extension when adding the suffix (when getting a unique directory name)
|
|
13
|
+
*/
|
|
14
|
+
ignoreFileExtension?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create an unique file name
|
|
18
|
+
* @param name The initial name to use
|
|
19
|
+
* @param otherNames Other names that are already used
|
|
20
|
+
* @param options Optional parameters for tuning the behavior
|
|
21
|
+
* @return {string} Either the initial name, if unique, or the name with the suffix so that the name is unique
|
|
22
|
+
*/
|
|
23
|
+
export declare function getUniqueName(name: string, otherNames: string[], options?: UniqueNameOptions): string;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type IdentifierFn<T> = (v: T) => unknown;
|
|
2
|
+
export type SortingOrder = 'asc' | 'desc';
|
|
3
|
+
/**
|
|
4
|
+
* Natural order a collection
|
|
5
|
+
* You can define identifiers as callback functions, that get the element and return the value to sort.
|
|
6
|
+
*
|
|
7
|
+
* @param collection The collection to order
|
|
8
|
+
* @param identifiers An array of identifiers to use, by default the identity of the element is used
|
|
9
|
+
* @param orders Array of orders, by default all identifiers are sorted ascening
|
|
10
|
+
*/
|
|
11
|
+
export declare function orderBy<T>(collection: readonly T[], identifiers?: IdentifierFn<T>[], orders?: SortingOrder[]): T[];
|
|
12
|
+
export {};
|
package/dist/vendor.LICENSE.txt
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextcloud/files",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.2",
|
|
4
4
|
"description": "Nextcloud files utils",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"require": "./dist/index.cjs"
|
|
14
14
|
},
|
|
15
15
|
"./dav": {
|
|
16
|
-
"types": "./dist/dav.d.ts",
|
|
16
|
+
"types": "./dist/dav/index.d.ts",
|
|
17
17
|
"import": "./dist/dav.mjs",
|
|
18
18
|
"require": "./dist/dav.cjs"
|
|
19
19
|
}
|
|
@@ -56,20 +56,21 @@
|
|
|
56
56
|
},
|
|
57
57
|
"homepage": "https://github.com/nextcloud-libraries/nextcloud-files",
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@codecov/vite-plugin": "^1.
|
|
59
|
+
"@codecov/vite-plugin": "^1.8.0",
|
|
60
60
|
"@nextcloud/eslint-config": "^8.4.1",
|
|
61
61
|
"@nextcloud/event-bus": "^3.3.1",
|
|
62
62
|
"@nextcloud/typings": "^1.9.1",
|
|
63
|
-
"@nextcloud/vite-config": "^2.
|
|
64
|
-
"@types/node": "^22.
|
|
65
|
-
"@vitest/coverage-istanbul": "^
|
|
66
|
-
"fast-xml-parser": "^4.5.
|
|
67
|
-
"jsdom": "^
|
|
63
|
+
"@nextcloud/vite-config": "^2.3.1",
|
|
64
|
+
"@types/node": "^22.13.1",
|
|
65
|
+
"@vitest/coverage-istanbul": "^3.0.5",
|
|
66
|
+
"fast-xml-parser": "^4.5.1",
|
|
67
|
+
"jsdom": "^26.0.0",
|
|
68
68
|
"tslib": "^2.8.1",
|
|
69
|
-
"typedoc": "^0.
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
69
|
+
"typedoc": "^0.27.6",
|
|
70
|
+
"typedoc-plugin-missing-exports": "^3.1.0",
|
|
71
|
+
"typescript": "^5.7.3",
|
|
72
|
+
"vite": "^6.1.0",
|
|
73
|
+
"vitest": "^3.0.4"
|
|
73
74
|
},
|
|
74
75
|
"dependencies": {
|
|
75
76
|
"@nextcloud/auth": "^2.4.0",
|
|
@@ -78,10 +79,9 @@
|
|
|
78
79
|
"@nextcloud/logger": "^3.0.2",
|
|
79
80
|
"@nextcloud/paths": "^2.2.1",
|
|
80
81
|
"@nextcloud/router": "^3.0.1",
|
|
81
|
-
"@nextcloud/sharing": "^0.2.
|
|
82
|
+
"@nextcloud/sharing": "^0.2.4",
|
|
82
83
|
"cancelable-promise": "^4.3.1",
|
|
83
84
|
"is-svg": "^5.1.0",
|
|
84
|
-
"typedoc-plugin-missing-exports": "^3.0.0",
|
|
85
85
|
"typescript-event-target": "^1.1.1",
|
|
86
86
|
"webdav": "^5.7.1"
|
|
87
87
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dav-BBwoJ8WE.cjs","sources":["../../lib/utils/logger.ts","../../lib/permissions.ts","../../lib/files/fileType.ts","../../lib/files/nodeData.ts","../../lib/files/node.ts","../../lib/files/file.ts","../../lib/files/folder.ts","../../lib/dav/davPermissions.ts","../../lib/dav/davProperties.ts","../../lib/dav/dav.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\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 */\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\nimport { join } from 'path'\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/** Unique ID */\n\tid?: number\n\n\t/**\n\t * URL to the ressource.\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/** 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/**\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/** 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 ressource\n */\nexport const isDavRessource = 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 const 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.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.root && typeof data.root !== 'string') {\n\t\tthrow new Error('Invalid root type')\n\t}\n\n\tif (data.root && !data.root.startsWith('/')) {\n\t\tthrow new Error('Root must start with a leading slash')\n\t}\n\n\tif (data.root && !data.source.includes(data.root)) {\n\t\tthrow new Error('Root must be part of the source')\n\t}\n\n\tif (data.root && isDavRessource(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.status && !Object.values(NodeStatus).includes(data.status)) {\n\t\tthrow new Error('Status must be a valid NodeStatus')\n\t}\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, NodeData, isDavRessource, validateData } from './nodeData'\nimport logger from '../utils/logger'\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 abstract class Node {\n\n\tprivate _data: NodeData\n\tprivate _attributes: Attribute\n\tprivate _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\t// TODO: This is deprecated and only needed for files v3\n\t\tget: (target: Attribute, prop: string, receiver) => {\n\t\t\tif (this.readonlyAttributes.includes(prop)) {\n\t\t\t\tlogger.warn(`Accessing \"Node.attributes.${prop}\" is deprecated, access it directly on the Node instance.`)\n\t\t\t\treturn Reflect.get(this, prop)\n\t\t\t}\n\t\t\treturn Reflect.get(target, prop, receiver)\n\t\t},\n\t} as ProxyHandler<Attribute>\n\n\tconstructor(data: NodeData, davService?: RegExp) {\n\t\t// Validate data\n\t\tvalidateData(data, davService || this._knownDavService)\n\n\t\tthis._data = {\n\t\t\t// TODO: Remove with next major release, this is just for compatibility\n\t\t\tdisplayname: data.attributes?.displayname,\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\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\tif (this.root) {\n\t\t\tlet source = this.source\n\t\t\tif (this.isDavRessource) {\n\t\t\t\t// ensure we only work on the real path in case root is not distinct\n\t\t\t\tsource = source.split(this._knownDavService).pop()!\n\t\t\t}\n\t\t\t// Using replace would remove all part matching root\n\t\t\tconst firstMatch = source.indexOf(this.root)\n\t\t\t// Ensure we do not remove the leading slash\n\t\t\tconst root = this.root.replace(/\\/$/, '')\n\t\t\treturn dirname(source.slice(firstMatch + root.length) || '/')\n\t\t}\n\n\t\t// This should always be a valid URL\n\t\t// as this is tested in the constructor\n\t\tconst url = new URL(this.source)\n\t\treturn dirname(url.pathname)\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 * There is no setter as the mime is not meant to be changed\n\t */\n\tget mime(): string|undefined {\n\t\treturn this._data.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\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\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 ressource, we can only read it\n\t\tif (this.owner === null && !this.isDavRessource) {\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\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 ressources have no owner\n\t\tif (!this.isDavRessource) {\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 ressource ?\n\t */\n\tget isDavRessource(): boolean {\n\t\treturn isDavRessource(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|null {\n\t\t// If provided (recommended), use the root and strip away the ending slash\n\t\tif (this._data.root) {\n\t\t\treturn this._data.root.replace(/^(.+)\\/$/, '$1')\n\t\t}\n\n\t\t// Use the source to get the root from the dav service\n\t\tif (this.isDavRessource) {\n\t\t\tconst root = dirname(this.source)\n\t\t\treturn root.split(this._knownDavService).pop() || null\n\t\t}\n\n\t\treturn null\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\tif (this.root) {\n\t\t\tlet source = this.source\n\t\t\tif (this.isDavRessource) {\n\t\t\t\t// ensure we only work on the real path in case root is not distinct\n\t\t\t\tsource = source.split(this._knownDavService).pop()!\n\t\t\t}\n\t\t\t// Using replace would remove all part matching root\n\t\t\tconst firstMatch = source.indexOf(this.root)\n\t\t\t// Ensure we do not remove the leading slash\n\t\t\tconst root = this.root.replace(/\\/$/, '')\n\t\t\treturn source.slice(firstMatch + root.length) || '/'\n\t\t}\n\t\treturn (this.dirname + '/' + this.basename).replace(/\\/\\//g, '/')\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\tthis._data.status = status\n\t}\n\n\t/**\n\t * Get the node data\n\t */\n\tget data(): NodeData {\n\t\treturn structuredClone(this._data)\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 Nextclouds 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\tthis.updateMtime()\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\tabstract clone(): Node\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 { FileType } from './fileType'\nimport { type INode, Node } from './node'\n\nexport class File extends Node {\n\n\tget type(): FileType {\n\t\treturn FileType.File\n\t}\n\n\t/**\n\t * Returns a clone of the file\n\t */\n\tclone(): File {\n\t\treturn new File(this.data)\n\t}\n\n}\n\n/**\n * Interface of the File class\n */\nexport interface IFile extends INode {\n\treadonly type: FileType.File\n}\n","/**\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { FileType } from './fileType'\nimport { type INode, Node } from './node'\nimport { type NodeData } from './nodeData'\n\nexport class Folder extends Node {\n\n\tconstructor(data: NodeData) {\n\t\t// enforcing mimes\n\t\tsuper({\n\t\t\t...data,\n\t\t\tmime: 'httpd/unix-directory',\n\t\t})\n\t}\n\n\tget type(): FileType {\n\t\treturn FileType.Folder\n\t}\n\n\tget extension(): string|null {\n\t\treturn null\n\t}\n\n\tget mime(): string {\n\t\treturn 'httpd/unix-directory'\n\t}\n\n\t/**\n\t * Returns a clone of the folder\n\t */\n\tclone(): Node {\n\t\treturn new Folder(this.data)\n\t}\n\n}\n\n/**\n * Interface of the folder class\n */\nexport interface IFolder extends INode {\n\treadonly type: FileType.Folder\n\treadonly extension: null\n\treadonly mime: 'httpd/unix-directory'\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { Permission } from '../permissions'\n\n/**\n * Parse the WebDAV permission string to a permission enum\n *\n * @param permString The DAV permission string\n */\nexport const parsePermissions = function(permString = ''): number {\n\tlet permissions = Permission.NONE\n\n\tif (!permString) { return permissions }\n\n\tif (permString.includes('C') || permString.includes('K')) { permissions |= Permission.CREATE }\n\n\tif (permString.includes('G')) { permissions |= Permission.READ }\n\n\tif (permString.includes('W') || permString.includes('N') || permString.includes('V')) { permissions |= Permission.UPDATE }\n\n\tif (permString.includes('D')) { permissions |= Permission.DELETE }\n\n\tif (permString.includes('R')) { permissions |= Permission.SHARE }\n\n\treturn permissions\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { getCurrentUser } from '@nextcloud/auth'\nimport logger from '../utils/logger'\n\nexport type DavProperty = { [key: string]: string }\n\nexport const defaultDavProperties = [\n\t'd:getcontentlength',\n\t'd:getcontenttype',\n\t'd:getetag',\n\t'd:getlastmodified',\n\t'd:creationdate',\n\t'd:displayname',\n\t'd:quota-available-bytes',\n\t'd:resourcetype',\n\t'nc:has-preview',\n\t'nc:is-encrypted',\n\t'nc:mount-type',\n\t'oc:comments-unread',\n\t'oc:favorite',\n\t'oc:fileid',\n\t'oc:owner-display-name',\n\t'oc:owner-id',\n\t'oc:permissions',\n\t'oc:size',\n]\n\nexport const defaultDavNamespaces = {\n\td: 'DAV:',\n\tnc: 'http://nextcloud.org/ns',\n\toc: 'http://owncloud.org/ns',\n\tocs: 'http://open-collaboration-services.org/ns',\n}\n\n/**\n * Register custom DAV properties\n *\n * Can be used if your app introduces custom DAV properties, so e.g. the files app can make use of it.\n *\n * @param prop The property\n * @param namespace The namespace of the property\n */\nexport const registerDavProperty = function(prop: string, namespace: DavProperty = { nc: 'http://nextcloud.org/ns' }): boolean {\n\tif (typeof window._nc_dav_properties === 'undefined') {\n\t\twindow._nc_dav_properties = [...defaultDavProperties]\n\t\twindow._nc_dav_namespaces = { ...defaultDavNamespaces }\n\t}\n\n\tconst namespaces = { ...window._nc_dav_namespaces, ...namespace }\n\n\t// Check duplicates\n\tif (window._nc_dav_properties.find((search) => search === prop)) {\n\t\tlogger.warn(`${prop} already registered`, { prop })\n\t\treturn false\n\t}\n\n\tif (prop.startsWith('<') || prop.split(':').length !== 2) {\n\t\tlogger.error(`${prop} is not valid. See example: 'oc:fileid'`, { prop })\n\t\treturn false\n\t}\n\n\tconst ns = prop.split(':')[0]\n\tif (!namespaces[ns]) {\n\t\tlogger.error(`${prop} namespace unknown`, { prop, namespaces })\n\t\treturn false\n\t}\n\n\twindow._nc_dav_properties.push(prop)\n\twindow._nc_dav_namespaces = namespaces\n\treturn true\n}\n\n/**\n * Get the registered dav properties\n */\nexport const getDavProperties = function(): string {\n\tif (typeof window._nc_dav_properties === 'undefined') {\n\t\twindow._nc_dav_properties = [...defaultDavProperties]\n\t}\n\n\treturn window._nc_dav_properties.map((prop) => `<${prop} />`).join(' ')\n}\n\n/**\n * Get the registered dav namespaces\n */\nexport const getDavNameSpaces = function(): string {\n\tif (typeof window._nc_dav_namespaces === 'undefined') {\n\t\twindow._nc_dav_namespaces = { ...defaultDavNamespaces }\n\t}\n\n\treturn Object.keys(window._nc_dav_namespaces)\n\t\t.map((ns) => `xmlns:${ns}=\"${window._nc_dav_namespaces?.[ns]}\"`)\n\t\t.join(' ')\n}\n\n/**\n * Get the default PROPFIND request body\n */\nexport const getDefaultPropfind = function(): string {\n\treturn `<?xml version=\"1.0\"?>\n\t\t<d:propfind ${getDavNameSpaces()}>\n\t\t\t<d:prop>\n\t\t\t\t${getDavProperties()}\n\t\t\t</d:prop>\n\t\t</d:propfind>`\n}\n\n/**\n * Get the REPORT body to filter for favorite nodes\n */\nexport const getFavoritesReport = function(): string {\n\treturn `<?xml version=\"1.0\"?>\n\t\t<oc:filter-files ${getDavNameSpaces()}>\n\t\t\t<d:prop>\n\t\t\t\t${getDavProperties()}\n\t\t\t</d:prop>\n\t\t\t<oc:filter-rules>\n\t\t\t\t<oc:favorite>1</oc:favorite>\n\t\t\t</oc:filter-rules>\n\t\t</oc:filter-files>`\n}\n\n/**\n * Get the SEARCH body to search for recently modified files\n *\n * @param lastModified Oldest timestamp to include (Unix timestamp)\n * @example\n * ```ts\n * // SEARCH for recent files need a different DAV endpoint\n * const client = davGetClient(generateRemoteUrl('dav'))\n * // Timestamp of last week\n * const lastWeek = Math.round(Date.now() / 1000) - (60 * 60 * 24 * 7)\n * const contentsResponse = await client.getDirectoryContents(path, {\n * details: true,\n * data: davGetRecentSearch(lastWeek),\n * headers: {\n * method: 'SEARCH',\n * 'Content-Type': 'application/xml; charset=utf-8',\n * },\n * deep: true,\n * }) as ResponseDataDetailed<FileStat[]>\n * ```\n */\nexport const getRecentSearch = function(lastModified: number): string {\n\treturn `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<d:searchrequest ${getDavNameSpaces()}\n\txmlns:ns=\"https://github.com/icewind1991/SearchDAV/ns\">\n\t<d:basicsearch>\n\t\t<d:select>\n\t\t\t<d:prop>\n\t\t\t\t${getDavProperties()}\n\t\t\t</d:prop>\n\t\t</d:select>\n\t\t<d:from>\n\t\t\t<d:scope>\n\t\t\t\t<d:href>/files/${getCurrentUser()?.uid}/</d:href>\n\t\t\t\t<d:depth>infinity</d:depth>\n\t\t\t</d:scope>\n\t\t</d:from>\n\t\t<d:where>\n\t\t\t<d:and>\n\t\t\t\t<d:or>\n\t\t\t\t\t<d:not>\n\t\t\t\t\t\t<d:eq>\n\t\t\t\t\t\t\t<d:prop>\n\t\t\t\t\t\t\t\t<d:getcontenttype/>\n\t\t\t\t\t\t\t</d:prop>\n\t\t\t\t\t\t\t<d:literal>httpd/unix-directory</d:literal>\n\t\t\t\t\t\t</d:eq>\n\t\t\t\t\t</d:not>\n\t\t\t\t\t<d:eq>\n\t\t\t\t\t\t<d:prop>\n\t\t\t\t\t\t\t<oc:size/>\n\t\t\t\t\t\t</d:prop>\n\t\t\t\t\t\t<d:literal>0</d:literal>\n\t\t\t\t\t</d:eq>\n\t\t\t\t</d:or>\n\t\t\t\t<d:gt>\n\t\t\t\t\t<d:prop>\n\t\t\t\t\t\t<d:getlastmodified/>\n\t\t\t\t\t</d:prop>\n\t\t\t\t\t<d:literal>${lastModified}</d:literal>\n\t\t\t\t</d:gt>\n\t\t\t</d:and>\n\t\t</d:where>\n\t\t<d:orderby>\n\t\t\t<d:order>\n\t\t\t\t<d:prop>\n\t\t\t\t\t<d:getlastmodified/>\n\t\t\t\t</d:prop>\n\t\t\t\t<d:descending/>\n\t\t\t</d:order>\n\t\t</d:orderby>\n\t\t<d:limit>\n\t\t\t<d:nresults>100</d:nresults>\n\t\t\t<ns:firstresult>0</ns:firstresult>\n\t\t</d:limit>\n\t</d:basicsearch>\n</d:searchrequest>`\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport type { DAVResultResponseProps, FileStat, ResponseDataDetailed, WebDAVClient } from 'webdav'\nimport type { Node } from '../files/node'\n\nimport { File } from '../files/file'\nimport { Folder } from '../files/folder'\nimport { NodeStatus } from '../files/node'\nimport { NodeData } from '../files/nodeData'\nimport { parsePermissions } from './davPermissions'\nimport { getFavoritesReport } from './davProperties'\n\nimport { getCurrentUser, getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'\nimport { generateRemoteUrl } from '@nextcloud/router'\nimport { CancelablePromise } from 'cancelable-promise'\nimport { createClient, getPatcher } from 'webdav'\nimport { getSharingToken, isPublicShare } from '@nextcloud/sharing/public'\n\n/**\n * Nextcloud DAV result response\n */\ninterface ResponseProps extends DAVResultResponseProps {\n\tcreationdate: string\n\tpermissions: string\n\tmime: string\n\tfileid: number\n\tsize: number\n\t'owner-id': string | number\n}\n\n/**\n * Get the DAV root path for the current user or public share\n */\nexport function getRootPath(): string {\n\tif (isPublicShare()) {\n\t\treturn `/files/${getSharingToken()}`\n\t}\n\treturn `/files/${getCurrentUser()?.uid}`\n}\n\n/**\n * The DAV root path for the current user\n * This is a cached version of `getRemoteURL`\n */\nexport const defaultRootPath = getRootPath()\n\n/**\n * Get the DAV remote URL used as base URL for the WebDAV client\n * It also handles public shares\n */\nexport function getRemoteURL(): string {\n\tconst url = generateRemoteUrl('dav')\n\tif (isPublicShare()) {\n\t\treturn url.replace('remote.php', 'public.php')\n\t}\n\treturn url\n}\n\n/**\n * The DAV remote URL used as base URL for the WebDAV client\n * This is a cached version of `getRemoteURL`\n */\nexport const defaultRemoteURL = getRemoteURL()\n\n/**\n * Get a WebDAV client configured to include the Nextcloud request token\n *\n * @param remoteURL The DAV server remote URL\n * @param headers Optional additional headers to set for every request\n */\nexport const getClient = function(remoteURL = defaultRemoteURL, headers: Record<string, string> = {}) {\n\tconst client = createClient(remoteURL, { headers })\n\n\t/**\n\t * Set headers for DAV requests\n\t * @param token CSRF token\n\t */\n\tfunction setHeaders(token: string | null) {\n\t\tclient.setHeaders({\n\t\t\t...headers,\n\t\t\t// Add this so the server knows it is an request from the browser\n\t\t\t'X-Requested-With': 'XMLHttpRequest',\n\t\t\t// Inject user auth\n\t\t\trequesttoken: token ?? '',\n\t\t})\n\t}\n\n\t// refresh headers when request token changes\n\tonRequestTokenUpdate(setHeaders)\n\tsetHeaders(getRequestToken())\n\n\t/**\n\t * Allow to override the METHOD to support dav REPORT\n\t *\n\t * @see https://github.com/perry-mitchell/webdav-client/blob/8d9694613c978ce7404e26a401c39a41f125f87f/source/request.ts\n\t */\n\tconst patcher = getPatcher()\n\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t// @ts-ignore\n\t// https://github.com/perry-mitchell/hot-patcher/issues/6\n\tpatcher.patch('fetch', (url: string, options: RequestInit): Promise<Response> => {\n\t\tconst headers = options.headers as Record<string, string>\n\t\tif (headers?.method) {\n\t\t\toptions.method = headers.method\n\t\t\tdelete headers.method\n\t\t}\n\t\treturn fetch(url, options)\n\t})\n\n\treturn client\n}\n\n/**\n * Use WebDAV to query for favorite Nodes\n *\n * @param davClient The WebDAV client to use for performing the request\n * @param path Base path for the favorites, if unset all favorites are queried\n * @param davRoot The root path for the DAV user (defaults to `defaultRootPath`)\n * @example\n * ```js\n * import { getClient, defaultRootPath, getFavoriteNodes } from '@nextcloud/files'\n *\n * const client = getClient()\n * // query favorites for the root\n * const favorites = await getFavoriteNodes(client)\n * // which is the same as writing:\n * const favorites = await getFavoriteNodes(client, '/', defaultRootPath)\n * ```\n */\nexport const getFavoriteNodes = (davClient: WebDAVClient, path = '/', davRoot = defaultRootPath): CancelablePromise<Node[]> => {\n\tconst controller = new AbortController()\n\treturn new CancelablePromise(async (resolve, reject, onCancel) => {\n\t\tonCancel(() => controller.abort())\n\t\ttry {\n\t\t\tconst contentsResponse = await davClient.getDirectoryContents(`${davRoot}${path}`, {\n\t\t\t\tsignal: controller.signal,\n\t\t\t\tdetails: true,\n\t\t\t\tdata: getFavoritesReport(),\n\t\t\t\theaders: {\n\t\t\t\t\t// see getClient for patched webdav client\n\t\t\t\t\tmethod: 'REPORT',\n\t\t\t\t},\n\t\t\t\tincludeSelf: true,\n\t\t\t}) as ResponseDataDetailed<FileStat[]>\n\n\t\t\tconst nodes = contentsResponse.data\n\t\t\t\t.filter(node => node.filename !== path) // exclude current dir\n\t\t\t\t.map((result) => resultToNode(result, davRoot))\n\t\t\tresolve(nodes)\n\t\t} catch (error) {\n\t\t\treject(error)\n\t\t}\n\t})\n}\n\n/**\n * Covert DAV result `FileStat` to `Node`\n *\n * @param node The DAV result\n * @param filesRoot The DAV files root path\n * @param remoteURL The DAV server remote URL (same as on `getClient`)\n */\nexport const resultToNode = function(node: FileStat, filesRoot = defaultRootPath, remoteURL = defaultRemoteURL): Node {\n\tlet userId = getCurrentUser()?.uid\n\tif (isPublicShare()) {\n\t\tuserId = userId ?? 'anonymous'\n\t} else if (!userId) {\n\t\tthrow new Error('No user id found')\n\t}\n\n\tconst props = node.props as ResponseProps\n\tconst permissions = parsePermissions(props?.permissions)\n\tconst owner = String(props?.['owner-id'] || userId)\n\tconst id = props.fileid || 0\n\n\tconst mtime = new Date(Date.parse(node.lastmod))\n\tconst crtime = new Date(Date.parse(props.creationdate))\n\n\tconst nodeData: NodeData = {\n\t\tid,\n\t\tsource: `${remoteURL}${node.filename}`,\n\t\tmtime: !isNaN(mtime.getTime()) && mtime.getTime() !== 0 ? mtime : undefined,\n\t\tcrtime: !isNaN(crtime.getTime()) && crtime.getTime() !== 0 ? crtime : undefined,\n\t\tmime: node.mime || 'application/octet-stream',\n\t\t// Manually cast to work around for https://github.com/perry-mitchell/webdav-client/pull/380\n\t\tdisplayname: props.displayname !== undefined ? String(props.displayname) : undefined,\n\t\tsize: props?.size || Number.parseInt(props.getcontentlength || '0'),\n\t\t// The fileid is set to -1 for failed requests\n\t\tstatus: id < 0 ? NodeStatus.FAILED : undefined,\n\t\tpermissions,\n\t\towner,\n\t\troot: filesRoot,\n\t\tattributes: {\n\t\t\t...node,\n\t\t\t...props,\n\t\t\thasPreview: props?.['has-preview'],\n\t\t},\n\t}\n\n\tdelete nodeData.attributes?.props\n\n\treturn node.type === 'file' ? new File(nodeData) : new Folder(nodeData)\n}\n"],"names":["getLoggerBuilder","Permission","FileType","join","NodeStatus","encodePath","basename","extname","dirname","getCurrentUser","isPublicShare","getSharingToken","generateRemoteUrl","createClient","onRequestTokenUpdate","getRequestToken","getPatcher","headers","path","CancelablePromise"],"mappings":"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"}
|