@samitouri / QOSami-HFS / commits / dd3ce2ff

better code

Massimo Melina committed Apr 12, 2024 at 12:40 UTC dd3ce2ffcf0138e25e256e4a41cb20b82adbaef8
4 files changed +17 -39
admin/src/state.ts
+9 -18
@@ -7,24 +7,13 @@ import _ from 'lodash'
7 import { subscribeKey } from 'valtio/utils'
8
9 const STORAGE_KEY = 'admin_state'
10 -export const state = proxy<{
11 - title: string
12 - config: Dict
13 - vfs: VfsNode | undefined
14 - movingFile: string
15 - selectedFiles: VfsNode[]
16 - loginRequired: boolean | number
17 - username: string
18 - monitorOnlyFiles: boolean
19 - customHtmlSection: string,
20 - onlinePluginsColumns: Dict<boolean>
21 -}>(Object.assign({
10 +const INIT = {
11 title: '',
23 - config: {},
24 - selectedFiles: [],
12 + config: {} as Dict,
13 + selectedFiles: [] as VfsNode[],
14 movingFile: '',
26 - vfs: undefined,
27 - loginRequired: false,
15 + vfs: undefined as VfsNode | undefined,
16 + loginRequired: false as boolean | number,
17 username: '',
18 monitorOnlyFiles: true,
19 customHtmlSection: '',
@@ -32,8 +21,10 @@ export const state = proxy<{
21 version: false,
22 pushed_at: false,
23 license: false,
35 - }
36 -}, JSON.parse(localStorage[STORAGE_KEY]||null)))
24 + } as Dict<boolean>
25 +}
26 +Object.assign(INIT, JSON.parse(localStorage[STORAGE_KEY]||null))
27 +export const state = proxy(INIT)
28
29 const SETTINGS_TO_STORE: (keyof typeof state)[] = ['onlinePluginsColumns', 'monitorOnlyFiles', 'customHtmlSection']
30 const storeSettings = _.debounce(() =>
src/api.plugins.ts
+1 -1
@@ -85,7 +85,7 @@ const apis: ApiHandlers = {
85 return {
86 enabled: enablePlugins.get().includes(id),
87 config: {
88 - ...newObj(getPluginConfigFields(id) ||{}, v => v?.defaultValue),
88 + ...newObj(getPluginConfigFields(id), v => v?.defaultValue),
89 ...pluginsConfig.get()[id]
90 }
91 }
src/cross.ts
+6 -18
@@ -33,16 +33,6 @@ type Truthy<T> = T extends false | '' | 0 | null | undefined | void ? never : T
33 export type Callback<IN=void, OUT=void> = (x:IN) => OUT
34 export type Promisable<T> = T | Promise<T>
35
36 -interface Mapping {
37 - public: { host: string; port: number }
38 - private: { host: string; port: number }
39 - protocol: string
40 - enabled: boolean
41 - description: string
42 - ttl: number
43 - local: boolean
44 -}
45 -
36 export interface VfsPerms {
37 can_see?: Who
38 can_read?: Who
@@ -241,14 +231,12 @@ export function findDefined<I, O>(a: I[] | Record<string, I>, cb:(v:I, k: string
231 }
232 }
233
244 -export function newObj<S extends (object | undefined | null),VR=any>(
234 +export function newObj<S extends (object | undefined | null),VR=unknown>(
235 src: S,
246 - returnNewValue: (value:Truthy<S[keyof S]>, key: Exclude<keyof S, symbol>, setK:(newK?: string)=>true, depth: number) => any,
236 + returnNewValue: (value: S[keyof S], key: Exclude<keyof S, symbol>, setK:(newK?: string)=>true, depth: number) => any,
237 recur: boolean | number=false
238 ) {
249 - if (!src)
250 - return {}
251 - const pairs = Object.entries(src).map( ([k,v]) => {
239 + const pairs = Object.entries(src || {}).map( ([k,v]) => {
240 if (typeof k === 'symbol') return
241 let _k: undefined | typeof k = k
242 const curDepth = typeof recur === 'number' ? recur : 0
@@ -433,10 +421,10 @@ export function matches(s: string, mask: string, emptyMaskReturns=false) {
421 return makeMatcher(mask, emptyMaskReturns)(s) // adding () will allow us to use the pipe at root level
422 }
423
436 -export function replace(s: string, symbols: Dict<string | Callback<string>>, delimiter='') {
424 +export function replace(s: string, symbols: Dict<string | Callback<string, string>>, delimiter='') {
425 const [open, close] = splitAt(' ', delimiter)
438 - for (const [k, v] of typedEntries(symbols))
439 - s = s.replace(open + k + close, _.isFunction(v) ? v() : v)
426 + for (const [k, v] of Object.entries(symbols))
427 + s = s.replaceAll(open + k + close, v as any) // typescript doesn't handle overloaded functions (like replaceAll) with union types https://stackoverflow.com/a/66510061/646132
428 return s
429 }
430
src/misc.ts
+1 -2
@@ -2,7 +2,6 @@
2
3 import { EventEmitter } from 'events'
4 import { basename } from 'path'
5 -import _ from 'lodash'
5 import Koa from 'koa'
6 import { Connection } from './connections'
7 import assert from 'assert'
@@ -107,7 +106,7 @@ export function asyncGeneratorToReadable<T>(generator: AsyncIterable<T>) {
106 return new Readable({
107 objectMode: true,
108 destroy() {
110 - iterator.return?.()
109 + void iterator.return?.()
110 },
111 read() {
112 iterator.next().then(it =>