@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
202 lines (201 loc) • 10.9 kB
TypeScript
import IFolder from "./IFolder";
import IFile from "./IFile";
import DifferenceSet from "./DifferenceSet";
import { FolderDifferenceType } from "./IFolderDifference";
import IStorage from "./IStorage";
import IVersionContent from "./IVersionContent";
export declare const MaxShareableContentStringLength = 65536;
export declare const VersionCoalescingTimeThresholdMs = 10000;
export declare const VersionCoalescingSizeThresholdBytes = 1024;
export declare const VersionCoalescingVersionsToConsider = 100;
export declare const PackContainerFolderHints: string[];
export declare const PackFolderHints: string[];
export declare const AllowedExtensionsSet: Set<string>;
export declare enum EncodingType {
ByteBuffer = 0,
Utf8String = 1
}
export default class StorageUtilities {
static standardFolderDelimiter: string;
private static textEncoder;
/**
* Debug flag: When true, getJsonObjectWithComments will use regular JSON.parse
* instead of comment-json to help isolate memory issues. Set via environment
* variable MCT_BYPASS_COMMENT_JSON=1 or programmatically.
*/
static bypassCommentJson: boolean;
/**
* Counter for tracking how many times comment-json parsing is invoked.
* Useful for debugging memory issues.
*/
static commentJsonParseCount: number;
/**
* Log every Nth comment-json parse call (0 = disabled)
*/
static commentJsonLogFrequency: number;
static isUsableFile(path: string): boolean;
static canIgnoreFileName(fileName: string): boolean;
static canIgnoreFileExtension(extension: string): boolean;
static isIgnorableFolder(folderName: string): boolean;
static getSerializationOfChangeList(versionContentList: IVersionContent[]): string;
static getEncodingByFileName(name: string): EncodingType;
static absolutize(path: string): string;
static stripExtension(path: string): string;
static getUniqueChildFolderName(name: string, folder: IFolder): string;
static ensureEndsDelimited(path: string): string;
static ensureEndsWithDelimiter(path: string): string;
/***
* returns true if IFile argument is a .json file
*/
static isJsonFile(file?: IFile | null): file is IFile;
/***
* Checks binary file contents for a UTF8 Byte Order Mark
*
* falsey contents will return false
*/
static hasUTF8ByteOrderMark(bytes?: Uint8Array | null): boolean;
/***
* Normalizes file contents by converting non-binary contents into binary
*
* falsey content will return as null
*/
static getContentsAsBinary(file: IFile): Uint8Array | null;
static ensureStartsWithDelimiter(path: string): string;
static ensureNotStartsWithDelimiter(path: string): string;
static getRootAndFocusPathFromInputPath(path: string): {
basePath: string;
focusPath: string;
};
static joinPath(pathA: string, pathB: string): string;
static getMimeTypeFromName(name: string): string;
static getMimeType(file: IFile): string;
static isImageMimeType(mimeType: string): boolean;
static getContentAsString(file: IFile): string;
static sortChangeList(changeList: IVersionContent[]): void;
static coalesceVersions(versionList: IVersionContent[]): IVersionContent[];
static getAvailableFolderName(folder: IFolder): string;
static getFileStorageFolder(file: IFile): Promise<IFolder | undefined | string>;
static getContaineredFileLeafPath(path: string | null | undefined): string;
static isMinecraftInternalFolder(folder: IFolder): boolean;
static isContainerFile(path: string): boolean;
static isFileStorageItem(file: IFile): boolean;
static canonicalizeName(name: string): string;
static isPathEqual(pathA: string, pathB: string): boolean;
static canonicalizePath(path: string): string;
static canonicalizePathAsFileName(path: string): string;
static ensureFileNameIsSafe(path: string): string;
static hasPathSeparator(path: string): boolean;
static getLeafName(path: string): string;
static getFolderPath(path: string): string;
static getParentFolderNameFromPath(path: string): string | undefined;
static removeContainerExtension(name: string): string;
static getBaseRelativePath(file: IFile, folder: IFolder): string;
static getBaseFromName(name: string): string;
static convertFolderPlaceholders(path: string): string;
static convertFolderPlaceholdersPartial(path: string, startIndex?: number): string;
/**
* Well-known path token prefixes used in Electron for folder abstraction.
* Maps the token prefix (e.g., "DOCP") to a user-friendly display name.
*/
private static readonly _friendlyTokenNames;
/**
* Strips the trailing random suffix (dash + 6 lowercase chars) that is appended
* to Electron path tokens for uniqueness. For example, "base-packs-4kp0sp" becomes "base-packs".
*/
private static _stripTokenSuffix;
/**
* Converts a path or name containing Electron folder tokens into a user-friendly
* display string. Handles both `<pt_name-random>` project tokens (stripping the
* `<pt_>` wrapper and random suffix) and well-known tokens like `<DOCP>`, `<BDRK>`, etc.
*
* Examples:
* "<pt_base-packs-4kp0sp>" -> "base-packs"
* "<DOCP>" -> "documents"
* "<DOCP>/my-project/" -> "documents/my-project/"
* "Opening <pt_my-addon-ab12cd>..." -> "Opening my-addon..."
*/
static getFriendlyDisplayName(path: string): string;
static getCoreBaseFromName(name: string): string;
static getTypeFromName(name: string): string;
static folderContentsEqual(folderA: IFolder | undefined, folderB: IFolder | undefined, excludingFilesOrFolders?: string[], whitespaceAgnostic?: boolean, ignoreAttributes?: string[], volatilePatterns?: Array<{
pattern: RegExp;
replacement: string;
}>): Promise<{
result: boolean;
reason: string;
}>;
static fileContentsEqual(fileA: IFile | undefined, fileB: IFile | undefined, whitespaceAgnostic?: boolean, ignoreAttributes?: string[], volatilePatterns?: Array<{
pattern: RegExp;
replacement: string;
}>): Promise<boolean>;
static jsonContentsAreEqualIgnoreWhitespace(contentA: string, contentB: string, ignoreAttributes?: string[], volatilePatterns?: Array<{
pattern: RegExp;
replacement: string;
}>): boolean;
/**
* Recursively applies volatile patterns to normalize dynamic content within string values
* @param obj The object to process
* @param patterns Array of regex patterns and their replacements
* @returns A new object with patterns applied to string values
*/
static applyVolatilePatternsToObject(obj: any, patterns: Array<{
pattern: RegExp;
replacement: string;
}>): any;
/**
* Recursively sets attributes to undefined in a JSON object if they match any of the provided attribute names
* @param obj The object to process
* @param attributeNames Array of attribute names to set to undefined
* @returns A new object with specified attributes set to undefined
*/
static removeAttributesFromObject(obj: any, attributeNames: string[]): any;
static stripWhitespace(content: string): string;
static contentsAreEqual(contentA: string | Uint8Array | null, contentB: string | Uint8Array | null): boolean;
static contentsAreEqualIgnoreWhitespace(contentA: string | Uint8Array | null, contentB: string | Uint8Array | null, volatilePatterns?: Array<{
pattern: RegExp;
replacement: string;
}>): boolean;
static getDifferences(original: IFolder, updated: IFolder, includeDeletions: boolean, matchSingleChildFolders: boolean): Promise<DifferenceSet>;
static getFirstFile(folder: IFolder): IFile | undefined;
static addDifferences(differences: DifferenceSet, original: IFolder, updated: IFolder, includeDeletions: boolean, matchSingleFolders: boolean): Promise<FolderDifferenceType>;
static relativizePathToOriginal(original: IFolder, updated: IFolder, path: string): string;
static addDifferencesAsFolderAdd(differences: DifferenceSet, childUpdated: IFolder, original: IFolder, updated: IFolder): Promise<void>;
static addDifferencesAsFolderDelete(differences: DifferenceSet, original: IFolder): Promise<void>;
static isPathRiskyForDelete(path: string): boolean;
static getParentOfParentFolderNamed(folderName: string, folder: IFolder): any;
static getJsonObject(file: IFile): any | undefined;
/**
* Gets the JSON object from a file, preserving any C-style comments (// and /* *\/).
* The returned object contains comment metadata as Symbol properties that will be
* preserved when serializing back with JsonUtilities.stringifyJsonWithComments().
*
* Use this instead of getJsonObject() when you want to preserve comments through
* read/edit/save cycles.
*
* @param file The file to parse
* @returns The parsed JSON object with comment metadata, or undefined if parsing failed
*/
static getJsonObjectWithComments(file: IFile): any | undefined;
static getUniqueFileName(baseName: string, extension: string, folder: IFolder): Promise<string>;
/**
* Write a file to a folder only if it doesn't already exist (prevents overwriting).
* Logs a debug message and returns false when the file is already present.
*/
static writeFileIfNew(folder: IFolder, fileName: string, content: string | Uint8Array): boolean;
/**
* Recursively deep-merges two plain JSON-compatible objects. Values in `override`
* take precedence over `base` for scalar and array keys; nested plain objects are
* merged recursively. Not suitable for Date, RegExp, class instances, etc.
*/
static deepMergeJsonObjects(base: any, override: any): any;
static ensureFilesFromJson(storage: IStorage, json: string | {
[name: string]: object | string;
}): Promise<string | undefined>;
static createStorageFromString(content: string): Promise<string | IStorage>;
static createStorageFromUntrustedString(untrustedContent: string): Promise<string | IStorage>;
static syncFolderTo(source: IFolder, target: IFolder, forceFolders: boolean, forceFileUpdates: boolean, removeOnTarget: boolean, exclude?: string[], include?: string[], messageUpdater?: (message: string) => Promise<void>, dontOverwriteExistingFiles?: boolean, skipFilesAtRoot?: boolean, extractContainers?: boolean): Promise<number>;
static matchesList(name: string, list: string[]): boolean;
static sanitizePathBasic(path: string): string;
static sanitizePath(path: string): string;
static syncFileTo(source: IFile, target: IFile, force: boolean, messageUpdater?: (message: string) => Promise<void>): Promise<boolean>;
}