import {z} from 'zod' export type PVService = 'NicoNicoDouga' | 'Youtube' | 'SoundCloud' | 'Vimeo' | 'Piapro' | 'Bilibili' | 'File' | 'LocalFile' | 'Creofuga' | 'Bandcamp'; export type ContentLanguagePreference = 'Default' | 'Japanese' | 'Romaji' | 'English'; export type GetApiApiPvsForSongsArgs = {name?: string | undefined, author?: string | undefined, service?: PVService | undefined, maxResults?: number | undefined, getTotalCount?: boolean | undefined, lang?: ContentLanguagePreference | undefined}; export type GetApiApiPvsForSongsOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const pVServices = z.enum(["Nothing", "NicoNicoDouga", "Youtube", "SoundCloud", "Vimeo", "Piapro", "Bilibili", "File", "LocalFile", "Creofuga", "Bandcamp"]); export const songType = z.enum(["Unspecified", "Original", "Remaster", "Remix", "Cover", "Arrangement", "Instrumental", "Mashup", "MusicPV", "DramaPV", "Live", "Illustration", "Other", "Rearrangement", "ShortVersion"]); export const entryStatus = z.enum(["Draft", "Finished", "Approved", "Locked"]); export const songContract = z.object({additionalNames: z.string().nullable().optional(), artistString: z.string().nullable().optional(), createDate: z.string().optional(), deleted: z.boolean().optional(), favoritedTimes: z.number().int().optional(), id: z.number().int().optional(), lengthSeconds: z.number().int().optional(), name: z.string().nullable().optional(), nicoId: z.string().nullable().optional(), publishDate: z.string().nullable().optional(), pvServices: pVServices.optional(), ratingScore: z.number().int().optional(), songType: songType.optional(), status: entryStatus.optional(), thumbUrl: z.string().nullable().optional(), version: z.number().int().optional()}); export const pVExtendedMetadata = z.object({json: z.string().nullable().optional()}); export const pVService = z.enum(["NicoNicoDouga", "Youtube", "SoundCloud", "Vimeo", "Piapro", "Bilibili", "File", "LocalFile", "Creofuga", "Bandcamp"]); export const pVType = z.enum(["Original", "Reprint", "Other"]); export const pVForSongContract = z.object({song: songContract.optional(), author: z.string().nullable().optional(), createdBy: z.number().int().nullable().optional(), description: z.string().nullable().optional(), disabled: z.boolean().optional(), extendedMetadata: pVExtendedMetadata.optional(), id: z.number().int().optional(), length: z.number().int().optional(), name: z.string().nullable().optional(), publishDate: z.string().nullable().optional(), pvId: z.string().nullable().optional(), service: pVService.optional(), pvType: pVType.optional(), thumbUrl: z.string().nullable().optional(), url: z.string().nullable().optional()}); export const pVForSongContractPartialFindResult = z.object({items: z.array(pVForSongContract).nullable().optional(), term: z.string().nullable().optional(), totalCount: z.number().int().optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * GET /api/pvs/for-songs */ export const getApiApiPvsForSongs = async (args: GetApiApiPvsForSongsArgs, options: GetApiApiPvsForSongsOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.name != null) query.append("name", String(args.name)) if (args.author != null) query.append("author", String(args.author)) if (args.service != null) query.append("service", String(args.service)) if (args.maxResults != null) query.append("maxResults", String(args.maxResults)) if (args.getTotalCount != null) query.append("getTotalCount", String(args.getTotalCount)) if (args.lang != null) query.append("lang", String(args.lang)) const url = `${baseUrl.replace(/\/+$/, '')}/api/pvs/for-songs${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(pVForSongContractPartialFindResult, await res.json()) };