Skip to content

Commit

Permalink
feat: Export public interfaces of Node, File and Folder
Browse files Browse the repository at this point in the history
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 <opensource@fthiessen.de>
  • Loading branch information
susnux committed Jun 14, 2024
1 parent b3d8079 commit 3e50052
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 16 deletions.
9 changes: 8 additions & 1 deletion lib/files/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -12,3 +12,10 @@ export class File extends Node {
}

}

/**
* Interface of the File class
*/
export interface IFile extends INode {
readonly type: FileType.File
}
13 changes: 11 additions & 2 deletions lib/files/folder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -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'
}
5 changes: 5 additions & 0 deletions lib/files/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,8 @@ export abstract class Node {
}

}

/**
* Interface of the node class
*/
export type INode = Pick<Node, keyof Node>
6 changes: 3 additions & 3 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
4 changes: 2 additions & 2 deletions lib/navigation/column.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion lib/navigation/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
14 changes: 7 additions & 7 deletions lib/utils/fileSorting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down

0 comments on commit 3e50052

Please sign in to comment.