UNPKG

snapshot-fs

Version:

Create a filesystem snapshot for use with memfs

1 lines 7.3 kB
{"version":3,"file":"tree.js","sourceRoot":"","sources":["../src/tree.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Provides {@link toTree a function} to dump the contents of a `Volume`,\n * comparing it to the real filesystem.\n *\n * Portions of this code adapted from\n * https://github.com/streamich/memfs/blob/2c6a6ca55ad2e661f40e488fe5ea4087438bae0e/src/print/index.ts#L6-L30\n * and are copyrighted by the original author and licesned under Apache-2.0.\n */\n\nimport type { Volume } from 'memfs';\nimport type { IDirent } from 'memfs/lib/node/types/misc.js';\n\nimport nodeFs, { type Dirent } from 'node:fs';\nimport path from 'node:path';\nimport { basename, sep } from 'path/posix';\nimport { printTree } from 'tree-dump';\n\nexport const toTree = (\n fs: Volume,\n {\n depth = 10,\n separator = sep,\n dir = separator,\n formatNew = (str) => `+ ${str}`,\n formatOverwrite = (str) => `! ${str}`,\n tab = '',\n }: ToTreeOptions,\n) => {\n if (dir[dir.length - 1] !== separator) {\n dir += separator;\n }\n let subtree = ' (...)';\n if (depth > 0) {\n const list = fs.readdirSync(dir, { withFileTypes: true }) as IDirent[];\n let actualFiles: Map<string, Dirent>;\n try {\n actualFiles = new Map(\n nodeFs\n .readdirSync(dir, { withFileTypes: true })\n .map((entry) => [entry.name, entry]),\n );\n } catch {\n actualFiles = new Map();\n }\n subtree = printTree(\n tab,\n list.map((entry) => (tab) => {\n if (entry.isDirectory()) {\n return toTree(fs, {\n depth: depth - 1,\n dir: `${dir}${entry.name}`,\n formatNew,\n formatOverwrite,\n tab,\n });\n }\n let formattedName: string;\n let willBeOverwritten = false;\n const willBeCreated = !actualFiles.has(`${entry.name}`);\n if (!willBeCreated) {\n const actualDirent = actualFiles.get(`${entry.name}`)!;\n if (entry.isSymbolicLink()) {\n if (!actualDirent.isSymbolicLink()) {\n willBeOverwritten = true;\n } else {\n try {\n const actualRealpath = nodeFs.realpathSync(\n path.join(dir, `${entry.name}`),\n );\n const realpath = fs.readlinkSync(\n path.join(dir, `${entry.name}`),\n );\n if (actualRealpath !== realpath) {\n willBeOverwritten = true;\n }\n } catch {\n willBeOverwritten = true;\n }\n }\n } else {\n // implies file\n if (!actualDirent.isFile()) {\n willBeOverwritten = true;\n } else {\n try {\n const actualStat = nodeFs.statSync(\n path.join(dir, `${entry.name}`),\n );\n const stat = fs.statSync(path.join(dir, `${entry.name}`));\n if (actualStat.size !== stat.size) {\n willBeOverwritten = true;\n }\n } catch {\n willBeOverwritten = true;\n }\n }\n }\n }\n if (willBeOverwritten) {\n formattedName = formatOverwrite(`${entry.name}`);\n } else if (willBeCreated) {\n formattedName = formatNew(`${entry.name}`);\n } else {\n // identical, hopefully\n formattedName = `${entry.name}`;\n }\n if (entry.isSymbolicLink()) {\n return `${formattedName} → ${fs.readlinkSync(path.join(dir, `${entry.name}`))}`;\n } else {\n return formattedName;\n }\n }),\n );\n }\n const base = basename(dir, separator) + separator;\n return base + subtree;\n};\n\nexport interface ToTreeOptions {\n depth?: number;\n dir?: string;\n formatNew?: (str: string) => string;\n formatOverwrite?: (str: string) => string;\n separator?: typeof sep;\n tab?: string;\n}\n"]}