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 authored and AndyScherzinger committed Jun 12, 2024
1 parent 535ff9a commit 83266c5
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 } 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: Node[], options: FilesSortingOptions = {}): Node[] {
export function sortNodes(nodes: INode[], options: FilesSortingOptions = {}): INode[] {
const sortingOptions = {
// Default to sort by name
sortingMode: FilesSortingMode.Name,
Expand All @@ -52,15 +52,15 @@ export function sortNodes(nodes: Node[], options: FilesSortingOptions = {}): Nod

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) => v.attributes?.displayName || v.basename,
(v: INode) => 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 83266c5

Please sign in to comment.