Repository navigation
Scripting Shops
Shop scripts power the JustHostMC Mod Shop window, enabling users to browse, search, and download mods and plugins from online sources such as Modrinth or CurseForge directly within the app.
Built-in shops live in the engine at engine/internal/scripting/builtin_shops/.
User-imported shops are managed via ShopService.Import and persist under <data>/shops/. The permission grants for these scripts are persisted in shop-grants.json.
A shop script must define a meta table. It can set needs_key = true if the source requires an API key.
meta = {
id = "myshop",
name = "My Shop",
version = "1.0.0",
needs_key = false, -- true => engine refuses calls until a key is configured by the user
permissions = { { kind = "network", reason = "Query the shop API" } },
}A shop script must define five global functions. Each takes a ctx table and returns a specifically formatted table.
Populates the default homepage of the shop.
-
Input:
ctxcontainsmc_version,loader,kind("mod" or "plugin"), andconfig(which containsapi_keyifneeds_keyis true). - Returns: A table of sections containing projects.
function home(ctx)
return { sections = { { title_key = "shop.home.popular", projects = { ... } } } }
endPerforms a search query.
-
Input: Extends the
homecontext withquery,sort("relevance"|"downloads"|"follows"|"newest"|"updated"),offset, andlimit. - Returns: A list of projects and the total count.
function search(ctx)
return { projects = { ... }, total = 123 }
endFetches detailed info for a single project.
-
Input:
ctx.project_id. - Returns: Project metadata, description body, and gallery.
function detail(ctx)
return {
project = {...},
body = "...",
body_format = "markdown", -- or "html"
gallery = {{url="...", title="...", description="..."}},
links = {website="...", source="...", issues="...", wiki="...", discord="..."}
}
endFetches available downloadable versions for a project.
-
Input:
ctxcontainsproject_id,mc_version, andloader. - Returns: A list of versions.
function versions(ctx)
return { versions = { { id="...", name="...", version_number="...", channel="release" } } }
endResolves the final download URL and checksums for a specific version.
-
Input:
ctxcontainsproject_id,version_id(empty string means latest compatible),mc_version, andloader. -
Returns: The URL, filename, and checksum (
sha1orsha512). The engine will handle the actual download and verification.
function resolve_file(ctx)
return { url="...", filename="...", size=1234, sha1="..." }
endWhen building a Shop script, it is highly recommended to use jhmc.http_cache instead of the standard jhmc.http_get.
jhmc.http_cache{ url=..., headers=..., ttl=... } acts as a disk-backed ETag cache (utilizing If-None-Match and 304 Not Modified). This ensures that repeated detail views cost almost nothing. The ttl (Time-To-Live) parameter specifies the number of seconds during which the engine will return the cached response without even making a network request.
Shop APIs may return specific errors when a file or project cannot be found or distributed. Raise an error to surface these explicitly to the UI:
-
error("... not found")maps toSHOP_PROJECT_NOT_FOUND -
error("... not distributable")maps toSHOP_FILE_NOT_DISTRIBUTABLE
- Back to the Scripting Hub