refactor: remove useBaseFetch for @modrinth/api-client (#5596)
* Reapply "fix: start swapping useBaseFetch usages to api-client" This reverts commit f4f33db7019ea861addb2c66c204d736800b7b6c. * fix: bugs * fix: analytics * fix: lint
This commit is contained in:
@@ -30,7 +30,7 @@ This is the Modrinth monorepo — it contains all Modrinth projects, both fronte
|
||||
| `api-client` | API client for Nuxt, Tauri, and Node/browser |
|
||||
| `app-lib` | Shared app library |
|
||||
| `blog` | Blog system and changelog data |
|
||||
| `utils` | Shared utility functions |
|
||||
| `utils` | Shared utility functions (mostly deprecated) |
|
||||
| `moderation` | Moderation utilities |
|
||||
| `daedalus` | Daedalus protocol |
|
||||
| `tooling-config` | ESLint, Prettier, TypeScript configs |
|
||||
@@ -85,6 +85,7 @@ Each project may have its own `CLAUDE.md` with detailed instructions:
|
||||
### General
|
||||
- Do not create new non-source code files (e.g. Bash scripts, SQL scripts) unless explicitly prompted to
|
||||
- For Frontend, when doing lint checks, only use the `prepr` commands, do not use `typecheck` or `tsc` etc.
|
||||
- Types in `@modrinth/utils` are considered highly outdated, if a component needs them, check if you can switch said component to use types from `packages/api-client`
|
||||
|
||||
## Edit Tool - Whitespace Handling (CLAUDE ONLY)
|
||||
|
||||
|
||||
@@ -328,6 +328,7 @@ import {
|
||||
Categories,
|
||||
CopyCode,
|
||||
DoubleIcon,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
ProjectStatusBadge,
|
||||
useFormatDateTime,
|
||||
@@ -341,6 +342,7 @@ import { acceptTeamInvite, removeSelfFromTeam } from '~/helpers/teams'
|
||||
|
||||
import ThreadSummary from './thread/ThreadSummary.vue'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const emit = defineEmits(['update:notifications'])
|
||||
const formatRelativeTime = useRelativeTime()
|
||||
@@ -407,7 +409,7 @@ async function read() {
|
||||
? props.notification.grouped_notifs.map((notif) => notif.id)
|
||||
: []),
|
||||
]
|
||||
const updateNotifs = await markAsRead(ids)
|
||||
const updateNotifs = await markAsRead(client, ids)
|
||||
const newNotifs = updateNotifs(props.notifications)
|
||||
emit('update:notifications', newNotifs)
|
||||
} catch (err) {
|
||||
|
||||
@@ -357,7 +357,7 @@ const props = withDefaults(
|
||||
},
|
||||
)
|
||||
|
||||
const projects = ref(props.projects || [])
|
||||
const projects = computed(() => props.projects || [])
|
||||
|
||||
// const selectedChart = ref('downloads')
|
||||
const selectedChart = computed({
|
||||
@@ -389,6 +389,13 @@ const tinyRevenueChart = ref()
|
||||
|
||||
const selectedDisplayProjects = ref(props.projects || [])
|
||||
|
||||
watch(
|
||||
() => props.projects,
|
||||
(newProjects) => {
|
||||
selectedDisplayProjects.value = newProjects || []
|
||||
},
|
||||
)
|
||||
|
||||
const removeProjectFromDisplay = (id: string) => {
|
||||
selectedDisplayProjects.value = selectedDisplayProjects.value.filter((p) => p.id !== id)
|
||||
}
|
||||
|
||||
@@ -42,13 +42,18 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { MessageIcon } from '@modrinth/assets'
|
||||
import { Admonition, ButtonStyled, defineMessages, useVIntl } from '@modrinth/ui'
|
||||
import {
|
||||
Admonition,
|
||||
ButtonStyled,
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { capitalizeString } from '@modrinth/utils'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { computed, watch } from 'vue'
|
||||
|
||||
import { useBaseFetch } from '~/composables/fetch.js'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const messages = defineMessages({
|
||||
@@ -100,33 +105,24 @@ const messages = defineMessages({
|
||||
},
|
||||
})
|
||||
|
||||
interface UserLimits {
|
||||
current: number
|
||||
max: number
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
type: 'project' | 'org' | 'collection'
|
||||
}>()
|
||||
|
||||
const model = defineModel<boolean>()
|
||||
|
||||
const apiEndpoint = computed(() => {
|
||||
switch (props.type) {
|
||||
case 'project':
|
||||
return 'limits/projects'
|
||||
case 'org':
|
||||
return 'limits/organizations'
|
||||
case 'collection':
|
||||
return 'limits/collections'
|
||||
default:
|
||||
return 'limits/projects'
|
||||
}
|
||||
})
|
||||
|
||||
const { data: limits } = useQuery({
|
||||
queryKey: computed(() => ['limits', props.type]),
|
||||
queryFn: () => useBaseFetch(apiEndpoint.value, { apiVersion: 3 }) as Promise<UserLimits>,
|
||||
queryFn: () => {
|
||||
switch (props.type) {
|
||||
case 'org':
|
||||
return client.labrinth.limits_v3.getOrganizationLimits()
|
||||
case 'collection':
|
||||
return client.labrinth.limits_v3.getCollectionLimits()
|
||||
default:
|
||||
return client.labrinth.limits_v3.getProjectLimits()
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const typeName = computed<{ singular: string; plural: string }>(() => {
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import {
|
||||
ArrowLeftRightIcon,
|
||||
ChevronRightIcon,
|
||||
@@ -131,7 +132,6 @@ import {
|
||||
getTaxThreshold,
|
||||
getTaxThresholdActual,
|
||||
type PaymentProvider,
|
||||
type PayoutMethod,
|
||||
provideWithdrawContext,
|
||||
type WithdrawStage,
|
||||
} from '@/providers/creator-withdraw.ts'
|
||||
@@ -146,21 +146,9 @@ import MuralpayKycStage from './withdraw-stages/MuralpayKycStage.vue'
|
||||
import TaxFormStage from './withdraw-stages/TaxFormStage.vue'
|
||||
import TremendousDetailsStage from './withdraw-stages/TremendousDetailsStage.vue'
|
||||
|
||||
type FormCompletionStatus = 'unknown' | 'unrequested' | 'unsigned' | 'tin-mismatch' | 'complete'
|
||||
|
||||
interface UserBalanceResponse {
|
||||
available: number
|
||||
withdrawn_lifetime: number
|
||||
withdrawn_ytd: number
|
||||
pending: number
|
||||
dates: Record<string, number>
|
||||
requested_form_type: string | null
|
||||
form_completion_status: FormCompletionStatus | null
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
balance: UserBalanceResponse | null
|
||||
preloadedPaymentData?: { country: string; methods: PayoutMethod[] } | null
|
||||
balance: Labrinth.Payout.v3.PayoutBalance | null | undefined
|
||||
preloadedPaymentData?: { country: string; methods: Labrinth.Payout.v3.PayoutMethod[] } | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import {
|
||||
ArrowDownIcon,
|
||||
ArrowUpIcon,
|
||||
@@ -89,31 +90,7 @@ import { Tooltip } from 'floating-vue'
|
||||
import { useGeneratedState } from '~/composables/generated'
|
||||
import { findRail } from '~/utils/muralpay-rails'
|
||||
|
||||
type PayoutStatus = 'in-transit' | 'cancelling' | 'cancelled' | 'success' | 'failed'
|
||||
type PayoutMethodType = 'paypal' | 'venmo' | 'tremendous' | 'muralpay'
|
||||
type PayoutSource = 'creator_rewards' | 'affilites'
|
||||
|
||||
type WithdrawalTransaction = {
|
||||
type: 'withdrawal'
|
||||
id: string
|
||||
status: PayoutStatus
|
||||
created: string
|
||||
amount: number
|
||||
fee?: number | null
|
||||
method_type?: PayoutMethodType | null
|
||||
method?: string
|
||||
method_id?: string
|
||||
method_address?: string | null
|
||||
}
|
||||
|
||||
type PayoutAvailableTransaction = {
|
||||
type: 'payout_available'
|
||||
created: string
|
||||
payout_source: PayoutSource
|
||||
amount: number
|
||||
}
|
||||
|
||||
type Transaction = WithdrawalTransaction | PayoutAvailableTransaction
|
||||
type Transaction = Labrinth.Payout.v3.TransactionItem
|
||||
|
||||
const props = defineProps<{
|
||||
transaction: Transaction
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { injectModrinthClient } from '@modrinth/ui'
|
||||
import { useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import Breadcrumbs from '~/components/ui/Breadcrumbs.vue'
|
||||
import ReportInfo from '~/components/ui/report/ReportInfo.vue'
|
||||
import ConversationThread from '~/components/ui/thread/ConversationThread.vue'
|
||||
import { useBaseFetch } from '~/composables/fetch.js'
|
||||
import { addReportMessage } from '~/helpers/threads.js'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -45,16 +45,13 @@ const props = defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
// Fetch raw report
|
||||
const { data: rawReport } = useQuery({
|
||||
queryKey: computed(() => ['report', props.reportId]),
|
||||
queryFn: async () => {
|
||||
const data = await useBaseFetch(`report/${props.reportId}`)
|
||||
data.item_id = data.item_id.replace(/"/g, '')
|
||||
return data
|
||||
},
|
||||
queryFn: () => client.labrinth.reports_v3.get(props.reportId),
|
||||
})
|
||||
|
||||
// Compute user IDs needed
|
||||
@@ -70,7 +67,7 @@ const userIds = computed(() => {
|
||||
// Fetch users
|
||||
const { data: users } = useQuery({
|
||||
queryKey: computed(() => ['users', userIds.value]),
|
||||
queryFn: () => useBaseFetch(`users?ids=${encodeURIComponent(JSON.stringify(userIds.value))}`),
|
||||
queryFn: () => client.labrinth.users_v2.getMultiple(userIds.value),
|
||||
enabled: computed(() => userIds.value.length > 0),
|
||||
})
|
||||
|
||||
@@ -82,7 +79,7 @@ const versionId = computed(() =>
|
||||
// Fetch version
|
||||
const { data: version } = useQuery({
|
||||
queryKey: computed(() => ['version', versionId.value]),
|
||||
queryFn: () => useBaseFetch(`version/${versionId.value}`),
|
||||
queryFn: () => client.labrinth.versions_v2.getVersion(versionId.value),
|
||||
enabled: computed(() => !!versionId.value),
|
||||
})
|
||||
|
||||
@@ -96,7 +93,7 @@ const projectId = computed(() => {
|
||||
// Fetch project
|
||||
const { data: project } = useQuery({
|
||||
queryKey: computed(() => ['project', projectId.value]),
|
||||
queryFn: () => useBaseFetch(`project/${projectId.value}`),
|
||||
queryFn: () => client.labrinth.projects_v2.get(projectId.value),
|
||||
enabled: computed(() => !!projectId.value),
|
||||
})
|
||||
|
||||
@@ -118,7 +115,7 @@ const report = computed(() => {
|
||||
// Fetch thread
|
||||
const { data: rawThread } = useQuery({
|
||||
queryKey: computed(() => ['thread', report.value?.thread_id]),
|
||||
queryFn: () => useBaseFetch(`thread/${report.value.thread_id}`),
|
||||
queryFn: () => client.labrinth.threads_v3.getThread(report.value.thread_id),
|
||||
enabled: computed(() => !!report.value?.thread_id),
|
||||
})
|
||||
|
||||
|
||||
@@ -24,14 +24,13 @@
|
||||
<p v-if="filteredReports.length === 0">You don't have any active reports.</p>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Chips } from '@modrinth/ui'
|
||||
import { Chips, injectModrinthClient } from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import ReportInfo from '~/components/ui/report/ReportInfo.vue'
|
||||
import { useBaseFetch } from '~/composables/fetch.js'
|
||||
import { addReportMessage } from '~/helpers/threads.js'
|
||||
import { asEncodedJsonArray, fetchSegmented } from '~/utils/fetch-helpers.ts'
|
||||
import { fetchSegmentedWith } from '~/utils/fetch-helpers.ts'
|
||||
|
||||
const props = defineProps({
|
||||
moderation: {
|
||||
@@ -44,6 +43,7 @@ const props = defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const viewMode = ref('open')
|
||||
const reasonFilter = ref('All')
|
||||
|
||||
@@ -51,16 +51,11 @@ const MAX_REPORTS = 1500
|
||||
|
||||
const { data: rawReportsData } = useQuery({
|
||||
queryKey: ['reports', MAX_REPORTS],
|
||||
queryFn: () => useBaseFetch(`report?count=${MAX_REPORTS}`),
|
||||
queryFn: () => client.labrinth.reports_v3.list({ count: MAX_REPORTS }),
|
||||
placeholderData: [],
|
||||
})
|
||||
|
||||
const rawReports = computed(() =>
|
||||
rawReportsData.value.map((report) => ({
|
||||
...report,
|
||||
item_id: report.item_id.replace(/"/g, ''),
|
||||
})),
|
||||
)
|
||||
const rawReports = computed(() => rawReportsData.value)
|
||||
|
||||
const reporterUsers = computed(() => rawReports.value.map((report) => report.reporter))
|
||||
const reportedUsers = computed(() =>
|
||||
@@ -85,7 +80,8 @@ const reasons = computed(() => [
|
||||
|
||||
const { data: users } = useQuery({
|
||||
queryKey: computed(() => ['users', userIds.value]),
|
||||
queryFn: () => fetchSegmented(userIds.value, (ids) => `users?ids=${asEncodedJsonArray(ids)}`),
|
||||
queryFn: () =>
|
||||
fetchSegmentedWith(userIds.value, (ids) => client.labrinth.users_v2.getMultiple(ids)),
|
||||
enabled: computed(() => userIds.value.length > 0),
|
||||
placeholderData: [],
|
||||
})
|
||||
@@ -93,14 +89,15 @@ const { data: users } = useQuery({
|
||||
const { data: versions } = useQuery({
|
||||
queryKey: computed(() => ['versions', versionIds.value]),
|
||||
queryFn: () =>
|
||||
fetchSegmented(versionIds.value, (ids) => `versions?ids=${asEncodedJsonArray(ids)}`),
|
||||
fetchSegmentedWith(versionIds.value, (ids) => client.labrinth.versions_v2.getVersions(ids)),
|
||||
enabled: computed(() => versionIds.value.length > 0),
|
||||
placeholderData: [],
|
||||
})
|
||||
|
||||
const { data: threads } = useQuery({
|
||||
queryKey: computed(() => ['threads', threadIds.value]),
|
||||
queryFn: () => fetchSegmented(threadIds.value, (ids) => `threads?ids=${asEncodedJsonArray(ids)}`),
|
||||
queryFn: () =>
|
||||
fetchSegmentedWith(threadIds.value, (ids) => client.labrinth.threads_v3.getMultiple(ids)),
|
||||
enabled: computed(() => threadIds.value.length > 0),
|
||||
placeholderData: [],
|
||||
})
|
||||
@@ -118,7 +115,7 @@ const projectIds = computed(() => [
|
||||
const { data: projects } = useQuery({
|
||||
queryKey: computed(() => ['projects', projectIds.value]),
|
||||
queryFn: () =>
|
||||
fetchSegmented(projectIds.value, (ids) => `projects?ids=${asEncodedJsonArray(ids)}`),
|
||||
fetchSegmentedWith(projectIds.value, (ids) => client.labrinth.projects_v2.getMultiple(ids)),
|
||||
enabled: computed(() => projectIds.value.length > 0),
|
||||
placeholderData: [],
|
||||
})
|
||||
|
||||
@@ -1,47 +1,15 @@
|
||||
import type { Organization, Project, Report, User, Version } from '@modrinth/utils'
|
||||
import type { AbstractModrinthClient, Labrinth } from '@modrinth/api-client'
|
||||
|
||||
type Thread = { id: string }
|
||||
type Notification = Labrinth.Notifications.v2.Notification
|
||||
|
||||
export type PlatformNotificationAction = {
|
||||
title: string
|
||||
action_route: [string, string]
|
||||
}
|
||||
|
||||
export type PlatformNotificationBody = {
|
||||
project_id?: string
|
||||
version_id?: string
|
||||
report_id?: string
|
||||
thread_id?: string
|
||||
invited_by?: string
|
||||
organization_id?: string
|
||||
}
|
||||
|
||||
export type PlatformNotification = {
|
||||
id: string
|
||||
user_id: string
|
||||
type: 'project_update' | 'team_invite' | 'status_change' | 'moderator_message'
|
||||
title: string
|
||||
text: string
|
||||
link: string
|
||||
read: boolean
|
||||
created: string
|
||||
actions: PlatformNotificationAction[]
|
||||
body?: PlatformNotificationBody
|
||||
export type PlatformNotification = Notification & {
|
||||
extra_data?: Record<string, unknown>
|
||||
grouped_notifs?: PlatformNotification[]
|
||||
}
|
||||
|
||||
async function getBulk<T extends { id: string }>(
|
||||
type: string,
|
||||
ids: string[],
|
||||
apiVersion = 2,
|
||||
): Promise<T[]> {
|
||||
if (!ids || ids.length === 0) {
|
||||
return []
|
||||
}
|
||||
const url = `${type}?ids=${encodeURIComponent(JSON.stringify([...new Set(ids)]))}`
|
||||
async function safeBulkFetch<T>(fn: () => Promise<T[]>): Promise<T[]> {
|
||||
try {
|
||||
const res = await useBaseFetch(url, { apiVersion })
|
||||
const res = await fn()
|
||||
return Array.isArray(res) ? res : []
|
||||
} catch {
|
||||
return []
|
||||
@@ -49,6 +17,7 @@ async function getBulk<T extends { id: string }>(
|
||||
}
|
||||
|
||||
export async function fetchExtraNotificationData(
|
||||
client: AbstractModrinthClient,
|
||||
notifications: PlatformNotification[],
|
||||
): Promise<PlatformNotification[]> {
|
||||
const bulk = {
|
||||
@@ -72,7 +41,14 @@ export async function fetchExtraNotificationData(
|
||||
}
|
||||
}
|
||||
|
||||
const reports = (await getBulk<Report>('reports', bulk.reports)).filter(Boolean)
|
||||
const reports = (
|
||||
await safeBulkFetch(() =>
|
||||
bulk.reports.length > 0
|
||||
? client.labrinth.reports_v3.getMultiple([...new Set(bulk.reports)])
|
||||
: Promise.resolve([]),
|
||||
)
|
||||
).filter(Boolean)
|
||||
|
||||
for (const r of reports) {
|
||||
if (!r?.item_type) continue
|
||||
if (r.item_type === 'project') bulk.projects.push(r.item_id)
|
||||
@@ -80,16 +56,42 @@ export async function fetchExtraNotificationData(
|
||||
else if (r.item_type === 'version') bulk.versions.push(r.item_id)
|
||||
}
|
||||
|
||||
const versions = (await getBulk<Version>('versions', bulk.versions)).filter(Boolean)
|
||||
const versions = (
|
||||
await safeBulkFetch(() =>
|
||||
bulk.versions.length > 0
|
||||
? client.labrinth.versions_v2.getVersions([...new Set(bulk.versions)])
|
||||
: Promise.resolve([]),
|
||||
)
|
||||
).filter(Boolean)
|
||||
|
||||
for (const v of versions) bulk.projects.push(v.project_id)
|
||||
|
||||
const [projects, threads, users, organizations] = await Promise.all([
|
||||
getBulk<Project>('projects', bulk.projects),
|
||||
getBulk<Thread>('threads', bulk.threads),
|
||||
getBulk<User>('users', bulk.users),
|
||||
getBulk<Organization>('organizations', bulk.organizations, 3),
|
||||
safeBulkFetch(() =>
|
||||
bulk.projects.length > 0
|
||||
? client.labrinth.projects_v2.getMultiple([...new Set(bulk.projects)])
|
||||
: Promise.resolve([]),
|
||||
),
|
||||
safeBulkFetch(() =>
|
||||
bulk.threads.length > 0
|
||||
? client.labrinth.threads_v3.getMultiple([...new Set(bulk.threads)])
|
||||
: Promise.resolve([]),
|
||||
),
|
||||
safeBulkFetch(() =>
|
||||
bulk.users.length > 0
|
||||
? client.labrinth.users_v2.getMultiple([...new Set(bulk.users)])
|
||||
: Promise.resolve([]),
|
||||
),
|
||||
safeBulkFetch(() =>
|
||||
bulk.organizations.length > 0
|
||||
? client.labrinth.organizations_v3.getMultiple([...new Set(bulk.organizations)])
|
||||
: Promise.resolve([]),
|
||||
),
|
||||
])
|
||||
|
||||
type Report = Labrinth.Reports.v3.Report
|
||||
type Version = Labrinth.Versions.v2.Version
|
||||
|
||||
for (const n of notifications) {
|
||||
n.extra_data = {}
|
||||
if (n.body) {
|
||||
@@ -153,11 +155,10 @@ function isSimilar(a: PlatformNotification, b: PlatformNotification | undefined)
|
||||
}
|
||||
|
||||
export async function markAsRead(
|
||||
client: AbstractModrinthClient,
|
||||
ids: string[],
|
||||
): Promise<(notifications: PlatformNotification[]) => PlatformNotification[]> {
|
||||
await useBaseFetch(`notifications?ids=${JSON.stringify([...new Set(ids)])}`, {
|
||||
method: 'PATCH',
|
||||
})
|
||||
await client.labrinth.notifications_v2.markMultipleAsRead(ids)
|
||||
return (notifications: PlatformNotification[]) => {
|
||||
const newNotifs = notifications ?? []
|
||||
newNotifs.forEach((n) => {
|
||||
|
||||
@@ -1541,7 +1541,7 @@ async function getLicenseData(event) {
|
||||
modalLicense.value.show(event)
|
||||
|
||||
try {
|
||||
const text = await useBaseFetch(`tag/license/${project.value.license.id}`)
|
||||
const text = await client.labrinth.tags_v2.getLicenseText(project.value.license.id)
|
||||
licenseText.value = text.body || formatMessage(messages.licenseErrorMessage)
|
||||
} catch {
|
||||
licenseText.value = formatMessage(messages.licenseErrorMessage)
|
||||
@@ -1895,10 +1895,7 @@ async function invalidateProject() {
|
||||
// Mutation for patching project data
|
||||
const patchProjectMutation = useMutation({
|
||||
mutationFn: async ({ projectId, data }) => {
|
||||
await useBaseFetch(`project/${projectId}`, {
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
})
|
||||
await client.labrinth.projects_v2.edit(projectId, data)
|
||||
return data
|
||||
},
|
||||
|
||||
@@ -1942,10 +1939,7 @@ const patchProjectMutation = useMutation({
|
||||
// Mutation for changing project status (setProcessing)
|
||||
const patchStatusMutation = useMutation({
|
||||
mutationFn: async ({ projectId, status }) => {
|
||||
await useBaseFetch(`project/${projectId}`, {
|
||||
method: 'PATCH',
|
||||
body: { status },
|
||||
})
|
||||
await client.labrinth.projects_v2.edit(projectId, { status })
|
||||
},
|
||||
|
||||
onMutate: async ({ projectId, status }) => {
|
||||
@@ -2038,13 +2032,8 @@ const patchProjectV3Mutation = useMutation({
|
||||
// Mutation for patching project icon
|
||||
const patchIconMutation = useMutation({
|
||||
mutationFn: async ({ projectId, icon }) => {
|
||||
await useBaseFetch(
|
||||
`project/${projectId}/icon?ext=${icon.type.split('/')[icon.type.split('/').length - 1]}`,
|
||||
{
|
||||
method: 'PATCH',
|
||||
body: icon,
|
||||
},
|
||||
)
|
||||
const ext = icon.type.split('/')[icon.type.split('/').length - 1]
|
||||
await client.labrinth.projects_v3.changeIcon(projectId, icon, ext)
|
||||
},
|
||||
|
||||
onSuccess: () => {
|
||||
@@ -2070,23 +2059,13 @@ const patchIconMutation = useMutation({
|
||||
|
||||
const createGalleryItemMutation = useMutation({
|
||||
mutationFn: async ({ projectId, file, title, description, featured, ordering }) => {
|
||||
let url = `project/${projectId}/gallery?ext=${
|
||||
file.type.split('/')[file.type.split('/').length - 1]
|
||||
}&featured=${featured ?? false}`
|
||||
|
||||
if (title != null) {
|
||||
url += `&title=${encodeURIComponent(title)}`
|
||||
}
|
||||
if (description != null) {
|
||||
url += `&description=${encodeURIComponent(description)}`
|
||||
}
|
||||
if (ordering !== null && ordering !== undefined) {
|
||||
url += `&ordering=${ordering}`
|
||||
}
|
||||
|
||||
await useBaseFetch(url, {
|
||||
method: 'POST',
|
||||
body: file,
|
||||
const ext = file.type.split('/')[file.type.split('/').length - 1]
|
||||
await client.labrinth.projects_v2.createGalleryImage(projectId, file, {
|
||||
ext,
|
||||
featured: featured ?? false,
|
||||
title,
|
||||
description,
|
||||
ordering,
|
||||
})
|
||||
},
|
||||
|
||||
@@ -2133,20 +2112,11 @@ const createGalleryItemMutation = useMutation({
|
||||
|
||||
const editGalleryItemMutation = useMutation({
|
||||
mutationFn: async ({ projectId, imageUrl, title, description, featured, ordering }) => {
|
||||
let url = `project/${projectId}/gallery?url=${encodeURIComponent(imageUrl)}&featured=${featured ?? false}`
|
||||
|
||||
if (title != null) {
|
||||
url += `&title=${encodeURIComponent(title)}`
|
||||
}
|
||||
if (description != null) {
|
||||
url += `&description=${encodeURIComponent(description)}`
|
||||
}
|
||||
if (ordering !== null && ordering !== undefined) {
|
||||
url += `&ordering=${ordering}`
|
||||
}
|
||||
|
||||
await useBaseFetch(url, {
|
||||
method: 'PATCH',
|
||||
await client.labrinth.projects_v2.editGalleryImage(projectId, imageUrl, {
|
||||
featured: featured ?? false,
|
||||
title,
|
||||
description,
|
||||
ordering,
|
||||
})
|
||||
},
|
||||
|
||||
@@ -2195,9 +2165,7 @@ const editGalleryItemMutation = useMutation({
|
||||
|
||||
const deleteGalleryItemMutation = useMutation({
|
||||
mutationFn: async ({ projectId, imageUrl }) => {
|
||||
await useBaseFetch(`project/${projectId}/gallery?url=${encodeURIComponent(imageUrl)}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
await client.labrinth.projects_v2.deleteGalleryImage(projectId, imageUrl)
|
||||
},
|
||||
|
||||
onMutate: async ({ imageUrl }) => {
|
||||
@@ -2562,9 +2530,7 @@ async function deleteVersion(id) {
|
||||
|
||||
startLoading()
|
||||
|
||||
await useBaseFetch(`version/${id}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
await client.labrinth.versions_v3.deleteVersion(id)
|
||||
|
||||
await invalidateProject()
|
||||
|
||||
|
||||
@@ -100,12 +100,16 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { CheckIcon, IssuesIcon, XIcon } from '@modrinth/assets'
|
||||
import { Badge, injectNotificationManager, injectProjectPageContext } from '@modrinth/ui'
|
||||
import {
|
||||
Badge,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
injectProjectPageContext,
|
||||
} from '@modrinth/ui'
|
||||
import { useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import ConversationThread from '~/components/ui/thread/ConversationThread.vue'
|
||||
import { useBaseFetch } from '~/composables/fetch.js'
|
||||
import {
|
||||
getProjectLink,
|
||||
isApproved,
|
||||
@@ -119,11 +123,12 @@ const { addNotification } = injectNotificationManager()
|
||||
const { projectV2: project, currentMember, invalidate } = injectProjectPageContext()
|
||||
|
||||
const auth = await useAuth()
|
||||
const client = injectModrinthClient()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const { data: thread } = useQuery({
|
||||
queryKey: computed(() => ['thread', project.value?.thread_id]),
|
||||
queryFn: () => useBaseFetch(`thread/${project.value.thread_id}`),
|
||||
queryFn: () => client.labrinth.threads_v3.getThread(project.value.thread_id),
|
||||
enabled: computed(() => !!project.value?.thread_id),
|
||||
})
|
||||
|
||||
@@ -131,12 +136,7 @@ async function setStatus(status) {
|
||||
startLoading()
|
||||
|
||||
try {
|
||||
const data = {}
|
||||
data.status = status
|
||||
await useBaseFetch(`project/${project.value.id}`, {
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
})
|
||||
await client.labrinth.projects_v2.edit(project.value.id, { status })
|
||||
|
||||
project.value.status = status
|
||||
await invalidate()
|
||||
|
||||
@@ -558,6 +558,7 @@ import {
|
||||
Checkbox,
|
||||
Combobox,
|
||||
ConfirmModal,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
injectProjectPageContext,
|
||||
StyledInput,
|
||||
@@ -566,9 +567,9 @@ import {
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
import ConfirmTransferProjectModal from '~/components/ui/ConfirmTransferProjectModal.vue'
|
||||
import { useBaseFetch } from '~/composables/fetch.js'
|
||||
import { removeSelfFromTeam } from '~/helpers/teams.js'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const {
|
||||
projectV2: project,
|
||||
@@ -623,10 +624,7 @@ const transferModal = ref(null)
|
||||
|
||||
const { data: organizations } = useQuery({
|
||||
queryKey: computed(() => ['user', auth.value?.user?.id, 'organizations']),
|
||||
queryFn: () =>
|
||||
useBaseFetch('user/' + auth.value?.user.id + '/organizations', {
|
||||
apiVersion: 3,
|
||||
}),
|
||||
queryFn: () => client.labrinth.users_v2.getOrganizations(auth.value?.user.id),
|
||||
enabled: computed(() => !!auth.value?.user?.id),
|
||||
})
|
||||
|
||||
@@ -655,12 +653,8 @@ const VIEW_PAYOUTS = 1 << 9
|
||||
const onAddToOrg = useClientTry(async () => {
|
||||
if (!selectedOrganizationId.value) return
|
||||
|
||||
await useBaseFetch(`organization/${selectedOrganizationId.value}/projects`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
project_id: project.value.id,
|
||||
}),
|
||||
apiVersion: 3,
|
||||
await client.labrinth.organizations_v3.addProject(selectedOrganizationId.value, {
|
||||
project_id: project.value.id,
|
||||
})
|
||||
|
||||
await updateMembers()
|
||||
@@ -675,13 +669,11 @@ const onAddToOrg = useClientTry(async () => {
|
||||
const onRemoveFromOrg = useClientTry(async () => {
|
||||
if (!project.value.organization || !auth.value?.user?.id) return
|
||||
|
||||
await useBaseFetch(`organization/${project.value.organization}/projects/${project.value.id}`, {
|
||||
method: 'DELETE',
|
||||
body: JSON.stringify({
|
||||
new_owner: auth.value.user.id,
|
||||
}),
|
||||
apiVersion: 3,
|
||||
})
|
||||
await client.labrinth.organizations_v3.removeProject(
|
||||
project.value.organization,
|
||||
project.value.id,
|
||||
{ new_owner: auth.value.user.id },
|
||||
)
|
||||
|
||||
await updateMembers()
|
||||
|
||||
@@ -701,13 +693,9 @@ const inviteTeamMember = async () => {
|
||||
startLoading()
|
||||
|
||||
try {
|
||||
const user = await useBaseFetch(`user/${currentUsername.value}`)
|
||||
const data = {
|
||||
const user = await client.labrinth.users_v2.get(currentUsername.value)
|
||||
await client.labrinth.teams_v2.addMember(project.value.team, {
|
||||
user_id: user.id.trim(),
|
||||
}
|
||||
await useBaseFetch(`team/${project.value.team}/members`, {
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
currentUsername.value = ''
|
||||
await updateMembers()
|
||||
@@ -726,11 +714,9 @@ const removeTeamMember = async (index) => {
|
||||
startLoading()
|
||||
|
||||
try {
|
||||
await useBaseFetch(
|
||||
`team/${project.value.team}/members/${allTeamMembers.value[index].user.id}`,
|
||||
{
|
||||
method: 'DELETE',
|
||||
},
|
||||
await client.labrinth.teams_v2.removeMember(
|
||||
project.value.team,
|
||||
allTeamMembers.value[index].user.id,
|
||||
)
|
||||
await updateMembers()
|
||||
addNotification({
|
||||
@@ -764,12 +750,10 @@ const updateTeamMember = async (index) => {
|
||||
role: allTeamMembers.value[index].role,
|
||||
}
|
||||
|
||||
await useBaseFetch(
|
||||
`team/${project.value.team}/members/${allTeamMembers.value[index].user.id}`,
|
||||
{
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
},
|
||||
await client.labrinth.teams_v2.editMember(
|
||||
project.value.team,
|
||||
allTeamMembers.value[index].user.id,
|
||||
data,
|
||||
)
|
||||
await updateMembers()
|
||||
addNotification({
|
||||
@@ -820,11 +804,8 @@ const transferOwnership = async (index) => {
|
||||
startLoading()
|
||||
|
||||
try {
|
||||
await useBaseFetch(`team/${project.value.team}/owner`, {
|
||||
method: 'PATCH',
|
||||
body: {
|
||||
user_id: allTeamMembers.value[index].user.id,
|
||||
},
|
||||
await client.labrinth.teams_v2.transferOwnership(project.value.team, {
|
||||
user_id: allTeamMembers.value[index].user.id,
|
||||
})
|
||||
addNotification({
|
||||
title: 'Member ownership transferred',
|
||||
@@ -848,32 +829,25 @@ async function updateOrgMember(index) {
|
||||
|
||||
try {
|
||||
if (allOrgMembers.value[index].override && !allOrgMembers.value[index].oldOverride) {
|
||||
await useBaseFetch(`team/${project.value.team}/members`, {
|
||||
method: 'POST',
|
||||
body: {
|
||||
await client.labrinth.teams_v2.addMember(project.value.team, {
|
||||
permissions: allOrgMembers.value[index].permissions,
|
||||
role: allOrgMembers.value[index].role,
|
||||
payouts_split: allOrgMembers.value[index].payouts_split,
|
||||
user_id: allOrgMembers.value[index].user.id,
|
||||
})
|
||||
} else if (!allOrgMembers.value[index].override && allOrgMembers.value[index].oldOverride) {
|
||||
await client.labrinth.teams_v2.removeMember(
|
||||
project.value.team,
|
||||
allOrgMembers.value[index].user.id,
|
||||
)
|
||||
} else {
|
||||
await client.labrinth.teams_v2.editMember(
|
||||
project.value.team,
|
||||
allOrgMembers.value[index].user.id,
|
||||
{
|
||||
permissions: allOrgMembers.value[index].permissions,
|
||||
role: allOrgMembers.value[index].role,
|
||||
payouts_split: allOrgMembers.value[index].payouts_split,
|
||||
user_id: allOrgMembers.value[index].user.id,
|
||||
},
|
||||
})
|
||||
} else if (!allOrgMembers.value[index].override && allOrgMembers.value[index].oldOverride) {
|
||||
await useBaseFetch(
|
||||
`team/${project.value.team}/members/${allOrgMembers.value[index].user.id}`,
|
||||
{
|
||||
method: 'DELETE',
|
||||
},
|
||||
)
|
||||
} else {
|
||||
await useBaseFetch(
|
||||
`team/${project.value.team}/members/${allOrgMembers.value[index].user.id}`,
|
||||
{
|
||||
method: 'PATCH',
|
||||
body: {
|
||||
permissions: allOrgMembers.value[index].permissions,
|
||||
role: allOrgMembers.value[index].role,
|
||||
payouts_split: allOrgMembers.value[index].payouts_split,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import { PlusIcon, SearchIcon, XCircleIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Accordion,
|
||||
@@ -91,20 +92,20 @@ import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
ConfirmModal,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
StyledInput,
|
||||
} from '@modrinth/ui'
|
||||
import type { AffiliateLink, User } from '@modrinth/utils'
|
||||
import type { User } from '@modrinth/utils'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { useBaseFetch } from '~/composables/fetch.js'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { handleError } = injectNotificationManager()
|
||||
|
||||
type UserGroup = {
|
||||
user: User
|
||||
affiliates: AffiliateLink[]
|
||||
affiliates: Labrinth.Affiliate.Internal.AffiliateCode[]
|
||||
}
|
||||
|
||||
const createModal = useTemplateRef<typeof AffiliateLinkCreateModal>('createModal')
|
||||
@@ -116,8 +117,7 @@ const {
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: ['affiliate'],
|
||||
queryFn: () =>
|
||||
useBaseFetch('affiliate', { method: 'GET', internal: true }) as Promise<AffiliateLink[]>,
|
||||
queryFn: () => client.labrinth.affiliate_internal.getAll(),
|
||||
})
|
||||
|
||||
const filterQuery = ref('')
|
||||
@@ -130,7 +130,9 @@ const userIds = computed(() => {
|
||||
const ids = new Set<string>()
|
||||
affiliateCodes.value.forEach((code) => {
|
||||
ids.add(code.affiliate)
|
||||
ids.add(code.created_by)
|
||||
if (code.created_by) {
|
||||
ids.add(code.created_by)
|
||||
}
|
||||
})
|
||||
return Array.from(ids)
|
||||
})
|
||||
@@ -139,7 +141,7 @@ const { data: users } = useQuery({
|
||||
queryKey: computed(() => ['users-bulk', userIds.value]),
|
||||
queryFn: () => {
|
||||
if (userIds.value.length === 0) return Promise.resolve([])
|
||||
return useBaseFetch(`users?ids=${JSON.stringify(userIds.value)}`) as Promise<User[]>
|
||||
return client.labrinth.users_v2.getMultiple(userIds.value)
|
||||
},
|
||||
})
|
||||
|
||||
@@ -189,7 +191,8 @@ const filteredGroupedAffiliates = computed(() => {
|
||||
)
|
||||
})
|
||||
|
||||
function getCreatedByUsername(createdBy: string): string {
|
||||
function getCreatedByUsername(createdBy: string | null): string {
|
||||
if (!createdBy) return 'Unknown'
|
||||
const user = userMap.value.get(createdBy)
|
||||
return user?.username || 'Unknown'
|
||||
}
|
||||
@@ -207,7 +210,7 @@ async function createAffiliateCode(data: { sourceName: string; username?: string
|
||||
|
||||
if (!user) {
|
||||
try {
|
||||
user = (await useBaseFetch(`user/${data.username}`)) as User
|
||||
user = await client.labrinth.users_v2.get(data.username)
|
||||
|
||||
if (users.value) {
|
||||
users.value.push(user)
|
||||
@@ -218,19 +221,15 @@ async function createAffiliateCode(data: { sourceName: string; username?: string
|
||||
}
|
||||
}
|
||||
|
||||
await useBaseFetch('affiliate', {
|
||||
method: 'PUT',
|
||||
body: {
|
||||
affiliate: user.id,
|
||||
source_name: data.sourceName,
|
||||
},
|
||||
internal: true,
|
||||
await client.labrinth.affiliate_internal.create({
|
||||
affiliate: user.id,
|
||||
source_name: data.sourceName,
|
||||
})
|
||||
|
||||
await refetch()
|
||||
createModal.value?.close()
|
||||
} catch (err) {
|
||||
handleError(err)
|
||||
handleError(err as Error)
|
||||
} finally {
|
||||
creatingLink.value = false
|
||||
}
|
||||
@@ -239,7 +238,7 @@ async function createAffiliateCode(data: { sourceName: string; username?: string
|
||||
const revokingAffiliateUsername = ref<string | null>(null)
|
||||
const revokingAffiliateId = ref<string | null>(null)
|
||||
|
||||
function revokeAffiliateCode(affiliate: AffiliateLink) {
|
||||
function revokeAffiliateCode(affiliate: Labrinth.Affiliate.Internal.AffiliateCode) {
|
||||
const user = userMap.value.get(affiliate.affiliate)
|
||||
revokingAffiliateUsername.value = user?.username || 'Unknown'
|
||||
revokingAffiliateId.value = affiliate.id
|
||||
@@ -252,10 +251,7 @@ async function confirmRevokeAffiliateCode() {
|
||||
}
|
||||
|
||||
try {
|
||||
await useBaseFetch(`affiliate/${revokingAffiliateId.value}`, {
|
||||
method: 'DELETE',
|
||||
internal: true,
|
||||
})
|
||||
await client.labrinth.affiliate_internal.delete(revokingAffiliateId.value)
|
||||
|
||||
await refetch()
|
||||
revokeModal.value?.hide()
|
||||
|
||||
@@ -328,6 +328,7 @@ import {
|
||||
CopyCode,
|
||||
defineMessages,
|
||||
DropdownSelect,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
StyledInput,
|
||||
@@ -343,9 +344,9 @@ import { useQuery } from '@tanstack/vue-query'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
import ModrinthServersIcon from '~/components/ui/servers/ModrinthServersIcon.vue'
|
||||
import { useBaseFetch } from '~/composables/fetch.js'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const client = injectModrinthClient()
|
||||
const formatPrice = useFormatPrice()
|
||||
const formatDateTime = useFormatDateTime({
|
||||
timeStyle: 'short',
|
||||
@@ -374,7 +375,7 @@ const messages = defineMessages({
|
||||
|
||||
const { data: user, error: userError } = useQuery({
|
||||
queryKey: ['user', route.params.id],
|
||||
queryFn: () => useBaseFetch(`user/${route.params.id}`),
|
||||
queryFn: () => client.labrinth.users_v2.get(route.params.id),
|
||||
})
|
||||
|
||||
watch(userError, (error) => {
|
||||
@@ -389,20 +390,14 @@ watch(userError, (error) => {
|
||||
|
||||
const { data: subscriptions } = useQuery({
|
||||
queryKey: computed(() => ['billing', 'subscriptions', user.value?.id]),
|
||||
queryFn: () =>
|
||||
useBaseFetch(`billing/subscriptions?user_id=${user.value.id}`, {
|
||||
internal: true,
|
||||
}),
|
||||
queryFn: () => client.labrinth.billing_internal.getSubscriptions(user.value.id),
|
||||
enabled: computed(() => !!user.value?.id),
|
||||
placeholderData: [],
|
||||
})
|
||||
|
||||
const { data: charges, refetch: refreshCharges } = useQuery({
|
||||
queryKey: computed(() => ['billing', 'payments', user.value?.id]),
|
||||
queryFn: () =>
|
||||
useBaseFetch(`billing/payments?user_id=${user.value.id}`, {
|
||||
internal: true,
|
||||
}),
|
||||
queryFn: () => client.labrinth.billing_internal.getPayments(user.value.id),
|
||||
enabled: computed(() => !!user.value?.id),
|
||||
placeholderData: [],
|
||||
})
|
||||
@@ -463,15 +458,11 @@ async function applyCredit() {
|
||||
crediting.value = true
|
||||
try {
|
||||
const daysParsed = Math.max(1, Math.floor(Number(creditDays.value) || 1))
|
||||
await useBaseFetch('billing/credit', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
subscription_ids: [selectedSubscription.value.id],
|
||||
days: daysParsed,
|
||||
send_email: creditSendEmail.value,
|
||||
message: DEFAULT_CREDIT_EMAIL_MESSAGE,
|
||||
}),
|
||||
internal: true,
|
||||
await client.labrinth.billing_internal.credit({
|
||||
subscription_ids: [selectedSubscription.value.id],
|
||||
days: daysParsed,
|
||||
send_email: creditSendEmail.value,
|
||||
message: DEFAULT_CREDIT_EMAIL_MESSAGE,
|
||||
})
|
||||
addNotification({
|
||||
title: 'Credit applied',
|
||||
@@ -501,11 +492,7 @@ async function refundCharge() {
|
||||
? { type: 'none', unprovision: unprovision.value }
|
||||
: { type: 'full', unprovision: unprovision.value }
|
||||
|
||||
await useBaseFetch(`billing/charge/${selectedCharge.value.id}/refund`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(payload),
|
||||
internal: true,
|
||||
})
|
||||
await client.labrinth.billing_internal.refundCharge(selectedCharge.value.id, payload)
|
||||
await refreshCharges()
|
||||
refundModal.value.hide()
|
||||
} catch (err) {
|
||||
@@ -521,12 +508,8 @@ async function refundCharge() {
|
||||
async function modifyCharge() {
|
||||
modifying.value = true
|
||||
try {
|
||||
await useBaseFetch(`billing/subscription/${selectedSubscription.value.id}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({
|
||||
cancelled: cancel.value,
|
||||
}),
|
||||
internal: true,
|
||||
await client.labrinth.billing_internal.editSubscription(selectedSubscription.value.id, {
|
||||
cancelled: cancel.value,
|
||||
})
|
||||
addNotification({
|
||||
title: 'Modifications made',
|
||||
|
||||
@@ -86,6 +86,7 @@ import {
|
||||
Button,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
normalizeChildren,
|
||||
@@ -96,8 +97,8 @@ import { computed } from 'vue'
|
||||
|
||||
import { useAuth } from '@/composables/auth.js'
|
||||
import { useScopes } from '@/composables/auth/scopes.ts'
|
||||
import { useBaseFetch } from '@/composables/fetch.js'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
@@ -139,20 +140,16 @@ const scope = router.query?.scope || false
|
||||
const state = router.query?.state || false
|
||||
|
||||
const getFlowIdAuthorization = async () => {
|
||||
const query = {
|
||||
const params = {
|
||||
client_id: clientId,
|
||||
redirect_uri: redirectUri,
|
||||
scope,
|
||||
}
|
||||
if (state) {
|
||||
query.state = state
|
||||
params.state = state
|
||||
}
|
||||
|
||||
const authorization = await useBaseFetch('oauth/authorize', {
|
||||
method: 'GET',
|
||||
internal: true,
|
||||
query,
|
||||
}) // This will contain the flow_id and oauth_client_id for accepting the oauth on behalf of the user
|
||||
const authorization = await client.labrinth.oauth_internal.authorize(params)
|
||||
|
||||
if (typeof authorization === 'string') {
|
||||
await navigateTo(authorization, {
|
||||
@@ -175,21 +172,13 @@ const {
|
||||
|
||||
const { data: app } = useQuery({
|
||||
queryKey: computed(() => ['oauth/app', clientId]),
|
||||
queryFn: () =>
|
||||
useBaseFetch('oauth/app/' + clientId, {
|
||||
method: 'GET',
|
||||
internal: true,
|
||||
}),
|
||||
queryFn: () => client.labrinth.oauth_internal.getApp(clientId),
|
||||
enabled: computed(() => !!clientId),
|
||||
})
|
||||
|
||||
const { data: createdBy } = useQuery({
|
||||
queryKey: computed(() => ['user', app.value?.created_by]),
|
||||
queryFn: () =>
|
||||
useBaseFetch('user/' + app.value.created_by, {
|
||||
method: 'GET',
|
||||
apiVersion: 3,
|
||||
}),
|
||||
queryFn: () => client.labrinth.users_v2.get(app.value.created_by),
|
||||
enabled: computed(() => !!app.value?.created_by),
|
||||
})
|
||||
|
||||
@@ -199,12 +188,8 @@ const scopeDefinitions = computed(() =>
|
||||
|
||||
const onAuthorize = async () => {
|
||||
try {
|
||||
const res = await useBaseFetch('oauth/accept', {
|
||||
method: 'POST',
|
||||
internal: true,
|
||||
body: {
|
||||
flow: authorizationData.value.flow_id,
|
||||
},
|
||||
const res = await client.labrinth.oauth_internal.accept({
|
||||
flow: authorizationData.value.flow_id,
|
||||
})
|
||||
|
||||
if (typeof res === 'string') {
|
||||
@@ -215,7 +200,7 @@ const onAuthorize = async () => {
|
||||
}
|
||||
|
||||
throw new Error(formatMessage(messages.noRedirectUrlError))
|
||||
} catch {
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: err.data ? err.data.description : err,
|
||||
@@ -226,11 +211,8 @@ const onAuthorize = async () => {
|
||||
|
||||
const onReject = async () => {
|
||||
try {
|
||||
const res = await useBaseFetch('oauth/reject', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
flow: authorizationData.value.flow_id,
|
||||
},
|
||||
const res = await client.labrinth.oauth_internal.reject({
|
||||
flow: authorizationData.value.flow_id,
|
||||
})
|
||||
|
||||
if (typeof res === 'string') {
|
||||
@@ -241,7 +223,7 @@ const onReject = async () => {
|
||||
}
|
||||
|
||||
throw new Error(formatMessage(messages.noRedirectUrlError))
|
||||
} catch {
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: err.data ? err.data.description : err,
|
||||
|
||||
@@ -69,6 +69,7 @@ import { KeyIcon, MailIcon, SendIcon } from '@modrinth/assets'
|
||||
import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
StyledInput,
|
||||
useVIntl,
|
||||
@@ -77,6 +78,7 @@ import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
import HCaptcha from '@/components/ui/HCaptcha.vue'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
@@ -167,10 +169,10 @@ const { data: globals } = useQuery({
|
||||
queryKey: ['auth-globals'],
|
||||
queryFn: async () => {
|
||||
try {
|
||||
return await useBaseFetch('globals', { internal: true })
|
||||
return await client.labrinth.globals_internal.get()
|
||||
} catch (err) {
|
||||
console.error('Error fetching globals:', err)
|
||||
return { captcha_enabled: true }
|
||||
return { captcha_enabled: true, tax_compliance_thresholds: {} }
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -181,12 +183,9 @@ const token = ref('')
|
||||
async function recovery() {
|
||||
startLoading()
|
||||
try {
|
||||
await useBaseFetch('auth/password/reset', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
username: email.value,
|
||||
challenge: token.value,
|
||||
},
|
||||
await client.labrinth.auth_v2.resetPasswordBegin({
|
||||
username: email.value,
|
||||
challenge: token.value,
|
||||
})
|
||||
|
||||
addNotification({
|
||||
@@ -211,12 +210,9 @@ const confirmNewPassword = ref('')
|
||||
async function changePassword() {
|
||||
startLoading()
|
||||
try {
|
||||
await useBaseFetch('auth/password', {
|
||||
method: 'PATCH',
|
||||
body: {
|
||||
new_password: newPassword.value,
|
||||
flow: route.query.flow,
|
||||
},
|
||||
await client.labrinth.auth_v2.changePassword({
|
||||
new_password: newPassword.value,
|
||||
flow: route.query.flow,
|
||||
})
|
||||
|
||||
addNotification({
|
||||
|
||||
@@ -139,6 +139,7 @@ import {
|
||||
import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
StyledInput,
|
||||
@@ -149,6 +150,7 @@ import { useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import HCaptcha from '@/components/ui/HCaptcha.vue'
|
||||
import { getAuthUrl, getLauncherRedirectUrl } from '@/composables/auth.js'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const queryClient = useQueryClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
@@ -211,10 +213,10 @@ const { data: globals } = useQuery({
|
||||
queryKey: ['auth-globals'],
|
||||
queryFn: async () => {
|
||||
try {
|
||||
return await useBaseFetch('globals', { internal: true })
|
||||
return await client.labrinth.globals_internal.get()
|
||||
} catch (err) {
|
||||
console.error('Error fetching globals:', err)
|
||||
return { captcha_enabled: true }
|
||||
return { captcha_enabled: true, tax_compliance_thresholds: {} }
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -228,13 +230,10 @@ const flow = ref(route.query.flow)
|
||||
async function beginPasswordSignIn() {
|
||||
startLoading()
|
||||
try {
|
||||
const res = await useBaseFetch('auth/login', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
username: email.value,
|
||||
password: password.value,
|
||||
challenge: token.value,
|
||||
},
|
||||
const res = await client.labrinth.auth_v2.login({
|
||||
username: email.value,
|
||||
password: password.value,
|
||||
challenge: token.value,
|
||||
})
|
||||
|
||||
if (res.flow) {
|
||||
@@ -257,12 +256,9 @@ const twoFactorCode = ref(null)
|
||||
async function begin2FASignIn() {
|
||||
startLoading()
|
||||
try {
|
||||
const res = await useBaseFetch('auth/login/2fa', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
flow: flow.value,
|
||||
code: twoFactorCode.value ? twoFactorCode.value.toString() : twoFactorCode.value,
|
||||
},
|
||||
const res = await client.labrinth.auth_v2.login2FA({
|
||||
flow: flow.value,
|
||||
code: twoFactorCode.value ? twoFactorCode.value.toString() : twoFactorCode.value,
|
||||
})
|
||||
|
||||
await finishSignIn(res.session)
|
||||
|
||||
@@ -141,6 +141,7 @@ import {
|
||||
Checkbox,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
StyledInput,
|
||||
@@ -151,6 +152,7 @@ import { useQuery } from '@tanstack/vue-query'
|
||||
import HCaptcha from '@/components/ui/HCaptcha.vue'
|
||||
import { getAuthUrl } from '@/composables/auth.js'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
@@ -205,10 +207,10 @@ const { data: globals } = useQuery({
|
||||
queryKey: ['auth-globals'],
|
||||
queryFn: async () => {
|
||||
try {
|
||||
return await useBaseFetch('globals', { internal: true })
|
||||
return await client.labrinth.globals_internal.get()
|
||||
} catch (err) {
|
||||
console.error('Error fetching globals:', err)
|
||||
return { captcha_enabled: true }
|
||||
return { captcha_enabled: true, tax_compliance_thresholds: {} }
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -235,15 +237,12 @@ async function createAccount() {
|
||||
captcha.value?.reset()
|
||||
}
|
||||
|
||||
const res = await useBaseFetch('auth/create', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
username: username.value,
|
||||
password: password.value,
|
||||
email: email.value,
|
||||
challenge: token.value,
|
||||
sign_up_newsletter: subscribe.value,
|
||||
},
|
||||
const res = await client.labrinth.auth_v2.createAccount({
|
||||
username: username.value,
|
||||
password: password.value,
|
||||
email: email.value,
|
||||
challenge: token.value,
|
||||
sign_up_newsletter: subscribe.value,
|
||||
})
|
||||
|
||||
await useAuth(res.session)
|
||||
|
||||
@@ -418,7 +418,6 @@ import dayjs from 'dayjs'
|
||||
|
||||
import AdPlaceholder from '~/components/ui/AdPlaceholder.vue'
|
||||
import NavTabs from '~/components/ui/NavTabs.vue'
|
||||
import { asEncodedJsonArray, fetchSegmented } from '~/utils/fetch-helpers.ts'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const api = injectModrinthClient()
|
||||
@@ -589,7 +588,7 @@ const refreshCollection = async () => {
|
||||
// Query for creator (only for regular collections)
|
||||
const { data: fetchedCreator, isPending: creatorIsPending } = useQuery({
|
||||
queryKey: computed(() => ['user', collection.value?.user]),
|
||||
queryFn: () => useBaseFetch(`user/${collection.value?.user}`),
|
||||
queryFn: () => api.labrinth.users_v2.get(collection.value.user),
|
||||
enabled: computed(() => !isFollowingCollection.value && !!collection.value?.user),
|
||||
})
|
||||
|
||||
@@ -606,7 +605,7 @@ const {
|
||||
} = useQuery({
|
||||
queryKey: computed(() => ['user', auth.value.user?.id, 'follows']),
|
||||
queryFn: async () => {
|
||||
const projects = await useBaseFetch(`user/${auth.value.user.id}/follows`)
|
||||
const projects = await api.labrinth.users_v2.getFollowedProjects(auth.value.user.id)
|
||||
for (const project of projects) {
|
||||
project.categories = project.categories.concat(project.loaders)
|
||||
}
|
||||
@@ -624,10 +623,16 @@ const {
|
||||
} = useQuery({
|
||||
queryKey: computed(() => ['projects', collection.value?.projects]),
|
||||
queryFn: async () => {
|
||||
const projects = await fetchSegmented(
|
||||
collection.value.projects,
|
||||
(ids) => `projects?ids=${asEncodedJsonArray(ids)}`,
|
||||
const projectIds = collection.value.projects
|
||||
const segmentSize = 800
|
||||
const segments = []
|
||||
for (let i = 0; i < projectIds.length; i += segmentSize) {
|
||||
segments.push(projectIds.slice(i, i + segmentSize))
|
||||
}
|
||||
const results = await Promise.all(
|
||||
segments.map((ids) => api.labrinth.projects_v2.getMultiple(ids)),
|
||||
)
|
||||
const projects = results.flat()
|
||||
for (const project of projects) {
|
||||
project.categories = project.categories.concat(project.loaders)
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import { PlusIcon, SearchIcon, XCircleIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Admonition,
|
||||
@@ -65,11 +66,11 @@ import {
|
||||
ButtonStyled,
|
||||
ConfirmModal,
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
StyledInput,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import type { AffiliateLink } from '@modrinth/utils'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
const createModal = useTemplateRef<typeof AffiliateLinkCreateModal>('createModal')
|
||||
@@ -77,6 +78,7 @@ const revokeModal = useTemplateRef<typeof ConfirmModal>('revokeModal')
|
||||
|
||||
const auth = await useAuth()
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { handleError } = injectNotificationManager()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
@@ -87,41 +89,35 @@ const {
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: ['affiliate'],
|
||||
queryFn: () =>
|
||||
useBaseFetch('affiliate', { method: 'GET', internal: true }) as Promise<AffiliateLink[]>,
|
||||
queryFn: () => client.labrinth.affiliate_internal.getAll(),
|
||||
})
|
||||
|
||||
const filterQuery = ref('')
|
||||
const creatingLink = ref(false)
|
||||
|
||||
const filteredAffiliates = computed(() =>
|
||||
affiliateLinks
|
||||
? affiliateLinks.value?.filter(
|
||||
(link: AffiliateLink) =>
|
||||
link.affiliate === auth.value?.user?.id &&
|
||||
(filterQuery.value.trim()
|
||||
? link.source_name.trim().toLowerCase().includes(filterQuery.value.trim().toLowerCase())
|
||||
: true),
|
||||
)
|
||||
: [],
|
||||
const filteredAffiliates = computed(
|
||||
() =>
|
||||
affiliateLinks.value?.filter(
|
||||
(link: Labrinth.Affiliate.Internal.AffiliateCode) =>
|
||||
link.affiliate === auth.value?.user?.id &&
|
||||
(filterQuery.value.trim()
|
||||
? link.source_name.trim().toLowerCase().includes(filterQuery.value.trim().toLowerCase())
|
||||
: true),
|
||||
) ?? [],
|
||||
)
|
||||
|
||||
async function createAffiliateCode(data: { sourceName: string }) {
|
||||
creatingLink.value = true
|
||||
|
||||
try {
|
||||
await useBaseFetch('affiliate', {
|
||||
method: 'PUT',
|
||||
body: {
|
||||
source_name: data.sourceName,
|
||||
},
|
||||
internal: true,
|
||||
await client.labrinth.affiliate_internal.create({
|
||||
source_name: data.sourceName,
|
||||
})
|
||||
|
||||
await refetch()
|
||||
createModal.value?.close()
|
||||
} catch (err) {
|
||||
handleError(err)
|
||||
handleError(err as Error)
|
||||
} finally {
|
||||
creatingLink.value = false
|
||||
}
|
||||
@@ -130,7 +126,7 @@ async function createAffiliateCode(data: { sourceName: string }) {
|
||||
const revokingTitle = ref<string | null>(null)
|
||||
const revokingId = ref<string | null>(null)
|
||||
|
||||
function revokeAffiliateLink(affiliate: AffiliateLink) {
|
||||
function revokeAffiliateLink(affiliate: Labrinth.Affiliate.Internal.AffiliateCode) {
|
||||
revokingTitle.value = affiliate.source_name
|
||||
revokingId.value = affiliate.id
|
||||
revokeModal.value?.show()
|
||||
@@ -142,10 +138,7 @@ async function confirmRevokeAffiliateLink() {
|
||||
}
|
||||
|
||||
try {
|
||||
await useBaseFetch(`affiliate/${revokingId.value}`, {
|
||||
method: 'DELETE',
|
||||
internal: true,
|
||||
})
|
||||
await client.labrinth.affiliate_internal.delete(revokingId.value)
|
||||
|
||||
await refetch()
|
||||
revokeModal.value?.hide()
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { injectModrinthClient } from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
import ChartDisplay from '~/components/ui/charts/ChartDisplay.vue'
|
||||
@@ -18,11 +19,12 @@ useHead({
|
||||
})
|
||||
|
||||
const auth = await useAuth()
|
||||
const client = injectModrinthClient()
|
||||
const id = auth.value?.user?.id
|
||||
|
||||
const { data: projects } = useQuery({
|
||||
queryKey: computed(() => ['user', id, 'projects']),
|
||||
queryFn: () => useBaseFetch(`user/${id}/projects`),
|
||||
queryFn: () => client.labrinth.users_v2.getProjects(id),
|
||||
enabled: computed(() => !!id),
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -155,6 +155,7 @@ import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
DropdownSelect,
|
||||
injectModrinthClient,
|
||||
StyledInput,
|
||||
useCompactNumber,
|
||||
useVIntl,
|
||||
@@ -162,7 +163,6 @@ import {
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
import CollectionCreateModal from '~/components/ui/create/CollectionCreateModal.vue'
|
||||
import { useBaseFetch } from '~/composables/fetch.js'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const { formatCompactNumber, formatCompactNumberPlural } = useCompactNumber()
|
||||
@@ -216,6 +216,7 @@ useHead({
|
||||
|
||||
const auth = await useAuth()
|
||||
const user = await useUser()
|
||||
const client = injectModrinthClient()
|
||||
|
||||
if (import.meta.client) {
|
||||
await initUserFollows()
|
||||
@@ -225,7 +226,7 @@ const filterQuery = ref('')
|
||||
|
||||
const { data: collections } = useQuery({
|
||||
queryKey: ['user', auth.value.user.id, 'collections'],
|
||||
queryFn: () => useBaseFetch(`user/${auth.value.user.id}/collections`, { apiVersion: 3 }),
|
||||
queryFn: () => client.labrinth.users_v2.getCollections(auth.value.user.id),
|
||||
})
|
||||
|
||||
const route = useNativeRoute()
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { ChevronRightIcon, HistoryIcon } from '@modrinth/assets'
|
||||
import { Avatar } from '@modrinth/ui'
|
||||
import { Avatar, injectModrinthClient } from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
import NotificationItem from '~/components/ui/NotificationItem.vue'
|
||||
@@ -108,10 +108,11 @@ useHead({
|
||||
})
|
||||
|
||||
const auth = await useAuth()
|
||||
const client = injectModrinthClient()
|
||||
|
||||
const { data: projects } = useQuery({
|
||||
queryKey: computed(() => ['user', auth.value?.user?.id, 'projects']),
|
||||
queryFn: async () => await useBaseFetch(`user/${auth.value?.user?.id}/projects`),
|
||||
queryFn: () => client.labrinth.users_v2.getProjects(auth.value?.user?.id),
|
||||
placeholderData: [],
|
||||
})
|
||||
|
||||
@@ -125,12 +126,14 @@ const followersProjectCount = computed(
|
||||
const { data, refetch } = useQuery({
|
||||
queryKey: computed(() => ['user', auth.value?.user?.id, 'notifications']),
|
||||
queryFn: async () => {
|
||||
const notifications = await useBaseFetch(`user/${auth.value?.user?.id}/notifications`)
|
||||
const notifications = await client.labrinth.notifications_v2.getUserNotifications(
|
||||
auth.value?.user?.id,
|
||||
)
|
||||
|
||||
const filteredNotifications = notifications.filter((notif) => !notif.read)
|
||||
const slice = filteredNotifications.slice(0, 30)
|
||||
|
||||
return fetchExtraNotificationData(slice).then((notifications) => {
|
||||
return fetchExtraNotificationData(client, slice).then((notifications) => {
|
||||
notifications = groupNotifications(notifications).slice(0, 3)
|
||||
return { notifications, extraNotifs: filteredNotifications.length - slice.length }
|
||||
})
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { CheckCheckIcon, HistoryIcon } from '@modrinth/assets'
|
||||
import { Button, Chips, Pagination } from '@modrinth/ui'
|
||||
import { Button, Chips, injectModrinthClient, Pagination } from '@modrinth/ui'
|
||||
import { formatProjectType } from '@modrinth/utils'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
@@ -73,6 +73,7 @@ useHead({
|
||||
title: 'Notifications - Modrinth',
|
||||
})
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const auth = await useAuth()
|
||||
const route = useNativeRoute()
|
||||
const router = useNativeRouter()
|
||||
@@ -94,7 +95,9 @@ const { data, isPending, error, refetch } = useQuery({
|
||||
queryFn: async () => {
|
||||
const pageNum = page.value - 1
|
||||
const showRead = history.value
|
||||
const notifications = await useBaseFetch(`user/${auth.value?.user?.id}/notifications`)
|
||||
const notifications = await client.labrinth.notifications_v2.getUserNotifications(
|
||||
auth.value?.user?.id,
|
||||
)
|
||||
|
||||
const typesInFeed = [
|
||||
...new Set(notifications.filter((n) => showRead || !n.read).map((n) => n.type)),
|
||||
@@ -108,6 +111,7 @@ const { data, isPending, error, refetch } = useQuery({
|
||||
const pages = Math.max(1, Math.ceil(filtered.length / perPage.value))
|
||||
|
||||
return fetchExtraNotificationData(
|
||||
client,
|
||||
filtered.slice(pageNum * perPage.value, pageNum * perPage.value + perPage.value),
|
||||
).then((notifs) => ({
|
||||
notifications: notifs,
|
||||
@@ -121,7 +125,7 @@ const { data, isPending, error, refetch } = useQuery({
|
||||
})
|
||||
|
||||
const notifications = computed(() =>
|
||||
data.value ? groupNotifications(data.value.notifications, history.value) : [],
|
||||
data.value ? groupNotifications(data.value.notifications) : [],
|
||||
)
|
||||
|
||||
const notifTypes = computed(() => data.value?.notifTypes || [])
|
||||
@@ -139,7 +143,7 @@ async function readAll() {
|
||||
...(n.grouped_notifs ? n.grouped_notifs.map((g) => g.id) : []),
|
||||
])
|
||||
|
||||
await markAsRead(ids)
|
||||
await markAsRead(client, ids)
|
||||
await refetch()
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
<script setup>
|
||||
import { PlusIcon, UsersIcon } from '@modrinth/assets'
|
||||
import { Avatar } from '@modrinth/ui'
|
||||
import { Avatar, injectModrinthClient } from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
import OrganizationCreateModal from '~/components/ui/create/OrganizationCreateModal.vue'
|
||||
@@ -59,14 +59,12 @@ import { useAuth } from '~/composables/auth.js'
|
||||
const createOrgModal = ref(null)
|
||||
|
||||
const auth = await useAuth()
|
||||
const client = injectModrinthClient()
|
||||
const uid = computed(() => auth.value.user?.id || null)
|
||||
|
||||
const { data: orgs, error } = useQuery({
|
||||
queryKey: computed(() => ['user', uid.value, 'organizations']),
|
||||
queryFn: () =>
|
||||
useBaseFetch('user/' + uid.value + '/organizations', {
|
||||
apiVersion: 3,
|
||||
}),
|
||||
queryFn: () => client.labrinth.users_v2.getOrganizations(uid.value),
|
||||
enabled: computed(() => !!uid.value),
|
||||
})
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@
|
||||
<div v-if="sortedPayouts.length > 0" class="flex flex-col gap-3 md:gap-4">
|
||||
<RevenueTransaction
|
||||
v-for="transaction in sortedPayouts.slice(0, 3)"
|
||||
:key="transaction.id || transaction.created"
|
||||
:key="('id' in transaction && transaction.id) || transaction.created"
|
||||
:transaction="transaction"
|
||||
@cancelled="refreshPayouts"
|
||||
/>
|
||||
@@ -260,13 +260,18 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ArrowUpRightIcon, InProgressIcon, UnknownIcon } from '@modrinth/assets'
|
||||
import { defineMessages, useFormatDateTime, useFormatMoney, useVIntl } from '@modrinth/ui'
|
||||
import {
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
useFormatDateTime,
|
||||
useFormatMoney,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import dayjs from 'dayjs'
|
||||
import { Tooltip } from 'floating-vue'
|
||||
|
||||
import { useUserCountry } from '@/composables/country.ts'
|
||||
import type { PayoutMethod } from '@/providers/creator-withdraw.ts'
|
||||
import CreatorWithdrawModal from '~/components/ui/dashboard/CreatorWithdrawModal.vue'
|
||||
import RevenueTransaction from '~/components/ui/dashboard/RevenueTransaction.vue'
|
||||
|
||||
@@ -276,20 +281,7 @@ const formatDate = useFormatDateTime({ dateStyle: 'medium' })
|
||||
|
||||
await useAuth()
|
||||
|
||||
// TODO: Deduplicate these types & interfaces in @modrinth/api-client PR.
|
||||
type FormCompletionStatus = 'unknown' | 'unrequested' | 'unsigned' | 'tin-mismatch' | 'complete'
|
||||
|
||||
type UserBalanceResponse = {
|
||||
available: number
|
||||
withdrawn_lifetime: number
|
||||
withdrawn_ytd: number
|
||||
pending: number
|
||||
// ISO 8601 date string -> amount
|
||||
dates: Record<string, number>
|
||||
// backend returns null when not applicable
|
||||
requested_form_type: string | null
|
||||
form_completion_status: FormCompletionStatus | null
|
||||
}
|
||||
const client = injectModrinthClient()
|
||||
|
||||
type RevenueBarSegment = {
|
||||
key: string
|
||||
@@ -359,26 +351,12 @@ const messages = defineMessages({
|
||||
|
||||
const { data: userBalance, refetch: refreshUserBalance } = useQuery({
|
||||
queryKey: ['payout', 'balance'],
|
||||
queryFn: async () => {
|
||||
const response = (await useBaseFetch(`payout/balance`, {
|
||||
apiVersion: 3,
|
||||
})) as UserBalanceResponse
|
||||
return {
|
||||
...response,
|
||||
available: Number(response.available),
|
||||
withdrawn_lifetime: Number(response.withdrawn_lifetime),
|
||||
withdrawn_ytd: Number(response.withdrawn_ytd),
|
||||
pending: Number(response.pending),
|
||||
}
|
||||
},
|
||||
queryFn: () => client.labrinth.payout_v3.getBalance(),
|
||||
})
|
||||
|
||||
const { data: payouts, refetch: refreshPayouts } = useQuery({
|
||||
queryKey: ['payout', 'history'],
|
||||
queryFn: () =>
|
||||
useBaseFetch(`payout/history`, {
|
||||
apiVersion: 3,
|
||||
}),
|
||||
queryFn: () => client.labrinth.payout_v3.getHistory(),
|
||||
})
|
||||
|
||||
const userCountry = useUserCountry()
|
||||
@@ -389,10 +367,7 @@ const { data: preloadedPaymentMethods } = useQuery({
|
||||
try {
|
||||
return {
|
||||
country: defaultCountry,
|
||||
methods: (await useBaseFetch('payout/methods', {
|
||||
apiVersion: 3,
|
||||
query: { country: defaultCountry },
|
||||
})) as PayoutMethod[],
|
||||
methods: await client.labrinth.payout_v3.getMethods(defaultCountry),
|
||||
}
|
||||
} catch {
|
||||
return null
|
||||
|
||||
@@ -92,6 +92,7 @@ import {
|
||||
Combobox,
|
||||
defineMessages,
|
||||
EmptyState,
|
||||
injectModrinthClient,
|
||||
useFormatDateTime,
|
||||
useFormatMoney,
|
||||
useVIntl,
|
||||
@@ -111,6 +112,7 @@ const formatMonth = useFormatDateTime({
|
||||
month: 'long',
|
||||
})
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const generatedState = useGeneratedState()
|
||||
|
||||
useHead({
|
||||
@@ -119,10 +121,7 @@ useHead({
|
||||
|
||||
const { data: transactions, refetch } = useQuery({
|
||||
queryKey: ['payout', 'history'],
|
||||
queryFn: () =>
|
||||
useBaseFetch(`payout/history`, {
|
||||
apiVersion: 3,
|
||||
}),
|
||||
queryFn: () => client.labrinth.payout_v3.getHistory(),
|
||||
})
|
||||
|
||||
const allTransactions = computed(() => {
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
ref="purchaseModal"
|
||||
:publishable-key="config.public.stripePublishableKey"
|
||||
:initiate-payment="
|
||||
async (body) =>
|
||||
await useBaseFetch('billing/payment', { internal: true, method: 'POST', body })
|
||||
async (body) => await client.labrinth.billing_internal.initiatePayment(body)
|
||||
"
|
||||
:available-products="pyroProducts"
|
||||
:on-error="handleError"
|
||||
@@ -641,6 +640,7 @@ import {
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
ModrinthServersPurchaseModal,
|
||||
@@ -651,16 +651,15 @@ import { monthsInInterval } from '@modrinth/ui/src/utils/billing.ts'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useBaseFetch } from '@/composables/fetch.js'
|
||||
import OptionGroup from '~/components/ui/OptionGroup.vue'
|
||||
import LoaderIcon from '~/components/ui/servers/icons/LoaderIcon.vue'
|
||||
import MedalPlanPromotion from '~/components/ui/servers/marketing/MedalPlanPromotion.vue'
|
||||
import ServerPlanSelector from '~/components/ui/servers/marketing/ServerPlanSelector.vue'
|
||||
import { useServersFetch } from '~/composables/servers/servers-fetch.ts'
|
||||
import { products } from '~/generated/state.json'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const client = injectModrinthClient()
|
||||
|
||||
const { setAffiliateCode, getAffiliateCode } = useAffiliates()
|
||||
|
||||
@@ -1017,7 +1016,7 @@ const { data: hasServers } = useQuery({
|
||||
queryFn: async () => {
|
||||
try {
|
||||
if (!auth.value.user) return false
|
||||
const response = await useServersFetch('servers')
|
||||
const response = await client.archon.servers_v0.list()
|
||||
return response.servers && response.servers.length > 0
|
||||
} catch {
|
||||
return false
|
||||
@@ -1027,13 +1026,7 @@ const { data: hasServers } = useQuery({
|
||||
})
|
||||
|
||||
function fetchStock(region, request) {
|
||||
return useServersFetch(`stock?region=${region.shortcode}`, {
|
||||
method: 'POST',
|
||||
body: {
|
||||
...request,
|
||||
},
|
||||
bypassAuth: true,
|
||||
}).then((res) => res.available)
|
||||
return client.archon.servers_v0.checkStock(region.shortcode, request).then((res) => res.available)
|
||||
}
|
||||
|
||||
async function fetchCapacityStatuses(customProduct = null) {
|
||||
@@ -1049,15 +1042,11 @@ async function fetchCapacityStatuses(customProduct = null) {
|
||||
const capacityChecks = []
|
||||
for (const product of productsToCheck) {
|
||||
capacityChecks.push(
|
||||
useServersFetch('stock', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
cpu: product.metadata.cpu,
|
||||
memory_mb: product.metadata.ram,
|
||||
swap_mb: product.metadata.swap,
|
||||
storage_mb: product.metadata.storage,
|
||||
},
|
||||
bypassAuth: true,
|
||||
client.archon.servers_v0.checkStockGlobal({
|
||||
cpu: product.metadata.cpu,
|
||||
memory_mb: product.metadata.ram,
|
||||
swap_mb: product.metadata.swap,
|
||||
storage_mb: product.metadata.storage,
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -1129,8 +1118,8 @@ async function fetchPaymentData() {
|
||||
if (!auth.value.user) return
|
||||
try {
|
||||
const [customerData, paymentMethodsData] = await Promise.all([
|
||||
useBaseFetch('billing/customer', { internal: true }),
|
||||
useBaseFetch('billing/payment_methods', { internal: true }),
|
||||
client.labrinth.billing_internal.getCustomer(),
|
||||
client.labrinth.billing_internal.getPaymentMethods(),
|
||||
])
|
||||
customer.value = customerData
|
||||
paymentMethods.value = paymentMethodsData
|
||||
@@ -1248,11 +1237,7 @@ const regions = ref([])
|
||||
const regionPings = ref([])
|
||||
|
||||
function pingRegions() {
|
||||
useServersFetch('regions', {
|
||||
method: 'GET',
|
||||
version: 1,
|
||||
bypassAuth: true,
|
||||
}).then((res) => {
|
||||
client.archon.servers_v1.getRegions().then((res) => {
|
||||
regions.value = res
|
||||
regions.value.forEach((region) => {
|
||||
runPingTest(region)
|
||||
|
||||
@@ -118,7 +118,7 @@ import {
|
||||
StyledInput,
|
||||
Toggle,
|
||||
} from '@modrinth/ui'
|
||||
import { useMutation, useQueryClient } from '@tanstack/vue-query'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import Fuse from 'fuse.js'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="item in platformRevenueData" :key="item.time">
|
||||
<td>{{ formatDate(dayjs.unix(item.time)) }}</td>
|
||||
<td>{{ formatDate(dayjs.unix(item.time).toDate()) }}</td>
|
||||
<td>{{ formatMoney(Number(item.revenue) + Number(item.creator_revenue)) }}</td>
|
||||
<td>{{ formatMoney(Number(item.creator_revenue)) }}</td>
|
||||
<td>{{ formatMoney(Number(item.revenue)) }}</td>
|
||||
@@ -162,11 +162,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { StyledInput, useFormatDateTime, useFormatMoney } from '@modrinth/ui'
|
||||
import { injectModrinthClient, StyledInput, useFormatDateTime, useFormatMoney } from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const formatMoney = useFormatMoney()
|
||||
const formatDate = useFormatDateTime({
|
||||
month: 'long',
|
||||
@@ -191,10 +192,7 @@ const withdrawalDate = computed(() => endOfMonthDate.value.add(60, 'days'))
|
||||
|
||||
const { data: transparencyInformation } = useQuery({
|
||||
queryKey: ['payout', 'platform_revenue'],
|
||||
queryFn: () =>
|
||||
useBaseFetch('payout/platform_revenue', {
|
||||
apiVersion: 3,
|
||||
}),
|
||||
queryFn: () => client.labrinth.payouts_v3.getPlatformRevenue(),
|
||||
})
|
||||
|
||||
const platformRevenue = (transparencyInformation.value as any)?.all_time
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { injectModrinthClient } from '@modrinth/ui'
|
||||
import type { Report } from '@modrinth/utils'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
import ModerationReportCard from '~/components/ui/moderation/ModerationReportCard.vue'
|
||||
import { enrichReportBatch } from '~/helpers/moderation.ts'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { params } = useRoute()
|
||||
const reportId = params.id as string
|
||||
|
||||
@@ -12,7 +14,7 @@ const { data: report } = useQuery({
|
||||
queryKey: computed(() => ['report', reportId]),
|
||||
queryFn: async () => {
|
||||
try {
|
||||
const report = (await useBaseFetch(`report/${reportId}`, { apiVersion: 3 })) as Report
|
||||
const report = (await client.labrinth.reports_v3.get(reportId)) as Report
|
||||
const enrichedReport = (await enrichReportBatch([report]))[0]
|
||||
return enrichedReport
|
||||
} catch (error) {
|
||||
|
||||
@@ -327,6 +327,7 @@ import {
|
||||
commonMessages,
|
||||
CopyCode,
|
||||
DropdownSelect,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
ProjectStatusBadge,
|
||||
@@ -341,6 +342,7 @@ import OrganizationProjectTransferModal from '~/components/ui/OrganizationProjec
|
||||
import { getProjectTypeForUrl } from '~/helpers/projects.js'
|
||||
import { injectOrganizationContext } from '~/providers/organization-context.ts'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
@@ -350,7 +352,7 @@ const auth = await useAuth()
|
||||
|
||||
const { data: userProjects, refetch: refreshUserProjects } = useQuery({
|
||||
queryKey: computed(() => ['user', auth.value?.user?.id, 'projects']),
|
||||
queryFn: () => useBaseFetch(`user/${auth.value.user.id}/projects`),
|
||||
queryFn: () => client.labrinth.users_v2.getProjects(auth.value.user.id),
|
||||
enabled: computed(() => !!auth.value?.user?.id),
|
||||
placeholderData: [],
|
||||
})
|
||||
@@ -366,11 +368,7 @@ watch(
|
||||
const projects = userProjects.value.filter((project) => project.organization === null)
|
||||
|
||||
const teamIds = projects.map((project) => project?.team).filter((x) => x)
|
||||
// Shape of teams is member[][]
|
||||
const teams = await useBaseFetch(`teams?ids=${JSON.stringify(teamIds)}`, {
|
||||
apiVersion: 3,
|
||||
})
|
||||
// for each team id, figure out if the user is a member, and is_owner. Then filter the projects to only include those that are owned by the user
|
||||
const teams = await client.labrinth.teams_v3.getMultiple(teamIds)
|
||||
const ownedTeamIds = teamIds.filter((_tid, i) => {
|
||||
const team = teams?.[i]
|
||||
if (!team) return false
|
||||
@@ -379,19 +377,15 @@ watch(
|
||||
})
|
||||
const ownedProjects = projects.filter((project) => ownedTeamIds.includes(project.team))
|
||||
usersOwnedProjects.value = ownedProjects
|
||||
}, // watch options
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
)
|
||||
|
||||
const onProjectTransferSubmit = async (projects) => {
|
||||
try {
|
||||
for (const project of projects) {
|
||||
await useBaseFetch(`organization/${organization.value.id}/projects`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
project_id: project.id,
|
||||
}),
|
||||
apiVersion: 3,
|
||||
await client.labrinth.organizations_v3.addProject(organization.value.id, {
|
||||
project_id: project.id,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -488,17 +482,17 @@ const updateDescending = () => {
|
||||
const onBulkEditLinks = async () => {
|
||||
try {
|
||||
const baseData = {
|
||||
issues_url: editLinks.value.issues.clear ? null : editLinks.value.issues.val.trim(),
|
||||
source_url: editLinks.value.source.clear ? null : editLinks.value.source.val.trim(),
|
||||
wiki_url: editLinks.value.wiki.clear ? null : editLinks.value.wiki.val.trim(),
|
||||
discord_url: editLinks.value.discord.clear ? null : editLinks.value.discord.val.trim(),
|
||||
issues_url: editLinks.issues.clear ? null : editLinks.issues.val.trim(),
|
||||
source_url: editLinks.source.clear ? null : editLinks.source.val.trim(),
|
||||
wiki_url: editLinks.wiki.clear ? null : editLinks.wiki.val.trim(),
|
||||
discord_url: editLinks.discord.clear ? null : editLinks.discord.val.trim(),
|
||||
}
|
||||
const filteredData = Object.fromEntries(Object.entries(baseData).filter(([, v]) => v !== ''))
|
||||
|
||||
await useBaseFetch(`projects?ids=${JSON.stringify(selectedProjects.value.map((x) => x.id))}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(filteredData),
|
||||
})
|
||||
await client.labrinth.projects_v2.bulkEdit(
|
||||
selectedProjects.value.map((x) => x.id),
|
||||
filteredData,
|
||||
)
|
||||
|
||||
editLinksModal.value?.hide()
|
||||
addNotification({
|
||||
@@ -508,14 +502,14 @@ const onBulkEditLinks = async () => {
|
||||
})
|
||||
selectedProjects.value = []
|
||||
|
||||
editLinks.value.issues.val = ''
|
||||
editLinks.value.source.val = ''
|
||||
editLinks.value.wiki.val = ''
|
||||
editLinks.value.discord.val = ''
|
||||
editLinks.value.issues.clear = false
|
||||
editLinks.value.source.clear = false
|
||||
editLinks.value.wiki.clear = false
|
||||
editLinks.value.discord.clear = false
|
||||
editLinks.issues.val = ''
|
||||
editLinks.source.val = ''
|
||||
editLinks.wiki.val = ''
|
||||
editLinks.discord.val = ''
|
||||
editLinks.issues.clear = false
|
||||
editLinks.source.clear = false
|
||||
editLinks.wiki.clear = false
|
||||
editLinks.discord.clear = false
|
||||
} catch (e) {
|
||||
addNotification({
|
||||
title: 'An error occurred',
|
||||
|
||||
@@ -253,6 +253,7 @@ import {
|
||||
CopyCode,
|
||||
defineMessages,
|
||||
FileInput,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
normalizeChildren,
|
||||
@@ -272,6 +273,7 @@ import {
|
||||
useScopes,
|
||||
} from '~/composables/auth/scopes.ts'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
const formatDate = useFormatDateTime()
|
||||
@@ -494,10 +496,7 @@ const auth = await useAuth()
|
||||
|
||||
const { data: usersApps, refetch: refresh } = useQuery({
|
||||
queryKey: computed(() => ['user', auth.value?.user?.id, 'oauth_apps']),
|
||||
queryFn: () =>
|
||||
useBaseFetch(`user/${auth.value.user.id}/oauth_apps`, {
|
||||
apiVersion: 3,
|
||||
}),
|
||||
queryFn: () => client.labrinth.oauth_internal.getUserApps(auth.value.user.id),
|
||||
enabled: computed(() => !!auth.value?.user?.id),
|
||||
})
|
||||
|
||||
@@ -551,14 +550,7 @@ async function onImageSelection(files) {
|
||||
const file = files[0]
|
||||
const extFromType = file.type.split('/')[1]
|
||||
|
||||
await useBaseFetch('oauth/app/' + editingId.value + '/icon', {
|
||||
method: 'PATCH',
|
||||
internal: true,
|
||||
body: file,
|
||||
query: {
|
||||
ext: extFromType,
|
||||
},
|
||||
})
|
||||
await client.labrinth.oauth_internal.uploadAppIcon(editingId.value, file, extFromType).promise
|
||||
|
||||
await refresh()
|
||||
|
||||
@@ -579,15 +571,10 @@ async function createApp() {
|
||||
startLoading()
|
||||
loading.value = true
|
||||
try {
|
||||
const createdAppInfo = await useBaseFetch('oauth/app', {
|
||||
method: 'POST',
|
||||
internal: true,
|
||||
body: {
|
||||
name: name.value,
|
||||
icon_url: icon.value,
|
||||
max_scopes: Number(scopesVal.value), // JS is 52 bit for ints so we're good for now
|
||||
redirect_uris: redirectUris.value,
|
||||
},
|
||||
const createdAppInfo = await client.labrinth.oauth_internal.createApp({
|
||||
name: name.value,
|
||||
max_scopes: Number(scopesVal.value),
|
||||
redirect_uris: redirectUris.value,
|
||||
})
|
||||
|
||||
createdApps.value.push(createdAppInfo)
|
||||
@@ -637,7 +624,7 @@ async function editApp() {
|
||||
|
||||
const body = {
|
||||
name: name.value,
|
||||
max_scopes: Number(scopesVal.value), // JS is 52 bit for ints so we're good for now
|
||||
max_scopes: Number(scopesVal.value),
|
||||
redirect_uris: redirectUris.value,
|
||||
}
|
||||
|
||||
@@ -653,11 +640,7 @@ async function editApp() {
|
||||
body.icon_url = icon.value
|
||||
}
|
||||
|
||||
await useBaseFetch('oauth/app/' + editingId.value, {
|
||||
method: 'PATCH',
|
||||
internal: true,
|
||||
body,
|
||||
})
|
||||
await client.labrinth.oauth_internal.editApp(editingId.value, body)
|
||||
|
||||
await refresh()
|
||||
setForm(null)
|
||||
@@ -681,10 +664,7 @@ async function removeApp() {
|
||||
if (!editingId.value) {
|
||||
throw new Error('No editing id')
|
||||
}
|
||||
await useBaseFetch(`oauth/app/${editingId.value}`, {
|
||||
internal: true,
|
||||
method: 'DELETE',
|
||||
})
|
||||
await client.labrinth.oauth_internal.deleteApp(editingId.value)
|
||||
await refresh()
|
||||
editingId.value = null
|
||||
} catch (err) {
|
||||
|
||||
@@ -95,6 +95,7 @@ import {
|
||||
Button,
|
||||
commonSettingsMessages,
|
||||
ConfirmModal,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
@@ -102,6 +103,7 @@ import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
import { useScopes } from '~/composables/auth/scopes.ts'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
@@ -119,32 +121,19 @@ useHead({
|
||||
|
||||
const { data: usersApps, refetch: refresh } = useQuery({
|
||||
queryKey: ['oauth', 'authorizations'],
|
||||
queryFn: () =>
|
||||
useBaseFetch(`oauth/authorizations`, {
|
||||
internal: true,
|
||||
}),
|
||||
queryFn: () => client.labrinth.oauth_internal.getAuthorizations(),
|
||||
})
|
||||
|
||||
const { data: appInformation } = useQuery({
|
||||
queryKey: computed(() => ['oauth', 'apps', usersApps.value?.map((c) => c.app_id)]),
|
||||
queryFn: () =>
|
||||
useBaseFetch('oauth/apps', {
|
||||
internal: true,
|
||||
query: {
|
||||
ids: JSON.stringify(usersApps.value.map((c) => c.app_id)),
|
||||
},
|
||||
}),
|
||||
queryFn: () => client.labrinth.oauth_internal.getApps(usersApps.value.map((c) => c.app_id)),
|
||||
enabled: computed(() => !!usersApps.value?.length),
|
||||
})
|
||||
|
||||
const { data: appCreatorsInformation } = useQuery({
|
||||
queryKey: computed(() => ['users', appInformation.value?.map((c) => c.created_by)]),
|
||||
queryFn: () =>
|
||||
useBaseFetch('users', {
|
||||
query: {
|
||||
ids: JSON.stringify(appInformation.value.map((c) => c.created_by)),
|
||||
},
|
||||
}),
|
||||
client.labrinth.users_v2.getMultiple(appInformation.value.map((c) => c.created_by)),
|
||||
enabled: computed(() => !!appInformation.value?.length),
|
||||
})
|
||||
|
||||
@@ -165,13 +154,7 @@ const appInfoLookup = computed(() => {
|
||||
|
||||
async function revokeApp(id) {
|
||||
try {
|
||||
await useBaseFetch(`oauth/authorizations`, {
|
||||
internal: true,
|
||||
method: 'DELETE',
|
||||
query: {
|
||||
client_id: id,
|
||||
},
|
||||
})
|
||||
await client.labrinth.oauth_internal.revokeAuthorization(id)
|
||||
revokingId.value = null
|
||||
await refresh()
|
||||
} catch (err) {
|
||||
|
||||
@@ -38,7 +38,13 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Badge, Breadcrumbs, useFormatDateTime, useFormatPrice } from '@modrinth/ui'
|
||||
import {
|
||||
Badge,
|
||||
Breadcrumbs,
|
||||
injectModrinthClient,
|
||||
useFormatDateTime,
|
||||
useFormatPrice,
|
||||
} from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
import { products } from '~/generated/state.json'
|
||||
@@ -47,6 +53,8 @@ definePageMeta({
|
||||
middleware: 'auth',
|
||||
})
|
||||
|
||||
const client = injectModrinthClient()
|
||||
|
||||
const formatPrice = useFormatPrice()
|
||||
const formatDate = useFormatDateTime({
|
||||
year: 'numeric',
|
||||
@@ -57,7 +65,7 @@ const formatDate = useFormatDateTime({
|
||||
const { data: charges } = useQuery({
|
||||
queryKey: ['billing', 'payments'],
|
||||
queryFn: async () => {
|
||||
const charges = await useBaseFetch('billing/payments', { internal: true })
|
||||
const charges = await client.labrinth.billing_internal.getPayments()
|
||||
return charges
|
||||
.filter((charge) => charge.status !== 'open' && charge.status !== 'cancelled')
|
||||
.map((charge) => {
|
||||
|
||||
@@ -458,8 +458,7 @@
|
||||
:country="country"
|
||||
:publishable-key="config.public.stripePublishableKey"
|
||||
:send-billing-request="
|
||||
async (body) =>
|
||||
await useBaseFetch('billing/payment', { internal: true, method: 'POST', body })
|
||||
async (body) => await client.labrinth.billing_internal.initiatePayment(body)
|
||||
"
|
||||
:on-error="
|
||||
(err) =>
|
||||
@@ -613,6 +612,7 @@ import {
|
||||
CopyCode,
|
||||
defineMessages,
|
||||
getPaymentMethodIcon,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
OverflowMenu,
|
||||
paymentMethodMessages,
|
||||
@@ -626,13 +626,12 @@ import { calculateSavings, getCurrency } from '@modrinth/utils'
|
||||
import { useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { useBaseFetch } from '@/composables/fetch.js'
|
||||
import ModrinthServersIcon from '~/components/ui/servers/ModrinthServersIcon.vue'
|
||||
import ServersUpgradeModalWrapper from '~/components/ui/servers/ServersUpgradeModalWrapper.vue'
|
||||
import { useServersFetch } from '~/composables/servers/servers-fetch.ts'
|
||||
import { products } from '~/generated/state.json'
|
||||
|
||||
const { addNotification, handleError } = injectNotificationManager()
|
||||
const client = injectModrinthClient()
|
||||
definePageMeta({
|
||||
middleware: 'auth',
|
||||
})
|
||||
@@ -742,27 +741,27 @@ const queryClient = useQueryClient()
|
||||
|
||||
const { data: paymentMethods } = useQuery({
|
||||
queryKey: ['billing', 'payment_methods'],
|
||||
queryFn: () => useBaseFetch('billing/payment_methods', { internal: true }),
|
||||
queryFn: () => client.labrinth.billing_internal.getPaymentMethods(),
|
||||
})
|
||||
const { data: charges } = useQuery({
|
||||
queryKey: ['billing', 'payments'],
|
||||
queryFn: () => useBaseFetch('billing/payments', { internal: true }),
|
||||
queryFn: () => client.labrinth.billing_internal.getPayments(),
|
||||
})
|
||||
const { data: customer } = useQuery({
|
||||
queryKey: ['billing', 'customer'],
|
||||
queryFn: () => useBaseFetch('billing/customer', { internal: true }),
|
||||
queryFn: () => client.labrinth.billing_internal.getCustomer(),
|
||||
})
|
||||
const { data: subscriptions } = useQuery({
|
||||
queryKey: ['billing', 'subscriptions'],
|
||||
queryFn: () => useBaseFetch('billing/subscriptions', { internal: true }),
|
||||
queryFn: () => client.labrinth.billing_internal.getSubscriptions(),
|
||||
})
|
||||
const { data: productsData } = useQuery({
|
||||
queryKey: ['billing', 'products'],
|
||||
queryFn: () => useBaseFetch('billing/products', { internal: true }),
|
||||
queryFn: () => client.labrinth.billing_internal.getProducts(),
|
||||
})
|
||||
const { data: serversData } = useQuery({
|
||||
queryKey: ['servers'],
|
||||
queryFn: () => useServersFetch('servers'),
|
||||
queryFn: () => client.archon.servers_v0.list(),
|
||||
})
|
||||
|
||||
const midasProduct = ref(products.find((x) => x.metadata?.type === 'midas'))
|
||||
@@ -826,10 +825,7 @@ function addPaymentMethod() {
|
||||
}
|
||||
|
||||
async function createSetupIntent() {
|
||||
return await useBaseFetch('billing/payment_method', {
|
||||
internal: true,
|
||||
method: 'POST',
|
||||
})
|
||||
return await client.labrinth.billing_internal.addPaymentMethodFlow()
|
||||
}
|
||||
|
||||
const removePaymentMethodIndex = ref()
|
||||
@@ -844,12 +840,8 @@ async function switchMidasInterval(interval) {
|
||||
changingInterval.value = true
|
||||
startLoading()
|
||||
try {
|
||||
await useBaseFetch(`billing/subscription/${midasSubscription.value.id}`, {
|
||||
internal: true,
|
||||
method: 'PATCH',
|
||||
body: {
|
||||
interval,
|
||||
},
|
||||
await client.labrinth.billing_internal.editSubscription(midasSubscription.value.id, {
|
||||
interval,
|
||||
})
|
||||
await refresh()
|
||||
} catch (error) {
|
||||
@@ -862,12 +854,8 @@ async function switchMidasInterval(interval) {
|
||||
async function editPaymentMethod(index, primary) {
|
||||
startLoading()
|
||||
try {
|
||||
await useBaseFetch(`billing/payment_method/${paymentMethods.value[index].id}`, {
|
||||
internal: true,
|
||||
method: 'PATCH',
|
||||
data: {
|
||||
primary,
|
||||
},
|
||||
await client.labrinth.billing_internal.editPaymentMethod(paymentMethods.value[index].id, {
|
||||
primary,
|
||||
})
|
||||
await refresh()
|
||||
} catch (err) {
|
||||
@@ -883,10 +871,7 @@ async function editPaymentMethod(index, primary) {
|
||||
async function removePaymentMethod(index) {
|
||||
startLoading()
|
||||
try {
|
||||
await useBaseFetch(`billing/payment_method/${paymentMethods.value[index].id}`, {
|
||||
internal: true,
|
||||
method: 'DELETE',
|
||||
})
|
||||
await client.labrinth.billing_internal.removePaymentMethod(paymentMethods.value[index].id)
|
||||
await refresh()
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
@@ -902,12 +887,8 @@ const cancelSubscriptionId = ref(null)
|
||||
async function cancelSubscription(id, cancelled) {
|
||||
startLoading()
|
||||
try {
|
||||
await useBaseFetch(`billing/subscription/${id}`, {
|
||||
internal: true,
|
||||
method: 'PATCH',
|
||||
body: {
|
||||
cancelled,
|
||||
},
|
||||
await client.labrinth.billing_internal.editSubscription(id, {
|
||||
cancelled,
|
||||
})
|
||||
await refresh()
|
||||
} catch (err) {
|
||||
@@ -975,12 +956,8 @@ const showPyroUpgradeModal = (subscription) => {
|
||||
|
||||
const resubscribePyro = async (subscriptionId, wasSuspended) => {
|
||||
try {
|
||||
await useBaseFetch(`billing/subscription/${subscriptionId}`, {
|
||||
internal: true,
|
||||
method: 'PATCH',
|
||||
body: {
|
||||
cancelled: false,
|
||||
},
|
||||
await client.labrinth.billing_internal.editSubscription(subscriptionId, {
|
||||
cancelled: false,
|
||||
})
|
||||
await refresh()
|
||||
if (wasSuspended) {
|
||||
|
||||
@@ -196,6 +196,7 @@ import {
|
||||
ConfirmModal,
|
||||
CopyCode,
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
StyledInput,
|
||||
@@ -203,7 +204,7 @@ import {
|
||||
useRelativeTime,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
|
||||
import Modal from '~/components/ui/Modal.vue'
|
||||
import {
|
||||
@@ -215,6 +216,8 @@ import {
|
||||
useScopes,
|
||||
} from '~/composables/auth/scopes.ts'
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const queryClient = useQueryClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
@@ -327,9 +330,9 @@ const deletePatIndex = ref(null)
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
const { data: pats, refetch: refresh } = useQuery({
|
||||
const { data: pats } = useQuery({
|
||||
queryKey: ['pat'],
|
||||
queryFn: () => useBaseFetch('pat'),
|
||||
queryFn: () => client.labrinth.pats_v2.list(),
|
||||
placeholderData: [],
|
||||
})
|
||||
const displayPats = computed(() => {
|
||||
@@ -395,13 +398,10 @@ async function createPat() {
|
||||
startLoading()
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await useBaseFetch('pat', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
name: name.value,
|
||||
scopes: Number(scopesVal.value),
|
||||
expires: data.$dayjs(expires.value).toISOString(),
|
||||
},
|
||||
const res = await client.labrinth.pats_v2.create({
|
||||
name: name.value,
|
||||
scopes: Number(scopesVal.value),
|
||||
expires: data.$dayjs(expires.value).toISOString(),
|
||||
})
|
||||
pats.value.push(res)
|
||||
patModal.value.hide()
|
||||
@@ -420,15 +420,12 @@ async function editPat() {
|
||||
startLoading()
|
||||
loading.value = true
|
||||
try {
|
||||
await useBaseFetch(`pat/${editPatId.value}`, {
|
||||
method: 'PATCH',
|
||||
body: {
|
||||
name: name.value,
|
||||
scopes: Number(scopesVal.value),
|
||||
expires: data.$dayjs(expires.value).toISOString(),
|
||||
},
|
||||
await client.labrinth.pats_v2.modify(editPatId.value, {
|
||||
name: name.value,
|
||||
scopes: Number(scopesVal.value),
|
||||
expires: data.$dayjs(expires.value).toISOString(),
|
||||
})
|
||||
await refresh()
|
||||
await queryClient.invalidateQueries({ queryKey: ['pat'] })
|
||||
patModal.value.hide()
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
@@ -445,10 +442,8 @@ async function removePat(id) {
|
||||
startLoading()
|
||||
try {
|
||||
pats.value = pats.value.filter((x) => x.id !== id)
|
||||
await useBaseFetch(`pat/${id}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
await refresh()
|
||||
await client.labrinth.pats_v2.delete(id)
|
||||
await queryClient.invalidateQueries({ queryKey: ['pat'] })
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
|
||||
@@ -47,17 +47,20 @@ import {
|
||||
commonMessages,
|
||||
commonSettingsMessages,
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
useFormatDateTime,
|
||||
useRelativeTime,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
|
||||
definePageMeta({
|
||||
middleware: 'auth',
|
||||
})
|
||||
|
||||
const client = injectModrinthClient()
|
||||
const queryClient = useQueryClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
const formatRelativeTime = useRelativeTime()
|
||||
@@ -102,19 +105,17 @@ useHead({
|
||||
title: () => `${formatMessage(commonSettingsMessages.sessions)} - Modrinth`,
|
||||
})
|
||||
|
||||
const { data: sessions, refetch: refresh } = useQuery({
|
||||
const { data: sessions } = useQuery({
|
||||
queryKey: ['session', 'list'],
|
||||
queryFn: () => useBaseFetch('session/list'),
|
||||
queryFn: () => client.labrinth.sessions_v2.list(),
|
||||
})
|
||||
|
||||
async function revokeSession(id) {
|
||||
startLoading()
|
||||
try {
|
||||
sessions.value = sessions.value.filter((x) => x.id !== id)
|
||||
await useBaseFetch(`session/${id}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
await refresh()
|
||||
await client.labrinth.sessions_v2.delete(id)
|
||||
await queryClient.invalidateQueries({ queryKey: ['session', 'list'] })
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import {
|
||||
BadgeDollarSignIcon,
|
||||
GiftIcon,
|
||||
@@ -43,29 +44,7 @@ export type PaymentProvider = 'tremendous' | 'muralpay' | 'paypal' | 'venmo'
|
||||
**/
|
||||
export type PaymentMethod = 'gift_card' | 'paypal' | 'venmo' | 'bank' | 'crypto'
|
||||
|
||||
export interface PayoutMethod {
|
||||
id: string
|
||||
type: string
|
||||
name: string
|
||||
category?: string
|
||||
image_url: string | null
|
||||
image_logo_url: string | null
|
||||
interval: {
|
||||
standard: {
|
||||
min: number
|
||||
max: number
|
||||
}
|
||||
fixed?: {
|
||||
values: number[]
|
||||
}
|
||||
}
|
||||
config?: {
|
||||
fiat?: string | null
|
||||
blockchain?: string[]
|
||||
}
|
||||
currency_code?: string | null
|
||||
exchange_rate?: number | null
|
||||
}
|
||||
export type PayoutMethod = Labrinth.Payout.v3.PayoutMethod
|
||||
|
||||
export interface PaymentOption {
|
||||
value: string
|
||||
|
||||
@@ -21,6 +21,16 @@ export function fetchSegmented<T>(
|
||||
).then((results) => results.flat())
|
||||
}
|
||||
|
||||
export function fetchSegmentedWith<TId, TResult>(
|
||||
data: TId[],
|
||||
fetchFn: (ids: TId[]) => Promise<TResult[]>,
|
||||
segmentSize = 800,
|
||||
): Promise<TResult[]> {
|
||||
return Promise.all(segmentData(data, segmentSize).map((ids) => fetchFn(ids))).then((results) =>
|
||||
results.flat(),
|
||||
)
|
||||
}
|
||||
|
||||
export function asEncodedJsonArray<T>(data: T[]): string {
|
||||
return encodeURIComponent(JSON.stringify(data))
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export class ArchonServersV0Module extends AbstractModule {
|
||||
|
||||
/**
|
||||
* Check stock availability for a region
|
||||
* POST /modrinth/v0/stock
|
||||
* POST /modrinth/v0/stock?region=:region
|
||||
*/
|
||||
public async checkStock(
|
||||
region: string,
|
||||
@@ -52,6 +52,23 @@ export class ArchonServersV0Module extends AbstractModule {
|
||||
version: 'modrinth/v0',
|
||||
method: 'POST',
|
||||
body: request,
|
||||
skipAuth: true,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Check stock availability (without region filter)
|
||||
* POST /modrinth/v0/stock
|
||||
*/
|
||||
public async checkStockGlobal(
|
||||
request: Archon.Servers.v0.StockRequest,
|
||||
): Promise<Archon.Servers.v0.StockResponse> {
|
||||
return this.client.request<Archon.Servers.v0.StockResponse>('/stock', {
|
||||
api: 'archon',
|
||||
version: 'modrinth/v0',
|
||||
method: 'POST',
|
||||
body: request,
|
||||
skipAuth: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ export class ArchonServersV1Module extends AbstractModule {
|
||||
api: 'archon',
|
||||
version: 1,
|
||||
method: 'GET',
|
||||
skipAuth: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -10,15 +10,28 @@ import { ISO3166Module } from './iso3166'
|
||||
import { KyrosContentV1Module } from './kyros/content/v1'
|
||||
import { KyrosFilesV0Module } from './kyros/files/v0'
|
||||
import { LabrinthVersionsV2Module, LabrinthVersionsV3Module } from './labrinth'
|
||||
import { LabrinthAffiliateInternalModule } from './labrinth/affiliate/internal'
|
||||
import { LabrinthAuthInternalModule } from './labrinth/auth/internal'
|
||||
import { LabrinthAuthV2Module } from './labrinth/auth/v2'
|
||||
import { LabrinthBillingInternalModule } from './labrinth/billing/internal'
|
||||
import { LabrinthGlobalsInternalModule } from './labrinth/globals/internal'
|
||||
import { LabrinthNotificationsV2Module } from './labrinth/notifications/v2'
|
||||
import { LabrinthOAuthInternalModule } from './labrinth/oauth/internal'
|
||||
import { LabrinthCollectionsModule } from './labrinth/collections'
|
||||
import { LabrinthOrganizationsV3Module } from './labrinth/organizations/v3'
|
||||
import { LabrinthPatsV2Module } from './labrinth/pats/v2'
|
||||
import { LabrinthLimitsV3Module } from './labrinth/limits/v3'
|
||||
import { LabrinthPayoutV3Module } from './labrinth/payout/v3'
|
||||
import { LabrinthPayoutsV3Module } from './labrinth/payouts/v3'
|
||||
import { LabrinthReportsV3Module } from './labrinth/reports/v3'
|
||||
import { LabrinthProjectsV2Module } from './labrinth/projects/v2'
|
||||
import { LabrinthProjectsV3Module } from './labrinth/projects/v3'
|
||||
import { LabrinthServerPingInternalModule } from './labrinth/server-ping/internal'
|
||||
import { LabrinthSessionsV2Module } from './labrinth/sessions/v2'
|
||||
import { LabrinthStateModule } from './labrinth/state'
|
||||
import { LabrinthTagsV2Module } from './labrinth/tags/v2'
|
||||
import { LabrinthTeamsV2Module } from './labrinth/teams/v2'
|
||||
import { LabrinthTeamsV3Module } from './labrinth/teams/v3'
|
||||
import { LabrinthTechReviewInternalModule } from './labrinth/tech-review/internal'
|
||||
import { LabrinthThreadsV3Module } from './labrinth/threads/v3'
|
||||
import { LabrinthUsersV2Module } from './labrinth/users/v2'
|
||||
@@ -48,15 +61,28 @@ export const MODULE_REGISTRY = {
|
||||
launchermeta_manifest_v0: LauncherMetaManifestV0Module,
|
||||
kyros_content_v1: KyrosContentV1Module,
|
||||
kyros_files_v0: KyrosFilesV0Module,
|
||||
labrinth_affiliate_internal: LabrinthAffiliateInternalModule,
|
||||
labrinth_auth_internal: LabrinthAuthInternalModule,
|
||||
labrinth_auth_v2: LabrinthAuthV2Module,
|
||||
labrinth_billing_internal: LabrinthBillingInternalModule,
|
||||
labrinth_collections: LabrinthCollectionsModule,
|
||||
labrinth_globals_internal: LabrinthGlobalsInternalModule,
|
||||
labrinth_notifications_v2: LabrinthNotificationsV2Module,
|
||||
labrinth_oauth_internal: LabrinthOAuthInternalModule,
|
||||
labrinth_organizations_v3: LabrinthOrganizationsV3Module,
|
||||
labrinth_pats_v2: LabrinthPatsV2Module,
|
||||
labrinth_limits_v3: LabrinthLimitsV3Module,
|
||||
labrinth_payout_v3: LabrinthPayoutV3Module,
|
||||
labrinth_payouts_v3: LabrinthPayoutsV3Module,
|
||||
labrinth_projects_v2: LabrinthProjectsV2Module,
|
||||
labrinth_projects_v3: LabrinthProjectsV3Module,
|
||||
labrinth_reports_v3: LabrinthReportsV3Module,
|
||||
labrinth_server_ping_internal: LabrinthServerPingInternalModule,
|
||||
labrinth_sessions_v2: LabrinthSessionsV2Module,
|
||||
labrinth_state: LabrinthStateModule,
|
||||
labrinth_tags_v2: LabrinthTagsV2Module,
|
||||
labrinth_teams_v2: LabrinthTeamsV2Module,
|
||||
labrinth_teams_v3: LabrinthTeamsV3Module,
|
||||
labrinth_tech_review_internal: LabrinthTechReviewInternalModule,
|
||||
labrinth_threads_v3: LabrinthThreadsV3Module,
|
||||
labrinth_users_v2: LabrinthUsersV2Module,
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthAffiliateInternalModule extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_affiliate_internal'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all affiliate codes for the authenticated user (or all if admin)
|
||||
* GET /_internal/affiliate
|
||||
*/
|
||||
public async getAll(): Promise<Labrinth.Affiliate.Internal.AffiliateCode[]> {
|
||||
return this.client.request<Labrinth.Affiliate.Internal.AffiliateCode[]>('/affiliate', {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new affiliate code
|
||||
* PUT /_internal/affiliate
|
||||
*/
|
||||
public async create(
|
||||
data: Labrinth.Affiliate.Internal.CreateRequest,
|
||||
): Promise<Labrinth.Affiliate.Internal.AffiliateCode> {
|
||||
return this.client.request<Labrinth.Affiliate.Internal.AffiliateCode>('/affiliate', {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'PUT',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific affiliate code by ID
|
||||
* GET /_internal/affiliate/{id}
|
||||
*/
|
||||
public async get(id: string): Promise<Labrinth.Affiliate.Internal.AffiliateCode> {
|
||||
return this.client.request<Labrinth.Affiliate.Internal.AffiliateCode>(`/affiliate/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an affiliate code
|
||||
* DELETE /_internal/affiliate/{id}
|
||||
*/
|
||||
public async delete(id: string): Promise<void> {
|
||||
return this.client.request<void>(`/affiliate/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an affiliate code's source name
|
||||
* PATCH /_internal/affiliate/{id}
|
||||
*/
|
||||
public async patch(id: string, data: Labrinth.Affiliate.Internal.PatchRequest): Promise<void> {
|
||||
return this.client.request<void>(`/affiliate/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
}
|
||||
87
packages/api-client/src/modules/labrinth/auth/v2.ts
Normal file
87
packages/api-client/src/modules/labrinth/auth/v2.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthAuthV2Module extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_auth_v2'
|
||||
}
|
||||
|
||||
/**
|
||||
* Log in with a password
|
||||
*
|
||||
* Returns a session token on success, or a flow ID if 2FA is required.
|
||||
*
|
||||
* @param data - Login credentials and captcha challenge
|
||||
* @returns Promise resolving to a login response with session or flow
|
||||
*/
|
||||
public async login(data: Labrinth.Auth.v2.LoginRequest): Promise<Labrinth.Auth.v2.LoginResponse> {
|
||||
return this.client.request<Labrinth.Auth.v2.LoginResponse>(`/auth/login`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete a 2FA login flow
|
||||
*
|
||||
* @param data - The 2FA code and flow ID
|
||||
* @returns Promise resolving to a session response
|
||||
*/
|
||||
public async login2FA(
|
||||
data: Labrinth.Auth.v2.Login2FARequest,
|
||||
): Promise<Labrinth.Auth.v2.Login2FAResponse> {
|
||||
return this.client.request<Labrinth.Auth.v2.Login2FAResponse>(`/auth/login/2fa`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new account with a password
|
||||
*
|
||||
* @param data - Account creation data
|
||||
* @returns Promise resolving to a session response
|
||||
*/
|
||||
public async createAccount(
|
||||
data: Labrinth.Auth.v2.CreateAccountRequest,
|
||||
): Promise<Labrinth.Auth.v2.CreateAccountResponse> {
|
||||
return this.client.request<Labrinth.Auth.v2.CreateAccountResponse>(`/auth/create`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin a password reset flow by sending a recovery email
|
||||
*
|
||||
* @param data - The username/email and captcha challenge
|
||||
*/
|
||||
public async resetPasswordBegin(data: Labrinth.Auth.v2.ResetPasswordRequest): Promise<void> {
|
||||
return this.client.request(`/auth/password/reset`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Change a user's password (via reset flow or with old password)
|
||||
*
|
||||
* @param data - The password change data
|
||||
*/
|
||||
public async changePassword(data: Labrinth.Auth.v2.ChangePasswordRequest): Promise<void> {
|
||||
return this.client.request(`/auth/password`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
}
|
||||
22
packages/api-client/src/modules/labrinth/globals/internal.ts
Normal file
22
packages/api-client/src/modules/labrinth/globals/internal.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthGlobalsInternalModule extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_globals_internal'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get configured global non-secret variables for this backend instance
|
||||
*
|
||||
* @returns Promise resolving to the global configuration
|
||||
*/
|
||||
public async get(): Promise<Labrinth.Globals.Internal.Globals> {
|
||||
return this.client.request<Labrinth.Globals.Internal.Globals>(`/globals`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'GET',
|
||||
skipAuth: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,20 @@
|
||||
export * from './auth/internal'
|
||||
export * from './auth/v2'
|
||||
export * from './billing/internal'
|
||||
export * from './collections'
|
||||
export * from './globals/internal'
|
||||
export * from './notifications/v2'
|
||||
export * from './oauth/internal'
|
||||
export * from './organizations/v3'
|
||||
export * from './pats/v2'
|
||||
export * from './limits/v3'
|
||||
export * from './payout/v3'
|
||||
export * from './payouts/v3'
|
||||
export * from './projects/v2'
|
||||
export * from './projects/v3'
|
||||
export * from './reports/v3'
|
||||
export * from './server-ping/internal'
|
||||
export * from './sessions/v2'
|
||||
export * from './state'
|
||||
export * from './tech-review/internal'
|
||||
export * from './threads/v3'
|
||||
|
||||
41
packages/api-client/src/modules/labrinth/limits/v3.ts
Normal file
41
packages/api-client/src/modules/labrinth/limits/v3.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module.js'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthLimitsV3Module extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_limits_v3'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get project creation limits for the authenticated user.
|
||||
*/
|
||||
public async getProjectLimits(): Promise<Labrinth.Limits.v3.UserLimits> {
|
||||
return this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/projects', {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get organization creation limits for the authenticated user.
|
||||
*/
|
||||
public async getOrganizationLimits(): Promise<Labrinth.Limits.v3.UserLimits> {
|
||||
return this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/organizations', {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection creation limits for the authenticated user.
|
||||
*/
|
||||
public async getCollectionLimits(): Promise<Labrinth.Limits.v3.UserLimits> {
|
||||
return this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/collections', {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
}
|
||||
128
packages/api-client/src/modules/labrinth/notifications/v2.ts
Normal file
128
packages/api-client/src/modules/labrinth/notifications/v2.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthNotificationsV2Module extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_notifications_v2'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all notifications for a user
|
||||
*
|
||||
* @param userId - The user's ID
|
||||
* @returns Promise resolving to the user's notifications
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const notifications = await client.labrinth.notifications_v2.getUserNotifications('user123')
|
||||
* ```
|
||||
*/
|
||||
public async getUserNotifications(
|
||||
userId: string,
|
||||
): Promise<Labrinth.Notifications.v2.Notification[]> {
|
||||
return this.client.request<Labrinth.Notifications.v2.Notification[]>(
|
||||
`/user/${userId}/notifications`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'GET',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple notifications by their IDs
|
||||
*
|
||||
* @param ids - Array of notification IDs
|
||||
* @returns Promise resolving to an array of notifications
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const notifications = await client.labrinth.notifications_v2.getMultiple(['id1', 'id2'])
|
||||
* ```
|
||||
*/
|
||||
public async getMultiple(ids: string[]): Promise<Labrinth.Notifications.v2.Notification[]> {
|
||||
return this.client.request<Labrinth.Notifications.v2.Notification[]>(
|
||||
`/notifications?ids=${encodeURIComponent(JSON.stringify(ids))}`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'GET',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a single notification as read
|
||||
*
|
||||
* @param id - Notification ID
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.notifications_v2.markAsRead('notif123')
|
||||
* ```
|
||||
*/
|
||||
public async markAsRead(id: string): Promise<void> {
|
||||
return this.client.request(`/notification/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'PATCH',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark multiple notifications as read
|
||||
*
|
||||
* @param ids - Array of notification IDs to mark as read
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.notifications_v2.markMultipleAsRead(['id1', 'id2'])
|
||||
* ```
|
||||
*/
|
||||
public async markMultipleAsRead(ids: string[]): Promise<void> {
|
||||
return this.client.request(`/notifications`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'PATCH',
|
||||
params: { ids: JSON.stringify([...new Set(ids)]) },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a single notification
|
||||
*
|
||||
* @param id - Notification ID
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.notifications_v2.delete('notif123')
|
||||
* ```
|
||||
*/
|
||||
public async delete(id: string): Promise<void> {
|
||||
return this.client.request(`/notification/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete multiple notifications
|
||||
*
|
||||
* @param ids - Array of notification IDs to delete
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.notifications_v2.deleteMultiple(['id1', 'id2'])
|
||||
* ```
|
||||
*/
|
||||
public async deleteMultiple(ids: string[]): Promise<void> {
|
||||
return this.client.request(`/notifications`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'DELETE',
|
||||
params: { ids: JSON.stringify([...new Set(ids)]) },
|
||||
})
|
||||
}
|
||||
}
|
||||
208
packages/api-client/src/modules/labrinth/oauth/internal.ts
Normal file
208
packages/api-client/src/modules/labrinth/oauth/internal.ts
Normal file
@@ -0,0 +1,208 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { UploadHandle } from '../../../types/upload'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthOAuthInternalModule extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_oauth_internal'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user's OAuth applications
|
||||
*
|
||||
* @param userId - The user's ID
|
||||
* @returns Promise resolving to an array of the user's OAuth clients
|
||||
*/
|
||||
public async getUserApps(userId: string): Promise<Labrinth.OAuth.Internal.OAuthClient[]> {
|
||||
return this.client.request<Labrinth.OAuth.Internal.OAuthClient[]>(
|
||||
`/user/${userId}/oauth_apps`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single OAuth application by ID
|
||||
*
|
||||
* @param id - The OAuth client ID
|
||||
* @returns Promise resolving to the OAuth client
|
||||
*/
|
||||
public async getApp(id: string): Promise<Labrinth.OAuth.Internal.OAuthClient> {
|
||||
return this.client.request<Labrinth.OAuth.Internal.OAuthClient>(`/oauth/app/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple OAuth applications by their IDs
|
||||
*
|
||||
* @param ids - Array of OAuth client IDs
|
||||
* @returns Promise resolving to an array of OAuth clients
|
||||
*/
|
||||
public async getApps(ids: string[]): Promise<Labrinth.OAuth.Internal.OAuthClient[]> {
|
||||
return this.client.request<Labrinth.OAuth.Internal.OAuthClient[]>(
|
||||
`/oauth/apps?ids=${encodeURIComponent(JSON.stringify(ids))}`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'GET',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new OAuth application
|
||||
*
|
||||
* @param data - The OAuth app creation data
|
||||
* @returns Promise resolving to the created OAuth client with its client secret
|
||||
*/
|
||||
public async createApp(
|
||||
data: Labrinth.OAuth.Internal.CreateOAuthAppRequest,
|
||||
): Promise<Labrinth.OAuth.Internal.OAuthClientCreationResult> {
|
||||
return this.client.request<Labrinth.OAuth.Internal.OAuthClientCreationResult>(`/oauth/app`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing OAuth application
|
||||
*
|
||||
* @param id - The OAuth client ID
|
||||
* @param data - The fields to update
|
||||
*/
|
||||
public async editApp(
|
||||
id: string,
|
||||
data: Labrinth.OAuth.Internal.EditOAuthAppRequest,
|
||||
): Promise<void> {
|
||||
return this.client.request(`/oauth/app/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an OAuth application
|
||||
*
|
||||
* @param id - The OAuth client ID
|
||||
*/
|
||||
public async deleteApp(id: string): Promise<void> {
|
||||
return this.client.request(`/oauth/app/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the icon for an OAuth application
|
||||
*
|
||||
* @param id - The OAuth client ID
|
||||
* @param file - The icon file
|
||||
* @param ext - The file extension (e.g. 'png', 'jpeg')
|
||||
* @returns UploadHandle for progress tracking and cancellation
|
||||
*/
|
||||
public uploadAppIcon(id: string, file: File | Blob, ext: string): UploadHandle<void> {
|
||||
return this.client.upload<void>(`/oauth/app/${id}/icon`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
file,
|
||||
params: { ext },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current user's OAuth authorizations
|
||||
*
|
||||
* @returns Promise resolving to an array of OAuth client authorizations
|
||||
*/
|
||||
public async getAuthorizations(): Promise<Labrinth.OAuth.Internal.OAuthClientAuthorization[]> {
|
||||
return this.client.request<Labrinth.OAuth.Internal.OAuthClientAuthorization[]>(
|
||||
`/oauth/authorizations`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'GET',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke an OAuth authorization for a client
|
||||
*
|
||||
* @param clientId - The OAuth client ID to revoke
|
||||
*/
|
||||
public async revokeAuthorization(clientId: string): Promise<void> {
|
||||
return this.client.request(`/oauth/authorizations`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'DELETE',
|
||||
params: { client_id: clientId },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an OAuth authorization flow
|
||||
*
|
||||
* Returns either an OAuthClientAccessRequest (if user needs to approve)
|
||||
* or a redirect URL string (if already authorized).
|
||||
*
|
||||
* @param params - The OAuth query parameters
|
||||
* @returns Promise resolving to an access request object or redirect URL string
|
||||
*/
|
||||
public async authorize(params: {
|
||||
client_id: string
|
||||
redirect_uri: string
|
||||
scope: string
|
||||
state?: string
|
||||
}): Promise<Labrinth.OAuth.Internal.OAuthClientAccessRequest | string> {
|
||||
return this.client.request<Labrinth.OAuth.Internal.OAuthClientAccessRequest | string>(
|
||||
`/oauth/authorize`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'GET',
|
||||
params: params as Record<string, string>,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept an OAuth authorization request
|
||||
*
|
||||
* @param data - The flow ID to accept
|
||||
* @returns Promise resolving to a redirect URL string
|
||||
*/
|
||||
public async accept(data: Labrinth.OAuth.Internal.AcceptRejectRequest): Promise<string> {
|
||||
return this.client.request<string>(`/oauth/accept`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject an OAuth authorization request
|
||||
*
|
||||
* @param data - The flow ID to reject
|
||||
* @returns Promise resolving to a redirect URL string
|
||||
*/
|
||||
public async reject(data: Labrinth.OAuth.Internal.AcceptRejectRequest): Promise<string> {
|
||||
return this.client.request<string>(`/oauth/reject`, {
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -49,4 +49,74 @@ export class LabrinthOrganizationsV3Module extends AbstractModule {
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple organizations by their IDs
|
||||
*
|
||||
* @param ids - Array of organization IDs
|
||||
* @returns Promise resolving to an array of organizations
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const orgs = await client.labrinth.organizations_v3.getMultiple(['id1', 'id2'])
|
||||
* ```
|
||||
*/
|
||||
public async getMultiple(ids: string[]): Promise<Labrinth.Organizations.v3.Organization[]> {
|
||||
return this.client.request<Labrinth.Organizations.v3.Organization[]>(
|
||||
`/organizations?ids=${encodeURIComponent(JSON.stringify(ids))}`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a project to an organization
|
||||
*
|
||||
* @param idOrSlug - Organization ID or slug
|
||||
* @param request - The project to add
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.organizations_v3.addProject('my-org', { project_id: 'AABBCCDD' })
|
||||
* ```
|
||||
*/
|
||||
public async addProject(
|
||||
idOrSlug: string,
|
||||
request: Labrinth.Organizations.v3.AddProjectRequest,
|
||||
): Promise<void> {
|
||||
return this.client.request(`/organization/${idOrSlug}/projects`, {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'POST',
|
||||
body: request,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a project from an organization
|
||||
*
|
||||
* @param idOrSlug - Organization ID or slug
|
||||
* @param projectId - Project ID to remove
|
||||
* @param data - Request body containing the new_owner user ID
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.organizations_v3.removeProject('my-org', 'proj123', { new_owner: 'user456' })
|
||||
* ```
|
||||
*/
|
||||
public async removeProject(
|
||||
idOrSlug: string,
|
||||
projectId: string,
|
||||
data: Labrinth.Organizations.v3.RemoveProjectRequest,
|
||||
): Promise<void> {
|
||||
return this.client.request(`/organization/${idOrSlug}/projects/${projectId}`, {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'DELETE',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
66
packages/api-client/src/modules/labrinth/pats/v2.ts
Normal file
66
packages/api-client/src/modules/labrinth/pats/v2.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthPatsV2Module extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_pats_v2'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all personal access tokens for the authenticated user
|
||||
*
|
||||
* @returns Promise resolving to an array of PATs
|
||||
*/
|
||||
public async list(): Promise<Labrinth.Pats.v2.PersonalAccessToken[]> {
|
||||
return this.client.request<Labrinth.Pats.v2.PersonalAccessToken[]>('/pat', {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new personal access token
|
||||
*
|
||||
* @param data - The PAT creation request data
|
||||
* @returns Promise resolving to the newly created PAT (includes access_token)
|
||||
*/
|
||||
public async create(
|
||||
data: Labrinth.Pats.v2.CreatePatRequest,
|
||||
): Promise<Labrinth.Pats.v2.PersonalAccessToken> {
|
||||
return this.client.request<Labrinth.Pats.v2.PersonalAccessToken>('/pat', {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify an existing personal access token
|
||||
*
|
||||
* @param id - The PAT ID
|
||||
* @param data - The fields to update
|
||||
*/
|
||||
public async modify(id: string, data: Labrinth.Pats.v2.ModifyPatRequest): Promise<void> {
|
||||
return this.client.request(`/pat/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a personal access token
|
||||
*
|
||||
* @param id - The PAT ID
|
||||
*/
|
||||
public async delete(id: string): Promise<void> {
|
||||
return this.client.request(`/pat/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -18,4 +18,45 @@ export class LabrinthPayoutV3Module extends AbstractModule {
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authenticated user's transaction history (withdrawals and payouts)
|
||||
*
|
||||
* @returns Promise resolving to an array of transaction items
|
||||
*/
|
||||
public async getHistory(): Promise<Labrinth.Payout.v3.TransactionItem[]> {
|
||||
return this.client.request<Labrinth.Payout.v3.TransactionItem[]>('/payout/history', {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available payout methods, optionally filtered by country
|
||||
*
|
||||
* @param country - Optional ISO country code to filter methods by supported countries
|
||||
* @returns Promise resolving to an array of payout methods
|
||||
*/
|
||||
public async getMethods(country?: string): Promise<Labrinth.Payout.v3.PayoutMethod[]> {
|
||||
return this.client.request<Labrinth.Payout.v3.PayoutMethod[]>('/payout/methods', {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
params: country ? { country } : undefined,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel a pending payout
|
||||
*
|
||||
* @param id - The payout ID to cancel
|
||||
*/
|
||||
public async cancel(id: string): Promise<void> {
|
||||
return this.client.request<void>(`/payout/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
26
packages/api-client/src/modules/labrinth/payouts/v3.ts
Normal file
26
packages/api-client/src/modules/labrinth/payouts/v3.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module.js'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthPayoutsV3Module extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_payouts_v3'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get platform revenue data.
|
||||
*
|
||||
* @param params - Optional start/end date filters
|
||||
* @returns Promise resolving to platform revenue data
|
||||
*/
|
||||
public async getPlatformRevenue(params?: {
|
||||
start?: string
|
||||
end?: string
|
||||
}): Promise<Labrinth.Payouts.v3.RevenueResponse> {
|
||||
return this.client.request<Labrinth.Payouts.v3.RevenueResponse>('/payout/platform_revenue', {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
params: params as Record<string, string>,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -256,4 +256,31 @@ export class LabrinthProjectsV2Module extends AbstractModule {
|
||||
params: { count: String(count) },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk edit multiple projects at once
|
||||
*
|
||||
* @param ids - Array of project IDs to edit
|
||||
* @param data - Fields to update across all specified projects
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.projects_v2.bulkEdit(['id1', 'id2'], {
|
||||
* issues_url: 'https://github.com/issues',
|
||||
* source_url: null,
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
public async bulkEdit(
|
||||
ids: string[],
|
||||
data: Labrinth.Projects.v2.BulkEditProjectRequest,
|
||||
): Promise<void> {
|
||||
return this.client.request(`/projects`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'PATCH',
|
||||
params: { ids: JSON.stringify(ids) },
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
141
packages/api-client/src/modules/labrinth/reports/v3.ts
Normal file
141
packages/api-client/src/modules/labrinth/reports/v3.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthReportsV3Module extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_reports_v3'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a report by ID
|
||||
*
|
||||
* @param id - Report ID
|
||||
* @returns Promise resolving to the report data
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const report = await client.labrinth.reports_v3.get('abc123')
|
||||
* ```
|
||||
*/
|
||||
public async get(id: string): Promise<Labrinth.Reports.v3.Report> {
|
||||
return this.client.request<Labrinth.Reports.v3.Report>(`/report/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* List reports for the current user (or all reports if moderator)
|
||||
*
|
||||
* @param params - Optional query parameters for count, offset, and whether to show all reports
|
||||
* @returns Promise resolving to an array of reports
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const reports = await client.labrinth.reports_v3.list({ count: 100 })
|
||||
* ```
|
||||
*/
|
||||
public async list(
|
||||
params?: Labrinth.Reports.v3.ListReportsParams,
|
||||
): Promise<Labrinth.Reports.v3.Report[]> {
|
||||
const queryParams: Record<string, string> = {}
|
||||
if (params?.count != null) queryParams.count = String(params.count)
|
||||
if (params?.offset != null) queryParams.offset = String(params.offset)
|
||||
if (params?.all != null) queryParams.all = String(params.all)
|
||||
|
||||
return this.client.request<Labrinth.Reports.v3.Report[]>(`/report`, {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple reports by IDs
|
||||
*
|
||||
* @param ids - Array of report IDs
|
||||
* @returns Promise resolving to an array of reports
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const reports = await client.labrinth.reports_v3.getMultiple(['id1', 'id2'])
|
||||
* ```
|
||||
*/
|
||||
public async getMultiple(ids: string[]): Promise<Labrinth.Reports.v3.Report[]> {
|
||||
return this.client.request<Labrinth.Reports.v3.Report[]>(
|
||||
`/reports?ids=${encodeURIComponent(JSON.stringify(ids))}`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new report
|
||||
*
|
||||
* @param data - Report creation data
|
||||
* @returns Promise resolving to the created report
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const report = await client.labrinth.reports_v3.create({
|
||||
* report_type: 'spam',
|
||||
* item_id: 'project123',
|
||||
* item_type: 'project',
|
||||
* body: 'This project is spam',
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
public async create(
|
||||
data: Labrinth.Reports.v3.CreateReportRequest,
|
||||
): Promise<Labrinth.Reports.v3.Report> {
|
||||
return this.client.request<Labrinth.Reports.v3.Report>(`/report`, {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a report
|
||||
*
|
||||
* @param id - Report ID
|
||||
* @param data - Report edit data
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.reports_v3.edit('abc123', { closed: true })
|
||||
* ```
|
||||
*/
|
||||
public async edit(id: string, data: Labrinth.Reports.v3.EditReportRequest): Promise<void> {
|
||||
return this.client.request(`/report/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a report (moderator only)
|
||||
*
|
||||
* @param id - Report ID
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.reports_v3.delete('abc123')
|
||||
* ```
|
||||
*/
|
||||
public async delete(id: string): Promise<void> {
|
||||
return this.client.request(`/report/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
}
|
||||
34
packages/api-client/src/modules/labrinth/sessions/v2.ts
Normal file
34
packages/api-client/src/modules/labrinth/sessions/v2.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthSessionsV2Module extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_sessions_v2'
|
||||
}
|
||||
|
||||
/**
|
||||
* List all sessions for the authenticated user
|
||||
*
|
||||
* @returns Promise resolving to an array of sessions
|
||||
*/
|
||||
public async list(): Promise<Labrinth.Sessions.v2.Session[]> {
|
||||
return this.client.request<Labrinth.Sessions.v2.Session[]>('/session/list', {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete (revoke) a session
|
||||
*
|
||||
* @param id - The session ID
|
||||
*/
|
||||
public async delete(id: string): Promise<void> {
|
||||
return this.client.request(`/session/${id}`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
}
|
||||
29
packages/api-client/src/modules/labrinth/tags/v2.ts
Normal file
29
packages/api-client/src/modules/labrinth/tags/v2.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthTagsV2Module extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_tags_v2'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get license text by SPDX identifier
|
||||
*
|
||||
* @param licenseId - SPDX license identifier (e.g., 'MIT', 'Apache-2.0')
|
||||
* @returns Promise resolving to the license title and body text
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const license = await client.labrinth.tags_v2.getLicenseText('MIT')
|
||||
* console.log(license.title) // "MIT License"
|
||||
* console.log(license.body) // full license text
|
||||
* ```
|
||||
*/
|
||||
public async getLicenseText(licenseId: string): Promise<Labrinth.Tags.v2.LicenseText> {
|
||||
return this.client.request<Labrinth.Tags.v2.LicenseText>(`/tag/license/${licenseId}`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
}
|
||||
101
packages/api-client/src/modules/labrinth/teams/v2.ts
Normal file
101
packages/api-client/src/modules/labrinth/teams/v2.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthTeamsV2Module extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_teams_v2'
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a member to a team
|
||||
*
|
||||
* @param teamId - Team ID
|
||||
* @param data - New member data including user_id
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.teams_v2.addMember('team123', { user_id: 'user456' })
|
||||
* ```
|
||||
*/
|
||||
public async addMember(
|
||||
teamId: string,
|
||||
data: Labrinth.Teams.v2.AddTeamMemberRequest,
|
||||
): Promise<void> {
|
||||
return this.client.request(`/team/${teamId}/members`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'POST',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a team member
|
||||
*
|
||||
* @param teamId - Team ID
|
||||
* @param userId - User ID of the member to edit
|
||||
* @param data - Member update data
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.teams_v2.editMember('team123', 'user456', {
|
||||
* role: 'Developer',
|
||||
* permissions: 0b111,
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
public async editMember(
|
||||
teamId: string,
|
||||
userId: string,
|
||||
data: Labrinth.Teams.v2.EditTeamMemberRequest,
|
||||
): Promise<void> {
|
||||
return this.client.request(`/team/${teamId}/members/${userId}`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a member from a team
|
||||
*
|
||||
* @param teamId - Team ID
|
||||
* @param userId - User ID of the member to remove
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.teams_v2.removeMember('team123', 'user456')
|
||||
* ```
|
||||
*/
|
||||
public async removeMember(teamId: string, userId: string): Promise<void> {
|
||||
return this.client.request(`/team/${teamId}/members/${userId}`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer team ownership to another member
|
||||
*
|
||||
* @param teamId - Team ID
|
||||
* @param data - Transfer data including the new owner's user_id
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await client.labrinth.teams_v2.transferOwnership('team123', { user_id: 'user456' })
|
||||
* ```
|
||||
*/
|
||||
public async transferOwnership(
|
||||
teamId: string,
|
||||
data: Labrinth.Teams.v2.TransferOwnershipRequest,
|
||||
): Promise<void> {
|
||||
return this.client.request(`/team/${teamId}/owner`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
})
|
||||
}
|
||||
}
|
||||
31
packages/api-client/src/modules/labrinth/teams/v3.ts
Normal file
31
packages/api-client/src/modules/labrinth/teams/v3.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthTeamsV3Module extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_teams_v3'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple teams by their IDs
|
||||
*
|
||||
* @param ids - Array of team IDs
|
||||
* @returns Promise resolving to an array of team member arrays (one per team)
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const teams = await client.labrinth.teams_v3.getMultiple(['team1', 'team2'])
|
||||
* // teams[0] = members of team1, teams[1] = members of team2
|
||||
* ```
|
||||
*/
|
||||
public async getMultiple(ids: string[]): Promise<Labrinth.Projects.v3.TeamMember[][]> {
|
||||
return this.client.request<Labrinth.Projects.v3.TeamMember[][]>(
|
||||
`/teams?ids=${encodeURIComponent(JSON.stringify(ids))}`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,28 @@ export class LabrinthThreadsV3Module extends AbstractModule {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple threads by IDs (v3)
|
||||
*
|
||||
* @param ids - Array of thread IDs
|
||||
* @returns Promise resolving to an array of threads
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const threads = await client.labrinth.threads_v3.getMultiple(['id1', 'id2'])
|
||||
* ```
|
||||
*/
|
||||
public async getMultiple(ids: string[]): Promise<Labrinth.Threads.v3.Thread[]> {
|
||||
return this.client.request<Labrinth.Threads.v3.Thread[]>(
|
||||
`/threads?ids=${encodeURIComponent(JSON.stringify(ids))}`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 3,
|
||||
method: 'GET',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a thread (v3)
|
||||
*
|
||||
|
||||
@@ -158,6 +158,83 @@ export namespace Labrinth {
|
||||
requested_form_type: string | null
|
||||
form_completion_status: string | null
|
||||
}
|
||||
|
||||
export type PayoutStatus =
|
||||
| 'success'
|
||||
| 'in-transit'
|
||||
| 'cancelled'
|
||||
| 'cancelling'
|
||||
| 'failed'
|
||||
| 'unknown'
|
||||
|
||||
export type PayoutMethodType = 'venmo' | 'paypal' | 'tremendous' | 'muralpay'
|
||||
|
||||
export type PayoutSource = 'creator_rewards' | 'affilites'
|
||||
|
||||
export type TransactionItem =
|
||||
| {
|
||||
type: 'withdrawal'
|
||||
id: string
|
||||
status: PayoutStatus
|
||||
created: string
|
||||
amount: number
|
||||
fee: number | null
|
||||
method_type: PayoutMethodType | null
|
||||
method_id: string | null
|
||||
method_address: string | null
|
||||
}
|
||||
| {
|
||||
type: 'payout_available'
|
||||
created: string
|
||||
payout_source: PayoutSource
|
||||
amount: number
|
||||
}
|
||||
|
||||
export type WithdrawalFees = {
|
||||
net_usd: number
|
||||
fee: number
|
||||
exchange_rate: number | null
|
||||
}
|
||||
|
||||
export type PayoutDecimal = number
|
||||
|
||||
export type PayoutInterval = {
|
||||
standard?: { min: number; max: number }
|
||||
fixed?: { values: PayoutDecimal[] }
|
||||
}
|
||||
|
||||
export type PayoutMethod = {
|
||||
id: string
|
||||
type: PayoutMethodType
|
||||
name: string
|
||||
category: string | null
|
||||
image_url: string | null
|
||||
image_logo_url: string | null
|
||||
interval: PayoutInterval
|
||||
currency_code: string | null
|
||||
exchange_rate: number | null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Affiliate {
|
||||
export namespace Internal {
|
||||
export type AffiliateCode = {
|
||||
id: string
|
||||
created_at: string | null
|
||||
created_by: string | null
|
||||
affiliate: string
|
||||
source_name: string
|
||||
}
|
||||
|
||||
export type CreateRequest = {
|
||||
affiliate?: string
|
||||
source_name: string
|
||||
}
|
||||
|
||||
export type PatchRequest = {
|
||||
source_name: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +244,123 @@ export namespace Labrinth {
|
||||
subscribed: boolean
|
||||
}
|
||||
}
|
||||
|
||||
export namespace v2 {
|
||||
export type LoginRequest = {
|
||||
username: string
|
||||
password: string
|
||||
challenge: string
|
||||
}
|
||||
|
||||
export type LoginResponse = {
|
||||
session?: string
|
||||
flow?: string
|
||||
}
|
||||
|
||||
export type Login2FARequest = {
|
||||
code: string
|
||||
flow: string
|
||||
}
|
||||
|
||||
export type Login2FAResponse = {
|
||||
session: string
|
||||
}
|
||||
|
||||
export type CreateAccountRequest = {
|
||||
username: string
|
||||
password: string
|
||||
email: string
|
||||
challenge: string
|
||||
sign_up_newsletter?: boolean
|
||||
}
|
||||
|
||||
export type CreateAccountResponse = {
|
||||
session: string
|
||||
}
|
||||
|
||||
export type ResetPasswordRequest = {
|
||||
username: string
|
||||
challenge: string
|
||||
}
|
||||
|
||||
export type ChangePasswordRequest = {
|
||||
flow?: string
|
||||
old_password?: string
|
||||
new_password?: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Globals {
|
||||
export namespace Internal {
|
||||
export type Globals = {
|
||||
tax_compliance_thresholds: Record<string, number>
|
||||
captcha_enabled: boolean
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace OAuth {
|
||||
export namespace Internal {
|
||||
export type OAuthClientAccessRequest = {
|
||||
flow_id: string
|
||||
client_id: string
|
||||
client_name: string
|
||||
client_icon: string | null
|
||||
requested_scopes: number
|
||||
}
|
||||
|
||||
export type AcceptRejectRequest = {
|
||||
flow: string
|
||||
}
|
||||
|
||||
export type OAuthRedirectUri = {
|
||||
id: string
|
||||
client_id: string
|
||||
uri: string
|
||||
}
|
||||
|
||||
export type OAuthClient = {
|
||||
id: string
|
||||
name: string
|
||||
icon_url: string | null
|
||||
max_scopes: number
|
||||
redirect_uris: OAuthRedirectUri[]
|
||||
created_by: string
|
||||
created: string
|
||||
url: string | null
|
||||
description: string | null
|
||||
}
|
||||
|
||||
export type OAuthClientCreationResult = OAuthClient & {
|
||||
client_secret: string
|
||||
}
|
||||
|
||||
export type OAuthClientAuthorization = {
|
||||
id: string
|
||||
app_id: string
|
||||
user_id: string
|
||||
scopes: number
|
||||
created: string
|
||||
}
|
||||
|
||||
export type CreateOAuthAppRequest = {
|
||||
name: string
|
||||
max_scopes: number
|
||||
redirect_uris: string[]
|
||||
url?: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
export type EditOAuthAppRequest = {
|
||||
name?: string
|
||||
max_scopes?: number
|
||||
redirect_uris?: string[]
|
||||
url?: string | null
|
||||
description?: string | null
|
||||
icon_url?: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Projects {
|
||||
@@ -318,6 +512,22 @@ export namespace Labrinth {
|
||||
projects: Project[]
|
||||
versions: Labrinth.Versions.v2.Version[]
|
||||
}
|
||||
|
||||
export type BulkEditProjectRequest = {
|
||||
categories?: string[]
|
||||
add_categories?: string[]
|
||||
remove_categories?: string[]
|
||||
additional_categories?: string[]
|
||||
add_additional_categories?: string[]
|
||||
remove_additional_categories?: string[]
|
||||
donation_urls?: DonationLink[]
|
||||
add_donation_urls?: DonationLink[]
|
||||
remove_donation_urls?: DonationLink[]
|
||||
issues_url?: string | null
|
||||
source_url?: string | null
|
||||
wiki_url?: string | null
|
||||
discord_url?: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export namespace v3 {
|
||||
@@ -882,6 +1092,36 @@ export namespace Labrinth {
|
||||
short: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export type LicenseText = {
|
||||
title: string
|
||||
body: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Teams {
|
||||
export namespace v2 {
|
||||
export type AddTeamMemberRequest = {
|
||||
user_id: string
|
||||
role?: string
|
||||
permissions?: number
|
||||
organization_permissions?: number | null
|
||||
payouts_split?: number
|
||||
ordering?: number
|
||||
}
|
||||
|
||||
export type EditTeamMemberRequest = {
|
||||
permissions?: number
|
||||
organization_permissions?: number | null
|
||||
role?: string
|
||||
payouts_split?: number
|
||||
ordering?: number
|
||||
}
|
||||
|
||||
export type TransferOwnershipRequest = {
|
||||
user_id: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1017,6 +1257,106 @@ export namespace Labrinth {
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Reports {
|
||||
export namespace v3 {
|
||||
export type ItemType = 'project' | 'version' | 'user' | 'unknown'
|
||||
|
||||
export type Report = {
|
||||
id: string
|
||||
report_type: string
|
||||
item_id: string
|
||||
item_type: ItemType
|
||||
reporter: string
|
||||
body: string
|
||||
created: string
|
||||
closed: boolean
|
||||
thread_id: string
|
||||
}
|
||||
|
||||
export type CreateReportRequest = {
|
||||
report_type: string
|
||||
item_id: string
|
||||
item_type: ItemType
|
||||
body: string
|
||||
uploaded_images?: string[]
|
||||
}
|
||||
|
||||
export type EditReportRequest = {
|
||||
body?: string
|
||||
closed?: boolean
|
||||
}
|
||||
|
||||
export type ListReportsParams = {
|
||||
count?: number
|
||||
offset?: number
|
||||
all?: boolean
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Notifications {
|
||||
export namespace v2 {
|
||||
export type NotificationAction = {
|
||||
title: string
|
||||
action_route: [string, string]
|
||||
}
|
||||
|
||||
export type NotificationBody = {
|
||||
type: string
|
||||
project_id?: string
|
||||
version_id?: string
|
||||
report_id?: string
|
||||
thread_id?: string
|
||||
message_id?: string
|
||||
invited_by?: string
|
||||
organization_id?: string
|
||||
team_id?: string
|
||||
role?: string
|
||||
old_status?: string
|
||||
new_status?: string
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
export type Notification = {
|
||||
id: string
|
||||
user_id: string
|
||||
type: string | null
|
||||
title: string
|
||||
text: string
|
||||
link: string
|
||||
read: boolean
|
||||
created: string
|
||||
actions: NotificationAction[]
|
||||
body: NotificationBody
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Payouts {
|
||||
export namespace v3 {
|
||||
export type RevenueData = {
|
||||
time: number
|
||||
revenue: string
|
||||
creator_revenue: string
|
||||
}
|
||||
|
||||
export type RevenueResponse = {
|
||||
all_time: string
|
||||
all_time_available: string
|
||||
data: RevenueData[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Limits {
|
||||
export namespace v3 {
|
||||
export type UserLimits = {
|
||||
current: number
|
||||
max: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Collections {
|
||||
export type CollectionStatus = 'listed' | 'unlisted' | 'private' | 'rejected' | 'unknown'
|
||||
|
||||
@@ -1267,4 +1607,52 @@ export namespace Labrinth {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Pats {
|
||||
export namespace v2 {
|
||||
export type PersonalAccessToken = {
|
||||
id: string
|
||||
name: string
|
||||
access_token: string | null
|
||||
scopes: number
|
||||
user_id: string
|
||||
created: string
|
||||
expires: string
|
||||
last_used: string | null
|
||||
}
|
||||
|
||||
export type CreatePatRequest = {
|
||||
scopes: number
|
||||
name: string
|
||||
expires: string
|
||||
}
|
||||
|
||||
export type ModifyPatRequest = {
|
||||
scopes?: number
|
||||
name?: string
|
||||
expires?: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Sessions {
|
||||
export namespace v2 {
|
||||
export type Session = {
|
||||
id: string
|
||||
session: string | null
|
||||
user_id: string
|
||||
created: string
|
||||
last_login: string
|
||||
expires: string
|
||||
refresh_expires: string
|
||||
os: string | null
|
||||
platform: string | null
|
||||
user_agent: string
|
||||
city: string | null
|
||||
country: string | null
|
||||
ip: string
|
||||
current: boolean
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +112,49 @@ export class LabrinthUsersV2Module extends AbstractModule {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user's notifications
|
||||
*
|
||||
* @param idOrUsername - The user's ID or username
|
||||
* @returns Promise resolving to an array of the user's notifications
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const notifications = await client.labrinth.users_v2.getNotifications('my_user')
|
||||
* ```
|
||||
*/
|
||||
public async getNotifications(
|
||||
idOrUsername: string,
|
||||
): Promise<Labrinth.Notifications.v2.Notification[]> {
|
||||
return this.client.request<Labrinth.Notifications.v2.Notification[]>(
|
||||
`/user/${idOrUsername}/notifications`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'GET',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get projects a user follows
|
||||
*
|
||||
* @param idOrUsername - The user's ID or username
|
||||
* @returns Promise resolving to an array of followed projects
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const projects = await client.labrinth.users_v2.getFollowedProjects('my_user')
|
||||
* ```
|
||||
*/
|
||||
public async getFollowedProjects(idOrUsername: string): Promise<Labrinth.Projects.v2.Project[]> {
|
||||
return this.client.request<Labrinth.Projects.v2.Project[]>(`/user/${idOrUsername}/follows`, {
|
||||
api: 'labrinth',
|
||||
version: 2,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a user
|
||||
*
|
||||
|
||||
@@ -31,15 +31,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import { AffiliateIcon, XCircleIcon } from '@modrinth/assets'
|
||||
import type { AffiliateLink } from '@modrinth/utils'
|
||||
|
||||
import { defineMessages, useVIntl } from '../../composables/i18n'
|
||||
import { AutoBrandIcon, ButtonStyled, CopyCode } from '../index'
|
||||
|
||||
type AffiliateCode = Labrinth.Affiliate.Internal.AffiliateCode
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
affiliate: AffiliateLink
|
||||
affiliate: AffiliateCode
|
||||
showRevoke?: boolean
|
||||
createdBy?: string
|
||||
}>(),
|
||||
@@ -50,7 +52,7 @@ withDefaults(
|
||||
)
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'revoke', affiliate: AffiliateLink): void
|
||||
(e: 'revoke', affiliate: AffiliateCode): void
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
Reference in New Issue
Block a user