128 lines
5.1 KiB
TypeScript
128 lines
5.1 KiB
TypeScript
import type { AudioContentDetail, AudioContentListItem } from "@/features/audio-contents/model/types";
|
|
import { audioContentDetailSchema, audioContentListResponseSchema } from "@/features/audio-contents/model/types";
|
|
import { audioContentCreateRequestSchema, audioContentCreateResponseSchema, audioContentDeactivateRequestSchema, audioContentUpdateRequestSchema } from "@/features/audio-contents/schemas/audio-content-schema";
|
|
import type { AudioContentCreateRequest, AudioContentCreateResponse, AudioContentDeactivateRequest, AudioContentUpdateRequest } from "@/features/audio-contents/schemas/audio-content-schema";
|
|
import type { ApiClient } from "@/shared/api/client";
|
|
import type { PageData } from "@/shared/api/pagination";
|
|
import { z } from "zod";
|
|
|
|
export type GetAudioContentsParams = {
|
|
readonly characterId: string;
|
|
readonly page?: number;
|
|
readonly search_word?: string;
|
|
readonly size?: number;
|
|
};
|
|
|
|
export type GetAudioContentParams = {
|
|
readonly characterId: string;
|
|
readonly contentId: string;
|
|
};
|
|
|
|
export type CreateAudioContentParams = {
|
|
readonly characterId: string;
|
|
readonly contentFile: File;
|
|
readonly coverImage: File;
|
|
readonly request: AudioContentCreateRequest;
|
|
};
|
|
|
|
export type UpdateAudioContentParams = {
|
|
readonly coverImage?: File;
|
|
readonly request: AudioContentUpdateRequest;
|
|
};
|
|
|
|
const nullSuccessSchema = z.null();
|
|
|
|
function createAudioContentFormData(contentFile: File | undefined, coverImage: File | undefined, request: object): FormData {
|
|
const body = new FormData();
|
|
if (contentFile !== undefined) {
|
|
body.append("contentFile", contentFile);
|
|
}
|
|
if (coverImage !== undefined) {
|
|
body.append("coverImage", coverImage);
|
|
}
|
|
body.append("request", new Blob([JSON.stringify(request)], { type: "application/json" }));
|
|
|
|
return body;
|
|
}
|
|
|
|
export function createAudioContentCreateBody(params: CreateAudioContentParams): FormData {
|
|
return createAudioContentFormData(params.contentFile, params.coverImage, audioContentCreateRequestSchema.parse(params.request));
|
|
}
|
|
|
|
export function createAudioContentUpdateBody(params: UpdateAudioContentParams): FormData {
|
|
return createAudioContentFormData(undefined, params.coverImage, audioContentUpdateRequestSchema.parse(params.request));
|
|
}
|
|
|
|
export function createAudioContentDeactivateBody(request: AudioContentDeactivateRequest): FormData {
|
|
return createAudioContentFormData(undefined, undefined, audioContentDeactivateRequestSchema.parse(request));
|
|
}
|
|
|
|
function normalizePage(value: number | undefined): number {
|
|
return Math.max(0, Math.trunc(value ?? 0));
|
|
}
|
|
|
|
function normalizeSize(value: number | undefined): number {
|
|
return Math.max(1, Math.trunc(value ?? 20));
|
|
}
|
|
|
|
export async function getAudioContents(apiClient: ApiClient, params: GetAudioContentsParams): Promise<PageData<AudioContentListItem>> {
|
|
const page = normalizePage(params.page);
|
|
const size = normalizeSize(params.size);
|
|
const query = new URLSearchParams({ page: String(page), size: String(size) });
|
|
const searchWord = params.search_word?.trim();
|
|
if (searchWord !== undefined && searchWord.length >= 2) {
|
|
query.set("search_word", searchWord);
|
|
}
|
|
const response = await apiClient.request({
|
|
path: `/api/v2/admin/ai-characters/${encodeURIComponent(params.characterId)}/audio-contents?${query.toString()}`,
|
|
responseSchema: audioContentListResponseSchema,
|
|
authentication: "required",
|
|
});
|
|
|
|
return {
|
|
totalCount: response.totalCount,
|
|
page,
|
|
size,
|
|
hasNext: (page + 1) * size < response.totalCount,
|
|
items: response.items,
|
|
};
|
|
}
|
|
|
|
export function getAudioContent(apiClient: ApiClient, params: GetAudioContentParams): Promise<AudioContentDetail> {
|
|
return apiClient.request({
|
|
path: `/api/v2/admin/ai-characters/${encodeURIComponent(params.characterId)}/audio-contents/${encodeURIComponent(params.contentId)}`,
|
|
responseSchema: audioContentDetailSchema,
|
|
authentication: "required",
|
|
});
|
|
}
|
|
|
|
export function createAudioContent(apiClient: ApiClient, params: CreateAudioContentParams): Promise<AudioContentCreateResponse> {
|
|
return apiClient.request({
|
|
path: `/api/v2/admin/ai-characters/${encodeURIComponent(params.characterId)}/audio-contents`,
|
|
method: "POST",
|
|
body: createAudioContentCreateBody(params),
|
|
responseSchema: audioContentCreateResponseSchema,
|
|
authentication: "required",
|
|
});
|
|
}
|
|
|
|
export function updateAudioContent(apiClient: ApiClient, characterId: string, contentId: string, params: UpdateAudioContentParams): Promise<null> {
|
|
return apiClient.request({
|
|
path: `/api/v2/admin/ai-characters/${encodeURIComponent(characterId)}/audio-contents/${encodeURIComponent(contentId)}`,
|
|
method: "PUT",
|
|
body: createAudioContentUpdateBody(params),
|
|
responseSchema: nullSuccessSchema,
|
|
authentication: "required",
|
|
});
|
|
}
|
|
|
|
export function deactivateAudioContent(apiClient: ApiClient, characterId: string, contentId: string): Promise<null> {
|
|
return apiClient.request({
|
|
path: `/api/v2/admin/ai-characters/${encodeURIComponent(characterId)}/audio-contents/${encodeURIComponent(contentId)}`,
|
|
method: "PUT",
|
|
body: createAudioContentDeactivateBody({ isActive: false }),
|
|
responseSchema: nullSuccessSchema,
|
|
authentication: "required",
|
|
});
|
|
}
|