mirror of
https://github.com/Kir-Antipov/mc-publish.git
synced 2024-11-25 09:51:01 -05:00
Implemented logic to work with Fabric dependencies
This commit is contained in:
parent
e8fdb3c1fa
commit
26ea239670
2 changed files with 178 additions and 0 deletions
95
src/loaders/fabric/fabric-dependency.ts
Normal file
95
src/loaders/fabric/fabric-dependency.ts
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
import { Dependency, createDependency } from "@/dependencies";
|
||||||
|
import { PlatformType } from "@/platforms";
|
||||||
|
import { $i } from "@/utils/collections";
|
||||||
|
import { FabricDependencyType } from "./fabric-dependency-type";
|
||||||
|
import { RawFabricMetadata } from "./raw-fabric-metadata";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a single dependency for a Fabric mod project.
|
||||||
|
*/
|
||||||
|
export interface FabricDependency {
|
||||||
|
/**
|
||||||
|
* The identifier for the dependency.
|
||||||
|
*/
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The version range for the dependency.
|
||||||
|
*
|
||||||
|
* Can be a single version or an array of version ranges.
|
||||||
|
*/
|
||||||
|
version: string | string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the dependency.
|
||||||
|
*/
|
||||||
|
type: FabricDependencyType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface representing a list of dependencies for a Fabric mod project.
|
||||||
|
*/
|
||||||
|
export interface FabricDependencyList {
|
||||||
|
/**
|
||||||
|
* The key is a Mod ID of the dependency.
|
||||||
|
*
|
||||||
|
* The value is a string or array of strings declaring supported version ranges.
|
||||||
|
*/
|
||||||
|
[id: string]: string | string[] | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of special dependencies that should be ignored.
|
||||||
|
*/
|
||||||
|
const IGNORED_DEPENDENCIES: readonly string[] = [
|
||||||
|
"minecraft",
|
||||||
|
"java",
|
||||||
|
"fabricloader",
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map of aliases for special dependencies for different platforms.
|
||||||
|
*/
|
||||||
|
const DEPENDENCY_ALIASES: ReadonlyMap<string, ReadonlyMap<PlatformType, string>> = new Map([
|
||||||
|
["fabric", "fabric-api"],
|
||||||
|
].map(([k, v]) =>
|
||||||
|
[k, typeof v === "string" ? $i(PlatformType.values()).map(x => [x, v] as const).toMap() : v],
|
||||||
|
));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves Fabric dependencies from the metadata.
|
||||||
|
*
|
||||||
|
* @param metadata - The raw Fabric metadata.
|
||||||
|
*
|
||||||
|
* @returns An array of Fabric dependencies.
|
||||||
|
*/
|
||||||
|
export function getFabricDependencies(metadata: RawFabricMetadata): FabricDependency[] {
|
||||||
|
return $i(FabricDependencyType.values()).flatMap(type => toFabricDependencyArray(metadata?.[type], type)).toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a {@link FabricDependencyList} to a proper array of Fabric dependencies.
|
||||||
|
*
|
||||||
|
* @param list - The list of fabric dependencies.
|
||||||
|
* @param type - The type of the dependencies in the list.
|
||||||
|
*
|
||||||
|
* @returns An array of Fabric dependencies.
|
||||||
|
*/
|
||||||
|
export function toFabricDependencyArray(list: FabricDependencyList, type: FabricDependencyType): FabricDependency[] {
|
||||||
|
return Object.entries(list || {}).map(([id, version]) => ({ id, version, type }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts {@link FabricDependency} to a {@link Dependency} object.
|
||||||
|
*
|
||||||
|
* @returns A Dependency object representing the given Fabric dependency, or `undefined` if the input is invalid..
|
||||||
|
*/
|
||||||
|
export function normalizeFabricDependency(dependency: FabricDependency): Dependency | undefined {
|
||||||
|
return createDependency({
|
||||||
|
id: dependency?.id,
|
||||||
|
versions: dependency?.version,
|
||||||
|
type: FabricDependencyType.toDependencyType(dependency?.type || FabricDependencyType.DEPENDS),
|
||||||
|
ignore: IGNORED_DEPENDENCIES.includes(dependency?.id),
|
||||||
|
aliases: DEPENDENCY_ALIASES.get(dependency?.id),
|
||||||
|
});
|
||||||
|
}
|
83
tests/unit/loaders/fabric/fabric-dependency.spec.ts
Normal file
83
tests/unit/loaders/fabric/fabric-dependency.spec.ts
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import { DependencyType } from "@/dependencies/dependency-type";
|
||||||
|
import { RawFabricMetadata } from "@/loaders/fabric/raw-fabric-metadata";
|
||||||
|
import { FabricDependencyType } from "@/loaders/fabric/fabric-dependency-type";
|
||||||
|
import { getFabricDependencies, normalizeFabricDependency, toFabricDependencyArray } from "@/loaders/fabric/fabric-dependency";
|
||||||
|
|
||||||
|
describe("getFabricDependencies", () => {
|
||||||
|
test("returns an array of dependencies specified in the given metadata", () => {
|
||||||
|
const metadata = {
|
||||||
|
schemaVersion: 1,
|
||||||
|
id: "example-mod",
|
||||||
|
version: "1.0.0",
|
||||||
|
|
||||||
|
depends: { "depends-id": "1.0.0" },
|
||||||
|
recommends: { "recommends-id": "2.0.0" },
|
||||||
|
suggests: { "suggests-id": "3.0.0" },
|
||||||
|
breaks: { "breaks-id": ["4.0.0", "5.0.0"] },
|
||||||
|
conflicts: {
|
||||||
|
"conflicts-id-1": "6.0.0",
|
||||||
|
"conflicts-id-2": "7.0.0",
|
||||||
|
},
|
||||||
|
} as RawFabricMetadata;
|
||||||
|
|
||||||
|
const dependencies = getFabricDependencies(metadata);
|
||||||
|
|
||||||
|
expect(dependencies).toEqual([
|
||||||
|
{ id: "depends-id", version: "1.0.0", type: FabricDependencyType.DEPENDS },
|
||||||
|
{ id: "recommends-id", version: "2.0.0", type: FabricDependencyType.RECOMMENDS },
|
||||||
|
{ id: "suggests-id", version: "3.0.0", type: FabricDependencyType.SUGGESTS },
|
||||||
|
{ id: "breaks-id", version: ["4.0.0", "5.0.0"], type: FabricDependencyType.BREAKS },
|
||||||
|
{ id: "conflicts-id-1", version: "6.0.0", type: FabricDependencyType.CONFLICTS },
|
||||||
|
{ id: "conflicts-id-2", version: "7.0.0", type: FabricDependencyType.CONFLICTS },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("returns an empty array if no dependencies were specified", () => {
|
||||||
|
expect(getFabricDependencies({} as RawFabricMetadata)).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("returns an empty array if metadata was null or undefined", () => {
|
||||||
|
expect(getFabricDependencies(null)).toEqual([]);
|
||||||
|
expect(getFabricDependencies(undefined)).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("toFabricDependencyArray", () => {
|
||||||
|
test("converts a dependency list to an array", () => {
|
||||||
|
const conflicting = {
|
||||||
|
"conflicts-id-1": "6.0.0",
|
||||||
|
"conflicts-id-2": ["7.0.0", "8.0.0"],
|
||||||
|
};
|
||||||
|
|
||||||
|
const dependencies = toFabricDependencyArray(conflicting, FabricDependencyType.CONFLICTS);
|
||||||
|
|
||||||
|
expect(dependencies).toEqual([
|
||||||
|
{ id: "conflicts-id-1", version: "6.0.0", type: FabricDependencyType.CONFLICTS },
|
||||||
|
{ id: "conflicts-id-2", version: ["7.0.0", "8.0.0"], type: FabricDependencyType.CONFLICTS },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("returns an empty array if no dependencies were specified", () => {
|
||||||
|
expect(toFabricDependencyArray({}, FabricDependencyType.DEPENDS)).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("returns an empty array if dependency list was null or undefined", () => {
|
||||||
|
expect(toFabricDependencyArray(null, FabricDependencyType.DEPENDS)).toEqual([]);
|
||||||
|
expect(toFabricDependencyArray(undefined, FabricDependencyType.DEPENDS)).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("normalizeFabricDependency", () => {
|
||||||
|
test("converts Fabric dependency to a more abstract Dependency object", () => {
|
||||||
|
const fabricDependency = { id: "recommends-id", version: "2.0.0", type: FabricDependencyType.RECOMMENDS };
|
||||||
|
|
||||||
|
const dependency = normalizeFabricDependency(fabricDependency);
|
||||||
|
|
||||||
|
expect(dependency).toMatchObject({ id: "recommends-id", versions: ["2.0.0"], type: DependencyType.RECOMMENDED });
|
||||||
|
});
|
||||||
|
|
||||||
|
test("returns undefined if dependency was null or undefined", () => {
|
||||||
|
expect(normalizeFabricDependency(null)).toBeUndefined();
|
||||||
|
expect(normalizeFabricDependency(undefined)).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue