Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/api-client/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ client.labrinth.collections
client.labrinth.billing_internal
client.archon.servers_v0
client.archon.servers_v1
client.archon.backups_v0
client.archon.backups_queue_v1
client.archon.backups_v1
client.archon.content_v0
client.kyros.files_v0
Expand Down
7 changes: 6 additions & 1 deletion packages/api-client/src/core/abstract-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import { AbstractUploadClient } from './abstract-upload-client'
import type { AbstractWebSocketClient } from './abstract-websocket'
import { ModrinthApiError, ModrinthServerError } from './errors'

type ArchonClientModules = Omit<InferredClientModules['archon'], 'backups_v1'> & {
/** @deprecated Use `backups_queue_v1` for the Backups Queue API. */
backups_v1: InferredClientModules['archon']['backups_v1']
}

/**
* Abstract base client for Modrinth APIs
*/
Expand All @@ -27,7 +32,7 @@ export abstract class AbstractModrinthClient extends AbstractUploadClient {
private _moduleNamespaces: Map<string, Record<string, AbstractModule>> = new Map()

public readonly labrinth!: InferredClientModules['labrinth']
public readonly archon!: InferredClientModules['archon'] & { sockets: AbstractWebSocketClient }
public readonly archon!: ArchonClientModules & { sockets: AbstractWebSocketClient }
public readonly kyros!: InferredClientModules['kyros']
public readonly iso3166!: InferredClientModules['iso3166']
public readonly mclogs!: InferredClientModules['mclogs']
Expand Down
93 changes: 93 additions & 0 deletions packages/api-client/src/modules/archon/backups-queue/v1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Archon } from '../types'

export class ArchonBackupsQueueV1Module extends AbstractModule {
public getModuleID(): string {
return 'archon_backups_queue_v1'
}

/** GET /v1/servers/:server_id/worlds/:world_id/backups-queue */
public async list(
serverId: string,
worldId: string,
): Promise<Archon.BackupsQueue.v1.BackupsQueueResponse> {
return this.client.request<Archon.BackupsQueue.v1.BackupsQueueResponse>(
`/servers/${serverId}/worlds/${worldId}/backups-queue`,
{ api: 'archon', version: 1, method: 'GET' },
)
}

/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue */
public async create(
serverId: string,
worldId: string,
request: Archon.BackupsQueue.v1.BackupRequest,
): Promise<Archon.BackupsQueue.v1.PostBackupQueueResponse> {
return this.client.request<Archon.BackupsQueue.v1.PostBackupQueueResponse>(
`/servers/${serverId}/worlds/${worldId}/backups-queue`,
{ api: 'archon', version: 1, method: 'POST', body: request },
)
}

/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/create/:operation_id/ack */
public async ackCreate(serverId: string, worldId: string, operationId: number): Promise<void> {
await this.client.request<void>(
`/servers/${serverId}/worlds/${worldId}/backups-queue/history/create/${operationId}/ack`,
{ api: 'archon', version: 1, method: 'POST' },
)
}

/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/restore/:operation_id/ack */
public async ackRestore(serverId: string, worldId: string, operationId: number): Promise<void> {
await this.client.request<void>(
`/servers/${serverId}/worlds/${worldId}/backups-queue/history/restore/${operationId}/ack`,
{ api: 'archon', version: 1, method: 'POST' },
)
}

/** DELETE /v1/servers/:server_id/worlds/:world_id/backups-queue/:backup_id */
public async delete(serverId: string, worldId: string, backupId: string): Promise<void> {
await this.client.request<void>(
`/servers/${serverId}/worlds/${worldId}/backups-queue/${backupId}`,
{
api: 'archon',
version: 1,
method: 'DELETE',
},
)
}

/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/delete-many */
public async deleteMany(serverId: string, worldId: string, backupIds: string[]): Promise<void> {
await this.client.request<void>(
`/servers/${serverId}/worlds/${worldId}/backups-queue/delete-many`,
{
api: 'archon',
version: 1,
method: 'POST',
body: { backup_ids: backupIds } satisfies Archon.BackupsQueue.v1.DeleteManyBackupRequest,
},
)
}

/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/:backup_id/restore */
public async restore(
serverId: string,
worldId: string,
backupId: string,
request: Archon.BackupsQueue.v1.BackupRequest,
): Promise<void> {
await this.client.request<void>(
`/servers/${serverId}/worlds/${worldId}/backups-queue/${backupId}/restore`,
{ api: 'archon', version: 1, method: 'POST', body: request },
)
}

/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/:backup_id/retry */
public async retry(serverId: string, worldId: string, backupId: string): Promise<void> {
await this.client.request<void>(
`/servers/${serverId}/worlds/${worldId}/backups-queue/${backupId}/retry`,
{ api: 'archon', version: 1, method: 'POST' },
)
}
}
24 changes: 24 additions & 0 deletions packages/api-client/src/modules/archon/backups/v1.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Archon } from '../types'

/**
* @deprecated Use `client.archon.backups_queue_v1` (Backups Queue API) instead.
*/
export class ArchonBackupsV1Module extends AbstractModule {
public getModuleID(): string {
return 'archon_backups_v1'
}

/**
* @deprecated Use `client.archon.backups_queue_v1.list` instead.
*/
/** GET /v1/servers/:server_id/worlds/:world_id/backups */
public async list(serverId: string, worldId: string): Promise<Archon.Backups.v1.Backup[]> {
return this.client.request<Archon.Backups.v1.Backup[]>(
Expand All @@ -14,6 +20,9 @@ export class ArchonBackupsV1Module extends AbstractModule {
)
}

/**
* @deprecated Use `client.archon.backups_queue_v1.list` instead.
*/
/** GET /v1/servers/:server_id/worlds/:world_id/backups/:backup_id */
public async get(
serverId: string,
Expand All @@ -26,6 +35,9 @@ export class ArchonBackupsV1Module extends AbstractModule {
)
}

/**
* @deprecated Use `client.archon.backups_queue_v1.create` instead.
*/
/** POST /v1/servers/:server_id/worlds/:world_id/backups */
public async create(
serverId: string,
Expand All @@ -38,6 +50,9 @@ export class ArchonBackupsV1Module extends AbstractModule {
)
}

/**
* @deprecated Use `client.archon.backups_queue_v1.restore` instead.
*/
/** POST /v1/servers/:server_id/worlds/:world_id/backups/:backup_id/restore */
public async restore(serverId: string, worldId: string, backupId: string): Promise<void> {
await this.client.request<void>(
Expand All @@ -50,6 +65,9 @@ export class ArchonBackupsV1Module extends AbstractModule {
)
}

/**
* @deprecated Use `client.archon.backups_queue_v1.delete` instead.
*/
/** DELETE /v1/servers/:server_id/worlds/:world_id/backups/:backup_id */
public async delete(serverId: string, worldId: string, backupId: string): Promise<void> {
await this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/backups/${backupId}`, {
Expand All @@ -59,6 +77,9 @@ export class ArchonBackupsV1Module extends AbstractModule {
})
}

/**
* @deprecated Use `client.archon.backups_queue_v1.retry` instead.
*/
/** POST /v1/servers/:server_id/worlds/:world_id/backups/:backup_id/retry */
public async retry(serverId: string, worldId: string, backupId: string): Promise<void> {
await this.client.request<void>(
Expand All @@ -71,6 +92,9 @@ export class ArchonBackupsV1Module extends AbstractModule {
)
}

/**
* @deprecated Legacy backups only; no queue equivalent. Prefer renaming via other supported flows if available.
*/
/** PATCH /v1/servers/:server_id/worlds/:world_id/backups/:backup_id */
public async rename(
serverId: string,
Expand Down
1 change: 1 addition & 0 deletions packages/api-client/src/modules/archon/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './backups/v1'
export * from './backups-queue/v1'
export * from './content/v1'
export * from './properties/v1'
export * from './servers/v0'
Expand Down
89 changes: 88 additions & 1 deletion packages/api-client/src/modules/archon/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,9 @@ export namespace Archon {
name: string
created_at: string
is_active: boolean
/**
* @deprecated Prefer `client.archon.backups_queue_v1.list()` for queue-aware backup state.
*/
backups: Archon.Backups.v1.Backup[]
content: WorldContentInfo | null
readiness: WorldReadiness
Expand Down Expand Up @@ -434,16 +437,24 @@ export namespace Archon {
}

export namespace Backups {
/**
* @deprecated Use {@link Archon.BackupsQueue.v1} and `client.archon.backups_queue_v1` instead.
*/
export namespace v1 {
/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */
export type BackupState = 'ongoing' | 'done' | 'failed' | 'cancelled' | 'unchanged'
/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */
export type BackupTask = 'file' | 'create' | 'restore'
/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */
export type BackupStatus = 'pending' | 'in_progress' | 'timed_out' | 'error' | 'done'

/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */
export type BackupTaskProgress = {
progress: number // 0.0 to 1.0
state: BackupState
}

/** @deprecated Use {@link Archon.BackupsQueue.v1.BackupQueueBackup} instead. */
export type Backup = {
id: string
physical_id: string
Expand All @@ -461,28 +472,102 @@ export namespace Archon {
}
}

/** @deprecated Use {@link Archon.BackupsQueue.v1.BackupRequest} instead. */
export type BackupRequest = {
name: string
}

/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */
export type PatchBackup = {
name?: string
}

/** @deprecated Use {@link Archon.BackupsQueue.v1.PostBackupQueueResponse} instead. */
export type PostBackupResponse = {
id: string
}
}
}

export namespace BackupsQueue {
export namespace v1 {
export type BackupQueueOperationType = 'create' | 'restore'

export type BackupQueueState =
| 'pending'
| 'ongoing'
| 'completed'
| 'cancelled'
| 'failed'
| 'timed_out'

export type BackupStatus = 'pending' | 'in_progress' | 'timed_out' | 'error' | 'done'

export type BackupRequest = {
name: string
}

export type PostBackupQueueResponse = {
id: string
}

export type DeleteManyBackupRequest = {
backup_ids: string[]
}

export type ActiveOperation = {
backup_id: string
operation_type: BackupQueueOperationType
operation_id?: number | null
has_parent: boolean
scheduled_for: string
synthetic_legacy: boolean
}

export type BackupQueueOperation = {
operation_type: BackupQueueOperationType
operation_id?: number | null
state: BackupQueueState
scheduled_for: string
completed_at?: string | null
has_parent: boolean
error?: string | null
should_prompt: boolean
synthetic_legacy: boolean
}

export type BackupQueueBackup = {
id: string
name: string
created_at: string
status: BackupStatus
locked: boolean
automated: boolean
history: BackupQueueOperation[]
}

export type BackupsQueueResponse = {
active_operations: ActiveOperation[]
backups: BackupQueueBackup[]
}
}
}

export namespace Websocket {
export namespace v0 {
export type WSAuth = {
url: string
token: string
}

export type BackupState = 'ongoing' | 'done' | 'failed' | 'cancelled' | 'unchanged'
export type BackupState =
| 'pending'
| 'ongoing'
| 'done'
| 'failed'
| 'cancelled'
| 'unchanged'
| 'damaged'
export type BackupTask = 'file' | 'create' | 'restore'

export type WSBackupProgressEvent = {
Expand All @@ -491,6 +576,8 @@ export namespace Archon {
task: BackupTask
state: BackupState
progress: number
start_time?: number | null
finish_time?: number | null
}

export type WSLogEvent = {
Expand Down
2 changes: 2 additions & 0 deletions packages/api-client/src/modules/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { AbstractModrinthClient } from '../core/abstract-client'
import type { AbstractModule } from '../core/abstract-module'
import { ArchonBackupsV1Module } from './archon/backups/v1'
import { ArchonBackupsQueueV1Module } from './archon/backups-queue/v1'
import { ArchonContentV1Module } from './archon/content/v1'
import { ArchonOptionsV1Module } from './archon/options/v1'
import { ArchonPropertiesV1Module } from './archon/properties/v1'
Expand Down Expand Up @@ -54,6 +55,7 @@ type ModuleConstructor = new (client: AbstractModrinthClient) => AbstractModule
* TODO: Better way? Probably not
*/
export const MODULE_REGISTRY = {
archon_backups_queue_v1: ArchonBackupsQueueV1Module,
archon_backups_v1: ArchonBackupsV1Module,
archon_content_v1: ArchonContentV1Module,
archon_options_v1: ArchonOptionsV1Module,
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/components/base/Checkbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
? 'cursor-not-allowed opacity-50'
: 'cursor-pointer hover:brightness-[--hover-brightness] focus-visible:brightness-[--hover-brightness]'
"
:aria-label="description || label"
:aria-checked="modelValue"
:aria-label="description || label || undefined"
:aria-checked="indeterminate ? 'mixed' : modelValue"
role="checkbox"
@click="toggle"
>
Expand Down
Loading
Loading