@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.
@@ -1,8 +1,9 @@
1
1
  import { ActionContext, ActionContextSingle } from '../types.ts';
2
- export declare enum DefaultType {
3
- DEFAULT = "default",
4
- HIDDEN = "hidden"
5
- }
2
+ export declare const DefaultType: Readonly<{
3
+ DEFAULT: "default";
4
+ HIDDEN: "hidden";
5
+ }>;
6
+ export type TDefaultType = typeof DefaultType[keyof typeof DefaultType];
6
7
  export interface IHotkeyConfig {
7
8
  /**
8
9
  * Short, translated, description what this action is doing.
@@ -11,6 +12,7 @@ export interface IHotkeyConfig {
11
12
  description: string;
12
13
  /**
13
14
  * The key to be pressed.
15
+ *
14
16
  * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
15
17
  */
16
18
  key: string;
@@ -42,16 +44,18 @@ export interface FileActionData {
42
44
  enabled?: (context: ActionContext) => boolean;
43
45
  /**
44
46
  * Function executed on single file action
47
+ *
45
48
  * @return true if the action was executed successfully,
46
49
  * false otherwise and null if the action is silent/undefined.
47
- * @throws Error if the action failed
50
+ * @throws {Error} If the action failed
48
51
  */
49
52
  exec: (context: ActionContextSingle) => Promise<boolean | null>;
50
53
  /**
51
54
  * Function executed on multiple files action
55
+ *
52
56
  * @return true if the action was executed successfully,
53
57
  * false otherwise and null if the action is silent/undefined.
54
- * @throws Error if the action failed
58
+ * @throws {Error} If the action failed
55
59
  */
56
60
  execBatch?: (context: ActionContext) => Promise<(boolean | null)[]>;
57
61
  /** This action order in the list */
@@ -72,14 +76,17 @@ export interface FileActionData {
72
76
  parent?: string;
73
77
  /**
74
78
  * Make this action the default.
75
- * If multiple actions are default, the first one
76
- * will be used. The other ones will be put as first
77
- * entries in the actions menu iff DefaultType.Hidden is not used.
78
- * A DefaultType.Hidden action will never be shown
79
+ *
80
+ * If multiple actions are default, the first one will be used.
81
+ * The other ones will be put as first entries in the actions menu iff `DefaultType.Hidden` is not used.
82
+ *
83
+ * A `DefaultType.Hidden` action will never be shown
79
84
  * in the actions menu even if another action takes
80
85
  * its place as default.
86
+ *
87
+ * @see DefaultType
81
88
  */
82
- default?: DefaultType;
89
+ default?: TDefaultType;
83
90
  /**
84
91
  * If true, the renderInline function will be called
85
92
  */
@@ -103,11 +110,19 @@ export declare class FileAction {
103
110
  get hotkey(): IHotkeyConfig | undefined;
104
111
  get order(): number | undefined;
105
112
  get parent(): string | undefined;
106
- get default(): DefaultType | undefined;
113
+ get default(): TDefaultType | undefined;
107
114
  get destructive(): boolean | undefined;
108
115
  get inline(): ((context: ActionContextSingle) => boolean) | undefined;
109
116
  get renderInline(): ((context: ActionContextSingle) => Promise<HTMLElement | null>) | undefined;
110
117
  private validateAction;
111
118
  }
112
- export declare const registerFileAction: (action: FileAction) => void;
113
- export declare const getFileActions: () => FileAction[];
119
+ /**
120
+ * Register a new file action.
121
+ *
122
+ * @param action - The file list action to register
123
+ */
124
+ export declare function registerFileAction(action: FileAction): void;
125
+ /**
126
+ *
127
+ */
128
+ export declare function getFileActions(): FileAction[];
@@ -14,9 +14,10 @@ interface FileListActionData {
14
14
  enabled?: (context: ViewActionContext) => boolean;
15
15
  /**
16
16
  * Function executed on single file action
17
+ *
17
18
  * @return true if the action was executed successfully,
18
19
  * false otherwise and null if the action is silent/undefined.
19
- * @throws Error if the action failed
20
+ * @throws {Error} If the action failed
20
21
  */
21
22
  exec: (context: ViewActionContext) => Promise<boolean | null>;
22
23
  }
@@ -31,6 +32,14 @@ export declare class FileListAction {
31
32
  get exec(): (context: ViewActionContext) => Promise<boolean | null>;
32
33
  private validateAction;
33
34
  }
34
- export declare const registerFileListAction: (action: FileListAction) => void;
35
- export declare const getFileListActions: () => FileListAction[];
35
+ /**
36
+ * Register a new file list action.
37
+ *
38
+ * @param action - The file list action to register
39
+ */
40
+ export declare function registerFileListAction(action: FileListAction): void;
41
+ /**
42
+ * Get all currently registered file list actions.
43
+ */
44
+ export declare function getFileListActions(): FileListAction[];
36
45
  export {};
@@ -1,3 +1,3 @@
1
1
  export type { FileActionData, IHotkeyConfig } from './fileAction.ts';
2
- export { FileAction, getFileActions, registerFileAction, DefaultType } from './fileAction.ts';
3
- export { getFileListActions, registerFileListAction, FileListAction } from './fileListAction.ts';
2
+ export { DefaultType, FileAction, getFileActions, registerFileAction } from './fileAction.ts';
3
+ export { FileListAction, getFileListActions, registerFileListAction } from './fileListAction.ts';
@@ -1,24 +1,47 @@
1
1
  import { getLoggerBuilder } from "@nextcloud/logger";
2
2
  import { join, encodePath, basename, extname, dirname } from "@nextcloud/paths";
3
3
  const logger = getLoggerBuilder().setApp("@nextcloud/files").detectUser().build();
4
- var FileType = /* @__PURE__ */ ((FileType2) => {
5
- FileType2["Folder"] = "folder";
6
- FileType2["File"] = "file";
7
- return FileType2;
8
- })(FileType || {});
9
- var Permission = /* @__PURE__ */ ((Permission2) => {
10
- Permission2[Permission2["NONE"] = 0] = "NONE";
11
- Permission2[Permission2["CREATE"] = 4] = "CREATE";
12
- Permission2[Permission2["READ"] = 1] = "READ";
13
- Permission2[Permission2["UPDATE"] = 2] = "UPDATE";
14
- Permission2[Permission2["DELETE"] = 8] = "DELETE";
15
- Permission2[Permission2["SHARE"] = 16] = "SHARE";
16
- Permission2[Permission2["ALL"] = 31] = "ALL";
17
- return Permission2;
18
- })(Permission || {});
19
- const isDavResource = function(source, davService) {
4
+ const FileType = Object.freeze({
5
+ Folder: "folder",
6
+ File: "file"
7
+ });
8
+ const Permission = Object.freeze({
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
+ function isDavResource(source, davService) {
20
43
  return source.match(davService) !== null;
21
- };
44
+ }
22
45
  function validateData(data, davService) {
23
46
  if (data.id && typeof data.id !== "number") {
24
47
  throw new Error("Invalid id type of value");
@@ -28,7 +51,7 @@ function validateData(data, davService) {
28
51
  }
29
52
  try {
30
53
  new URL(data.source);
31
- } catch (e) {
54
+ } catch {
32
55
  throw new Error("Invalid source format, source must be a valid URL");
33
56
  }
34
57
  if (!data.source.startsWith("http")) {
@@ -80,7 +103,7 @@ function validateData(data, davService) {
80
103
  throw new Error("Status must be a valid NodeStatus");
81
104
  }
82
105
  }
83
- const fixDates = (data) => {
106
+ function fixDates(data) {
84
107
  if (data.mtime && typeof data.mtime === "string") {
85
108
  if (!isNaN(Date.parse(data.mtime)) && JSON.stringify(new Date(data.mtime)) === JSON.stringify(data.mtime)) {
86
109
  data.mtime = new Date(data.mtime);
@@ -91,8 +114,8 @@ const fixDates = (data) => {
91
114
  data.crtime = new Date(data.crtime);
92
115
  }
93
116
  }
94
- };
95
- const fixRegExp = (pattern) => {
117
+ }
118
+ function fixRegExp(pattern) {
96
119
  if (pattern instanceof RegExp) {
97
120
  return pattern;
98
121
  }
@@ -102,14 +125,17 @@ const fixRegExp = (pattern) => {
102
125
  }
103
126
  const validFlags = Array.from(new Set(matches[3])).filter((flag) => "gimsuy".includes(flag)).join("");
104
127
  return new RegExp(matches[2], validFlags);
105
- };
106
- var NodeStatus = /* @__PURE__ */ ((NodeStatus2) => {
107
- NodeStatus2["NEW"] = "new";
108
- NodeStatus2["FAILED"] = "failed";
109
- NodeStatus2["LOADING"] = "loading";
110
- NodeStatus2["LOCKED"] = "locked";
111
- return NodeStatus2;
112
- })(NodeStatus || {});
128
+ }
129
+ const NodeStatus = Object.freeze({
130
+ /** This is a new node and it doesn't exists on the filesystem yet */
131
+ NEW: "new",
132
+ /** This node has failed and is unavailable */
133
+ FAILED: "failed",
134
+ /** This node is currently loading or have an operation in progress */
135
+ LOADING: "loading",
136
+ /** This node is locked and cannot be modified */
137
+ LOCKED: "locked"
138
+ });
113
139
  class Node {
114
140
  _attributes;
115
141
  _data;
@@ -342,7 +368,7 @@ class Node {
342
368
  /**
343
369
  * Move the node to a new destination
344
370
  *
345
- * @param {string} destination the new source.
371
+ * @param destination the new source.
346
372
  * e.g. https://cloud.domain.com/remote.php/dav/files/emma/Photos/picture.jpg
347
373
  */
348
374
  move(destination) {
@@ -442,4 +468,4 @@ export {
442
468
  NodeStatus as c,
443
469
  logger as l
444
470
  };
445
- //# sourceMappingURL=folder-Bf-tAYWu.mjs.map
471
+ //# sourceMappingURL=folder-CeyZUHai.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folder-CeyZUHai.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 const FileType = Object.freeze({\n\tFolder: 'folder',\n\tFile: 'file',\n})\n\nexport type TFileType = typeof FileType[keyof typeof FileType]\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 const Permission = Object.freeze({\n\t/**\n\t * No permissions granted\n\t */\n\tNONE: 0,\n\t/**\n\t * Can read the file content\n\t */\n\tREAD: 1,\n\t/**\n\t * Can modify the file itself (move, rename, etc)\n\t */\n\tUPDATE: 2,\n\t/**\n\t * Can create new files/folders inside a folder\n\t */\n\tCREATE: 4,\n\t/**\n\t * Can change the file content\n\t */\n\tWRITE: 4,\n\t/**\n\t * Can delete the node\n\t */\n\tDELETE: 8,\n\t/**\n\t * Can share the node\n\t */\n\tSHARE: 16,\n\t/**\n\t * All permissions are granted\n\t */\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 type { TNodeStatus } from './node.ts'\n\nimport { join } from '@nextcloud/paths'\nimport { Permission } from '../permissions.ts'\nimport { NodeStatus } from './node.ts'\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/**\n\t * The node permissions.\n\t *\n\t * A binary mask of `Permission` values.\n\t *\n\t * @see Permission\n\t */\n\tpermissions?: number\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?: TNodeStatus\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 function isDavResource(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\tnew URL(data.source)\n\t} catch {\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 function 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 function 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 type { TFileType } from './fileType.ts'\nimport type { Attribute, NodeData } from './nodeData.ts'\n\nimport { basename, dirname, encodePath, extname } from '@nextcloud/paths'\nimport { Permission } from '../permissions.ts'\nimport { fixDates, fixRegExp, isDavResource, validateData } from './nodeData.ts'\n\nexport const NodeStatus = Object.freeze({\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 TNodeStatus = typeof NodeStatus[keyof typeof NodeStatus]\n\nexport type NodeConstructorData = [NodeData, RegExp?]\n\nexport abstract class Node {\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(): TFileType\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(): number {\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: number) {\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(): TNodeStatus | undefined {\n\t\treturn this._data?.status\n\t}\n\n\t/**\n\t * Set the node status.\n\t */\n\tset status(status: TNodeStatus | 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 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 * 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 */\n\nimport type { NodeConstructorData } from './node.ts'\n\nimport { FileType } from './fileType.ts'\nimport { Node } from './node.ts'\n\nexport class File extends Node {\n\tpublic constructor(...[data, davService]: NodeConstructorData) {\n\t\tsuper(data, davService)\n\t}\n\n\tget type(): typeof FileType.File {\n\t\treturn FileType.File\n\t}\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 */\n\nimport type { NodeConstructorData } from './node.ts'\n\nimport { FileType } from './fileType.ts'\nimport { Node } from './node.ts'\n\nexport class Folder extends Node {\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(): typeof 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 * Interface of the folder class\n */\nexport type IFolder = Pick<Folder, keyof Folder>\n"],"names":["basename"],"mappings":"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"}
package/dist/dav/dav.d.ts CHANGED
@@ -25,7 +25,7 @@ export declare const defaultRemoteURL: string;
25
25
  * @param remoteURL The DAV server remote URL
26
26
  * @param headers Optional additional headers to set for every request
27
27
  */
28
- export declare const getClient: (remoteURL?: string, headers?: Record<string, string>) => WebDAVClient;
28
+ export declare function getClient(remoteURL?: string, headers?: Record<string, string>): WebDAVClient;
29
29
  /**
30
30
  * Use WebDAV to query for favorite Nodes
31
31
  *
@@ -69,4 +69,4 @@ export declare function getFavoriteNodes(options?: {
69
69
  * @param filesRoot The DAV files root path
70
70
  * @param remoteURL The DAV server remote URL (same as on `getClient`)
71
71
  */
72
- export declare const resultToNode: (node: FileStat, filesRoot?: string, remoteURL?: string) => Node;
72
+ export declare function resultToNode(node: FileStat, filesRoot?: string, remoteURL?: string): Node;
@@ -1,6 +1,10 @@
1
+ /*!
2
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
3
+ * SPDX-License-Identifier: AGPL-3.0-or-later
4
+ */
1
5
  /**
2
6
  * Parse the WebDAV permission string to a permission enum
3
7
  *
4
- * @param permString The DAV permission string
8
+ * @param permString - The DAV permission string
5
9
  */
6
- export declare const parsePermissions: (permString?: string) => number;
10
+ export declare function parsePermissions(permString?: string): number;
@@ -1,3 +1,7 @@
1
+ /**
2
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
3
+ * SPDX-License-Identifier: AGPL-3.0-or-later
4
+ */
1
5
  export type DavProperty = {
2
6
  [key: string]: string;
3
7
  };
@@ -16,23 +20,23 @@ export declare const defaultDavNamespaces: {
16
20
  * @param prop The property
17
21
  * @param namespace The namespace of the property
18
22
  */
19
- export declare const registerDavProperty: (prop: string, namespace?: DavProperty) => boolean;
23
+ export declare function registerDavProperty(prop: string, namespace?: DavProperty): boolean;
20
24
  /**
21
25
  * Get the registered dav properties
22
26
  */
23
- export declare const getDavProperties: () => string;
27
+ export declare function getDavProperties(): string;
24
28
  /**
25
29
  * Get the registered dav namespaces
26
30
  */
27
- export declare const getDavNameSpaces: () => string;
31
+ export declare function getDavNameSpaces(): string;
28
32
  /**
29
33
  * Get the default PROPFIND request body
30
34
  */
31
- export declare const getDefaultPropfind: () => string;
35
+ export declare function getDefaultPropfind(): string;
32
36
  /**
33
37
  * Get the REPORT body to filter for favorite nodes
34
38
  */
35
- export declare const getFavoritesReport: () => string;
39
+ export declare function getFavoritesReport(): string;
36
40
  /**
37
41
  * Get the SEARCH body to search for recently modified files
38
42
  *
@@ -54,4 +58,4 @@ export declare const getFavoritesReport: () => string;
54
58
  * }) as ResponseDataDetailed<FileStat[]>
55
59
  * ```
56
60
  */
57
- export declare const getRecentSearch: (lastModified: number) => string;
61
+ export declare function getRecentSearch(lastModified: number): string;
@@ -6,8 +6,9 @@
6
6
  * This module provides utils to work with the Nextcloud WebDAV interface.
7
7
  *
8
8
  * The DAV functions are based on the [`webdav`](https://www.npmjs.com/package/webdav) package.
9
+ *
9
10
  * @packageDocumentation
10
11
  */
11
- export * from './dav';
12
- export * from './davPermissions';
13
- export * from './davProperties';
12
+ export * from './dav.ts';
13
+ export * from './davPermissions.ts';
14
+ export * from './davProperties.ts';
package/dist/dav.mjs CHANGED
@@ -1,20 +1,27 @@
1
1
  import { getCurrentUser, onRequestTokenUpdate, getRequestToken } from "@nextcloud/auth";
2
- import { isPublicShare, getSharingToken } from "@nextcloud/sharing/public";
3
2
  import { generateRemoteUrl } from "@nextcloud/router";
3
+ import { isPublicShare, getSharingToken } from "@nextcloud/sharing/public";
4
4
  import { createClient, getPatcher } from "webdav";
5
- import { P as Permission, l as logger, c as NodeStatus, a as File, b as Folder } from "./chunks/folder-Bf-tAYWu.mjs";
6
- const parsePermissions = function(permString = "") {
5
+ import { P as Permission, l as logger, c as NodeStatus, a as File, b as Folder } from "./chunks/folder-CeyZUHai.mjs";
6
+ /*!
7
+ * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
8
+ * SPDX-License-Identifier: AGPL-3.0-or-later
9
+ */
10
+ function parsePermissions(permString = "") {
7
11
  let permissions = Permission.NONE;
8
12
  if (!permString) {
9
13
  return permissions;
10
14
  }
11
- if (permString.includes("C") || permString.includes("K")) {
12
- permissions |= Permission.CREATE;
13
- }
14
15
  if (permString.includes("G")) {
15
16
  permissions |= Permission.READ;
16
17
  }
17
- if (permString.includes("W") || permString.includes("N") || permString.includes("V")) {
18
+ if (permString.includes("W")) {
19
+ permissions |= Permission.WRITE;
20
+ }
21
+ if (permString.includes("CK")) {
22
+ permissions |= Permission.CREATE;
23
+ }
24
+ if (permString.includes("NV")) {
18
25
  permissions |= Permission.UPDATE;
19
26
  }
20
27
  if (permString.includes("D")) {
@@ -24,7 +31,7 @@ const parsePermissions = function(permString = "") {
24
31
  permissions |= Permission.SHARE;
25
32
  }
26
33
  return permissions;
27
- };
34
+ }
28
35
  const defaultDavProperties = [
29
36
  "d:getcontentlength",
30
37
  "d:getcontenttype",
@@ -51,7 +58,7 @@ const defaultDavNamespaces = {
51
58
  oc: "http://owncloud.org/ns",
52
59
  ocs: "http://open-collaboration-services.org/ns"
53
60
  };
54
- const registerDavProperty = function(prop, namespace = { nc: "http://nextcloud.org/ns" }) {
61
+ function registerDavProperty(prop, namespace = { nc: "http://nextcloud.org/ns" }) {
55
62
  if (typeof window._nc_dav_properties === "undefined") {
56
63
  window._nc_dav_properties = [...defaultDavProperties];
57
64
  window._nc_dav_namespaces = { ...defaultDavNamespaces };
@@ -73,28 +80,28 @@ const registerDavProperty = function(prop, namespace = { nc: "http://nextcloud.o
73
80
  window._nc_dav_properties.push(prop);
74
81
  window._nc_dav_namespaces = namespaces;
75
82
  return true;
76
- };
77
- const getDavProperties = function() {
83
+ }
84
+ function getDavProperties() {
78
85
  if (typeof window._nc_dav_properties === "undefined") {
79
86
  window._nc_dav_properties = [...defaultDavProperties];
80
87
  }
81
88
  return window._nc_dav_properties.map((prop) => `<${prop} />`).join(" ");
82
- };
83
- const getDavNameSpaces = function() {
89
+ }
90
+ function getDavNameSpaces() {
84
91
  if (typeof window._nc_dav_namespaces === "undefined") {
85
92
  window._nc_dav_namespaces = { ...defaultDavNamespaces };
86
93
  }
87
94
  return Object.keys(window._nc_dav_namespaces).map((ns) => `xmlns:${ns}="${window._nc_dav_namespaces?.[ns]}"`).join(" ");
88
- };
89
- const getDefaultPropfind = function() {
95
+ }
96
+ function getDefaultPropfind() {
90
97
  return `<?xml version="1.0"?>
91
98
  <d:propfind ${getDavNameSpaces()}>
92
99
  <d:prop>
93
100
  ${getDavProperties()}
94
101
  </d:prop>
95
102
  </d:propfind>`;
96
- };
97
- const getFavoritesReport = function() {
103
+ }
104
+ function getFavoritesReport() {
98
105
  return `<?xml version="1.0"?>
99
106
  <oc:filter-files ${getDavNameSpaces()}>
100
107
  <d:prop>
@@ -104,8 +111,8 @@ const getFavoritesReport = function() {
104
111
  <oc:favorite>1</oc:favorite>
105
112
  </oc:filter-rules>
106
113
  </oc:filter-files>`;
107
- };
108
- const getRecentSearch = function(lastModified) {
114
+ }
115
+ function getRecentSearch(lastModified) {
109
116
  return `<?xml version="1.0" encoding="UTF-8"?>
110
117
  <d:searchrequest ${getDavNameSpaces()}
111
118
  xmlns:ns="https://github.com/icewind1991/SearchDAV/ns">
@@ -161,7 +168,7 @@ const getRecentSearch = function(lastModified) {
161
168
  </d:limit>
162
169
  </d:basicsearch>
163
170
  </d:searchrequest>`;
164
- };
171
+ }
165
172
  function getRootPath() {
166
173
  if (isPublicShare()) {
167
174
  return `/files/${getSharingToken()}`;
@@ -177,7 +184,7 @@ function getRemoteURL() {
177
184
  return url;
178
185
  }
179
186
  const defaultRemoteURL = getRemoteURL();
180
- const getClient = function(remoteURL = defaultRemoteURL, headers = {}) {
187
+ function getClient(remoteURL = defaultRemoteURL, headers = {}) {
181
188
  const client = createClient(remoteURL, { headers });
182
189
  function setHeaders(token) {
183
190
  client.setHeaders({
@@ -200,7 +207,7 @@ const getClient = function(remoteURL = defaultRemoteURL, headers = {}) {
200
207
  return fetch(url, options);
201
208
  });
202
209
  return client;
203
- };
210
+ }
204
211
  async function getFavoriteNodes(options = {}) {
205
212
  const client = options.client ?? getClient();
206
213
  const path = options.path ?? "/";
@@ -217,7 +224,7 @@ async function getFavoriteNodes(options = {}) {
217
224
  });
218
225
  return contentsResponse.data.filter((node) => node.filename !== path).map((result) => resultToNode(result, davRoot));
219
226
  }
220
- const resultToNode = function(node, filesRoot = defaultRootPath, remoteURL = defaultRemoteURL) {
227
+ function resultToNode(node, filesRoot = defaultRootPath, remoteURL = defaultRemoteURL) {
221
228
  let userId = getCurrentUser()?.uid;
222
229
  if (isPublicShare()) {
223
230
  userId = userId ?? "anonymous";
@@ -252,7 +259,7 @@ const resultToNode = function(node, filesRoot = defaultRootPath, remoteURL = def
252
259
  };
253
260
  delete nodeData.attributes?.props;
254
261
  return node.type === "file" ? new File(nodeData) : new Folder(nodeData);
255
- };
262
+ }
256
263
  export {
257
264
  defaultDavNamespaces,
258
265
  defaultDavProperties,