@neodx/vfs
Version:
Simple virtual file system - working dir context, lazy changes, different modes, integrations and moreover
1 lines • 18.3 kB
Source Map (JSON)
{"version":3,"file":"operations-DJhEnMA2.cjs","sources":["../../../src/backend/create-in-memory-backend.ts","../../../src/core/operations.ts"],"sourcesContent":["import { entries, isTypeOfString, uniq } from '@neodx/std';\nimport { dirname, join } from 'pathe';\nimport type { VfsContentLike } from '../core/types';\nimport type { VfsBackend } from './shared';\n\nexport interface VirtualInitializer {\n [path: string]: string | VirtualInitializer;\n}\n\n/**\n * In-memory VFS backend.\n * Useful for testing, emulating file system, etc.\n */\nexport function createInMemoryBackend(root = '/', initializer: VirtualInitializer = {}) {\n // generate new implementation based on old one\n const store = new Map<string, Buffer>(\n entries(createInMemoryFilesRecord(initializer, root)).map(([path, content]) => [\n path,\n Buffer.from(content)\n ])\n );\n const deleted = new Set<string>();\n\n const isFile = (path: string) => store.has(path);\n const isDir = (path: string) =>\n !isFile(path) && Array.from(store.keys()).some(pathStartsBy(path));\n const deletePath = (path: string) => {\n store.delete(path);\n deleted.add(path);\n };\n\n return {\n read(path: string) {\n return store.get(path) ?? null;\n },\n\n isFile,\n isDir,\n exists(path: string) {\n return isFile(path) || isDir(path);\n },\n\n readDir(path: string) {\n return uniq(\n Array.from(store.keys())\n .filter(pathStartsBy(path))\n .map(name => name.split(withTrailingSlash(path))[1]!.split('/')[0]!)\n ).map(name => createInMemoryDirent(name, isFile(join(path, name))));\n },\n\n write(path: string, content: VfsContentLike) {\n store.set(path, Buffer.from(content));\n while (path !== '/') {\n deleted.delete(path);\n path = dirname(path);\n }\n },\n\n delete(path: string) {\n deletePath(path);\n for (const name of store.keys()) {\n if (pathStartsWith(name, path)) {\n deletePath(name);\n }\n }\n },\n\n __: {\n kind: 'in-memory',\n getStore: () => new Map(store),\n getDeleted: () => new Set(deleted)\n }\n } satisfies VfsBackend;\n}\n\nexport const createInMemoryDirent = (name: string, file: boolean, symlink = false) => ({\n isFile: () => file,\n isDirectory: () => !file,\n isSymbolicLink: () => symlink,\n name\n});\n\nexport const withTrailingSlash = (path: string) => (path.endsWith('/') ? path : `${path}/`);\nexport const pathStartsWith = (fullPath: string, basePath: string) =>\n fullPath.startsWith(withTrailingSlash(basePath));\nexport const pathStartsBy = (basePath: string) => (fullPath: string) =>\n pathStartsWith(fullPath, basePath);\n\n/**\n * @param initializer Virtual files tree\n * @param base Root path\n * @example\n * ```ts\n * createInMemoryFilesRecord({\n * \"package.json\": \"{...}\",\n * \"src\": {\n * \"foo\": {\n * \"bar.ts\": \"export const a = 1\"\n * \"baz.ts\": \"export const b = 2\"\n * },\n * \"index.ts\": \"export const c = 3\"\n * }\n * });\n * // {\n * // \"package.json\": \"{...}\",\n * // \"src/foo/bar.ts\": \"export const a = 1\",\n * // \"src/foo/baz.ts\": \"export const b = 2\",\n * // \"src/index.ts\": \"export const c = 3\"\n * // }\n * ```\n */\nexport function createInMemoryFilesRecord(initializer: VirtualInitializer, base = '') {\n const result = {} as Record<string, string>;\n\n for (const [name, value] of entries(initializer)) {\n const path = join(base, name);\n\n if (isTypeOfString(value)) result[path] = value;\n else Object.assign(result, createInMemoryFilesRecord(value, path));\n }\n return result;\n}\n","import { colors } from '@neodx/colors';\nimport { compact, concurrently, isTruthy, uniqBy } from '@neodx/std';\nimport { dirname, relative, sep } from 'pathe';\nimport { createInMemoryDirent } from '../backend/create-in-memory-backend.ts';\nimport type { VfsContext } from './context';\nimport type { VfsContentLike, VfsFileAction } from './types';\n\nexport async function existsVfsPath(ctx: VfsContext, path = '.') {\n const meta = ctx.get(path);\n\n ctx.log.debug('Check exists %s', displayPath(ctx, path));\n if (isKnownDeletedPath(ctx, path)) return false;\n // If we know any non-deleted descendants of this path, then it's exists\n if (meta || getVfsNonDeletedDescendants(ctx, path).length > 0) return true;\n return await ctx.backend.exists(path);\n}\n\nexport async function isVfsFile(ctx: VfsContext, path = '.') {\n const meta = ctx.get(path);\n\n return meta ? !meta.deleted : await ctx.backend.isFile(path);\n}\n\nexport async function isVfsDir(ctx: VfsContext, path = '.') {\n return (\n ctx.getRelativeChanges(path).some(meta => !meta.deleted) || (await ctx.backend.isDir(path))\n );\n}\n\n/**\n * Returns actual children of a directory.\n */\nexport async function readVfsDir(ctx: VfsContext, path = '.') {\n ctx.log.debug('Read dir %s', displayPath(ctx, path));\n const actualChildren = await ctx.backend.readDir(path);\n const changes = ctx.getRelativeChanges(path);\n const isNotDeleted = (name: string) => !isKnownDeletedPath(ctx, name);\n const basePath = ctx.resolve(path);\n const getDirentName = (path: string) => relative(basePath, ctx.resolve(path)).split(sep)[0]!;\n\n return uniqBy(\n [\n ...actualChildren.filter(entry => isNotDeleted(ctx.resolve(path, entry.name))),\n ...changes\n .filter(meta => isNotDeleted(meta.path))\n .map(meta => createInMemoryDirent(getDirentName(meta.path), true))\n .filter(entry => Boolean(entry.name.replaceAll('.', '')))\n ],\n entry => entry.name\n );\n}\n\nexport async function tryReadVfsFile(ctx: VfsContext, path: string): Promise<Buffer | null>;\nexport async function tryReadVfsFile(\n ctx: VfsContext,\n path: string,\n encoding: BufferEncoding\n): Promise<string | null>;\nexport async function tryReadVfsFile(\n ctx: VfsContext,\n path: string,\n encoding?: BufferEncoding\n): Promise<Buffer | string | null> {\n ctx.log.debug('Read %s', displayPath(ctx, path));\n if (!(await isVfsFile(ctx, path))) return null;\n const content = ctx.get(path)?.content ?? (await ctx.backend.read(path));\n\n return encoding ? content!.toString(encoding) : content;\n}\n\nexport async function readVfsFile(ctx: VfsContext, path: string): Promise<Buffer>;\nexport async function readVfsFile(\n ctx: VfsContext,\n path: string,\n encoding: BufferEncoding\n): Promise<string>;\nexport async function readVfsFile(\n ctx: VfsContext,\n path: string,\n encoding?: BufferEncoding\n): Promise<Buffer | string> {\n const content = await tryReadVfsFile(ctx, path, encoding!);\n\n if (content === null) {\n throw new Error(`\"${path}\" is not file`);\n }\n return content;\n}\n\nexport async function writeVfsFile(ctx: VfsContext, path: string, content: VfsContentLike) {\n ctx.log.debug('Write %s', displayPath(ctx, path));\n const actualContent = await tryReadVfsBackendFile(ctx, path);\n\n ensureVfsPath(ctx, ctx.resolve(path));\n if (actualContent && Buffer.from(content).equals(actualContent)) {\n // If content is not changed, then we can just forget about this file\n ctx.unregister(path);\n } else {\n ctx.writePathContent(path, content);\n }\n}\n\nexport async function deleteVfsPath(ctx: VfsContext, path: string) {\n ctx.log.debug('Delete %s', displayPath(ctx, path));\n ctx.deletePath(path, true);\n for (const meta of ctx.getRelativeChanges(path)) {\n ctx.unregister(meta.path);\n }\n const parentDirName = dirname(ctx.resolve(path));\n const children = await readVfsDir(ctx, parentDirName);\n\n // TODO SEC-55 add condition\n if (children.length === 0) {\n await deleteVfsPath(ctx, parentDirName);\n }\n}\n\nexport async function renameVfs(ctx: VfsContext, from: string, ...to: string[]) {\n ctx.log.debug(\n 'Rename %s to %s',\n displayPath(ctx, from),\n to.map(path => displayPath(ctx, path)).join(', ')\n );\n if (!(await existsVfsPath(ctx, from))) {\n ctx.log.debug('Path %s not exists, rename skipped', displayPath(ctx, from));\n return;\n }\n const content = await readVfsFile(ctx, from);\n\n await deleteVfsPath(ctx, from);\n await concurrently(to, path => writeVfsFile(ctx, path, content), 5);\n}\n\nexport async function getVfsActions(ctx: VfsContext): Promise<VfsFileAction[]>;\nexport async function getVfsActions<T extends VfsFileAction['type']>(\n ctx: VfsContext,\n types: T[]\n): Promise<Extract<VfsFileAction, { type: T }>[]>;\nexport async function getVfsActions(ctx: VfsContext, types?: VfsFileAction['type'][]) {\n const changes = await concurrently(\n ctx.getAllDirectChanges(),\n async ({ path, deleted, content, ...meta }): Promise<VfsFileAction | null> => {\n // ctx.log.debug('Resolving required action for %s', displayPath(ctx, path));\n const exists = await ctx.backend.exists(path);\n\n if (deleted && !exists) {\n return null;\n }\n if (deleted) {\n return { ...meta, path, type: 'delete' };\n }\n return {\n ...meta,\n path,\n type: exists ? 'update' : 'create',\n content: content!\n };\n }\n );\n\n // ctx.log.debug('Found %d changes under \"%s\" working directory', changes.length, ctx.path);\n\n return types\n ? changes.filter(action => isTruthy(action) && types.includes(action.type))\n : compact(changes);\n}\n\n/** Guarantees all ancestor directories not deleted */\nexport function ensureVfsPath(ctx: VfsContext, path: string) {\n const parent = dirname(path);\n\n if (parent !== path) {\n ctx.unregister(parent);\n ensureVfsPath(ctx, parent);\n }\n}\n\nexport function getVfsNonDeletedDescendants(ctx: VfsContext, path: string) {\n return ctx.getRelativeChanges(path).filter(meta => !meta.deleted);\n}\n\nexport async function tryReadVfsBackendFile(ctx: VfsContext, path: string) {\n const resolved = ctx.resolve(path);\n\n return (await ctx.backend.isFile(resolved)) ? await ctx.backend.read(resolved) : null;\n}\n\nexport const displayPath = (ctx: VfsContext, path: string) => {\n const prefix =\n ctx.path.length > prefixSize\n ? `${ctx.path.slice(0, prefixSize / 4)}...${ctx.path.slice((-prefixSize * 3) / 4)}`\n : ctx.path;\n\n return `${colors.gray(prefix + sep)}${ctx.relative(path)}`;\n};\n\nconst isDirectDeletedPath = (ctx: VfsContext, path: string) => ctx.get(path)?.deleted;\n/** The directory itself or any of its ancestors is deleted */\nconst isKnownDeletedPath = (ctx: VfsContext, path: string) =>\n isDirectDeletedPath(ctx, path) ||\n ctx\n .relative(path)\n .split('/')\n .filter(path => !path.startsWith('.'))\n .some(path => isDirectDeletedPath(ctx, path));\nconst prefixSize = 28;\n"],"names":["createInMemoryDirent","name","file","symlink","isFile","isDirectory","isSymbolicLink","withTrailingSlash","path","endsWith","pathStartsWith","fullPath","basePath","startsWith","pathStartsBy","createInMemoryFilesRecord","initializer","base","result","value","entries","join","isTypeOfString","Object","assign","existsVfsPath","ctx","meta","get","log","debug","displayPath","isKnownDeletedPath","getVfsNonDeletedDescendants","getRelativeChanges","filter","deleted","length","backend","exists","isVfsFile","isVfsDir","some","isDir","readVfsDir","actualChildren","readDir","changes","isNotDeleted","resolve","getDirentName","relative","split","sep","uniqBy","entry","map","Boolean","replaceAll","tryReadVfsFile","encoding","content","read","toString","readVfsFile","Error","writeVfsFile","actualContent","tryReadVfsBackendFile","ensureVfsPath","parent","dirname","unregister","Buffer","from","equals","writePathContent","deleteVfsPath","deletePath","parentDirName","children","renameVfs","to","concurrently","getVfsActions","types","getAllDirectChanges","type","action","isTruthy","includes","compact","resolved","prefix","prefixSize","slice","colors","gray","isDirectDeletedPath","root","store","Map","Set","has","Array","keys","delete","add","uniq","write","set","__","kind","getStore","getDeleted"],"mappings":"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"}