import {z} from 'zod' export type AudioBuffer = string; export type CheckLiveness = boolean; export type CheckQuality = boolean; export type LivenessThreshold = number; export type MinimumSnrDb = number; export type MinimumAudioLengthMs = number; export type MinimumSpeechRelativeLength = number; export type MaximumMultipleSpeakersDetectorScore = number; export type ExtraData = string; export type EnrollmentBody = {audios: Array, check_liveness?: CheckLiveness | undefined, check_quality?: CheckQuality | undefined, liveness_threshold?: LivenessThreshold | undefined, minimum_snr_db?: MinimumSnrDb | undefined, minimum_speech_duration_ms?: MinimumAudioLengthMs | undefined, minimum_speech_relative_length?: MinimumSpeechRelativeLength | undefined, maximum_multiple_speakers_detector_score?: MaximumMultipleSpeakersDetectorScore | undefined, extra_data?: ExtraData | undefined}; export type CreateApiApiV1EnrollmentArgs = {body: EnrollmentBody}; export type CreateApiApiV1EnrollmentOptions = {baseUrl: string, BearerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const operationResult = z.number(); export const templateType = z.string(); export const audioTemplate = z.string(); export const audioPosition = z.number().int(); export const livenessScore = z.number(); export const matchingScore = z.number(); export const snrDbDetected = z.number(); export const speechLengthMsDetected = z.number(); export const speechRelativeLengthDetected = z.number(); export const multipleSpeakersScoreDetected = z.number(); export const audioResult = z.object({audio_position: audioPosition.optional(), result_code: operationResult.optional(), liveness_score: livenessScore.optional(), matching_score: matchingScore.optional(), snr_db_detected: snrDbDetected.optional(), speech_length_ms_detected: speechLengthMsDetected.optional(), speech_relative_length_detected: speechRelativeLengthDetected.optional(), multiple_speakers_score_detected: multipleSpeakersScoreDetected.optional()}); export const enrollmentResponse = z.object({operation_result: operationResult.optional(), template_type: templateType.optional(), template: audioTemplate.optional(), validate_audios_result: z.array(audioResult).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 }; /** * Este endpoint se utiliza para registrar (enroll) una nueva voz. Recibe uno o varios archivos de audio y devuelve una plantilla de voz (voice template). La plantilla de voz es una cadena que contiene la información biométrica de la voz. Esta plantilla puede utilizarse para autenticar las voces en el futuro. * * POST /api/v1/enrollment * * Also accepts auth: ApiKeyAuth */ export const createApiApiV1Enrollment = async (args: CreateApiApiV1EnrollmentArgs, options: CreateApiApiV1EnrollmentOptions) => { const {baseUrl, fetch: fetchFn = fetch, BearerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (BearerAuth !== undefined) headers.set('authorization', `Bearer ${BearerAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/api/v1/enrollment${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(enrollmentResponse, await res.json()) };