Files
AstralRinth/packages/api-client
Truman Gao 9958600121 feat: managing project versions (#4811)
* start modal, working show modal

* add stages and implement MultiModalStage component

* add project versions context and add file button

* implement add files stage

* export interfaces

* move MultiStageModal to /base

* small update to file input

* add version types to api-client

* wrap version namespace under v3

* implement add details stage fields and loaders component

* start create MC versions stage

* implement changelog stage and bring width into a per stage concern

* implement loader picker with grouping

* improve grouping and sorting for loader picker

* use chips component

* small updaets

* fix loader icon color

* componentize mc version picker

* initial version of shift click to select range

* use newModal for markdown editor

* start add dependencies stage with search

* implement showing mod options in search

* componentize modselect and add version/dependency relation select

* hide version and dependency relation when no project selected

* fix project facet search

* implement api-client versions requests

* fix search api request facet type to be string

* fix new modal outer container scroll

* implement add dependency stage

* fix parse error

* add placeholders

* fix types

* update dependency row styles

* small change

* fix the types on manage versions to be correct with labrinth request bodies

* fix create version file parts

* use draft version ref in flow and implement proper file handlling

* use draft version ref for mc versions select

* implement reactive modal state and conditionally disabled next buttons

* ensure all data is using draftVersion ref

* remove shift click to select range since it sucks

* fix up add dependencies stage state/types

* small fixes

* implement adding dependencies connected to api calls and make adding dependencies work

* add final create version button config

* start create version backend call and bring versions table to project settings

* set add files stage width

* remove version file upload in project page

* small fix

* fix create version api call

* implement error handling

* implement mc versions search

* implement showing all mc versions

* small fix

* implement prefill data

* add success notification

* add cancel button

* add new dropzone file input

* run pnpm run fix

* add tailwind preset in ui package

* polish file version row

* fix modal widths

* hide added versions when no versions added

* implement add loaders stage

* implement small chips and small fixes

* implement grouping for all releases

* implement new all releases grouping

* implement better shift click for version select

* small fixes

* fix search input style

* delete versions provider and start project type inferring

* implement getting project type

* add versions empty state, add folder up icon and pnpm run fix

* implement create version in project versions table

* update side nav

* implement dynamic create version flow depending on project type and detected data

* add id to stages and fix calling setStage not working

* move added loaded out of loader picker

* remove selected and detected MC versions

* add loading message to dependency search and fix dependency type always being "required"

* fix components in ref

* fix width on dropdown

* implement toggle all mc versions based on state of last in range

* fix mc version text colour

* do proper clean up

* update loaders to use tag item

* update UI to use TagItem and better match styles

* handle detected data when setting primary file

* add progress bar

* hide progress bar for non-progress stage

* add loading state on submit

* properly cache dependencies projects/versions

* pnpm run fix

* add dragover show purple border on dropzone file input

* better handle added dependencies

* move versions in side nav

* implement adding file type

* fix api body format for file type

* implement working edit existing version
- working add/remove file
- working edit version details

* a step towards proper versions refresh

* add gallery to project settings

* actually figured out refresh versions

* move checklist into settings page

* remove editing version from version page and add button to versions table in project settings

* remove edit and delete buttons from gallery in project page

* add empty state messages for project page

* add default scroll bar styles

* implement support for new file types

* remove edit from dropdown in project page versions table

* redirect to settings page

* move changelog to row with actions

* fix overflow on added dependencies

* fix redirect

* update scroll styles

* implement add environment stage (create and modify version not persisting environment to backend)

* small style fixes

* small spacing fix

* small style fixes

* add a flag for loading dependency projects

* address PR comments

* fix modrinth ui imports

* use magic keys instead of window.addeventlistener

* add spacing in bottom of settings page

* useDebounceFn from vue

* fix inconsistent stroke

* persist scroll through

* fix remove button

* fix api fields

* fix version file dropdown: hide primary option in edit mode and fix setting initial value

* fix links in nags

* implement skipped field for skipping steps instead of mutating stages array's elements

* implement suggested dependencies components

* implement suggested dependencies api call

* refactor cached get project and get version calls

* always hide environments

* update links

* set scroll in 10ms

* update links

* fix links pt2

* fix shadow

* fix progress bar

* dont include mc versions in suggested versions finder

* fix text overflow styles

* use tooltip

* fix change version name api

* implement set environment api call

* delete unused vue pages

* implement detected environment, edit environment step, and fix showing loaders in details for no loader projects

* small fix

* no loaders project wrong check

* fix not having 'minecraft' loader for resource pack

* implement updating existing files file type

* move add minecraft loader outside try catch

* add datapack to have environment

* fix being able to select duplicate MC versions

* remove datapack project from environment

* fix version fetch

* fix having detected environment not properly skipping step

* only add detected data when primary file changes

* fix unknown environemtn

* implement gallery and versions have moved admonition

* update project page for creator view

* small copy update

* merge fixes

* pnpm run fix

* fix checkmark squished

* fix version type can be deselected

* refactor: DI context + better typed MultistageModal

* fix type import

* Misc QA fixes

* fix allowed file types with no project type

* implement new add files stage

* fix versiosn header with new pagination

* hide buttons when no files for add file stage

* use prettier formatter

* allow signature file types

* add detecting primary file

* fix progress bar in firefox

* fix environment not correctly being hidden/shown

* remove environment missing nag

* temp bring back environment page

* remove delete version action from project page

* replace "continue" next button label with actual next step

* fix types

* pnpm run fix

* move supplementary files alert up and update border radius style on dropzone

* copy updates

* small update on version num placeholder

* update placeholder

* make timeout on upload routes 2 minutes

* fix lint issues

* run pnpm intl:extract

---------

Co-authored-by: Calum H. (IMB11) <contact@cal.engineer>
2025-12-18 19:56:15 +00:00
..
2025-11-12 20:29:12 +00:00
2025-11-12 20:29:12 +00:00

Modrinth Monorepo Cover

@modrinth/api-client

TypeScript License: GPL-3.0

A flexible, type-safe API client for Modrinth's APIs (Labrinth, Kyros & Archon). Works across Node.js, browsers, Nuxt, and Tauri with a feature system for authentication, retries, circuit breaking and other custom processing of requests and responses.

Installation

pnpm add @modrinth/api-client
# or
npm install @modrinth/api-client
# or
yarn add @modrinth/api-client

Usage

Plain JavaScript/Node.js

import { GenericModrinthClient, AuthFeature, ProjectV2 } from '@modrinth/api-client'

const client = new GenericModrinthClient({
	userAgent: 'my-app/1.0.0',
	features: [new AuthFeature({ token: 'mrp_...' })],
})

// Explicitly make a request using client.request
const project: any = await client.request('/project/sodium', { api: 'labrinth', version: 2 })

// Example for archon (Modrinth Servers)
const servers = await client.request('/servers?limit=10', { api: 'archon', version: 0 })

// Or use the provided wrappers for better type support.
const project: ProjectV2 = await client.projects_v2.get('sodium')

Nuxt

import { NuxtModrinthClient, AuthFeature, NuxtCircuitBreakerStorage } from '@modrinth/api-client'

// Alternatively you can create a singleton of the client and provide it via DI.
export const useModrinthClient = () => {
	const config = useRuntimeConfig()

	// example using the useAuth composable from our frontend, replace this with whatever you're using to store auth token
	const auth = await useAuth()

	return new NuxtModrinthClient({
		userAgent: 'my-nuxt-app/1.0.0', // leave blank to use default user agent from fetch function
		rateLimitKey: import.meta.server ? config.rateLimitKey : undefined,
		features: [
			new AuthFeature({
				token: async () => auth.value.token,
			}),
			new CircuitBreakerFeature({
				storage: new NuxtCircuitBreakerStorage(),
			}),
		],
	})
}

const client = useModrinthClient()
const project = await client.request('/project/sodium', { api: 'labrinth', version: 2 })

Tauri

import { TauriModrinthClient, AuthFeature } from '@modrinth/api-client'
import { getVersion } from '@tauri-apps/api/app'

const version = await getVersion()
const client = new TauriModrinthClient({
	userAgent: `modrinth/theseus/${version} (support@modrinth.com)`,
	features: [new AuthFeature({ token: 'mrp_...' })],
})

const project = await client.request('/project/sodium', { api: 'labrinth', version: 2 })

Overriding Base URLs

By default, the client uses the production base URLs:

  • labrinthBaseUrl: https://api.modrinth.com/ (Labrinth API)
  • archonBaseUrl: https://archon.modrinth.com/ (Archon/Servers API)

You can override these for staging environments or custom instances:

const client = new GenericModrinthClient({
	userAgent: 'my-app/1.0.0',
	labrinthBaseUrl: 'https://staging-api.modrinth.com/',
	archonBaseUrl: 'https://staging-archon.modrinth.com/',
	features: [new AuthFeature({ token: 'mrp_...' })],
})

// Now requests will use the staging URLs
await client.request('/project/sodium', { api: 'labrinth', version: 2 })
// -> https://staging-api.modrinth.com/v2/project/sodium

You can also use custom URLs directly in requests:

// One-off custom URL (useful for Kyros nodes or dynamic endpoints)
await client.request('/some-endpoint', {
	api: 'https://eu-lim16.nodes.modrinth.com/',
	version: 0,
})

Features

Authentication

Supports both static and dynamic tokens:

// Static token
new AuthFeature({ token: 'mrp_...' })

// Dynamic token (e.g., from auth state)
const auth = await useAuth()
new AuthFeature({
	token: async () => auth.value.token,
})

Retry

Automatically retries failed requests with configurable backoff:

new RetryFeature({
	maxAttempts: 3,
	backoffStrategy: 'exponential',
	initialDelay: 1000,
	maxDelay: 15000,
})

Circuit Breaker

Prevents cascade failures by opening circuits after repeated failures:

new CircuitBreakerFeature({
	maxFailures: 3,
	resetTimeout: 30000,
	failureStatusCodes: [500, 502, 503, 504],
})

Documentation

This package is self-documenting through TypeScript types and JSDoc comments. Use your IDE's IntelliSense to explore available methods, classes, and configuration options.

For Modrinth API endpoints and routes, refer to the Modrinth API Documentation.

Contributing

  • Modules are available in the modules/<api>/... folders.
    • When a module has different versions available, you should do it like so: modules/labrinth/projects/v2.ts etc.
    • Types for a module's requests should be made available in modules/<api>/module/types.ts or .../types/v2.ts.
    • You should expose these types in the modules/types.ts file.
  • When creating a new module, add it to the modules/index.ts's MODULE_REGISTRY for it to become available in the api client class.

Dont forget to run pnpm fix before committing.

License

Licensed under GPL-3.0 - see the LICENSE file for details.