@nextcloud/files 4.0.0-beta.8 → 4.0.0-beta.9

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.
@@ -2,6 +2,6 @@
2
2
  * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
3
3
  * SPDX-License-Identifier: AGPL-3.0-or-later
4
4
  */
5
- export * from './navigation';
6
- export * from './column';
7
- export * from './view';
5
+ export * from './navigation.ts';
6
+ export * from './column.ts';
7
+ export * from './view.ts';
@@ -1,4 +1,4 @@
1
- import { IView } from './view';
1
+ import { IView } from './view.ts';
2
2
  import { TypedEventTarget } from 'typescript-event-target';
3
3
  /**
4
4
  * The event is emitted when the navigation view was updated.
@@ -18,6 +18,7 @@ interface UpdateViewsEvent extends CustomEvent<never> {
18
18
  *
19
19
  * Custom views for the files app can be registered (examples are the favorites views or the shared-with-you view).
20
20
  * It is also possible to listen on changes of the registered views or when the current active view is changed.
21
+ *
21
22
  * @example
22
23
  * ```js
23
24
  * const navigation = getNavigation()
@@ -42,6 +43,7 @@ export declare class Navigation extends TypedEventTarget<{
42
43
  private _currentView;
43
44
  /**
44
45
  * Register a new view on the navigation
46
+ *
45
47
  * @param view The view to register
46
48
  * @throws {Error} if a view with the same id is already registered
47
49
  * @throws {Error} if the registered view is invalid
@@ -49,6 +51,7 @@ export declare class Navigation extends TypedEventTarget<{
49
51
  register(view: IView): void;
50
52
  /**
51
53
  * Remove a registered view
54
+ *
52
55
  * @param id The id of the view to remove
53
56
  */
54
57
  remove(id: string): void;
@@ -72,5 +75,5 @@ export declare class Navigation extends TypedEventTarget<{
72
75
  /**
73
76
  * Get the current files navigation
74
77
  */
75
- export declare const getNavigation: () => Navigation;
78
+ export declare function getNavigation(): Navigation;
76
79
  export {};
@@ -38,9 +38,8 @@ export interface IView {
38
38
  * This method _must_ also return the current directory
39
39
  * information alongside with its content.
40
40
  *
41
- * An abort signal is provided to be able to
42
- * cancel the request if the user change directory
43
- * {@see https://developer.mozilla.org/en-US/docs/Web/API/AbortController }.
41
+ * An [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) is provided
42
+ * to be able to cancel the request if the user change directory.
44
43
  */
45
44
  getContents(path: string, options: IGetContentsOptions): Promise<ContentsWithRoot>;
46
45
  /**
@@ -1,32 +1,36 @@
1
1
  import { IFolder, INode } from '../node/index.ts';
2
- export declare enum NewMenuEntryCategory {
2
+ export declare const NewMenuEntryCategory: Readonly<{
3
3
  /**
4
4
  * For actions where the user is intended to upload from their device
5
5
  */
6
- UploadFromDevice = 0,
6
+ UploadFromDevice: 0;
7
7
  /**
8
8
  * For actions that create new nodes on the server without uploading
9
9
  */
10
- CreateNew = 1,
10
+ CreateNew: 1;
11
11
  /**
12
12
  * For everything not matching the other categories
13
13
  */
14
- Other = 2
15
- }
14
+ Other: 2;
15
+ }>;
16
+ export type TNewMenuEntryCategory = typeof NewMenuEntryCategory[keyof typeof NewMenuEntryCategory];
16
17
  export interface NewMenuEntry {
17
18
  /** Unique ID */
18
19
  id: string;
19
20
  /**
20
21
  * Category to put this entry in
21
22
  * (supported since Nextcloud 30)
22
- * @since 3.3.0
23
+ *
23
24
  * @default NewMenuEntryCategory.CreateNew
25
+ * @see NewMenuEntryCategory
26
+ * @since 3.3.0
24
27
  */
25
- category?: NewMenuEntryCategory;
28
+ category?: TNewMenuEntryCategory;
26
29
  /** Translatable string displayed in the menu */
27
30
  displayName: string;
28
31
  /**
29
32
  * Condition wether this entry is shown or not
33
+ *
30
34
  * @param context the creation context. Usually the current folder
31
35
  */
32
36
  enabled?: (context: IFolder) => boolean;
@@ -39,6 +43,7 @@ export interface NewMenuEntry {
39
43
  order?: number;
40
44
  /**
41
45
  * Function to be run after creation
46
+ *
42
47
  * @param context - The creation context. Usually the current folder
43
48
  * @param content - List of file/folders present in the context folder
44
49
  */
@@ -1,8 +1,8 @@
1
- import { NodeConstructorData, Node } from './node';
2
- import { FileType } from './fileType';
1
+ import { NodeConstructorData, Node } from './node.ts';
2
+ import { FileType } from './fileType.ts';
3
3
  export declare class File extends Node {
4
4
  constructor(...[data, davService]: NodeConstructorData);
5
- get type(): FileType.File;
5
+ get type(): typeof FileType.File;
6
6
  }
7
7
  /**
8
8
  * Interface of the File class
@@ -2,7 +2,8 @@
2
2
  * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
3
3
  * SPDX-License-Identifier: AGPL-3.0-or-later
4
4
  */
5
- export declare enum FileType {
6
- Folder = "folder",
7
- File = "file"
8
- }
5
+ export declare const FileType: Readonly<{
6
+ Folder: "folder";
7
+ File: "file";
8
+ }>;
9
+ export type TFileType = typeof FileType[keyof typeof FileType];
@@ -1,8 +1,8 @@
1
- import { NodeConstructorData, Node } from './node';
2
- import { FileType } from './fileType';
1
+ import { NodeConstructorData, Node } from './node.ts';
2
+ import { FileType } from './fileType.ts';
3
3
  export declare class Folder extends Node {
4
4
  constructor(...[data, davService]: NodeConstructorData);
5
- get type(): FileType.Folder;
5
+ get type(): typeof FileType.Folder;
6
6
  get extension(): null;
7
7
  get mime(): 'httpd/unix-directory';
8
8
  }
@@ -1,16 +1,16 @@
1
- import { Permission } from '../permissions';
2
- import { FileType } from './fileType';
3
- import { Attribute, NodeData } from './nodeData';
4
- export declare enum NodeStatus {
1
+ import { TFileType } from './fileType.ts';
2
+ import { Attribute, NodeData } from './nodeData.ts';
3
+ export declare const NodeStatus: Readonly<{
5
4
  /** This is a new node and it doesn't exists on the filesystem yet */
6
- NEW = "new",
5
+ NEW: "new";
7
6
  /** This node has failed and is unavailable */
8
- FAILED = "failed",
7
+ FAILED: "failed";
9
8
  /** This node is currently loading or have an operation in progress */
10
- LOADING = "loading",
9
+ LOADING: "loading";
11
10
  /** This node is locked and cannot be modified */
12
- LOCKED = "locked"
13
- }
11
+ LOCKED: "locked";
12
+ }>;
13
+ export type TNodeStatus = typeof NodeStatus[keyof typeof NodeStatus];
14
14
  export type NodeConstructorData = [NodeData, RegExp?];
15
15
  export declare abstract class Node {
16
16
  private _attributes;
@@ -63,7 +63,7 @@ export declare abstract class Node {
63
63
  /**
64
64
  * Is it a file or a folder ?
65
65
  */
66
- abstract get type(): FileType;
66
+ abstract get type(): TFileType;
67
67
  /**
68
68
  * Get the file mime
69
69
  */
@@ -102,11 +102,11 @@ export declare abstract class Node {
102
102
  /**
103
103
  * Get the file permissions
104
104
  */
105
- get permissions(): Permission;
105
+ get permissions(): number;
106
106
  /**
107
107
  * Set the file permissions
108
108
  */
109
- set permissions(permissions: Permission);
109
+ set permissions(permissions: number);
110
110
  /**
111
111
  * Get the file owner
112
112
  * There is no setter as the owner is not meant to be changed
@@ -133,15 +133,15 @@ export declare abstract class Node {
133
133
  /**
134
134
  * Get the node status.
135
135
  */
136
- get status(): NodeStatus | undefined;
136
+ get status(): TNodeStatus | undefined;
137
137
  /**
138
138
  * Set the node status.
139
139
  */
140
- set status(status: NodeStatus | undefined);
140
+ set status(status: TNodeStatus | undefined);
141
141
  /**
142
142
  * Move the node to a new destination
143
143
  *
144
- * @param {string} destination the new source.
144
+ * @param destination the new source.
145
145
  * e.g. https://cloud.domain.com/remote.php/dav/files/emma/Photos/picture.jpg
146
146
  */
147
147
  move(destination: string): void;
@@ -1,5 +1,4 @@
1
- import { Permission } from '../permissions';
2
- import { NodeStatus } from './node';
1
+ import { TNodeStatus } from './node.ts';
3
2
  export interface Attribute {
4
3
  [key: string]: any;
5
4
  }
@@ -26,8 +25,14 @@ export interface NodeData {
26
25
  mime?: string;
27
26
  /** The node size type */
28
27
  size?: number;
29
- /** The node permissions */
30
- permissions?: Permission;
28
+ /**
29
+ * The node permissions.
30
+ *
31
+ * A binary mask of `Permission` values.
32
+ *
33
+ * @see Permission
34
+ */
35
+ permissions?: number;
31
36
  /** The owner UID of this node */
32
37
  owner: string | null;
33
38
  /** Optional the displayname of this node */
@@ -35,7 +40,7 @@ export interface NodeData {
35
40
  /** The node attributes */
36
41
  attributes?: Attribute;
37
42
  /** The node status */
38
- status?: NodeStatus;
43
+ status?: TNodeStatus;
39
44
  }
40
45
  /**
41
46
  * Check if a node source is from a specific DAV service
@@ -43,7 +48,7 @@ export interface NodeData {
43
48
  * @param source The source to check
44
49
  * @param davService Pattern to check if source is DAV resource
45
50
  */
46
- export declare const isDavResource: (source: string, davService: RegExp) => boolean;
51
+ export declare function isDavResource(source: string, davService: RegExp): boolean;
47
52
  /**
48
53
  * Validate Node construct data
49
54
  *
@@ -57,10 +62,10 @@ export declare function validateData(data: NodeData, davService: RegExp): void;
57
62
  *
58
63
  * @param data The internal node data
59
64
  */
60
- export declare const fixDates: (data: NodeData) => void;
65
+ export declare function fixDates(data: NodeData): void;
61
66
  /**
62
67
  * Fix a RegExp pattern from string or RegExp to RegExp
63
68
  *
64
69
  * @param pattern The pattern as string or RegExp
65
70
  */
66
- export declare const fixRegExp: (pattern: string | RegExp) => RegExp;
71
+ export declare function fixRegExp(pattern: string | RegExp): RegExp;
@@ -5,12 +5,37 @@
5
5
  /**
6
6
  * Node permissions
7
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
- }
8
+ export declare const Permission: Readonly<{
9
+ /**
10
+ * No permissions granted
11
+ */
12
+ NONE: 0;
13
+ /**
14
+ * Can read the file content
15
+ */
16
+ READ: 1;
17
+ /**
18
+ * Can modify the file itself (move, rename, etc)
19
+ */
20
+ UPDATE: 2;
21
+ /**
22
+ * Can create new files/folders inside a folder
23
+ */
24
+ CREATE: 4;
25
+ /**
26
+ * Can change the file content
27
+ */
28
+ WRITE: 4;
29
+ /**
30
+ * Can delete the node
31
+ */
32
+ DELETE: 8;
33
+ /**
34
+ * Can share the node
35
+ */
36
+ SHARE: 16;
37
+ /**
38
+ * All permissions are granted
39
+ */
40
+ ALL: 31;
41
+ }>;
@@ -42,7 +42,7 @@ export interface ISidebarAction {
42
42
  * Register a new sidebar action.
43
43
  *
44
44
  * @param action - The sidebar action to register
45
- * @throws If the provided action is not a valid sidebar action and thus cannot be registered.
45
+ * @throws {Error} If the provided action is not a valid sidebar action and thus cannot be registered.
46
46
  */
47
47
  export declare function registerSidebarAction(action: ISidebarAction): void;
48
48
  /**
@@ -69,7 +69,7 @@ export interface ISidebarTab {
69
69
  * Register a new sidebar tab for the files app.
70
70
  *
71
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.
72
+ * @throws {Error} If the provided tab is not a valid sidebar tab and thus cannot be registered.
73
73
  */
74
74
  export declare function registerSidebarTab(tab: ISidebarTab): void;
75
75
  /**
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { IFolder, INode } from './node/index.ts';
2
1
  import { IView } from './navigation/index.ts';
2
+ import { IFolder, INode } from './node/index.ts';
3
3
  export type ActionContextSingle = {
4
4
  nodes: [INode];
5
5
  view: IView;
@@ -18,8 +18,8 @@ export declare function formatFileSize(size: number | string, skipSmallSizes?: b
18
18
  * Returns a file size in bytes from a humanly readable string
19
19
  * Note: `b` and `B` are both parsed as bytes and not as bit or byte.
20
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
21
+ * @param value file size in human-readable format
22
+ * @param forceBinary for backwards compatibility this allows values to be base 2 (so 2KB means 2048 bytes instead of 2000 bytes)
23
+ * @return or null if string could not be parsed
24
24
  */
25
25
  export declare function parseFileSize(value: string, forceBinary?: boolean): number | null;
@@ -1,33 +1,38 @@
1
1
  import { INode } from '../node/node.ts';
2
2
  import { SortingOrder } from './sorting.ts';
3
- export declare enum FilesSortingMode {
4
- Name = "basename",
5
- Modified = "mtime",
6
- Size = "size"
7
- }
3
+ export declare const FilesSortingMode: Readonly<{
4
+ Name: "basename";
5
+ Modified: "mtime";
6
+ Size: "size";
7
+ }>;
8
+ export type TFilesSortingMode = typeof FilesSortingMode[keyof typeof FilesSortingMode];
8
9
  export interface FilesSortingOptions {
9
10
  /**
10
11
  * They key to order the files by
12
+ *
11
13
  * @default FilesSortingMode.Name
12
14
  */
13
- sortingMode?: FilesSortingMode | string;
15
+ sortingMode?: TFilesSortingMode | string;
14
16
  /**
15
17
  * @default 'asc'
16
18
  */
17
19
  sortingOrder?: SortingOrder;
18
20
  /**
19
21
  * If set to true nodes marked as favorites are ordered on top of all other nodes
22
+ *
20
23
  * @default false
21
24
  */
22
25
  sortFavoritesFirst?: boolean;
23
26
  /**
24
27
  * If set to true folders are ordered on top of files
28
+ *
25
29
  * @default false
26
30
  */
27
31
  sortFoldersFirst?: boolean;
28
32
  }
29
33
  /**
30
34
  * Sort files and folders according to the sorting options
35
+ *
31
36
  * @param nodes Nodes to sort
32
37
  * @param options Sorting options
33
38
  */
@@ -2,11 +2,12 @@
2
2
  * SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
3
3
  * SPDX-License-Identifier: AGPL-3.0-or-later or LGPL-3.0-or-later
4
4
  */
5
- export declare enum InvalidFilenameErrorReason {
6
- ReservedName = "reserved name",
7
- Character = "character",
8
- Extension = "extension"
9
- }
5
+ export declare const InvalidFilenameErrorReason: Readonly<{
6
+ ReservedName: "reserved name";
7
+ Character: "character";
8
+ Extension: "extension";
9
+ }>;
10
+ export type TInvalidFilenameErrorReason = typeof InvalidFilenameErrorReason[keyof typeof InvalidFilenameErrorReason];
10
11
  interface InvalidFilenameErrorOptions {
11
12
  /**
12
13
  * The filename that was validated
@@ -15,7 +16,7 @@ interface InvalidFilenameErrorOptions {
15
16
  /**
16
17
  * Reason why the validation failed
17
18
  */
18
- reason: InvalidFilenameErrorReason;
19
+ reason: TInvalidFilenameErrorReason;
19
20
  /**
20
21
  * Part of the filename that caused this error
21
22
  */
@@ -30,7 +31,7 @@ export declare class InvalidFilenameError extends Error {
30
31
  /**
31
32
  * Reason why the validation failed
32
33
  */
33
- get reason(): InvalidFilenameErrorReason;
34
+ get reason(): TInvalidFilenameErrorReason;
34
35
  /**
35
36
  * Part of the filename that caused this error
36
37
  */
@@ -38,6 +39,7 @@ export declare class InvalidFilenameError extends Error {
38
39
  }
39
40
  /**
40
41
  * Validate a given filename
42
+ *
41
43
  * @param filename The filename to check
42
44
  * @throws {InvalidFilenameError}
43
45
  */
@@ -45,6 +47,7 @@ export declare function validateFilename(filename: string): void;
45
47
  /**
46
48
  * Check the validity of a filename
47
49
  * This is a convenient wrapper for `checkFilenameValidity` to only return a boolean for the valid
50
+ *
48
51
  * @param filename Filename to check validity
49
52
  */
50
53
  export declare function isFilenameValid(filename: string): boolean;
@@ -5,6 +5,7 @@
5
5
  interface UniqueNameOptions {
6
6
  /**
7
7
  * A function that takes an index and returns a suffix to add to the file name, defaults to '(index)'
8
+ *
8
9
  * @param index The current index to add
9
10
  */
10
11
  suffix?: (index: number) => string;
@@ -15,10 +16,11 @@ interface UniqueNameOptions {
15
16
  }
16
17
  /**
17
18
  * Create an unique file name
19
+ *
18
20
  * @param name The initial name to use
19
21
  * @param otherNames Other names that are already used
20
22
  * @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
23
+ * @return Either the initial name, if unique, or the name with the suffix so that the name is unique
22
24
  */
23
25
  export declare function getUniqueName(name: string, otherNames: string[], options?: UniqueNameOptions): string;
24
26
  export {};
@@ -3,5 +3,5 @@ export type { FilesSortingOptions } from './fileSorting.ts';
3
3
  export * from './filename-validation.ts';
4
4
  export { getUniqueName } from './filename.ts';
5
5
  export { formatFileSize, parseFileSize } from './fileSize.ts';
6
- export { sortNodes, FilesSortingMode } from './fileSorting.ts';
6
+ export { FilesSortingMode, sortNodes } from './fileSorting.ts';
7
7
  export { orderBy } from './sorting.ts';
@@ -1,3 +1,7 @@
1
+ /**
2
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3
+ * SPDX-License-Identifier: AGPL-3.0-or-later
4
+ */
1
5
  type IdentifierFn<T> = (v: T) => unknown;
2
6
  export type SortingOrder = 'asc' | 'desc';
3
7
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextcloud/files",
3
- "version": "4.0.0-beta.8",
3
+ "version": "4.0.0-beta.9",
4
4
  "description": "Nextcloud files utils",
5
5
  "keywords": [
6
6
  "nextcloud",
@@ -57,16 +57,16 @@
57
57
  "@nextcloud/router": "^3.1.0",
58
58
  "@nextcloud/sharing": "^0.3.0",
59
59
  "is-svg": "^6.1.0",
60
- "typescript-event-target": "^1.1.1",
60
+ "typescript-event-target": "^1.1.2",
61
61
  "webdav": "^5.8.0"
62
62
  },
63
63
  "devDependencies": {
64
64
  "@codecov/vite-plugin": "^1.9.1",
65
- "@nextcloud/eslint-config": "^8.4.2",
65
+ "@nextcloud/eslint-config": "^9.0.0-rc.5",
66
66
  "@nextcloud/event-bus": "^3.3.3",
67
67
  "@nextcloud/typings": "^1.10.0",
68
68
  "@nextcloud/vite-config": "^2.5.2",
69
- "@types/node": "^25.0.3",
69
+ "@types/node": "^25.0.5",
70
70
  "@vitest/coverage-istanbul": "^4.0.16",
71
71
  "css.escape": "^1.5.1",
72
72
  "fast-xml-parser": "^5.3.3",
@@ -75,7 +75,7 @@
75
75
  "typedoc": "^0.28.15",
76
76
  "typedoc-plugin-missing-exports": "^4.1.2",
77
77
  "typescript": "^5.9.3",
78
- "vite": "^7.3.0",
78
+ "vite": "^7.3.1",
79
79
  "vitest": "^4.0.14"
80
80
  },
81
81
  "engines": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"folder-Bf-tAYWu.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 '@nextcloud/paths'\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 */\n\nimport { basename, dirname, encodePath, extname } from '@nextcloud/paths'\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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"}