better code: removed duplicated code

Massimo Melina committed May 10, 2026 at 18:02 UTC ef89c1276fce14bfd7c9b018325da96fc2cdda65
4 files changed +10 -11
src/api.get_file_list.ts
+3 -3
@@ -1,7 +1,7 @@
1 // This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3 import {
4 - applyParentToChild, getNodeName, hasDefaultFile, hasPermission, masksCouldGivePermission, nodeIsFolder, nodeStats,
4 + applyParentToChild, getNodeName, getDefaultFile, hasPermission, masksCouldGivePermission, nodeIsFolder, nodeStats,
5 statusCodeForMissingPerm, urlToNode, VfsNode, walkNode
6 } from './vfs'
7 import { ApiError, ApiHandler } from './apiMiddleware'
@@ -37,7 +37,7 @@ export const get_file_list: ApiHandler = async ({ uri='/', offset, limit, c, onl
37 if (!node)
38 return fail(HTTP_NOT_FOUND)
39 admin &&= ctxAdminAccess(ctx) // validate 'admin' flag
40 - if (await hasDefaultFile(node, ctx) || !nodeIsFolder(node)) // for files without permission, the frontend is sent, and the location is the file itself
40 + if (await getDefaultFile(node, ctx) || !nodeIsFolder(node)) // for files without permission, the frontend is sent, and the location is the file itself
41 // so, we first check if you have a permission problem, to tell frontend to show login, otherwise we fall back to method_not_allowed, as it's proper for files.
42 return fail(!admin && statusCodeForMissingPerm(node, 'can_read', ctx) ? undefined : HTTP_METHOD_NOT_ALLOWED)
43 if (!admin && statusCodeForMissingPerm(node, 'can_list', ctx))
@@ -119,7 +119,7 @@ export const get_file_list: ApiHandler = async ({ uri='/', offset, limit, c, onl
119 const isFolder = nodeIsFolder(node)
120 try {
121 const [web, comment, st] = await Promise.all([
122 - hasDefaultFile(node, ctx).then(x => x ? true : undefined),
122 + getDefaultFile(node, ctx).then(x => x ? true : undefined),
123 node.comment ?? getCommentFor(source),
124 nodeStats(node).catch(e => {
125 if (!isFolder || !node.children?.length) // folders with virtual children, keep them
src/basicWeb.ts
+2 -2
@@ -2,7 +2,7 @@ import { getCurrentUsername, setLoggedIn } from './auth'
2 import { BASIC_AUTHENTICATE_HEADER, HTTP_UNAUTHORIZED } from './cross-const'
3 import Koa from 'koa'
4 import { defineConfig } from './config'
5 -import { getNodeName, hasDefaultFile, nodeIsFolder, VfsNode, walkNode } from './vfs'
5 +import { getNodeName, getDefaultFile, nodeIsFolder, VfsNode, walkNode } from './vfs'
6 import { asyncGeneratorToReadable, Dict, filterMapGenerator, pathEncode } from './misc'
7 import _ from 'lodash'
8 import { title } from './adminApis'
@@ -36,7 +36,7 @@ export function basicWeb(ctx: Koa.Context, node: VfsNode) {
36 const stream = asyncGeneratorToReadable(filterMapGenerator(walker, async el => {
37 const isFolder = nodeIsFolder(el)
38 const name = getNodeName(el) + (isFolder ? '/' : '')
39 - return `<li>${a(pathEncode(name) + (isFolder && !await hasDefaultFile(el, ctx) ? force : ''), name)}\n`
39 + return `<li>${a(pathEncode(name) + (isFolder && !await getDefaultFile(el, ctx) ? force : ''), name)}\n`
40 }))
41 ctx.body = stream
42 stream.push(`<meta name="viewport" content="width=device-width" />`)
src/serveGuiAndSharedFiles.ts
+4 -5
@@ -1,6 +1,6 @@
1 import Koa from 'koa'
2 import { basename, dirname, join } from 'path'
3 -import { getNodeName, nodeIsFolder, statusCodeForMissingPerm, urlToNode, vfs, VfsNode, walkNode } from './vfs'
3 +import { getDefaultFile, getNodeName, nodeIsFolder, statusCodeForMissingPerm, urlToNode, vfs, VfsNode, walkNode } from './vfs'
4 import { sendErrorPage } from './errorPages'
5 import events from './events'
6 import {
@@ -120,11 +120,10 @@ export const serveSharedFiles: Koa.Middleware = async (ctx, next) => {
120 return ctx.status = HTTP_SERVER_ERROR
121 }
122 }
123 - if (node.default && path.endsWith('/') && !get) { // final/ needed on browser to make resource urls correctly with html pages
124 - const found = await urlToNode(node.default, ctx, node)
125 - if (found && /\.html?/i.test(node.default))
123 + if (path.endsWith('/') && !get) { // final slash needed on browsers to make resource urls working with html pages
124 + const found = await getDefaultFile(node, ctx)
125 + if (found && /\.html?/i.test(getNodeName(node = found)))
126 ctx.state.considerAsGui = true
127 - node = found ?? node
127 }
128 if (get === 'icon')
129 return serveFile(ctx, node.icon || '|') // pipe to cause not-found
src/vfs.ts
+1 -1
@@ -252,7 +252,7 @@ export function nodeIsFolder(node: VfsNode) {
252 }
253 }
254
255 -export async function hasDefaultFile(node: VfsNode, ctx: Koa.Context) {
255 +export async function getDefaultFile(node: VfsNode, ctx: Koa.Context) {
256 return node.default && nodeIsFolder(node) && await urlToNode(node.default, ctx, node) || undefined
257 }
258