Skip to content

Commit f924255

Browse files
committed
refactor: move state types into api-client
1 parent 7d44194 commit f924255

File tree

23 files changed

+793
-495
lines changed

23 files changed

+793
-495
lines changed

apps/app-frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"test": "vue-tsc --noEmit"
1414
},
1515
"dependencies": {
16+
"@modrinth/api-client": "workspace:^",
1617
"@modrinth/assets": "workspace:*",
1718
"@modrinth/ui": "workspace:*",
1819
"@modrinth/utils": "workspace:*",

apps/app-frontend/src/App.vue

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
RefreshCwIcon,
1919
RestoreIcon,
2020
RightArrowIcon,
21+
ServerIcon,
2122
SettingsIcon,
2223
UserIcon,
2324
WorldIcon,
@@ -32,6 +33,7 @@ import {
3233
NotificationPanel,
3334
OverflowMenu,
3435
ProgressSpinner,
36+
provideModrinthClient,
3537
provideNotificationManager,
3638
} from '@modrinth/ui'
3739
import { renderString } from '@modrinth/utils'
@@ -90,7 +92,7 @@ import {
9092
import { useError } from '@/store/error.js'
9193
import { useInstall } from '@/store/install.js'
9294
import { useLoading, useTheming } from '@/store/state'
93-
95+
import { AuthFeature, TauriModrinthClient } from '@modrinth/api-client'
9496
import { create_profile_and_install_from_file } from './helpers/pack'
9597
import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer'
9698
import { get_available_capes, get_available_skins } from './helpers/skins'
@@ -102,6 +104,16 @@ const notificationManager = new AppNotificationManager()
102104
provideNotificationManager(notificationManager)
103105
const { handleError, addNotification } = notificationManager
104106
107+
const tauriApiClient = new TauriModrinthClient({
108+
userAgent: `modrinth/theseus/${getVersion()} (support@modrinth.com)`,
109+
features: [
110+
new AuthFeature({
111+
token: getCreds,
112+
}),
113+
],
114+
})
115+
provideModrinthClient(tauriApiClient)
116+
105117
const news = ref([])
106118
const availableSurvey = ref(false)
107119
@@ -738,6 +750,13 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
738750
<NavButton v-if="themeStore.featureFlags.worlds_tab" v-tooltip.right="'Worlds'" to="/worlds">
739751
<WorldIcon />
740752
</NavButton>
753+
<NavButton
754+
v-if="themeStore.featureFlags.servers_in_app"
755+
v-tooltip.right="'Servers'"
756+
to="/servers/manage"
757+
>
758+
<ServerIcon />
759+
</NavButton>
741760
<NavButton
742761
v-tooltip.right="'Discover content'"
743762
to="/browse/modpack"

apps/app-frontend/src/routes.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as Pages from '@/pages'
44
import * as Instance from '@/pages/instance'
55
import * as Library from '@/pages/library'
66
import * as Project from '@/pages/project'
7-
import { sharedRoutes } from '@modrinth/ui/pages'
7+
import { ServersManagePageIndex } from '@modrinth/ui'
88

99
/**
1010
* Configures application routing. Add page to pages/index and then add to route table here.
@@ -28,6 +28,14 @@ export default new createRouter({
2828
breadcrumb: [{ name: 'Worlds' }],
2929
},
3030
},
31+
{
32+
path: '/servers/manage/',
33+
name: 'Servers',
34+
component: ServersManagePageIndex,
35+
meta: {
36+
breadcrumb: [{ name: 'Servers' }],
37+
},
38+
},
3139
{
3240
path: '/browse/:projectType',
3341
name: 'Discover content',
@@ -171,8 +179,6 @@ export default new createRouter({
171179
},
172180
],
173181
},
174-
// Shared routes from @modrinth/ui
175-
...sharedRoutes,
176182
],
177183
linkActiveClass: 'router-link-active',
178184
linkExactActiveClass: 'router-link-exact-active',

apps/app-frontend/src/store/theme.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const DEFAULT_FEATURE_FLAGS = {
55
page_path: false,
66
worlds_tab: false,
77
worlds_in_home: true,
8+
servers_in_app: false,
89
}
910

1011
export const THEME_OPTIONS = ['dark', 'light', 'oled', 'system'] as const

apps/frontend/nuxt.config.ts

Lines changed: 11 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,16 @@
11
import { pathToFileURL } from 'node:url'
22

33
import { match as matchLocale } from '@formatjs/intl-localematcher'
4+
import { GenericModrinthClient, type Labrinth } from '@modrinth/api-client'
45
import serverSidedVue from '@vitejs/plugin-vue'
56
import { consola } from 'consola'
67
import { promises as fs } from 'fs'
78
import { globIterate } from 'glob'
89
import { defineNuxtConfig } from 'nuxt/config'
9-
import { $fetch } from 'ofetch'
10-
import Papa from 'papaparse'
1110
import { basename, relative, resolve } from 'pathe'
1211
import svgLoader from 'vite-svg-loader'
1312

14-
import type { GeneratedState } from './src/composables/generated'
15-
1613
const STAGING_API_URL = 'https://staging-api.modrinth.com/v2/'
17-
// ISO 3166 data from https://github.com/ipregistry/iso3166
18-
// Licensed under CC BY-SA 4.0
19-
const ISO3166_REPO = 'https://raw.githubusercontent.com/ipregistry/iso3166/master'
2014

2115
const preloadedFonts = [
2216
'inter/Inter-Regular.woff2',
@@ -139,7 +133,7 @@ export default defineNuxtConfig({
139133
// 30 minutes
140134
const TTL = 30 * 60 * 1000
141135

142-
let state: Partial<GeneratedState> = {}
136+
let state: Partial<Labrinth.State.GeneratedState & Record<string, any>> = {}
143137

144138
try {
145139
state = JSON.parse(await fs.readFile('./src/generated/state.json', 'utf8'))
@@ -165,124 +159,19 @@ export default defineNuxtConfig({
165159
return
166160
}
167161

168-
state.lastGenerated = new Date().toISOString()
162+
const client = new GenericModrinthClient({
163+
labrinthBaseUrl: API_URL.replace('/v2/', ''),
164+
userAgent: 'Knossos generator (support@modrinth.com)',
165+
})
169166

167+
const generatedState = await client.labrinth.state.build()
168+
state.lastGenerated = new Date().toISOString()
170169
state.apiUrl = API_URL
171-
172-
const headers = {
173-
headers: {
174-
'user-agent': 'Knossos generator (support@modrinth.com)',
175-
},
176-
}
177-
178-
const caughtErrorCodes = new Set<number>()
179-
180-
function handleFetchError(err: any, defaultValue: any) {
181-
console.error('Error generating state: ', err)
182-
caughtErrorCodes.add(err.status)
183-
return defaultValue
170+
state = {
171+
...state,
172+
...generatedState,
184173
}
185174

186-
const [
187-
categories,
188-
loaders,
189-
gameVersions,
190-
donationPlatforms,
191-
reportTypes,
192-
homePageProjects,
193-
homePageSearch,
194-
homePageNotifs,
195-
products,
196-
muralBankDetails,
197-
countriesCSV,
198-
subdivisionsCSV,
199-
] = await Promise.all([
200-
$fetch(`${API_URL}tag/category`, headers).catch((err) => handleFetchError(err, [])),
201-
$fetch(`${API_URL}tag/loader`, headers).catch((err) => handleFetchError(err, [])),
202-
$fetch(`${API_URL}tag/game_version`, headers).catch((err) => handleFetchError(err, [])),
203-
$fetch(`${API_URL}tag/donation_platform`, headers).catch((err) =>
204-
handleFetchError(err, []),
205-
),
206-
$fetch(`${API_URL}tag/report_type`, headers).catch((err) => handleFetchError(err, [])),
207-
$fetch(`${API_URL}projects_random?count=60`, headers).catch((err) =>
208-
handleFetchError(err, []),
209-
),
210-
$fetch(`${API_URL}search?limit=3&query=leave&index=relevance`, headers).catch((err) =>
211-
handleFetchError(err, {}),
212-
),
213-
$fetch(`${API_URL}search?limit=3&query=&index=updated`, headers).catch((err) =>
214-
handleFetchError(err, {}),
215-
),
216-
$fetch(`${API_URL.replace('/v2/', '/_internal/')}billing/products`, headers).catch((err) =>
217-
handleFetchError(err, []),
218-
),
219-
$fetch(`${API_URL.replace('/v2/', '/_internal/')}mural/bank-details`, headers).catch(
220-
(err) => handleFetchError(err, null),
221-
),
222-
$fetch<string>(`${ISO3166_REPO}/countries.csv`, {
223-
...headers,
224-
responseType: 'text',
225-
}).catch((err) => handleFetchError(err, '')),
226-
$fetch<string>(`${ISO3166_REPO}/subdivisions.csv`, {
227-
...headers,
228-
responseType: 'text',
229-
}).catch((err) => handleFetchError(err, '')),
230-
])
231-
232-
const countriesData = Papa.parse(countriesCSV, {
233-
header: true,
234-
skipEmptyLines: true,
235-
transformHeader: (header) => (header.startsWith('#') ? header.slice(1) : header),
236-
}).data
237-
const subdivisionsData = Papa.parse(subdivisionsCSV, {
238-
header: true,
239-
skipEmptyLines: true,
240-
transformHeader: (header) => (header.startsWith('#') ? header.slice(1) : header),
241-
}).data
242-
243-
const subdivisionsByCountry = (subdivisionsData as any[]).reduce(
244-
(acc, sub) => {
245-
const countryCode = sub.country_code_alpha2
246-
247-
if (!countryCode || typeof countryCode !== 'string' || countryCode.trim() === '') {
248-
return acc
249-
}
250-
251-
if (!acc[countryCode]) acc[countryCode] = []
252-
253-
acc[countryCode].push({
254-
code: sub['subdivision_code_iso3166-2'],
255-
name: sub.subdivision_name,
256-
localVariant: sub.localVariant || null,
257-
category: sub.category,
258-
parent: sub.parent_subdivision || null,
259-
language: sub.language_code,
260-
})
261-
return acc
262-
},
263-
{} as Record<string, any[]>,
264-
)
265-
266-
state.categories = categories
267-
state.loaders = loaders
268-
state.gameVersions = gameVersions
269-
state.donationPlatforms = donationPlatforms
270-
state.reportTypes = reportTypes
271-
state.homePageProjects = homePageProjects
272-
state.homePageSearch = homePageSearch
273-
state.homePageNotifs = homePageNotifs
274-
state.products = products
275-
state.muralBankDetails = muralBankDetails.bankDetails
276-
state.countries = (countriesData as any[]).map((c) => ({
277-
alpha2: c.country_code_alpha2,
278-
alpha3: c.country_code_alpha3,
279-
numeric: c.numeric_code,
280-
nameShort: c.name_short,
281-
nameLong: c.name_long,
282-
}))
283-
state.subdivisions = subdivisionsByCountry
284-
state.errors = [...caughtErrorCodes]
285-
286175
await fs.writeFile('./src/generated/state.json', JSON.stringify(state))
287176

288177
console.log('Tags generated!')

0 commit comments

Comments
 (0)