NormalPage component w/ Collections refactor (#4873)

* Refactor search page, migrate to /discover/

* Add NormalPage component for common layouts, refactor Collections page as an example, misc ui pkg cleanup

* intl:extract

* lint

* lint

* remove old components

* Refactor search page, migrate to /discover/

* Add NormalPage component for common layouts, refactor Collections page as an example, misc ui pkg cleanup

* intl:extract

* lint

* lint

* remove old components
This commit is contained in:
Prospector
2025-12-09 14:44:10 -08:00
committed by GitHub
parent 1d64b2e22a
commit 0a8f489234
67 changed files with 1201 additions and 1771 deletions

View File

@@ -7,6 +7,7 @@ import { ArchonServersV1Module } from './archon/servers/v1'
import { ISO3166Module } from './iso3166'
import { KyrosFilesV0Module } from './kyros/files/v0'
import { LabrinthBillingInternalModule } from './labrinth/billing/internal'
import { LabrinthCollectionsModule } from './labrinth/collections'
import { LabrinthProjectsV2Module } from './labrinth/projects/v2'
import { LabrinthProjectsV3Module } from './labrinth/projects/v3'
import { LabrinthStateModule } from './labrinth/state'
@@ -30,6 +31,7 @@ export const MODULE_REGISTRY = {
iso3166_data: ISO3166Module,
kyros_files_v0: KyrosFilesV0Module,
labrinth_billing_internal: LabrinthBillingInternalModule,
labrinth_collections: LabrinthCollectionsModule,
labrinth_projects_v2: LabrinthProjectsV2Module,
labrinth_projects_v3: LabrinthProjectsV3Module,
labrinth_state: LabrinthStateModule,

View File

@@ -0,0 +1,128 @@
import { AbstractModule } from '../../core/abstract-module.js'
import type { Labrinth } from '../types'
export class LabrinthCollectionsModule extends AbstractModule {
public getModuleID(): string {
return 'labrinth_collections'
}
/**
* Get a collection by ID (v3)
*
* @param id - Collection ID
* @returns Promise resolving to the collection data
*
* @example
* ```typescript
* const collection = await client.labrinth.collections.get('AANobbMI')
* ```
*/
public async get(id: string): Promise<Labrinth.Collections.Collection> {
return this.client.request<Labrinth.Collections.Collection>(`/collection/${id}`, {
api: 'labrinth',
version: 3,
method: 'GET',
})
}
/**
* Get multiple collections by IDs (v3)
*
* @param ids - Array of collection IDs
* @returns Promise resolving to array of collections
*
* @example
* ```typescript
* const collections = await client.labrinth.collections.getMultiple(['AANobbMI', 'BBNoobMI'])
* ```
*/
public async getMultiple(ids: string[]): Promise<Labrinth.Collections.Collection[]> {
return this.client.request<Labrinth.Collections.Collection[]>(`/collections`, {
api: 'labrinth',
version: 3,
method: 'GET',
params: { ids: JSON.stringify(ids) },
})
}
/**
* Edit a collection (v3)
*
* @param id - Collection ID
* @param data - Collection update data
*
* @example
* ```typescript
* await client.labrinth.collections.edit('AANobbMI', {
* name: 'Updated name',
* description: 'Updated description',
* status: 'listed'
* })
* ```
*/
public async edit(id: string, data: Labrinth.Collections.EditCollectionRequest): Promise<void> {
return this.client.request(`/collection/${id}`, {
api: 'labrinth',
version: 3,
method: 'PATCH',
body: data,
})
}
/**
* Delete a collection (v3)
*
* @param id - Collection ID
*
* @example
* ```typescript
* await client.labrinth.collections.delete('AANobbMI')
* ```
*/
public async delete(id: string): Promise<void> {
return this.client.request(`/collection/${id}`, {
api: 'labrinth',
version: 3,
method: 'DELETE',
})
}
/**
* Edit a collection icon (v3)
*
* @param id - Collection ID
* @param icon - Icon file
* @param ext - File extension (e.g., 'png', 'jpg')
*
* @example
* ```typescript
* await client.labrinth.collections.editIcon('AANobbMI', iconFile, 'png')
* ```
*/
public async editIcon(id: string, icon: Blob, ext: string): Promise<void> {
return this.client.request(`/collection/${id}/icon?ext=${ext}`, {
api: 'labrinth',
version: 3,
method: 'PATCH',
body: icon,
})
}
/**
* Delete a collection icon (v3)
*
* @param id - Collection ID
*
* @example
* ```typescript
* await client.labrinth.collections.deleteIcon('AANobbMI')
* ```
*/
public async deleteIcon(id: string): Promise<void> {
return this.client.request(`/collection/${id}/icon`, {
api: 'labrinth',
version: 3,
method: 'DELETE',
})
}
}

View File

@@ -1,4 +1,5 @@
export * from './billing/internal'
export * from './collections'
export * from './projects/v2'
export * from './projects/v3'
export * from './state'

View File

@@ -477,6 +477,77 @@ export namespace Labrinth {
}
}
export namespace Users {
namespace Common {
export type Role = 'developer' | 'moderator' | 'admin'
export type AuthProvider =
| 'github'
| 'discord'
| 'microsoft'
| 'gitlab'
| 'google'
| 'steam'
| 'paypal'
export type UserPayoutData = {
paypal_address?: string
paypal_country?: string
venmo_handle?: string
balance: number
}
}
export namespace v2 {
export type Role = Common.Role
export type AuthProvider = Common.AuthProvider
export type UserPayoutData = Common.UserPayoutData
export type User = {
id: string
username: string
name?: string
avatar_url?: string
bio?: string
created: string
role: Role
badges: number
auth_providers?: AuthProvider[]
email?: string
email_verified?: boolean
has_password?: boolean
has_totp?: boolean
payout_data?: UserPayoutData
github_id?: number
}
}
export namespace v3 {
export type Role = Common.Role
export type AuthProvider = Common.AuthProvider
export type UserPayoutData = Common.UserPayoutData
export type User = {
id: string
username: string
avatar_url?: string
bio?: string
created: string
role: Role
badges: number
auth_providers?: AuthProvider[]
email?: string
email_verified?: boolean
has_password?: boolean
has_totp?: boolean
payout_data?: UserPayoutData
stripe_customer_id?: string
allow_friend_requests?: boolean
github_id?: number
}
}
}
export namespace Tags {
export namespace v2 {
export interface Category {
@@ -541,6 +612,30 @@ export namespace Labrinth {
}
}
export namespace Collections {
export type CollectionStatus = 'listed' | 'unlisted' | 'private' | 'rejected' | 'unknown'
export type Collection = {
id: string
user: string
name: string
description: string | null
icon_url: string | null
color: number | null
status: CollectionStatus
created: string
updated: string
projects: string[]
}
export type EditCollectionRequest = {
name?: string
description?: string | null
status?: CollectionStatus
new_projects?: string[]
}
}
export namespace State {
export interface GeneratedState {
categories: Tags.v2.Category[]