UNPKG

fomod

Version:

A library for creating, parsing, editing, and validating XML-based Fomod installers, widely popularized in the Bethesda modding scene

892 lines (875 loc) 57.6 kB
/** A valid tag for an XML-Based Fomod installer */ declare enum TagName { Fomod = "fomod", Config = "config", ModuleName = "moduleName", ModuleImage = "moduleImage", ModuleDependencies = "moduleDependencies", Dependencies = "dependencies", FileDependency = "fileDependency", FlagDependency = "flagDependency", GameDependency = "gameDependency", FOMMDependency = "fommDependency", FOSEDependency = "foseDependency", RequiredInstallFiles = "requiredInstallFiles", File = "file", Folder = "folder", InstallSteps = "installSteps", InstallStep = "installStep", Visible = "visible", OptionalFileGroups = "optionalFileGroups", Group = "group", Plugins = "plugins", Plugin = "plugin", Description = "description", Image = "image", ConditionFlags = "conditionFlags", Flag = "flag", Files = "files", TypeDescriptor = "typeDescriptor", Type = "type", DependencyType = "dependencyType", DefaultType = "defaultType", Patterns = "patterns", Pattern = "pattern", ConditionalFileInstalls = "conditionalFileInstalls" } /** A valid attribute for an XML-Based Fomod installer */ declare enum AttributeName { Color = "colour", Colour = "colour", Path = "path", Position = "position", Height = "height", ShowFade = "showFade", ShowImage = "showImage", Operator = "operator", Source = "source", Destination = "destination", Priority = "priority", AlwaysInstall = "alwaysInstall", InstallIfUsable = "installIfUsable", Order = "order", Name = "name", Type = "type", File = "file", State = "state", Flag = "flag", Value = "value", Version = "version" } /** Describes how the group should behave when allowing users to select its options */ declare enum GroupBehaviorType { /** Users may select or deselect any otherwise-selectable option within the group without restriction. */ SelectAny = "SelectAny", /** Users must select at least one otherwise-selectable option within the group. */ SelectAtLeastOne = "SelectAtLeastOne", /** Users may select no option or a single, otherwise-selectable option within the group. */ SelectAtMostOne = "SelectAtMostOne", /** Users must select exactly one otherwise-selectable option within the group; no more, no less. This is the default behavior. */ SelectExactlyOne = "SelectExactlyOne", /** All options in the group are forcibly selected and cannot be deselected. */ SelectAll = "SelectAll" } /** Describes how an option should behave in regard to user selection */ declare enum OptionType { /** The option will not be selected and cannot be selected. */ NotUsable = "NotUsable", /** Acts the same as `Optional`, except that mod managers may show a warning to the user when selecting this option. This is not universal, though, and the majority of mainstream mod managers at the moment forego this. */ CouldBeUsable = "CouldBeUsable", /** The option will be selectable. This is the default behavior. */ Optional = "Optional", /** The option will be selected by default but may be deselected. */ Recommended = "Recommended", /** The option will be selected by default and cannot be deselected. */ Required = "Required" } /** Describes how the group should behave when allowing users to select its options */ declare enum SortingOrder { /** Items are ordered alphabetically starting with A and ending with Z. This is the default behavior. */ Ascending = "Ascending", /** Items are ordered alphabetically starting with Z and ending with A. */ Descending = "Descending", /** Items are ordered precisely as they appear in the XML (and, consequently, the Set within JS) */ Explicit = "Explicit" } /** A state which this FileDependency expects the file to be in to be satisfied */ declare enum FileDependencyState { /** The file must not exist on the user's system */ Missing = "Missing", /** The file must be on the user's system but NOT loaded by the game */ Inactive = "Inactive", /** The file must be on the user's system and loaded by the game */ Active = "Active" } /** An operator which determines the behavior of the dependency group */ declare enum DependencyGroupOperator { /** The dependency group is satisfied if *any* of its children are satisfied */ Or = "Or", /** The dependency group is only satisfied if **all** of its children are satisfied */ And = "And" } declare enum ModuleNamePosition { /** Positions the title on the left side of the form header. */ Left = "Left", /** Positions the title on the right side of the form header. */ Right = "Right", /** Positions the title on the right side of the image in the form header. */ RightOfImage = "RightOfImage" } declare enum BooleanString { true = "true", false = "false" } interface FomodDocumentConfig { /** [asElement] Whether or to include a third-party schema for Info.xml * * If a string is provided, we'll use that string as the schema location. Otherwise, we'll use the library's default. * * @default true */ includeInfoSchema?: boolean | string; /** [asElement] Whether to move all conditional installs with only a dependency on a single option to the <files> tag of that option * * Note that this may cause slight performance issues with Vortex on slower machines. * * @default false */ flattenConditionalInstalls?: boolean; /** [asElement] Whether to reorganize all conditional installs with no dependencies into the <requiredInstallFiles> tag * * @default false */ flattenConditionalInstallsNoDependencies?: boolean; /** [asElement] Whether to remove conditional installs with no dependencies and no files (has no effect when `flattenConditionalInstallsNoDependencies` is `true`) * * @default true */ removeEmptyConditionalInstalls?: boolean; /** [parse/asElement] String used for the flag value of option dependencies * * @default 'OPTION_SELECTED' */ optionSelectedValue?: string; /** [parse] Whether to attempt to determine if a flag is an option flag to the best of our knowledge * * If `'loose'` is provided, we'll accept any flag name or value so long as it's only set by one option. * * @default true */ parseOptionFlags?: boolean | 'loose'; /** * [asElement] Whether to discard existing option flag names and generate new ones for all options * * @default false */ generateNewOptionFlagNames?: boolean; } declare const DefaultFomodDocumentConfig: { readonly includeInfoSchema: true; readonly flattenConditionalInstalls: false; readonly flattenConditionalInstallsNoDependencies: false; readonly removeEmptyConditionalInstalls: true; readonly optionSelectedValue: "OPTION_SELECTED"; readonly parseOptionFlags: true; readonly generateNewOptionFlagNames: false; }; /** A list of reasons why a Fomod might be invalid * * If you are using this to provide an explanation for end users, it is up to you to provide human-readable translations. */ declare enum InvalidityReason { FomodModuleNameMetadataInvalidPosition = "fomod.module_name_metadata.position", FomodModuleNameMetadataColorHexNotHexNumber = "fomod.module_name_metadata.color_hex.not_hex_number", FomodModuleNameMetadataColorHexNotEvenNumberOfHexDigits = "fomod.module_name_metadata.color_hex.odd_digit_count", FomodModuleImageMetadataShowFadeNotBool = "fomod.module_image_metadata.show_fade.not_boolean", FomodModuleImageMetadataShowImageNotBool = "fomod.module_image_metadata.show_image.not_boolean", DependenciesUnknownOperator = "dependencies.operator.unknown", DependencyFileInvalidState = "dependencies.file.state.unknown", StepUnknownGroupSortingOrder = "step.sorting_order.unknown", GroupUnknownBehaviorType = "group.behavior_type.unknown", GroupUnknownOptionSortingOrder = "group.sorting_order.unknown", OptionTypeDescriptorUnknownOptionType = "option.type_descriptor.option_type.unknown", InstallPriorityNotInteger = "install.priority.not_integer", InstallAlwaysInstallNotBoolean = "install.always_install.not_boolean", InstallInstallIfUsableNotBoolean = "install.install_if_usable.not_boolean" } /** A report detailing what part of a Fomod is invalid */ interface InvalidityReport { /** The reason the item is invalid */ reason: InvalidityReason; /** The value causing the item to be invalid */ offendingValue: string; /** The tree leading up to the most immediate invalid item */ tree: Omit<Verifiable<false>, 'isValid' | 'reasonForInvalidity'>[]; } /** The foundation of a class that can be validated against a schema. * * This model is important because it allows for the parsing of unsafe documents while providing maximum type safety for generated documents. */ declare abstract class Verifiable<TStrict extends boolean> { /** Checks if this item is compliant with the schema. Can be used both for type narrowing and input validation. */ abstract isValid(): this is Verifiable<true>; /** Query the reason why the given item is invalid. Returns `null` if the object is valid. * * This method tends to be very, very, very slow. If you are only interested in whether or not the object is valid, please use `isValid()` instead. * * Depending on how often you expect the object to be invalid, it may be faster to use `isValid()` as a fail-fast check before calling this method. */ abstract reasonForInvalidity(...tree: Omit<Verifiable<false>, 'isValid' | 'reasonForInvalidity'>[]): InvalidityReport | null; } declare const ElementObjectMap: WeakMap<Element, XmlRepresentation<boolean>>; /** A representation of an XML element for use with various Fomod classes. helps to facilitate in-place editing of Fomod documents. * */ declare abstract class XmlRepresentation<TStrict extends boolean> extends Verifiable<TStrict> { static readonly tagName: TagName | TagName[]; abstract readonly tagName: TagName; /** A [weak map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) of documents to this representation's associated element within that document. * * Without this map, in-place editing would be significantly more difficult. */ documentMap: WeakMap<Document, Element>; /** Assigns an element for a document. * * @throws If the tag name of the element does not match the tag name of this class. * @throws If an element has already been assigned for this document * @throws If the element has already been assigned to a different instance of any Fomod class. */ assignElement(element: Element): void; /** Returns the element assigned to the document. Will create a new one if it does not exist. */ getElementForDocument(document: Document): Element; /** Preforms non-serializing operations to associate this object with a document. */ abstract associateWithDocument(document: Document): unknown; abstract decommission?(currentDocument?: Document): unknown; /** Generates an XML element from this object. */ abstract asElement(document: Document, config?: FomodDocumentConfig): Element; static parse(element: Element, config?: FomodDocumentConfig): XmlRepresentation<boolean> | null; } interface FlagInstances { all: Set<FlagInstance<boolean, boolean>>; byName: Map<string | Option<boolean>, Set<FlagInstance<boolean, boolean>>>; } /** A [weak map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) of documents to flag instances within that document. * * This map allows for quick access to all flag instances within a document as well as all flag instances with a given name. */ declare const FlagInstanceStoresByDocument: WeakMap<Document, FlagInstances>; declare class FlagInstance<TIsOption extends boolean, TWrite extends (TIsOption extends true ? false : boolean)> { /** The name of the flag this instance refers to * * Automatically updates the flag instance map when changed. */ private _name; /** The value being checked/set by this instance * * When the flag represents a traditional key-value, this will be a string. When the flag represents an option's select state, this will be `true`. */ usedValue: TIsOption extends true ? true : string; /** Whether this instance is reading or writing the flag value * * When the flag represents an option's select state, this mist be `false` (since you cannot set the value of an option's select state) */ write: TWrite; static isOptionFlagGetter(flag: FlagInstance<boolean, boolean>): flag is FlagInstance<true, false>; static isRegularFlagOrOptionFlagSetter(flag: FlagInstance<boolean, boolean>): flag is FlagInstance<false, boolean>; get name(): TIsOption extends true ? Option<boolean> : string; set name(value: TIsOption extends true ? Option<boolean> : string); /** A list of documents this flag is a part of */ documents: Set<Document>; /** If this flag instance is the setter for an option flag (not the getter, which would make TIsOption = true), * this is a map of documents to the option instance that this flag represents. */ optionFlagOptionByDocument: WeakMap<Document, Option<boolean>>; constructor(_name: TIsOption extends true ? never : string, usedValue: string, write: TWrite, document?: Document); constructor(_name: TIsOption extends true ? Option<boolean> : never, usedValue: true, write: TWrite, document?: Document); /** Attaches this flag instance to a document */ attachDocument(document: Document): void; /** Removes this flag instance from a document */ removeFromDocument(document: Document): void; /** Cleans up the document map */ delete(): void; decommission(currentDocument?: Document): void; associateWithDocument(document: Document): void; } type SuggestedString<T extends string> = string & {} | T; type MaybeStrictString<T extends string, TStrict extends boolean> = TStrict extends true ? T : SuggestedString<T>; type MaybeStrictBoolString<TStrict extends boolean> = MaybeStrictString<BooleanString, TStrict>; type MaybeStrictIntString<TStrict extends boolean> = MaybeStrictString<`${bigint}`, TStrict>; /*** * $$$$$$\ $$\ $$\ $$$$$$$$\ $$\ $$\ * $$ __$$\ \__| $$ | $$ _____|\__|$$ | * $$ / \__|$$\ $$$$$$$\ $$$$$$\ $$ | $$$$$$\ $$ | $$\ $$ | $$$$$$\ * \$$$$$$\ $$ |$$ __$$\ $$ __$$\ $$ |$$ __$$\ $$$$$$\ $$$$$\ $$ |$$ |$$ __$$\ * \____$$\ $$ |$$ | $$ |$$ / $$ |$$ |$$$$$$$$ |\______|$$ __| $$ |$$ |$$$$$$$$ | * $$\ $$ |$$ |$$ | $$ |$$ | $$ |$$ |$$ ____| $$ | $$ |$$ |$$ ____| * \$$$$$$ |$$ |$$ | $$ |\$$$$$$$ |$$ |\$$$$$$$\ $$ | $$ |$$ |\$$$$$$$\ * \______/ \__|\__| \__| \____$$ |\__| \_______| \__| \__|\__| \_______| * $$\ $$ | * \$$$$$$ | * \______/ * $$$$$$\ $$\ $$\ $$\ * \_$$ _| $$ | $$ |$$ | * $$ | $$$$$$$\ $$$$$$$\ $$$$$$\ $$$$$$\ $$ |$$ | * $$ | $$ __$$\ $$ _____|\_$$ _| \____$$\ $$ |$$ | * $$ | $$ | $$ |\$$$$$$\ $$ | $$$$$$$ |$$ |$$ | * $$ | $$ | $$ | \____$$\ $$ |$$\ $$ __$$ |$$ |$$ | * $$$$$$\ $$ | $$ |$$$$$$$ | \$$$$ |\$$$$$$$ |$$ |$$ | * \______|\__| \__|\_______/ \____/ \_______|\__|\__| * * * */ interface InstallInstances { all: Set<Install<boolean>>; bySource: Map<string, Set<Install<boolean>>>; byDestination: Map<string, Set<Install<boolean>>>; } /** A [weak map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) of documents to flag instances within that document. * * This map allows for quick access to all flag instances within a document as well as all flag instances with a given name. */ declare const InstallInstancesByDocument: WeakMap<Document, InstallInstances>; type InstallTagName = TagName.File | TagName.Folder; declare class Install<TStrict extends boolean> extends XmlRepresentation<TStrict> { /** File path relative to the archive root to install this file from. * * Whether a folder is being installed or not will be determined by if the path ends with a slash. It **WILL** cause errors later down the line if the source and destination paths are not the same type. */ fileSource: string; /** File path relative to the archive root to install this file from. If no destination is provided, the file will be installed to the same path as the source. * * Whether a folder is being installed or not will be determined by if the path ends with a slash. It **WILL** cause errors later down the line if the source and destination paths are not the same type. */ fileDestination: string | null; /** The priority of this file install. Higher priority files will be installed first. Must be an integer. * * Defaults to `0`. If the value is `0`, the value will not be written to the element. */ priority: MaybeStrictIntString<TStrict>; /** Whether to always install the file if it is considered "usable" * * @deprecated Has inconsistent behavior between mod managers. Instead, you might consider duplicating the `dependencies` object to specify when a file should be installed. Included for completeness. */ installIfUsable: MaybeStrictBoolString<TStrict>; /** Whether to always install the file, even if the user has not selected it. * * @deprecated Has inconsistent behavior between mod managers. Instead, you might consider removing the `dependencies` object instead. Included for completeness. */ alwaysInstall: MaybeStrictBoolString<TStrict>; static readonly tagName: [TagName.File, TagName.Folder]; tagName: InstallTagName; /** A list of documents this install is a part of */ documents: Set<Document>; isValid(): this is Install<true>; reasonForInvalidity(...tree: Omit<Verifiable<false>, 'isValid' | 'reasonForInvalidity'>[]): InvalidityReport | null; constructor( /** File path relative to the archive root to install this file from. * * Whether a folder is being installed or not will be determined by if the path ends with a slash. It **WILL** cause errors later down the line if the source and destination paths are not the same type. */ fileSource?: string, /** File path relative to the archive root to install this file from. If no destination is provided, the file will be installed to the same path as the source. * * Whether a folder is being installed or not will be determined by if the path ends with a slash. It **WILL** cause errors later down the line if the source and destination paths are not the same type. */ fileDestination?: string | null, /** The priority of this file install. Higher priority files will be installed first. Must be an integer. * * Defaults to `0`. If the value is `0`, the value will not be written to the element. */ priority?: MaybeStrictIntString<TStrict>, document?: Document, /** Whether to always install the file if it is considered "usable" * * @deprecated Has inconsistent behavior between mod managers. Instead, you might consider duplicating the `dependencies` object to specify when a file should be installed. Included for completeness. */ installIfUsable?: MaybeStrictBoolString<TStrict>, /** Whether to always install the file, even if the user has not selected it. * * @deprecated Has inconsistent behavior between mod managers. Instead, you might consider removing the `dependencies` object instead. Included for completeness. */ alwaysInstall?: MaybeStrictBoolString<TStrict>); /** Generates an XML element from this object. */ asElement(document: Document, config?: FomodDocumentConfig): Element; static parse(element: Element, config?: FomodDocumentConfig): Install<boolean>; getElementForDocument(document: Document): Element; assignElement(element: Element): void; /** Attaches this flag instance to a document */ attachDocument(document: Document): void; /** Removes this flag instance from a document */ removeFromDocument(document: Document): void; associateWithDocument(document: Document): void; decommission(currentDocument?: Document): void; } /*** * $$$$$$$$\ $$\ $$\ $$\ $$\ * $$ _____|\__|$$ | $$ | $\ $$ | * $$ | $$\ $$ | $$$$$$\ $$$$$$$\ $$ |$$$\ $$ | $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ * $$$$$\ $$ |$$ |$$ __$$\ $$ _____| $$ $$ $$\$$ |$$ __$$\ \____$$\ $$ __$$\ $$ __$$\ $$ __$$\ $$ __$$\ * $$ __| $$ |$$ |$$$$$$$$ |\$$$$$$\ $$$$ _$$$$ |$$ | \__| $$$$$$$ |$$ / $$ |$$ / $$ |$$$$$$$$ |$$ | \__| * $$ | $$ |$$ |$$ ____| \____$$\ $$$ / \$$$ |$$ | $$ __$$ |$$ | $$ |$$ | $$ |$$ ____|$$ | * $$ | $$ |$$ |\$$$$$$$\ $$$$$$$ | $$ / \$$ |$$ | \$$$$$$$ |$$$$$$$ |$$$$$$$ |\$$$$$$$\ $$ | * \__| \__|\__| \_______|\_______/ \__/ \__|\__| \_______|$$ ____/ $$ ____/ \_______|\__| * $$ | $$ | * $$ | $$ | * \__| \__| */ /** A helper class to represent the <files> element. Contains a list of files to be installed by a dependency or option. */ declare class InstallPatternFilesWrapper<TStrict extends boolean> extends XmlRepresentation<TStrict> { installs: Set<Install<TStrict>>; static tagName: TagName; readonly tagName = TagName.Files; constructor(installs?: Set<Install<TStrict>>); asElement(document: Document, config?: FomodDocumentConfig): Element; isValid(): this is InstallPatternFilesWrapper<true>; static parse(element: Element, config?: FomodDocumentConfig): InstallPatternFilesWrapper<boolean>; reasonForInvalidity(...tree: Omit<Verifiable<false>, 'isValid' | 'reasonForInvalidity'>[]): InvalidityReport | null; associateWithDocument(document: Document): void; decommission(currentDocument?: Document): void; } /*** * $$$$$$\ $$\ $$\ $$\ * \_$$ _| $$ | $$ |$$ | * $$ | $$$$$$$\ $$$$$$$\ $$$$$$\ $$$$$$\ $$ |$$ | * $$ | $$ __$$\ $$ _____|\_$$ _| \____$$\ $$ |$$ | * $$ | $$ | $$ |\$$$$$$\ $$ | $$$$$$$ |$$ |$$ | * $$ | $$ | $$ | \____$$\ $$ |$$\ $$ __$$ |$$ |$$ | * $$$$$$\ $$ | $$ |$$$$$$$ | \$$$$ |\$$$$$$$ |$$ |$$ | * \______|\__| \__|\_______/ \____/ \_______|\__|\__| * * * * $$$$$$$\ $$\ $$\ * $$ __$$\ $$ | $$ | * $$ | $$ | $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$$\ * $$$$$$$ | \____$$\ \_$$ _| \_$$ _| $$ __$$\ $$ __$$\ $$ __$$\ * $$ ____/ $$$$$$$ | $$ | $$ | $$$$$$$$ |$$ | \__|$$ | $$ | * $$ | $$ __$$ | $$ |$$\ $$ |$$\ $$ ____|$$ | $$ | $$ | * $$ | \$$$$$$$ | \$$$$ | \$$$$ |\$$$$$$$\ $$ | $$ | $$ | * \__| \_______| \____/ \____/ \_______|\__| \__| \__| * * * */ /** A helper class to represent the <pattern> element. Contains a list of files to install and a list of dependencies that must first be fulfilled. */ declare class InstallPattern<TStrict extends boolean> extends XmlRepresentation<TStrict> { dependencies: DependenciesGroup<TagName.Dependencies, TStrict>; filesWrapper: InstallPatternFilesWrapper<TStrict>; static tagName: TagName; readonly tagName = TagName.Pattern; constructor(dependencies?: DependenciesGroup<TagName.Dependencies, TStrict>, filesWrapper?: InstallPatternFilesWrapper<TStrict>); asElement(document: Document, config?: FomodDocumentConfig, knownOptions?: Option<boolean>[]): Element; isValid(): this is InstallPattern<true>; static parse(element: Element, config?: FomodDocumentConfig): InstallPattern<boolean>; reasonForInvalidity(...tree: Omit<Verifiable<false>, 'isValid' | 'reasonForInvalidity'>[]): InvalidityReport | null; decommission(currentDocument?: Document): void; associateWithDocument(document: Document): void; } /*** * $$$$$$\ $$\ $$\ $$$$$$$\ $$\ * $$ __$$\ $$ | \__| $$ __$$\ $$ | * $$ / $$ | $$$$$$\ $$$$$$\ $$\ $$$$$$\ $$$$$$$\ $$ | $$ | $$$$$$\ $$$$$$$ |$$\ $$\ * $$ | $$ |$$ __$$\ \_$$ _| $$ |$$ __$$\ $$ __$$\ $$$$$$$\ |$$ __$$\ $$ __$$ |$$ | $$ | * $$ | $$ |$$ / $$ | $$ | $$ |$$ / $$ |$$ | $$ | $$ __$$\ $$ / $$ |$$ / $$ |$$ | $$ | * $$ | $$ |$$ | $$ | $$ |$$\ $$ |$$ | $$ |$$ | $$ | $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ | * $$$$$$ |$$$$$$$ | \$$$$ |$$ |\$$$$$$ |$$ | $$ | $$$$$$$ |\$$$$$$ |\$$$$$$$ |\$$$$$$$ | * \______/ $$ ____/ \____/ \__| \______/ \__| \__| \_______/ \______/ \_______| \____$$ | * $$ | $$\ $$ | * $$ | \$$$$$$ | * \__| \______/ */ /** A single option (or "plugin") for a Fomod. These are typically presented as checkboxes or radio buttons. */ declare class Option<TStrict extends boolean> extends XmlRepresentation<TStrict> { name: string; description: string; image: string | null; typeDescriptor: TypeDescriptor<TStrict>; flagsToSet: Set<FlagSetter>; installsToSet: InstallPattern<TStrict>; static readonly tagName = TagName.Plugin; readonly tagName = TagName.Plugin; constructor(name?: string, description?: string, image?: string | null, typeDescriptor?: TypeDescriptor<TStrict>, flagsToSet?: Set<FlagSetter>, installsToSet?: InstallPattern<TStrict>); asElement(document: Document, config?: FomodDocumentConfig, knownOptions?: Option<boolean>[]): Element; isValid(): this is Option<true>; reasonForInvalidity(...tree: Omit<Verifiable<false>, "isValid" | "reasonForInvalidity">[]): InvalidityReport | null; existingOptionFlagSetterByDocument: WeakMap<Document, FlagSetter>; getOptionFlagSetter(this: Option<boolean>, document: Document, config?: FomodDocumentConfig, knownOptions?: Option<boolean>[]): FlagSetter; static parse(element: Element, config?: FomodDocumentConfig): Option<boolean> | null; decommission(currentDocument?: Document): void; associateWithDocument(document: Document): void; } declare class FlagSetter extends XmlRepresentation<true> { readonly flagInstance: FlagInstance<false, true>; static readonly tagName = TagName.Flag; readonly tagName = TagName.Flag; get name(): string; set name(name: string); get value(): string; set value(value: string); constructor(flagInstance: FlagInstance<false, true>); asElement(document: Document, config?: FomodDocumentConfig): Element; isValid(): this is FlagSetter; reasonForInvalidity(): null; static parse(element: Element, config?: FomodDocumentConfig): FlagSetter | null; decommission(currentDocument?: Document): void; associateWithDocument(document: Document): void; } /*** * $$$$$$$$\ * \__$$ __| * $$ | $$\ $$\ $$$$$$\ $$$$$$\ * $$ | $$ | $$ |$$ __$$\ $$ __$$\ * $$ | $$ | $$ |$$ / $$ |$$$$$$$$ | * $$ | $$ | $$ |$$ | $$ |$$ ____| * $$ | \$$$$$$$ |$$$$$$$ |\$$$$$$$\ * \__| \____$$ |$$ ____/ \_______| * $$\ $$ |$$ | * \$$$$$$ |$$ | * \______/ \__| * $$$$$$$\ $$\ $$\ * $$ __$$\ \__| $$ | * $$ | $$ | $$$$$$\ $$$$$$$\ $$$$$$$\ $$$$$$\ $$\ $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ * $$ | $$ |$$ __$$\ $$ _____|$$ _____|$$ __$$\ $$ |$$ __$$\ \_$$ _| $$ __$$\ $$ __$$\ * $$ | $$ |$$$$$$$$ |\$$$$$$\ $$ / $$ | \__|$$ |$$ / $$ | $$ | $$ / $$ |$$ | \__| * $$ | $$ |$$ ____| \____$$\ $$ | $$ | $$ |$$ | $$ | $$ |$$\ $$ | $$ |$$ | * $$$$$$$ |\$$$$$$$\ $$$$$$$ |\$$$$$$$\ $$ | $$ |$$$$$$$ | \$$$$ |\$$$$$$ |$$ | * \_______/ \_______|\_______/ \_______|\__| \__|$$ ____/ \____/ \______/ \__| * $$ | * $$ | * \__| */ /** Describes the desired `OptionType` for an option * * Supports setting a default type and an optional list of conditions ('patterns') that can change the type. * * @see `OptionType` */ declare class TypeDescriptor<TStrict extends boolean> extends XmlRepresentation<TStrict> { /** The type name descriptor */ defaultTypeNameDescriptor: TypeNameDescriptor<TypeDescriptorTagName, TStrict, false>; patterns: TypeDescriptorPattern<TStrict>[]; static readonly tagName = TagName.TypeDescriptor; readonly tagName = TagName.TypeDescriptor; constructor( /** The type name descriptor */ defaultTypeNameDescriptor?: TypeNameDescriptor<TypeDescriptorTagName, TStrict, false>, patterns?: TypeDescriptorPattern<TStrict>[]); asElement(document: Document, config?: FomodDocumentConfig): Element; static parse(element: Element, config?: FomodDocumentConfig): TypeDescriptor<boolean>; isValid(): this is TypeDescriptor<true>; reasonForInvalidity(...tree: Omit<Verifiable<false>, "isValid" | "reasonForInvalidity">[]): InvalidityReport | null; decommission(currentDocument?: Document): void; associateWithDocument(document: Document): void; } declare class TypeDescriptorPattern<TStrict extends boolean> extends XmlRepresentation<TStrict> { typeNameDescriptor: TypeNameDescriptor<TagName.Type, TStrict, true>; dependencies: DependenciesGroup<TagName.Dependencies, TStrict>; static readonly tagName = TagName.Pattern; readonly tagName = TagName.Pattern; constructor(typeNameDescriptor?: TypeNameDescriptor<TagName.Type, TStrict, true>, dependencies?: DependenciesGroup<TagName.Dependencies, TStrict>); asElement(document: Document, config?: FomodDocumentConfig): Element; static parse(element: Element, config?: FomodDocumentConfig): TypeDescriptorPattern<boolean>; isValid(): this is TypeDescriptorPattern<true>; reasonForInvalidity(...tree: Omit<Verifiable<false>, "isValid" | "reasonForInvalidity">[]): InvalidityReport | null; decommission(currentDocument?: Document): void; associateWithDocument(document: Document): void; } type TypeDescriptorTagName = TagName.Type | TagName.DefaultType; declare class TypeNameDescriptor<TTagName extends TypeDescriptorTagName, TStrict extends boolean, TTagNameIsReadOnly extends boolean = true> extends XmlRepresentation<TStrict> { private _tagName; targetType: MaybeStrictString<OptionType, TStrict>; tagNameIsReadonly: TTagNameIsReadOnly; static readonly tagName: [TagName.Type, TagName.DefaultType]; get tagName(): TTagNameIsReadOnly extends true ? TTagName : TypeDescriptorTagName; set tagName(tagName: TTagNameIsReadOnly extends true ? TTagName : TypeDescriptorTagName); constructor(_tagName: TTagNameIsReadOnly extends true ? TTagName : TypeDescriptorTagName, targetType: MaybeStrictString<OptionType, TStrict>, tagNameIsReadonly: TTagNameIsReadOnly); asElement(document: Document, config?: FomodDocumentConfig): Element; static parse<TTagName extends TypeDescriptorTagName = TypeDescriptorTagName, TTagNameIsReadOnly extends boolean = false>(element: Element, config?: FomodDocumentConfig, tagNameIsReadonly?: TTagNameIsReadOnly): TypeNameDescriptor<TTagName, boolean, TTagNameIsReadOnly>; isValid(): this is TypeNameDescriptor<TTagName, true, TTagNameIsReadOnly>; reasonForInvalidity(...tree: Omit<Verifiable<false>, "isValid" | "reasonForInvalidity">[]): InvalidityReport | null; getElementForDocument(document: Document): Element; assignElement(element: Element): void; decommission(currentDocument?: Document): void; associateWithDocument(document: Document): void; } /** A parent class to all forms of dependency. * * @template TStrict Whether or not to use strict typing for this class. Any data parsed from user input should be considered untrusted and thus `false` should be used. Otherwise, `true` should be used. * * NOTE: Many of the Dependency types cannot be statically validated and thus do not have a `TStrict` parameter. */ declare abstract class Dependency<TStrict extends boolean = boolean> extends XmlRepresentation<TStrict> { abstract asElement(document: Document, config?: FomodDocumentConfig | undefined, knownOptions?: Option<boolean>[]): Element; } type DependencyTagName = TagName.Dependencies | TagName.ModuleDependencies | TagName.Visible; declare class DependenciesGroup<TTagName extends DependencyTagName, TStrict extends boolean> extends Dependency { readonly tagName: TTagName; operator: MaybeStrictString<DependencyGroupOperator, TStrict>; dependencies: Set<ValidDependency<TStrict>>; static readonly tagName: [TagName.Dependencies, TagName.ModuleDependencies, TagName.Visible]; constructor(tagName: TTagName, operator?: MaybeStrictString<DependencyGroupOperator, TStrict>, dependencies?: Set<ValidDependency<TStrict>>); isValid(): this is DependenciesGroup<TTagName, true>; reasonForInvalidity(...tree: Omit<Verifiable<false>, "isValid" | "reasonForInvalidity">[]): InvalidityReport | null; associateWithDocument(document: Document): void; asElement(document: Document, config?: FomodDocumentConfig, knownOptions?: Option<boolean>[]): Element; static parse<TTagName extends DependencyTagName = DependencyTagName>(element: Element, config?: FomodDocumentConfig): DependenciesGroup<TTagName, false>; decommission(currentDocument?: Document): void; } declare class FileDependency<TStrict extends boolean> extends Dependency<TStrict> { filePath: string; desiredState: MaybeStrictString<FileDependencyState, TStrict>; static readonly tagName = TagName.FileDependency; readonly tagName = TagName.FileDependency; constructor(filePath?: string, desiredState?: MaybeStrictString<FileDependencyState, TStrict>); isValid(): this is FileDependency<true>; reasonForInvalidity(...tree: Omit<Verifiable<false>, 'isValid' | 'reasonForInvalidity'>[]): InvalidityReport | null; associateWithDocument(document: Document): void; asElement(document: Document): Element; static parse(element: Element, config?: FomodDocumentConfig): FileDependency<false>; decommission: undefined; } /** Common parent for version check dependencies to reduce code duplication. * * Version dependencies work as a minimum value dependency. [SemVer](https://semver.org/) is used for comparisons. */ declare abstract class VersionDependency extends Dependency { /** The version to use in the comparison * * Version dependencies work as a minimum value dependency. [SemVer](https://semver.org/) is used for comparisons. */ desiredVersion: string; constructor( /** The version to use in the comparison * * Version dependencies work as a minimum value dependency. [SemVer](https://semver.org/) is used for comparisons. */ desiredVersion?: string); isValid(): this is VersionDependency; asElement(document: Document): Element; static parse(element: Element, config?: FomodDocumentConfig): ScriptExtenderVersionDependency | GameVersionDependency | ModManagerVersionDependency | null; decommission: undefined; reasonForInvalidity(): null; associateWithDocument(document: Document): void; } /** A dependency on the version of the game. * * Version dependencies work as a minimum value dependency. [SemVer](https://semver.org/) is used for comparisons. * * Can be useful in a number of circumstances where the game executable version matters, such as determining what version of a script extender plugin to install. */ declare class GameVersionDependency extends VersionDependency { static readonly tagName = TagName.GameDependency; readonly tagName = TagName.GameDependency; constructor(desiredVersion?: string); static parse(element: Element, config?: FomodDocumentConfig): GameVersionDependency; } /** A dependency on the version of the installed script extender. * * Version dependencies work as a minimum value dependency. [SemVer](https://semver.org/) is used for comparisons. * * Can be useful in a number of circumstances where the script extender version matters, such as determining if a mod is compatible with the given version. */ declare class ScriptExtenderVersionDependency extends VersionDependency { static readonly tagName = TagName.FOSEDependency; readonly tagName = TagName.FOSEDependency; constructor(desiredVersion?: string); static parse(element: Element, config?: FomodDocumentConfig): ScriptExtenderVersionDependency; } /** A dependency on the version of the mod manager. * * Version dependencies work as a minimum value dependency. [SemVer](https://semver.org/) is used for comparisons. * * @deprecated Should generally not be used as the value is inconsistent between mod managers. Included for completeness. */ declare class ModManagerVersionDependency extends VersionDependency { static readonly tagName = TagName.FOMMDependency; readonly tagName = TagName.FOMMDependency; constructor(desiredVersion?: string); static parse(element: Element, config?: FomodDocumentConfig): ModManagerVersionDependency; } declare class FlagDependency extends Dependency { static readonly tagName = TagName.FlagDependency; readonly tagName = TagName.FlagDependency; protected readonly flagInstance: FlagInstance<boolean, false>; get flagKey(): string | Option<boolean>; set flagKey(value: string | Option<boolean>); get desiredValue(): string | true; set desiredValue(value: string | true); constructor(flagName?: string, desiredValue?: string); constructor(flagName: Option<boolean>, desiredValue: true); isValid(): this is FlagDependency; reasonForInvalidity(): null; associateWithDocument(document: Document): void; decommission(currentDocument?: Document): void; asElement(document: Document, config?: FomodDocumentConfig, knownOptions?: Option<boolean>[]): Element; static parse(element: Element, config?: FomodDocumentConfig): FlagDependency; } type ValidDependency<TStrict extends boolean> = FileDependency<TStrict> | FlagDependency | GameVersionDependency | ScriptExtenderVersionDependency | ModManagerVersionDependency | DependenciesGroup<DependencyTagName, TStrict>; declare class Group<TStrict extends boolean> extends XmlRepresentation<TStrict> { name: string; behaviorType: MaybeStrictString<GroupBehaviorType, TStrict>; sortingOrder: MaybeStrictString<SortingOrder, TStrict>; options: Set<Option<TStrict>>; static readonly tagName = TagName.Group; readonly tagName = TagName.Group; constructor(name?: string, behaviorType?: MaybeStrictString<GroupBehaviorType, TStrict>, sortingOrder?: MaybeStrictString<SortingOrder, TStrict>, options?: Set<Option<TStrict>>); asElement(document: Document, config?: FomodDocumentConfig, knownOptions?: Option<boolean>[]): Element; isValid(): this is Group<true>; reasonForInvalidity(...tree: Omit<Verifiable<false>, 'isValid' | 'reasonForInvalidity'>[]): InvalidityReport | null; gatherOptions(): Option<TStrict>[]; static parse(element: Element, config?: FomodDocumentConfig): Group<boolean>; decommission(currentDocument?: Document): void; associateWithDocument(document: Document): void; } declare class Step<TStrict extends boolean> extends XmlRepresentation<TStrict> { name: string; sortingOrder: MaybeStrictString<typeof SortingOrder[keyof typeof SortingOrder], TStrict>; groups: Set<Group<TStrict>>; visibilityDeps: DependenciesGroup<TagName.Visible, TStrict>; static readonly tagName = TagName.InstallStep; readonly tagName = TagName.InstallStep; constructor(name?: string, sortingOrder?: MaybeStrictString<typeof SortingOrder[keyof typeof SortingOrder], TStrict>, groups?: Set<Group<TStrict>>, visibilityDeps?: DependenciesGroup<TagName.Visible, TStrict>); asElement(document: Document, config?: FomodDocumentConfig, knownOptions?: Option<boolean>[]): Element; isValid(): this is Step<true>; reasonForInvalidity(...tree: Omit<Verifiable<false>, 'isValid' | 'reasonForInvalidity'>[]): InvalidityReport | null; gatherOptions(): Option<TStrict>[]; static parse(element: Element, config?: FomodDocumentConfig): Step<boolean>; decommission(currentDocument?: Document | undefined): void; associateWithDocument(document: Document): void; } interface ModuleImageMetadata<TStrict extends boolean> { showFade?: MaybeStrictBoolString<TStrict>; showImage?: MaybeStrictBoolString<TStrict>; height?: MaybeStrictIntString<TStrict>; } interface ModuleNameMetadata<TStrict extends boolean> { position?: MaybeStrictString<ModuleNamePosition, TStrict>; /** Must be an XML-valid hex string. XML-valid hex strings accept the standard `1234567890ABCDEF` range and the length must be even * * Should ideally appear as a 6-digit hex string, however this is not enforced by the schema. */ colour?: string; } /** A FOMOD installer in its entirety. * * @template TStrict Whether or not to use strict typing for this class. Any data parsed from user input should be considered untrusted and thus `false` should be used. Otherwise, `true` should be used. */ declare class Fomod<TStrict extends boolean> extends XmlRepresentation<TStrict> { /** The name of the FOMOD. Must be specified in the installer however can be an empty string. * * Note that Info.xml also has its own name. */ moduleName: string; moduleImage: string | null; /** Dependencies required for this FOMOD to be shown to the user. * * Mod managers will show the user an error message if attempting to install a FOMOD that does not meet the requirements specified here. */ moduleDependencies: DependenciesGroup<TagName.ModuleDependencies, TStrict>; /** Top-level file installs for the FOMOD * * Covers both the `requiredInstallFiles` and `conditionalFileInstalls` tags. */ installs: Set<Install<TStrict> | InstallPattern<TStrict>>; sortingOrder: MaybeStrictString<SortingOrder, TStrict>; steps: Set<Step<TStrict>>; /** Unused metadata for `moduleName`. Included for completeness. * * @deprecated */ moduleNameMetadata: (TStrict extends true ? Record<never, string> : Record<string, string>) & ModuleNameMetadata<TStrict>; /** Unused metadata for `moduleImage`. Included for completeness. * * @deprecated */ moduleImageMetadata: (TStrict extends true ? Record<never, string> : Record<Exclude<string, 'path'>, string>) & ModuleImageMetadata<TStrict>; static readonly tagName = TagName.Config; readonly tagName = TagName.Config; constructor( /** The name of the FOMOD. Must be specified in the installer however can be an empty string. * * Note that Info.xml also has its own name. */ moduleName?: string, moduleImage?: string | null, /** Dependencies required for this FOMOD to be shown to the user. * * Mod managers will show the user an error message if attempting to install a FOMOD that does not meet the requirements specified here. */ moduleDependencies?: DependenciesGroup<TagName.ModuleDependencies, TStrict>, /** Top-level file installs for the FOMOD * * Covers both the `requiredInstallFiles` and `conditionalFileInstalls` tags. */ installs?: Set<Install<TStrict> | InstallPattern<TStrict>>, sortingOrder?: MaybeStrictString<SortingOrder, TStrict>, steps?: Set<Step<TStrict>>, /** Unused metadata for `moduleName`. Included for completeness. * * @deprecated */ moduleNameMetadata?: (TStrict extends true ? Record<never, string> : Record<string, string>) & ModuleNameMetadata<TStrict>, /** Unused metadata for `moduleImage`. Included for completeness. * * @deprecated */ moduleImageMetadata?: (TStrict extends true ? Record<never, string> : Record<Exclude<string, 'path'>, string>) & ModuleImageMetadata<TStrict>); isValid(): this is Fomod<true>; reasonForInvalidity(...tree: Omit<Verifiable<false>, "isValid" | "reasonForInvalidity">[]): InvalidityReport | null; asElement(document: Document, config?: FomodDocumentConfig, knownOptions?: Option<boolean>[]): Element; gatherOptions(): Option<TStrict>[]; static parse(element: Element, config?: FomodDocumentConfig): Fomod<boolean>; decommission(currentDocument?: Document): void; associateWithDocument(document: Document): void; } declare enum DependencyType { Group = "group", File = "file", Flag = "flag", ScriptExtenderVersion = "fose", GameVersion = "game", ModManagerVersion = "fomm" } interface DependencyJsonItemBase<TSerializable extends boolean> { type: DependencyType; } interface DependenciesJsonGroup<TSerializable extends boolean> extends DependencyJsonItemBase<TSerializable> { type: DependencyType.Group; dependencies: DependenciesJsonItem<TSerializable>[]; operator: DependencyGroupOperator; tagName: typeof DependenciesGroup.tagName extends Array<infer T> ? T : never; } interface DependenciesJsonFile extends DependencyJsonItemBase<boolean> { type: DependencyType.File; path: string; state: FileDependencyState; } interface DependenciesJsonFlag<TSerializable extends boolean> extends DependencyJsonItemBase<TSerializable> { type: DependencyType.Flag; flag: string | (TSerializable extends true ? never : Option<boolean>); value: string | (TSerializable extends true ? never : true); isOptionFlag: boolean; } interface DependenciesJsonScriptExtender extends DependencyJsonItemBase<boolean> { type: DependencyType.ScriptExtenderVersion; version: string; } interface DependenciesJsonGameVersion extends DependencyJsonItemBase<boolean> { type: DependencyType.GameVersion; version: string; } interface DependenciesJsonModManager extends DependencyJsonItemBase<boolean> { type: DependencyType.ModManagerVersion; version: string; } type DependenciesJsonItem<TSerializable extends boolean> = DependenciesJsonGroup<TSerializable> | DependenciesJsonFile | DependenciesJsonFlag<TSerializable> | DependenciesJsonScriptExtender | DependenciesJsonGameVersion | DependenciesJsonModManager; declare function jsonifyDependencyElements(elements: Iterable<ValidDependency<true>>, serializable: false, document?: Document): DependenciesJsonItem<false>[]; declare function jsonifyDependencyElements(elements: Iterable<ValidDependency<true>>, serializable: true, document: Document): DependenciesJsonItem<true>[]; declare function jsonifyDependencyElements<TSerializable extends true | false>(elements: Iterable<ValidDependency<true>>, serializable: TSerializable, document: Document | (TSerializable extends true ? never : undefined)): DependenciesJsonItem<TSerializable>[]; declare function jsonifyDependencyElement(dependency: ValidDependency<true>, serializable: false, document?: Document): DependenciesJsonItem<false>; declare function jsonifyDependencyElement(dependency: ValidDependency<true>, serializable: true, document: Document): DependenciesJsonItem<true>; declare function jsonifyDependencyElement<TSerializable extends boolean>(dependency: ValidDependency<true>, serializable: TSerializable, document: Document | (TSerializable extends true ? never : undefined)): DependenciesJsonItem<TSerializable>; declare function jsonifyDependenciesGroup(dependencyGroup: DependenciesGroup<DependencyTagName, true>, serializable: false, document?: undefined): DependenciesJsonGroup<false>; declare function jsonifyDependenciesGroup(dependencyGroup: DependenciesGroup<DependencyTagName, true>, serializable: true, document: Document): DependenciesJsonGroup<true>; declare function jsonifyDependenciesGroup<TSerializable extends boolean>(dependencyGroup: DependenciesGroup<DependencyTagName, true>, serializable: TSerializable, document: Document | (TSerializable extends true ? never : undefined)): DependenciesJsonGroup<TSerializable>; declare function jsonifyFileDependency(file: FileDependency<true>): DependenciesJsonFile; declare function jsonifyFlagDependency(flagDependency: FlagDependency, serializable: false, document?: undefined): DependenciesJsonFlag<false>; declare function jsonifyFlagDependency(flagDependency: FlagDependency, serializable: true, document: Document): DependenciesJsonFlag<true>; declare function jsonifyFlagDependency<TSerializable extends boolean>(flag