Release 202505310921
This commit is contained in:
5
web/src/actions/api/index.ts
Normal file
5
web/src/actions/api/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { apiServiceActions } from './service'
|
||||
|
||||
export const apiActions = {
|
||||
service: apiServiceActions,
|
||||
}
|
||||
113
web/src/actions/api/service.ts
Normal file
113
web/src/actions/api/service.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import { z } from 'astro/zod'
|
||||
import { ActionError } from 'astro:actions'
|
||||
import { pick } from 'lodash-es'
|
||||
|
||||
import { getKycLevelInfo } from '../../constants/kycLevels'
|
||||
import { getVerificationStatusInfo } from '../../constants/verificationStatus'
|
||||
import { defineProtectedAction } from '../../lib/defineProtectedAction'
|
||||
import { prisma } from '../../lib/prisma'
|
||||
import { zodUrlOptionalProtocol } from '../../lib/zodUtils'
|
||||
|
||||
import type { Prisma } from '@prisma/client'
|
||||
|
||||
export const apiServiceActions = {
|
||||
get: defineProtectedAction({
|
||||
accept: 'json',
|
||||
permissions: 'guest',
|
||||
input: z.object({
|
||||
id: z.coerce.number().int().positive().optional(),
|
||||
slug: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(2048)
|
||||
.regex(/^[a-z0-9-]+$/, 'Allowed characters: lowercase letters, numbers, and hyphens')
|
||||
.optional(),
|
||||
url: zodUrlOptionalProtocol.optional(),
|
||||
}),
|
||||
handler: async (input) => {
|
||||
if (!input.id && !input.slug && !input.url) {
|
||||
throw new ActionError({
|
||||
code: 'BAD_REQUEST',
|
||||
message: 'At least one of the following parameters is required: id, slug, url',
|
||||
})
|
||||
}
|
||||
|
||||
const urlVariants = input.url
|
||||
? [input.url]
|
||||
.flatMap((url) =>
|
||||
[
|
||||
url,
|
||||
url.startsWith('http://') ? url.replace('http://', 'https://') : undefined,
|
||||
url.startsWith('https://') ? url.replace('https://', 'http://') : undefined,
|
||||
].filter((url) => url !== undefined)
|
||||
)
|
||||
.flatMap((url) => [url, url.endsWith('/') ? url.slice(0, -1) : `${url}/`])
|
||||
: undefined
|
||||
|
||||
const service = await prisma.service.findFirst({
|
||||
where: {
|
||||
OR: [
|
||||
...(input.id ? ([{ id: input.id }] satisfies Prisma.ServiceWhereInput[]) : []),
|
||||
...(input.slug ? ([{ slug: input.slug }] satisfies Prisma.ServiceWhereInput[]) : []),
|
||||
...(urlVariants
|
||||
? ([
|
||||
{ serviceUrls: { hasSome: urlVariants } },
|
||||
{ onionUrls: { hasSome: urlVariants } },
|
||||
{ i2pUrls: { hasSome: urlVariants } },
|
||||
] satisfies Prisma.ServiceWhereInput[])
|
||||
: []),
|
||||
],
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
slug: true,
|
||||
description: true,
|
||||
kycLevel: true,
|
||||
verificationStatus: true,
|
||||
categories: {
|
||||
select: {
|
||||
name: true,
|
||||
slug: true,
|
||||
},
|
||||
},
|
||||
serviceUrls: true,
|
||||
onionUrls: true,
|
||||
i2pUrls: true,
|
||||
tosUrls: true,
|
||||
referral: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (!service) {
|
||||
throw new ActionError({
|
||||
code: 'NOT_FOUND',
|
||||
message: 'Service not found',
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
id: service.id,
|
||||
slug: service.slug,
|
||||
name: service.name,
|
||||
description: service.description,
|
||||
verificationStatus: service.verificationStatus,
|
||||
verificationStatusInfo: pick(getVerificationStatusInfo(service.verificationStatus), [
|
||||
'value',
|
||||
'slug',
|
||||
'label',
|
||||
'labelShort',
|
||||
'description',
|
||||
]),
|
||||
kycLevel: service.kycLevel,
|
||||
kycLevelInfo: pick(getKycLevelInfo(service.kycLevel.toString()), ['value', 'name', 'description']),
|
||||
categories: service.categories,
|
||||
serviceUrls: [...service.serviceUrls, ...service.onionUrls, ...service.i2pUrls].map(
|
||||
(url) => url + (service.referral ?? '')
|
||||
),
|
||||
tosUrls: service.tosUrls,
|
||||
kycnotmeUrl: `https://kycnot.me/service/${service.slug}`,
|
||||
}
|
||||
},
|
||||
}),
|
||||
}
|
||||
Reference in New Issue
Block a user