From 3e5005219d3abb0e256150ad7d51bb4cb431e3b2 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Wed, 5 Jun 2024 13:04:53 +0200 Subject: [PATCH] feat: Export public interfaces of `Node`, `File` and `Folder` If you using those classes in Vue (e.g. in data) they will cause errors, as Vue unrefs data deeply and this causes all private fields to be stripped off from the interface. Passing one of those classes from data to a function that expects e.g. `Node` will then cause a Typescript error because the passed value is lacking the private fields. So instead this provives interfaces that can be used whenever a parameter should be of one of those types. Signed-off-by: Ferdinand Thiessen --- lib/files/file.ts | 9 ++++++++- lib/files/folder.ts | 13 +++++++++++-- lib/files/node.ts | 5 +++++ lib/index.ts | 6 +++--- lib/navigation/column.ts | 4 ++-- lib/navigation/navigation.ts | 2 +- lib/utils/fileSorting.ts | 14 +++++++------- 7 files changed, 37 insertions(+), 16 deletions(-) diff --git a/lib/files/file.ts b/lib/files/file.ts index 8f948a5d..dfc3d064 100644 --- a/lib/files/file.ts +++ b/lib/files/file.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ import { FileType } from './fileType' -import { Node } from './node' +import { type INode, Node } from './node' export class File extends Node { @@ -12,3 +12,10 @@ export class File extends Node { } } + +/** + * Interface of the File class + */ +export interface IFile extends INode { + readonly type: FileType.File +} diff --git a/lib/files/folder.ts b/lib/files/folder.ts index 7019f1a7..940612d7 100644 --- a/lib/files/folder.ts +++ b/lib/files/folder.ts @@ -3,8 +3,8 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ import { FileType } from './fileType' -import { Node } from './node' -import { NodeData } from './nodeData' +import { type INode, Node } from './node' +import { type NodeData } from './nodeData' export class Folder extends Node { @@ -29,3 +29,12 @@ export class Folder extends Node { } } + +/** + * Interface of the folder class + */ +export interface IFolder extends INode { + readonly type: FileType.Folder + readonly extension: null + readonly mime: 'httpd/unix-directory' +} diff --git a/lib/files/node.ts b/lib/files/node.ts index 4f3260e0..e933bb74 100644 --- a/lib/files/node.ts +++ b/lib/files/node.ts @@ -358,3 +358,8 @@ export abstract class Node { } } + +/** + * Interface of the node class + */ +export type INode = Pick diff --git a/lib/index.ts b/lib/index.ts index a44c1e86..273c12d1 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -16,9 +16,9 @@ export * from './dav/davPermissions' export * from './dav/dav' export { FileType } from './files/fileType' -export { File } from './files/file' -export { Folder } from './files/folder' -export { Node, NodeStatus } from './files/node' +export { File, type IFile } from './files/file' +export { Folder, type IFolder } from './files/folder' +export { Node, NodeStatus, type INode } from './files/node' export { isFilenameValid, getUniqueName } from './utils/filename' export { formatFileSize, parseFileSize } from './utils/fileSize' diff --git a/lib/navigation/column.ts b/lib/navigation/column.ts index 5efbbb69..dcdb038b 100644 --- a/lib/navigation/column.ts +++ b/lib/navigation/column.ts @@ -2,8 +2,8 @@ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -import { View } from './view' -import { Node } from '../files/node' +import type { Node } from '../files/node' +import type { View } from './view' interface ColumnData { /** Unique column ID */ diff --git a/lib/navigation/navigation.ts b/lib/navigation/navigation.ts index e2e04482..79fbea9a 100644 --- a/lib/navigation/navigation.ts +++ b/lib/navigation/navigation.ts @@ -2,7 +2,7 @@ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -import { View } from './view' +import type { View } from './view' import logger from '../utils/logger' export class Navigation { diff --git a/lib/utils/fileSorting.ts b/lib/utils/fileSorting.ts index 1b1d7959..16e0ff3f 100644 --- a/lib/utils/fileSorting.ts +++ b/lib/utils/fileSorting.ts @@ -2,7 +2,7 @@ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -import type { Node } from '../files/node' +import type { INode } from '../files/node' import { orderBy } from './sorting' export enum FilesSortingMode { @@ -41,7 +41,7 @@ export interface FilesSortingOptions { * @param nodes Nodes to sort * @param options Sorting options */ -export function sortNodes(nodes: readonly Node[], options: FilesSortingOptions = {}): Node[] { +export function sortNodes(nodes: readonly INode[], options: FilesSortingOptions = {}): INode[] { const sortingOptions = { // Default to sort by name sortingMode: FilesSortingMode.Name, @@ -58,15 +58,15 @@ export function sortNodes(nodes: readonly Node[], options: FilesSortingOptions = const identifiers = [ // 1: Sort favorites first if enabled - ...(sortingOptions.sortFavoritesFirst ? [(v: Node) => v.attributes?.favorite !== 1] : []), + ...(sortingOptions.sortFavoritesFirst ? [(v: INode) => v.attributes?.favorite !== 1] : []), // 2: Sort folders first if sorting by name - ...(sortingOptions.sortFoldersFirst ? [(v: Node) => v.type !== 'folder'] : []), + ...(sortingOptions.sortFoldersFirst ? [(v: INode) => v.type !== 'folder'] : []), // 3: Use sorting mode if NOT basename (to be able to use displayName too) - ...(sortingOptions.sortingMode !== FilesSortingMode.Name ? [(v: Node) => v[sortingOptions.sortingMode]] : []), + ...(sortingOptions.sortingMode !== FilesSortingMode.Name ? [(v: INode) => v[sortingOptions.sortingMode]] : []), // 4: Use displayName if available, fallback to name - (v: Node) => basename(v.attributes?.displayName || v.basename), + (v: INode) => basename(v.attributes?.displayName || v.basename), // 5: Finally, use basename if all previous sorting methods failed - (v: Node) => v.basename, + (v: INode) => v.basename, ] const orders = [ // (for 1): always sort favorites before normal files