@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
508 lines (507 loc) • 17.8 kB
JavaScript
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const StorageUtilities_1 = __importDefault(require("./StorageUtilities"));
const Utilities_1 = __importDefault(require("./../core/Utilities"));
const AllFolderFileIterator_1 = __importDefault(require("./AllFolderFileIterator"));
const Log_1 = __importDefault(require("../core/Log"));
const ste_events_1 = require("ste-events");
class FolderBase {
get ensuredName() {
return this.name;
}
isDisposed = false;
#lastLoadedOrSaved;
manager;
#onFolderMoved = new ste_events_1.EventDispatcher();
#onChildFolderMoved = new ste_events_1.EventDispatcher();
errorStatus;
get onFolderMoved() {
return this.#onFolderMoved.asEvent();
}
get onChildFolderMoved() {
return this.#onChildFolderMoved.asEvent();
}
get isLoaded() {
return this.#lastLoadedOrSaved !== null;
}
get canIgnore() {
return StorageUtilities_1.default.isIgnorableFolder(this.name);
}
get allFiles() {
let parentFolder = this;
return {
[Symbol.asyncIterator]() {
return new AllFolderFileIterator_1.default(parentFolder);
},
};
}
get folderCount() {
let i = 0;
for (const folderName in this.folders) {
if (this.folders[folderName]) {
i++;
}
}
return i;
}
get fileCount() {
let i = 0;
// eslint-disable-next-line
for (const fileName in this.files) {
if (this.files[fileName]) {
i++;
}
}
return i;
}
get storageRelativePath() {
if (this.parentFolder === null) {
return "/";
}
else {
return this.parentFolder.storageRelativePath + this.name + "/";
}
}
get lastLoadedOrSaved() {
return this.#lastLoadedOrSaved;
}
get fullPath() {
return this.storageRelativePath;
}
get extendedPath() {
let start = "";
if (this.storage.storagePath) {
start = this.storage.storagePath;
}
let result = start + this.fullPath;
if (!result.endsWith(this.storage.folderDelimiter)) {
result += this.storage.folderDelimiter;
}
return result;
}
constructor() {
this.#lastLoadedOrSaved = null;
}
updateLastLoadedOrSaved() {
this.#lastLoadedOrSaved = new Date();
}
getFolderRelativePath(toFolder) {
if (toFolder.storage !== this.storage && this.storage.storagePath) {
const parentPath = toFolder.storageRelativePath;
if (parentPath &&
this.extendedPath &&
this.extendedPath.startsWith(parentPath) &&
StorageUtilities_1.default.ensureEndsWithDelimiter(parentPath)) {
const subPath = this.extendedPath.substring(parentPath.length - 1);
return subPath;
}
return this.extendedPath;
}
else if (this === toFolder) {
return "/";
}
else if (this.parentFolder === null) {
return undefined;
}
else {
const result = this.parentFolder.getFolderRelativePath(toFolder);
if (result === undefined) {
return undefined;
}
return result + this.name + "/";
}
}
dispose() {
this.manager = undefined;
if (this.folders) {
for (const folderName in this.folders) {
const folder = this.folders[folderName];
if (folder) {
folder.dispose();
this.folders[folderName] = undefined;
}
}
}
if (this.files) {
for (const fileName in this.files) {
const file = this.files[fileName];
if (file) {
file.dispose();
this.files[fileName] = undefined;
}
}
}
this.isDisposed = true;
}
async setStructureFromFileList(fileList) {
this.updateLastLoadedOrSaved();
for (const file of fileList) {
let folderPath = StorageUtilities_1.default.getFolderPath(file);
if (folderPath) {
folderPath = StorageUtilities_1.default.ensureEndsDelimited(folderPath);
if (folderPath.length > 2) {
const folder = (await this.ensureFolderFromRelativePath(folderPath, true));
folder.updateLastLoadedOrSaved();
let parentFolder = folder.parentFolder;
while (parentFolder && parentFolder !== this) {
parentFolder.updateLastLoadedOrSaved();
parentFolder = parentFolder.parentFolder;
}
}
await this.ensureFileFromRelativePath(file, true);
}
}
}
isSameFolder(newFolderStorageRelativePath) {
if (StorageUtilities_1.default.canonicalizePath(newFolderStorageRelativePath) ===
StorageUtilities_1.default.canonicalizePath(this.storageRelativePath)) {
return true;
}
return false;
}
_addExistingFolderToParent(folder) {
const nameCanon = StorageUtilities_1.default.canonicalizeName(folder.name);
if (Utilities_1.default.isUsableAsObjectKey(nameCanon)) {
this.folders[nameCanon] = folder;
}
}
_removeExistingFolderFromParent(folder) {
const nameCanon = StorageUtilities_1.default.canonicalizeName(folder.name);
if (Utilities_1.default.isUsableAsObjectKey(nameCanon)) {
this.folders[nameCanon] = undefined;
}
}
folderExists(name) {
if (this.isDisposed) {
Log_1.default.throwIsDisposed();
}
const nameCanon = StorageUtilities_1.default.canonicalizeName(name);
return !Utilities_1.default.isNullOrUndefined(this.folders[nameCanon]);
}
fileExists(name) {
if (this.isDisposed) {
Log_1.default.throwIsDisposed();
}
const nameCanon = StorageUtilities_1.default.canonicalizeName(name);
return !Utilities_1.default.isNullOrUndefined(this.files[nameCanon]);
}
async deleteFileFromRelativePath(path) {
path = this.canonicalizePath(path);
const file = await this.getFileFromRelativePath(path);
if (file !== undefined) {
return await file.deleteThisFile();
}
return false;
}
canonicalizePath(path) {
return path.replace(/\\/g, "/");
}
async getFileFromRelativePath(path) {
if (this.isDisposed) {
Log_1.default.throwIsDisposed();
}
if (path.length < 2) {
throw Error("Path is too short.");
}
path = this.canonicalizePath(path);
if (path[0] !== "/") {
throw Error("Storage relative path '" + path + "' is not in the right format.");
}
await this.ensureExists();
await this.load(false);
const nextSlash = path.indexOf("/", 1);
if (nextSlash < 0) {
const fileName = path.substring(1, path.length);
return this.files[StorageUtilities_1.default.canonicalizeName(fileName)];
}
else {
const folderName = path.substring(1, nextSlash);
const folder = this.folders[StorageUtilities_1.default.canonicalizeName(folderName)];
if (folder === undefined || folder === null) {
return undefined;
}
return await folder.getFileFromRelativePath(path.substring(nextSlash, path.length));
}
}
clearAllManagers() {
if (this.manager) {
this.manager = undefined;
}
for (const fileName in this.files) {
const file = this.files[fileName];
if (file) {
file.manager = undefined;
}
}
for (const folderName in this.folders) {
const folder = this.folders[folderName];
if (folder) {
folder.clearAllManagers();
}
}
}
async getFolderFromRelativePath(path) {
if (this.isDisposed) {
Log_1.default.throwIsDisposed();
}
if (path === "/" || path === "\\") {
return this;
}
if (path.length < 2) {
throw Error("Path is too short.");
}
path = this.canonicalizePath(path);
if (path[0] !== "/") {
throw Error("Storage relative path '" + path + "' is not in the right format.");
}
await this.ensureExists();
await this.load(false);
const nextSlash = path.indexOf("/", 1);
if (nextSlash < 0) {
const folderName = path.substring(1, path.length);
return this.folders[StorageUtilities_1.default.canonicalizeName(folderName)];
}
else {
let folderName = path.substring(1, nextSlash);
folderName = StorageUtilities_1.default.canonicalizeName(folderName);
const folder = this.folders[folderName];
if (folder === undefined || folder === null) {
return undefined;
}
const nextPath = path.substring(nextSlash, path.length);
if (nextPath === "/" || nextPath === "\\") {
return folder;
}
return await folder.getFolderFromRelativePath(nextPath);
}
}
getFolderByIndex(index) {
let curIndex = 0;
for (const folderName in this.folders) {
const folder = this.folders[folderName];
if (folder && curIndex === index) {
return folder;
}
if (folder) {
curIndex++;
}
}
return undefined;
}
getSortedFolderKeys() {
return Object.keys(this.folders).sort();
}
getSortedFileKeys() {
return Object.keys(this.files).sort();
}
getSummary() {
let str = "P: " + this.fullPath + " FO:";
for (const folderName in this.folders) {
str += " " + folderName;
}
str += " FI:";
for (const fileName in this.files) {
str += " " + fileName;
}
return str;
}
getFolderFromRelativePathLocal(path) {
if (this.isDisposed) {
Log_1.default.throwIsDisposed();
}
if (path === "/" || path === "\\") {
return this;
}
if (path.length < 2) {
throw Error("Path is too short.");
}
path = this.canonicalizePath(path);
if (path[0] !== "/") {
throw Error("Storage relative path '" + path + "' is not in the right format.");
}
const nextSlash = path.indexOf("/", 1);
if (nextSlash < 0) {
const folderName = path.substring(1, path.length);
return this.folders[StorageUtilities_1.default.canonicalizeName(folderName)];
}
else {
const folderName = path.substring(1, nextSlash);
let folder = this.folders[StorageUtilities_1.default.canonicalizeName(folderName)];
if (folder === undefined || folder === null) {
if (folderName.endsWith("#")) {
const storageFile = this.files[StorageUtilities_1.default.canonicalizeName(folderName.substring(0, folderName.length - 1))];
if (storageFile) {
if (storageFile.fileContainerStorage) {
folder = storageFile.fileContainerStorage.rootFolder;
}
}
}
if (folder === undefined || folder === null) {
return undefined;
}
}
const nextPath = path.substring(nextSlash, path.length);
if (nextPath === "/" || nextPath === "\\") {
return folder;
}
return folder.getFolderFromRelativePathLocal(nextPath);
}
}
async saveAll(force) {
// Log.verbose("Saving all at " + this.storageRelativePath);
if (this.isDisposed) {
Log_1.default.throwIsDisposed();
}
for (const fileName in this.files) {
const file = this.files[fileName];
if (file !== undefined && (file.needsSave || force)) {
await file.saveContent(force);
}
}
for (const folderName in this.folders) {
const folder = this.folders[folderName];
if (folder !== undefined && !folder.errorStatus) {
await folder.saveAll(force);
}
}
return true;
}
async ensureFolderFromRelativePath(path, ignoreLoad) {
if (this.isDisposed) {
Log_1.default.throwIsDisposed();
}
if (path === "/" || path === "\\") {
return this;
}
if (path.startsWith("./")) {
path = path.substring(1);
}
path = this.canonicalizePath(path);
if (path[path.length - 1] !== "/") {
path = path + "/";
}
if (path[0] !== "/") {
throw Error("Storage relative path '" + path + "' is not in the right format.");
}
if (!ignoreLoad) {
await this.ensureExists();
await this.load(false);
}
const nextSlash = path.indexOf("/", 1);
if (nextSlash < 0) {
throw new Error("Unexpected path format error");
}
else {
const folderName = path.substring(1, nextSlash);
const folder = this.ensureFolder(folderName);
if (nextSlash === path.length - 1) {
return folder;
}
else {
return folder.ensureFolderFromRelativePath(path.substring(nextSlash, path.length), ignoreLoad);
}
}
}
async ensureFileFromRelativePath(path, ignoreLoad) {
if (this.isDisposed) {
Log_1.default.throwIsDisposed();
}
if (path.length < 2) {
throw Error("Path is too short.");
}
path = this.canonicalizePath(path);
if (path[0] !== "/") {
throw Error("Storage relative path '" + path + "' is not in the right format.");
}
await this.ensureExists();
if (!ignoreLoad) {
await this.load(false);
}
const nextSlash = path.indexOf("/", 1);
if (nextSlash < 0) {
const file = this.ensureFile(path.substring(1, path.length));
return file;
}
else {
const folderName = path.substring(1, nextSlash);
const folder = this.ensureFolder(folderName);
const file = await folder.ensureFileFromRelativePath(path.substring(nextSlash, path.length), ignoreLoad);
return file;
}
}
async deleteFile(name) {
const nameCanon = StorageUtilities_1.default.canonicalizeName(name);
const file = this.files[nameCanon];
if (file !== undefined) {
return await file.deleteThisFile();
}
this.files[nameCanon] = undefined;
return false;
}
removeFolder(name) {
const nameCanon = StorageUtilities_1.default.canonicalizeName(name);
if (!Utilities_1.default.isUsableAsObjectKey(nameCanon)) {
throw new Error();
}
const exists = this.folders[nameCanon] !== undefined;
this.folders[nameCanon] = undefined;
return exists;
}
async rename(name) {
let targetPath = name;
if (this.parentFolder !== null) {
targetPath = this.storage.joinPath(this.parentFolder.storageRelativePath, targetPath);
}
return await this.moveTo(targetPath);
}
async recursiveDeleteThisFolder() {
let isAllDeletes = await this.recursiveDeleteContentsOfThisFolder();
this.removeMeFromParent();
return isAllDeletes;
}
async recursiveDeleteContentsOfThisFolder() {
let isAllDeletes = true;
await this.load(true);
for (const folderName in this.folders) {
const folder = this.folders[folderName];
if (folder) {
if (!(await folder.deleteThisFolder())) {
isAllDeletes = false;
}
}
}
for (const fileName in this.files) {
const file = this.files[fileName];
if (file) {
if (!(await file.deleteThisFile(true))) {
isAllDeletes = false;
}
}
}
return isAllDeletes;
}
notifyFolderMoved(folderMove) {
this.#onFolderMoved.dispatch(this, folderMove);
if (this.parentFolder) {
this.parentFolder.notifyChildFolderMoved(folderMove);
}
this.storage.notifyFolderMoved(folderMove);
}
notifyChildFolderMoved(folderMove) {
this.#onChildFolderMoved.dispatch(this, folderMove);
if (this.parentFolder) {
this.parentFolder.notifyChildFolderMoved(folderMove);
}
}
removeMeFromParent() {
if (this.parentFolder) {
this.parentFolder.removeFolder(this.name);
}
}
}
exports.default = FolderBase;