You've already forked AstralRinth
forked from didirus/AstralRinth
Create send function for API requests
This commit is contained in:
@@ -3,6 +3,7 @@ import { landingPage } from './outputs/landingPage.js'
|
||||
import { projectColors } from './outputs/projectColors.js'
|
||||
import { gameVersions } from './outputs/gameVersions.js'
|
||||
import { tags } from './outputs/tags.js'
|
||||
import { openapi } from './outputs/openapi.js'
|
||||
|
||||
const API_URL =
|
||||
process.env.VITE_API_URL && process.env.VITE_API_URL === 'https://staging-api.modrinth.com/v2/'
|
||||
@@ -25,6 +26,7 @@ const TTL = 7 * 24 * 60 * 60 * 1000
|
||||
* @param {boolean} options.landingPage
|
||||
* @param {boolean} options.gameVersions
|
||||
* @param {boolean} options.tags
|
||||
* @param {boolean} options.openapi
|
||||
* @returns {PluginResult}
|
||||
*/
|
||||
export default function Generator(options) {
|
||||
@@ -57,6 +59,7 @@ export default function Generator(options) {
|
||||
if (options.tags) await tags(API_URL)
|
||||
if (options.landingPage) await landingPage(API_URL)
|
||||
if (options.gameVersions) await gameVersions(API_URL)
|
||||
if (options.openapi) await openapi(API_URL)
|
||||
if (options.projectColors) await projectColors(API_URL)
|
||||
},
|
||||
}
|
||||
|
||||
22
src/plugins/generator/outputs/openapi.js
Normal file
22
src/plugins/generator/outputs/openapi.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import { promises as fs } from 'fs'
|
||||
import cliProgress from 'cli-progress'
|
||||
import openapiTS from 'openapi-typescript'
|
||||
|
||||
export async function openapi() {
|
||||
const progressBar = new cliProgress.SingleBar({
|
||||
format: 'Generating openapi types | {bar} | {percentage}%',
|
||||
barCompleteChar: '\u2588',
|
||||
barIncompleteChar: '\u2591',
|
||||
hideCursor: true,
|
||||
})
|
||||
progressBar.start(2, 0)
|
||||
|
||||
const output = await openapiTS('https://docs.modrinth.com/redocusaurus/plugin-redoc-0.yaml')
|
||||
progressBar.increment()
|
||||
|
||||
// Write JSON file
|
||||
await fs.writeFile('./generated/openapi.ts', output)
|
||||
progressBar.increment()
|
||||
|
||||
progressBar.stop()
|
||||
}
|
||||
@@ -2,3 +2,4 @@ export { ago } from './ago'
|
||||
export { Permissions } from './permissions'
|
||||
export { formatVersions, getPrimary, downloadUrl } from './versions'
|
||||
export { markdown, markdownInline } from './parse'
|
||||
export { send } from './send'
|
||||
|
||||
82
src/utils/send.ts
Normal file
82
src/utils/send.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */ /* `svelte-check` doesn't find issues but VSCode does */
|
||||
// @ts-ignore: `$stores/account` needs to be created in consumer package
|
||||
import { token as tokenStore } from '$stores/account'
|
||||
import { get, writable } from 'svelte/store'
|
||||
import type { operations } from '$generated/openapi'
|
||||
|
||||
export const fetching = writable<number>(0)
|
||||
|
||||
type method = 'GET' | 'POST' | 'PATCH' | 'DELETE' | 'HEAD'
|
||||
|
||||
/* On get requests with query params, pass them in data */
|
||||
export async function send<Operation extends keyof operations>(
|
||||
method: method,
|
||||
route: string,
|
||||
data: // @ts-ignore: Not always present
|
||||
| (operations[Operation]['requestBody']['content']['application/json'] &
|
||||
// @ts-ignore
|
||||
operations[Operation]['requestBody']['content']['multipart/form-data'] &
|
||||
// @ts-ignore
|
||||
operations[Operation]['parameters']['query'])
|
||||
| FormData
|
||||
| null = null,
|
||||
options: {
|
||||
token?: string
|
||||
fetch?: (info: RequestInfo, init?: RequestInit) => Promise<Response>
|
||||
file?: File
|
||||
} = {
|
||||
token: '',
|
||||
}
|
||||
): Promise<
|
||||
// @ts-ignore: On some API routes, a response body is available, if not, defaults to `unknown`
|
||||
operations[Operation]['responses'][200]['content']['application/json']
|
||||
> {
|
||||
fetching.set(get(fetching) + 1)
|
||||
|
||||
const fetchOptions: RequestInit = {
|
||||
method,
|
||||
}
|
||||
|
||||
const token = get(tokenStore) || options.token
|
||||
if (token) {
|
||||
fetchOptions.headers['Authorization'] = token
|
||||
}
|
||||
|
||||
let url = (import.meta.env.VITE_API_URL || 'https://api.modrinth.com/v2/') + route
|
||||
|
||||
if (data) {
|
||||
if (data instanceof FormData) {
|
||||
fetchOptions.body = data
|
||||
} else {
|
||||
if (method === 'GET' || options.file) {
|
||||
url += '?' + new URLSearchParams(data as Record<string, any>).toString()
|
||||
} else {
|
||||
fetchOptions.headers['Content-Type'] = 'application/json'
|
||||
fetchOptions.body = JSON.stringify(data)
|
||||
}
|
||||
if (options.file) {
|
||||
fetchOptions.headers['Content-Type'] = options.file.type
|
||||
fetchOptions.body = options.file
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const response = await (options.fetch || fetch)(url, fetchOptions)
|
||||
|
||||
fetching.set(get(fetching) - 1)
|
||||
|
||||
if (!response.ok) {
|
||||
throw response
|
||||
}
|
||||
|
||||
let parsed: any
|
||||
if (response.status !== 204) {
|
||||
try {
|
||||
parsed = await response.json()
|
||||
} catch {
|
||||
console.error('Could not parse API response')
|
||||
}
|
||||
}
|
||||
|
||||
return parsed
|
||||
}
|
||||
Reference in New Issue
Block a user