diff --git a/packages/lib/src/ModStore.ts b/packages/lib/src/ModStore.ts index e53fdb39..979df95d 100644 --- a/packages/lib/src/ModStore.ts +++ b/packages/lib/src/ModStore.ts @@ -1,8 +1,9 @@ import fs from "fs-extra"; import path from "path"; -import { Static } from "@sinclair/typebox"; +import { Static, StringContentEncodingOption, Type } from "@sinclair/typebox"; import { logger } from "./logging"; import { ModInfo } from "./data"; +import * as libSchema from "./schema"; import TypedEventEmitter from "./TypedEventEmitter"; import { safeOutputFile } from "./file_ops"; @@ -11,6 +12,58 @@ export interface ModStoreEvents { change: (mod: ModInfo) => void; } +interface ModRelease { + download_url: string, + // /download/maraxsis/670de301df21001f6147fd1c -- append to mods.factorio.com to download file, auth required + file_name: string, + // maraxsis_1.8.0.zip -- the file name of the downloaded file ^^ + info_json: { + dependencies?: Array, + factorio_version: string; + }; + released_at: string, + // 2024-10-15T03:35:29.892000Z -- (ISO 8601) + sha1: string, + // e227ee560d93485c7f215c9451eaa9cc38d81c98 + version: string; // 1.8.0 -- just a normal version string +} + +interface ModImage { + id: string, + thumbnail: string, + url: string; +} + +interface ModLicense { + description: string, + id: string, + name: string, + title: string, + url: string; +} + +interface ModDetails { + category: string, // content -- what mod catogory is this apart of, a mod can only be apart of 1 category + download_count: number, // 3653 -- how many downloads does the mod have as a number + name: string, // maraxsis -- the name of the mod + owner: string, // notnotmelon -- the name of the author of the mod + releases: Array, // an array of all releases and version of the mod + score: number, // 1054.8333333333333 -- it's prob used for sorting purposes + summary: string, // the mod description + thumbnail: string, // append path to assets-mods.factorio.com to get full url to thumbnail file + title: string, // the full title of the mod, shown on the mod page + changelog?: string, + created_at?: string, + description?: string, + homepage?: string, + images?: Array, + license?: ModLicense, + source_url?: string, + tags?: Array, + updated_at?: string, + deprecated?: boolean; +} + export default class ModStore extends TypedEventEmitter { constructor( public modsDirectory: string, @@ -134,4 +187,55 @@ export default class ModStore extends TypedEventEmitter { + const modDetails: ModDetails = await ( + await fetch(`https://mods.factorio.com/api/mods/${modName}`) + ).json() as ModDetails; + return modDetails.releases[modDetails.releases.length].version; + } + + // gets the latest version of the mod provided as a string + static async fetchLatestVersionModInfo(modName: string): Promise { + const modDetails: ModDetails = await ( + await fetch(`https://mods.factorio.com/api/mods/${modName}/full`) + ).json() as ModDetails; + const latestRelease: ModRelease = modDetails.releases[modDetails.releases.length]; + let modInfo = new ModInfo(); + const info_json = latestRelease.info_json; + + // info.json fields + if (modDetails.name) { modInfo.name = modDetails.name; } + if (latestRelease.version) { modInfo.version = latestRelease.version; } + if (modDetails.title) { modInfo.title = modDetails.title; } + if (modDetails.owner) { modInfo.author = modDetails.owner; } + if (modDetails.homepage) { modInfo.homepage = modDetails.homepage; } + if (modDetails.description) { modInfo.description = modDetails.description; } + if (info_json.factorio_version) { modInfo.factorioVersion = info_json.factorio_version; } + if (info_json.dependencies) { modInfo.dependencies = info_json.dependencies; } + + const infoJsonSchema = Type.Object({ + "name": Type.String(), + "version": Type.String(), + "title": Type.String(), + "author": Type.String(), + "contact": Type.Optional(Type.String()), + "homepage": Type.Optional(Type.String()), + "description": Type.Optional(Type.String()), + "factorio_version": Type.Optional(Type.String()), + "dependencies": Type.Optional(Type.Array(Type.String())), + }); + + const validateInfo = libSchema.compile>(infoJsonSchema as any); + + const valid = validateInfo(modInfo); + + if (valid) { + return modInfo; + } + + return modInfo; + + } } diff --git a/packages/lib/src/factorio/mod_update_thingy.ts b/packages/lib/src/factorio/mod_update_thingy.ts deleted file mode 100644 index d55cf335..00000000 --- a/packages/lib/src/factorio/mod_update_thingy.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { ModInfo } from "../data"; - - -// the example comments are from the mod maraxsis - -interface modRelease { - download_url: string, // /download/maraxsis/670de301df21001f6147fd1c -- append to mods.factorio.com to download file, auth required - file_name: string, // maraxsis_1.8.0.zip -- the file name of the downloaded file ^^ - info_json: { factorio_version: string } // 2.0 -- seems to just hold what factorio version it supports, due to it being nested, it could other info, not sure - released_at: string, // 2024-10-15T03:35:29.892000Z -- some kind of time stamp, i'm sure that can be imported/converted to a useable format if it useful to have - sha1: string, // e227ee560d93485c7f215c9451eaa9cc38d81c98 -- it's a hash, not much to say - version: string // 1.8.0 -- just a normal version string -} - -interface modDetails { - category: string, // content -- what mod catogory is this apart of, i think a mod can only be apart of 1 category - download_count: number, // 3653 -- how many downloads does the mod have as a number - name: string, // maraxsis -- the name of the mod - owner: string, // notnotmelon -- the name of the author of the mod - releases: Array, // an array of all releases and version of the mod, the type is declared above - score: number, // 1054.8333333333333 -- not sure, seems some kind of float or double, based on name, it's prob used for sorting purposes - summary: string, // the mod description - thumbnail: string, // append path to assets-mods.factorio.com to get full url to thumbnail file - title: string // the full title of the mod, shown on the mod page -} - - -async function getLatestVersion(mod: ModInfo) { - const modStuff: modDetails = await (await fetch("https://mods.factorio.com/api/mods/" + mod.name)).json() as modDetails - const latestVersion = modStuff.releases[modStuff.releases.length].version -}