import {z} from 'zod' export type LinkMark = {id?: {required: boolean} | undefined}; export type Creator = {nonce?: string | undefined, name?: string | undefined, email?: string | undefined}; export type AuthenticationOptions = Array<'GEOLOCATION' | 'IP' | 'OTP_EMAIL' | 'OTP_PHONE' | 'OTP_WHATSAPP' | 'SELFIE' | 'DRIVER_LICENSE' | 'DATAVALID' | 'LIVENESS' | 'PERSONAL_IDENTIFIER' | 'VIEW_DOCUMENTS'>; export type SignatureConfig = {mode: 'SIMPLE' | 'ADVANCED' | 'QUALIFIED', hashAlgorithm?: string | undefined, profile?: string | undefined}; export type TypeMessaging = Array<'LINK' | 'EMAIL' | 'WHATSAPP'>; export type TypeReport = Array<'REPORT' | 'DOCUMENT' | 'REPORT_UNIFIED'>; export type TypeReportNotify = Array<'EMAIL' | 'SMS'>; export type BiometricOptions = {similarity?: number | undefined, datavalid?: number | undefined, livenessCaptureProbability?: number | undefined, livenessCaptureScore?: number | undefined, livenessFaceProbability?: number | undefined}; export type Signer = {signerNonce?: string | undefined, name: string, email?: string | undefined, phone?: string | undefined, personal_identifier?: string | undefined, personal_identifier_type?: string | undefined, language?: ('pt-br' | 'en-us' | 'es-cl') | undefined, positioningMode?: ('CREATOR' | 'PRESET' | 'SIGNEE') | undefined, signInBatch?: boolean | undefined, groupNonce?: string | undefined, purpose?: string | undefined, authenticationOptions?: AuthenticationOptions | undefined, signatureConfig?: SignatureConfig | undefined, typeMessaging?: TypeMessaging | undefined, typeReport?: TypeReport | undefined, typeReportNotify?: TypeReportNotify | undefined, biometricOptions?: BiometricOptions | undefined, metadata?: {[key: string]: unknown} | undefined}; export type Hash = {value?: string | undefined, algorithm?: string | undefined}; export type Document = {type?: ('PDF' | 'CMS' | 'XML') | undefined, name?: string | undefined, size?: number | undefined, hash?: Hash | undefined}; export type Image = {image: string, imageNonce: string}; export type CreateApiApiServiceSignV1SignaturesArgs = {body: {name: string, clientName: string, expiration?: number | undefined, signatureOrder?: ('ORDERED' | 'UNORDERED' | 'GROUPED') | undefined, language?: ('pt-br' | 'en-us' | 'es-cl') | undefined, sendNotifications?: boolean | undefined, startAsDraft?: boolean | undefined, keepDocument?: boolean | undefined, linkMark?: LinkMark | undefined, creator?: Creator | undefined, signersData: Array, documents: Array, images?: Array | undefined, groups?: (Array<{groupNonce?: string | undefined}>) | undefined}}; export type CreateApiApiServiceSignV1SignaturesOptions = {baseUrl?: string | undefined, bearer?: string | undefined, fetch?: typeof fetch | undefined}; export const linkMark = z.object({id: z.object({required: z.boolean()}).optional()}); export const creator = z.object({nonce: z.string().optional(), name: z.string().optional(), email: z.string().optional()}); export const authenticationOptions = z.array(z.enum(["GEOLOCATION", "IP", "OTP_EMAIL", "OTP_PHONE", "OTP_WHATSAPP", "SELFIE", "DRIVER_LICENSE", "DATAVALID", "LIVENESS", "PERSONAL_IDENTIFIER", "VIEW_DOCUMENTS"])); export const typeMessaging = z.array(z.enum(["LINK", "EMAIL", "WHATSAPP"])); export const typeReport = z.array(z.enum(["REPORT", "DOCUMENT", "REPORT_UNIFIED"])); export const typeReportNotify = z.array(z.enum(["EMAIL", "SMS"])); export const biometricOptions = z.object({similarity: z.number().optional(), datavalid: z.number().optional(), livenessCaptureProbability: z.number().optional(), livenessCaptureScore: z.number().optional(), livenessFaceProbability: z.number().optional()}); export const signerResponse = z.object({signerNonce: z.string().optional(), signerUuid: z.string().optional(), name: z.string().optional(), email: z.string().optional(), phone: z.string().optional(), personal_identifier: z.string().optional(), personal_identifier_type: z.string().optional(), language: z.enum(["pt-br", "en-us", "es-cl"]).optional(), positioningMode: z.enum(["CREATOR", "PRESET", "SIGNEE"]).optional(), signInBatch: z.boolean().optional(), canSign: z.boolean().optional(), status: z.enum(["PENDING", "SIGNED", "REFUSED"]).optional(), groupNonce: z.string().optional(), evidenceDate: z.string().optional(), purpose: z.string().optional(), signatureConfig: z.object({mode: z.string().optional(), hashAlgorithm: z.string().optional(), profile: z.string().optional(), signatureOrder: z.number().int().optional()}).optional(), authentications: authenticationOptions.optional(), link: z.object({href: z.string().optional()}).optional(), iframe: z.object({href: z.string().optional()}).optional(), typeMessaging: typeMessaging.optional(), typeReport: typeReport.optional(), typeReportNotify: typeReportNotify.optional(), biometricOptions: biometricOptions.optional(), metadata: z.record(z.string(), z.unknown()).optional()}); export const documentResponse = z.object({documentNonce: z.string().optional(), documentUuid: z.string().optional(), name: z.string().optional(), status: z.enum(["AVAILABLE", "DELETED"]).optional(), deletion: z.string().optional(), currentDocumentSize: z.number().optional(), currentDocumentLink: z.object({href: z.string().optional()}).optional(), originalDocumentLink: z.object({href: z.string().optional()}).optional()}); export const createApiApiServiceSignV1SignaturesResponse = z.object({uuid: z.string().optional(), name: z.string().optional(), clientName: z.string().optional(), accessPassword: z.string().optional(), language: z.enum(["pt-br", "en-us", "es-cl"]).optional(), status: z.enum(["DRAFT", "CREATED", "ONGOING", "FINISHED", "EXPIRED", "DELETED"]).optional(), signatureOrder: z.enum(["UNORDERED", "ORDERED", "GROUPED"]).optional(), expiration: z.string().optional(), creation: z.string().optional(), deletion: z.string().optional(), keepDocument: z.boolean().optional(), linkMark: linkMark.optional(), creator: creator.optional(), signers: z.array(signerResponse).optional(), documents: z.array(documentResponse).optional(), groups: z.array(z.object({groupNonce: z.string().optional(), groupOrder: z.number().optional()})).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 }; /** * Iniciar uma requisição de assinatura * * POST /api/service/sign/v1/signatures */ export const createApiApiServiceSignV1Signatures = async (args: CreateApiApiServiceSignV1SignaturesArgs, options?: CreateApiApiServiceSignV1SignaturesOptions) => { const {baseUrl = "https://cloud-hom.bry.com.br", fetch: fetchFn = fetch, bearer} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (bearer !== undefined) headers.set('authorization', `Bearer ${bearer}`) const url = `${baseUrl.replace(/\/+$/, '')}/api/service/sign/v1/signatures${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(createApiApiServiceSignV1SignaturesResponse, await res.json()) };