UNPKG

@softwareventures/maintain-project

Version:

Automatically create and maintain TypeScript projects with standard settings for Software Ventures Limited

80 lines 2.92 kB
import { first, tail } from "@softwareventures/array"; import { chain } from "@softwareventures/chain"; import { failure, mapFailure, mapFailureFn, mapResultFn, success } from "../result/result.js"; import { insert as mapInsert } from "../collections/maps.js"; import { emptyDirectory } from "./directory.js"; import { resolvePathSegments } from "./path.js"; export function readFileNode(root, path) { const segments = resolvePathSegments(path); if (segments == null) { return failure([{ type: "invalid-path", path }]); } return readFileNodeInternal(root, segments); } function readFileNodeInternal(root, path) { const entryName = first(path); const rest = tail(path); if (entryName == null) { return success(root); } else if (rest.length === 0) { return success(root); } else if (root.type !== "directory") { return failure([{ type: "not-a-directory", path: entryName }]); } const entry = root.entries.get(entryName); if (entry == null) { return failure([{ type: "file-not-found", path: entryName }]); } else { return mapFailure(readFileNodeInternal(entry, rest), reason => ({ ...reason, path: `${entryName}/${reason.path}` })); } } export function insert(root, path, node) { if (root.type !== "directory") { return failure([{ type: "not-a-directory", path: "" }]); } const segments = resolvePathSegments(path); if (segments == null) { return failure([{ type: "invalid-path", path }]); } return insertInternal(root, segments, node); } export function insertSubdirectory(root, path) { return insert(root, path, emptyDirectory); } function insertInternal(root, path, file) { const entryName = first(path); if (entryName == null) { if (file.type === "directory") { return success(root); } else { return failure([{ type: "file-exists", path: "" }]); } } const defaultEntry = path.length > 1 ? emptyDirectory : undefined; const existingEntry = root.entries.get(entryName) ?? defaultEntry; if (existingEntry == null) { return success({ ...root, entries: mapInsert(root.entries, entryName, file) }); } else if (path.length === 1 && file.type !== "directory") { return failure([{ type: "file-exists", path: entryName }]); } else if (existingEntry.type !== "directory") { return failure([{ type: "not-a-directory", path: entryName }]); } else { return chain(insertInternal(existingEntry, tail(path), file)) .map(mapFailureFn(reason => ({ ...reason, path: `${entryName}/${reason.path}` }))) .map(mapResultFn(newEntry => ({ ...root, entries: mapInsert(root.entries, entryName, newEntry) }))).value; } } //# sourceMappingURL=file-node.js.map