@softwareventures/maintain-project
Version:
Automatically create and maintain TypeScript projects with standard settings for Software Ventures Limited
80 lines • 2.92 kB
JavaScript
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