vfs.hide and .remove as single mask, no array
Massimo Melina committed
Feb 1, 2022 at 15:36 UTC
0e1ea9f847894fd1241b237a2054c5d0d1211779
2 files changed
+12
-13
README.md
+2
-1
@@ -94,7 +94,8 @@ Valid keys in a node are:
94
- `forbid`: set `true` to forbid listing for this folder
95
- `hide`: similar to hidden, but it's from the parent node point of view.
96
Use this to hide children read from the source, not listed in the VFS.
97
- Value can be just a file name, a mask, or a list of names/masks.
97
+ Value is a file mask.
98
+- `remove`: use this to not only hide files but also prevent downloads in a folder with a source. Value is a file mask.
99
- `rename`: similar to name, but it's from the parent node point.
100
Use this to change the name of entries that are read from the source, not listed in the VFS.
101
Value is a dictionary, where the key is the original name.
src/vfs.ts
+10
-12
@@ -1,7 +1,7 @@
1
import fs from 'fs/promises'
2
import { basename } from 'path'
3
import { isMatch } from 'micromatch'
4
-import { complySlashes, enforceFinal, isDirectory, prefix, wantArray } from './misc'
4
+import { enforceFinal, isDirectory, prefix } from './misc'
5
import Koa from 'koa'
6
import glob from 'fast-glob'
7
import _ from 'lodash'
@@ -17,8 +17,8 @@ export interface VfsNode {
17
name: string,
18
source?: string,
19
children?: VfsNode[],
20
- hide?: string | string[],
21
- remove?: string | string[],
20
+ hide?: string,
21
+ remove?: string,
22
hidden?: boolean,
23
forbid?: boolean,
24
rename?: Record<string,string>,
@@ -57,7 +57,7 @@ export class Vfs {
57
const relativeSource = piece + prefix('/', rest.join('/'))
58
const baseSource = run.source+ '/'
59
const source = baseSource + relativeSource
60
- if (isMatch(source, wantArray(run.remove).map(x => baseSource + x)))
60
+ if (run.remove && isMatch(source, run.remove.split('|').map(x => baseSource + x)))
61
return
62
try { await fs.stat(source) } // check existence
63
catch { return }
@@ -110,26 +110,24 @@ export async function* walkNode(parent:VfsNode, ctx: Koa.Context, depth:number=0
110
}
111
if (!source)
112
return
113
- const base = enforceFinal('/', complySlashes(source)) // fast-glob lib wants forward-slashes
114
- const baseForGlob = glob.escapePath(base)
115
- const ignore = [parent.hide, parent.remove].flat().filter(Boolean).map(x => baseForGlob+x)
113
const depthPath = depth === Infinity ? '**/' : _.repeat('*/',depth)
114
try {
118
- const dirStream = glob.stream(baseForGlob + depthPath + '*', {
115
+ const dirStream = glob.stream(depthPath + '*', {
116
dot: true,
117
onlyFiles: false,
121
- ignore,
118
+ cwd: source,
119
+ ignore: [parent.hide, parent.remove].filter(Boolean) as string[],
120
})
121
+ const base = enforceFinal('/', source)
122
for await (let path of dirStream) {
123
if (ctx.req.aborted)
124
return
125
if (path instanceof Buffer)
126
path = path.toString('utf8')
128
- const name = path.slice(base.length)
127
yield {
128
type: VfsNodeType.temp,
131
- source: path,
132
- name: prefixPath + (parent!.rename?.[name] || name)
129
+ source: base + path,
130
+ name: prefixPath + (parent!.rename?.[path] || path)
131
}
132
}
133
}