@beltec/face-gate 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,259 @@
1
+ import * as react from 'react';
2
+ import { CSSProperties } from 'react';
3
+
4
+ /** Caixa do rosto dominante, em frações da imagem (0 a 1). */
5
+ type FaceBox = {
6
+ xmin: number;
7
+ ymin: number;
8
+ xmax: number;
9
+ ymax: number;
10
+ };
11
+ /** Tokens de uma análise (unidade de processamento do Face Gate: megapixels × peso de cada etapa). */
12
+ type TokenUsage = {
13
+ tokens: number;
14
+ /** `validate` conta em dobro com melhoria (valida antes e depois); `enhance` = custo da melhoria. */
15
+ breakdown: {
16
+ decode: number;
17
+ validate: number;
18
+ clean: number;
19
+ enhance?: number;
20
+ avatar?: number;
21
+ };
22
+ /** Saldo da janela do plano (ex.: 5 h a partir do 1º uso). */
23
+ window?: {
24
+ used: number;
25
+ limit: number;
26
+ hours: number;
27
+ started_on: string | null;
28
+ resets_at: string | null;
29
+ };
30
+ /** Saldo do teto mensal (renova no aniversário do contrato). */
31
+ month?: {
32
+ used: number;
33
+ limit: number;
34
+ cycle_start: string;
35
+ cycle_end: string;
36
+ };
37
+ };
38
+ /**
39
+ * Melhoria de imagem (serviço "validate_enhance"):
40
+ * - "classic": luz, cor, contraste, ruído e nitidez leve; determinística, não altera o rosto;
41
+ * - "gfpgan": a clássica + restauração do rosto com IA (recria detalhes; avisa `face_restored_ai`).
42
+ */
43
+ type EnhanceMethod = "classic" | "gfpgan";
44
+ /** Resumo de uma validação dentro de `enhancement` (antes = foto original, depois = melhorada). */
45
+ type ValidationSummary = {
46
+ accepted: boolean;
47
+ score: number | null;
48
+ hard_fails: string[];
49
+ };
50
+ type Enhancement = {
51
+ method: EnhanceMethod;
52
+ /** Etapas aplicadas: white_balance, exposure, local_contrast, denoise, sharpen, face_restoration. */
53
+ steps: string[];
54
+ /** Dispositivo do GFPGAN (null na clássica). */
55
+ device: "cpu" | "gpu" | null;
56
+ before: ValidationSummary;
57
+ after: ValidationSummary;
58
+ /** Falhas da original que a melhoria não corrige (desfoque, olhos fechados…): continuam reprovando. */
59
+ carried_over: string[];
60
+ /** Foto melhorada (JPEG em data URL). */
61
+ enhanced_image: string;
62
+ };
63
+ /** Formato do avatar (serviço "avatar"): redondo (fora do círculo transparente) ou quadrado. */
64
+ type AvatarShape = "square" | "round";
65
+ /**
66
+ * Onde a pessoa fica no avatar (só com fundo de cor ou imagem): centro; apoiada na base (o fundo aparece em
67
+ * cima); na base à esquerda ou à direita.
68
+ */
69
+ type AvatarLayout = "center" | "bottom" | "left" | "right";
70
+ /** Dados do avatar gerado (POST /v1/photos/avatar). */
71
+ type AvatarInfo = {
72
+ shape: AvatarShape;
73
+ /** Lado em pixels (64 a 1024). */
74
+ size: number;
75
+ /** Modelo de remoção de fundo que separou a pessoa. */
76
+ model: string;
77
+ /** "transparent", "image" (fundo enviado) ou a cor "#rrggbb". */
78
+ background: string;
79
+ /** % do quadro deixado para o fundo (0 com fundo transparente). */
80
+ margin?: number;
81
+ layout?: AvatarLayout;
82
+ };
83
+ /** Avisos da validação. `face_restored_ai`: o GFPGAN recriou detalhes do rosto. */
84
+ type ValidationWarning = "face_restored_ai" | "gpu_fallback_cpu" | (string & {});
85
+ /** Resultado da validação de uma foto (mesmo formato de POST /v1/photos/*). */
86
+ type ValidationResult = {
87
+ accepted: boolean;
88
+ score: number;
89
+ checks: Record<string, boolean | null>;
90
+ /** Critérios que reprovaram (ex.: "eyes_closed", "sunglasses", "low_light"). */
91
+ hard_fails?: string[];
92
+ reasons?: string[];
93
+ warnings?: ValidationWarning[];
94
+ error?: string;
95
+ dominant_face_bbox?: FaceBox | null;
96
+ /** Foto com o fundo removido, recortada no rosto (PNG em data URL), quando pedido `clean`. */
97
+ cleaned_image?: string;
98
+ rembg_model?: string;
99
+ device?: "cpu" | "gpu";
100
+ timings?: {
101
+ validation_ms?: number;
102
+ };
103
+ usage?: TokenUsage;
104
+ /** Presente quando a foto passou pela melhoria (`enhance`). */
105
+ enhancement?: Enhancement;
106
+ /** Avatar (só com a foto aprovada): PNG em data URL só com a pessoa do rosto em foco. */
107
+ avatar_image?: string;
108
+ avatar?: AvatarInfo;
109
+ };
110
+ type StreamOptions = {
111
+ /** Remover o fundo da foto capturada (serviço "validate_clean" contratado). */
112
+ clean?: boolean;
113
+ model?: "u2net" | "u2netp" | "birefnet-portrait";
114
+ device?: "cpu" | "gpu";
115
+ /** Limiares de validação (mesmos nomes de GET /v1/thresholds). */
116
+ thresholds?: Record<string, number>;
117
+ /**
118
+ * Melhorar a foto capturada antes de validar (serviço "validate_enhance" contratado). Os quadros ao
119
+ * vivo não passam pela melhoria. null/undefined = sem melhoria.
120
+ */
121
+ enhance?: EnhanceMethod | null;
122
+ };
123
+ /** Ticket de uso único (60 s) para o navegador abrir a webcam, emitido pelo SEU servidor. */
124
+ type StreamTicket = {
125
+ ticket: string;
126
+ url: string;
127
+ expiresIn?: number;
128
+ };
129
+ /** Há quanto tempo os quadros seguidos estão aprovados e parados, e o alvo para capturar. */
130
+ type Stable = {
131
+ ms: number;
132
+ needed: number;
133
+ };
134
+ type FaceGateErrorCode = "unauthorized" | "forbidden" | "token_month_limit" | "token_window_limit" | "bad_request" | "camera_denied" | "camera_unavailable" | "network" | "server";
135
+ declare class FaceGateError extends Error {
136
+ code: FaceGateErrorCode;
137
+ status?: number | undefined;
138
+ /** Quando o limite renova (ISO), se a API informou. */
139
+ resetsAt?: string | undefined;
140
+ constructor(code: FaceGateErrorCode, message: string, status?: number | undefined,
141
+ /** Quando o limite renova (ISO), se a API informou. */
142
+ resetsAt?: string | undefined);
143
+ }
144
+
145
+ /** Textos do componente (pt-BR). Passe `labels` no <FaceGate> para trocar qualquer um. */
146
+ declare const DEFAULT_LABELS: {
147
+ start: string;
148
+ stop: string;
149
+ retry: string;
150
+ connecting: string;
151
+ searching: string;
152
+ hold: string;
153
+ allGood: string;
154
+ fix: string;
155
+ analyzing: string;
156
+ analyzingClean: string;
157
+ analyzingEnhance: string;
158
+ enhanced: string;
159
+ enhancedAi: string;
160
+ approved: string;
161
+ rejected: string;
162
+ cameraOff: string;
163
+ cameraHint: string;
164
+ insecure: string;
165
+ noCamera: string;
166
+ denied: string;
167
+ notFound: string;
168
+ busy: string;
169
+ };
170
+ type FaceGateLabels = typeof DEFAULT_LABELS;
171
+ /** Critério reprovado (hard_fails da API) → orientação curta para quem está na câmera. */
172
+ declare const FAIL_LABELS: Record<string, string>;
173
+ declare function describeFails(codes?: string[]): string;
174
+
175
+ type FaceGateCapture = {
176
+ /**
177
+ * Foto final: sem fundo (PNG) quando `clean`; senão a melhorada (JPEG) quando `enhance`; senão o quadro
178
+ * capturado (JPEG). Data URL ou blob URL.
179
+ */
180
+ image: string;
181
+ /** O quadro capturado, como enviado à API. */
182
+ frame: Blob;
183
+ result: ValidationResult;
184
+ };
185
+ type FaceGateProps = StreamOptions & {
186
+ /** Pede ao SEU servidor um ticket de uso único (ex.: fetch("/api/face-gate/ticket", { method: "POST" })). */
187
+ getTicket: () => Promise<StreamTicket>;
188
+ /** Foto capturada e validada (aprovada ou reprovada na validação final). */
189
+ onCapture?: (capture: FaceGateCapture) => void;
190
+ /** Cada quadro analisado ao vivo. */
191
+ onLive?: (result: ValidationResult) => void;
192
+ onError?: (error: FaceGateError) => void;
193
+ /** Liga a câmera ao montar (padrão: espera o clique em "Ligar câmera"). */
194
+ autoStart?: boolean;
195
+ /** Abertura animada do escudo ao ligar a câmera (padrão: true; desligada com prefers-reduced-motion). */
196
+ intro?: boolean;
197
+ /** Marca d'água do escudo no canto do vídeo (padrão: true). */
198
+ watermark?: boolean;
199
+ /**
200
+ * Enquadramento automático (padrão: true): a imagem aproxima e acompanha o rosto, mantendo-o no centro; a foto
201
+ * capturada é esse recorte e só sai com o rosto centralizado (tolerância de 8%). Ignora as tarjas pretas que
202
+ * algumas câmeras acrescentam.
203
+ */
204
+ autoFrame?: boolean;
205
+ /** Prévia espelhada, como um espelho (padrão: true). A foto enviada e a final não são espelhadas. */
206
+ mirror?: boolean;
207
+ labels?: Partial<FaceGateLabels>;
208
+ className?: string;
209
+ style?: CSSProperties;
210
+ };
211
+ /**
212
+ * Webcam com validação em tempo real do Face Gate: uma conexão WebSocket por sessão, mira que segue o
213
+ * rosto, captura automática só depois de ~0,8 s aprovado e parado, scanner sobre a foto até a resposta.
214
+ * Importe também "@beltec/face-gate/styles.css".
215
+ */
216
+ declare function FaceGate({ getTicket, onCapture, onLive, onError, autoStart, intro, watermark, labels, className, style, clean, model, device, thresholds, enhance, autoFrame, mirror, }: FaceGateProps): react.JSX.Element;
217
+
218
+ /**
219
+ * Escudo BelTec (Face Gate, uma solução BelTec): a faixa do escudo Belfort liga três pontos — a lente
220
+ * (a caixa que vê), a Central que entende e as pessoas que agem. Com `animated`, se desenha como na
221
+ * abertura da câmera do app (CSS em styles.css, classes .fg-emblem-*).
222
+ */
223
+ declare function Emblem({ animated, className }: {
224
+ animated?: boolean;
225
+ className?: string;
226
+ }): react.JSX.Element;
227
+
228
+ /**
229
+ * Cliente do WebSocket /v1/stream do Face Gate (uma conexão por sessão de câmera).
230
+ *
231
+ * O navegador manda quadros JPEG (mensagens binárias) num ritmo fixo, o `max_fps` que a API informa no "ready":
232
+ * ela analisa sempre o mais novo e descarta os que ficaram para trás. Recebe o resultado de cada quadro
233
+ * analisado. A API só captura depois de ~0,8 s de quadros aprovados e parados (`stable`), avisa `captured`
234
+ * com o seq do melhor quadro e devolve a validação final.
235
+ */
236
+ type StreamHandlers = {
237
+ /** `maxFps`: quantos quadros por segundo a API analisa (o ritmo para mandar os quadros). */
238
+ onReady?: (maxFps: number) => void;
239
+ onFrame?: (seq: number, result: ValidationResult, stable: Stable) => void;
240
+ onCaptured?: (seq: number) => void;
241
+ onFinal?: (seq: number, result: ValidationResult) => void;
242
+ /** Conexão encerrada sem ter sido pedida (`close()`). */
243
+ onError?: (error: FaceGateError) => void;
244
+ };
245
+ type FaceGateStream = {
246
+ /**
247
+ * Envia o quadro e devolve o seq dele (1, 2, 3… igual ao servidor); null se a conexão não está aberta ou o
248
+ * quadro anterior ainda está subindo.
249
+ */
250
+ sendFrame: (frame: Blob) => number | null;
251
+ configure: (options: StreamOptions) => void;
252
+ /** Recomeça depois de uma captura, na mesma conexão. */
253
+ reset: () => void;
254
+ close: () => void;
255
+ };
256
+ type WebSocketLike = new (url: string) => WebSocket;
257
+ declare function openFaceGateStream(url: string, ticket: string, options: StreamOptions, handlers: StreamHandlers, WS?: WebSocketLike): FaceGateStream;
258
+
259
+ export { type AvatarInfo, type AvatarLayout, type AvatarShape, DEFAULT_LABELS, Emblem, type EnhanceMethod, type Enhancement, FAIL_LABELS, type FaceBox, FaceGate, type FaceGateCapture, FaceGateError, type FaceGateErrorCode, type FaceGateLabels, type FaceGateProps, type FaceGateStream, type Stable, type StreamHandlers, type StreamOptions, type StreamTicket, type TokenUsage, type ValidationResult, type ValidationSummary, type ValidationWarning, describeFails, openFaceGateStream };