npm package: @forsigndigital/sdk
Description: SDK oficial da ForSign para integração com a plataforma de assinaturas eletrônicas em aplicações TypeScript/Node.js.
Author: ForSign
Latest version: 2.0.0

# Documentação Completa do SDK ForSign para TypeScript/JavaScript (v2)

Bem-vindo à documentação oficial do SDK ForSign para Node.js e TypeScript! A ForSign oferece a integração mais simples do mercado para assinaturas eletrônicas, tornando seus processos mais eficientes, seguros e amigáveis.

Este SDK foi projetado para ser intuitivo e poderoso, permitindo que você integre um fluxo de assinatura digital completo em sua aplicação com o mínimo de esforço.

## ✨ Principais Funcionalidades

- **Autenticação Simplificada:** Conecte-se à nossa API usando apenas uma **API Key**.
- **Múltiplos Tipos de Assinatura:** Suporte para clique, desenho, rubrica e carimbos personalizados.
- **Segurança Robusta:** Valide a identidade dos Assinantes com **duplo fator de autenticação (2FA)** via E-mail.
- **Workflows Flexíveis:** Defina a ordem de assinatura, datas de expiração e redirecionamento pós-assinatura.
- **Formulários Interativos:** Colete dados estruturados diretamente no documento com campos de texto, checkboxes e listas de seleção.
- **Anexos Seguros:** Solicite documentos adicionais (como RG, CNH) dos Assinantes durante o processo.
- **Gerenciamento Completo:** Tenha controle total sobre o ciclo de vida das operações: finalize, cancele, baixe documentos e gerencie anexos.

---

## ⚙️ 1. Instalação e Configuração

Começar a usar o SDK ForSign é um processo rápido e direto.

### Requisitos

- **Node.js:** Versão 16 ou superior.
- **TypeScript (Opcional):** Versão 4.5 ou superior para aproveitar a tipagem estática.

### Instalação via NPM ou Yarn

```bash
# Usando NPM
npm install @forsign/sdk

# Usando Yarn
yarn add @forsign/sdk
```

### Configurando suas Credenciais (API Key)

A autenticação com a API ForSign é feita através de uma API Key. Você pode gerar a sua no painel de desenvolvedor da ForSign.

```typescript
import { ForSignClient, ApiKeyCredential } from '@forsign/sdk';

// 1. Crie uma instância do cliente ForSign.
const forsignClient = new ForSignClient();

// 2. Substitua "SUA_API_KEY_AQUI" pela chave obtida no painel.
const API_KEY = 'SUA_API_KEY_AQUI';

// 3. Crie o objeto de credencial.
const credential = new ApiKeyCredential(API_KEY);

// 4. Defina a credencial no cliente. O cliente usará esta chave em todas as chamadas.
forsignClient.setCredential(credential);

console.log('Cliente ForSign configurado com sucesso!');
```

> **⚠️ Dica de Segurança:** Nunca exponha sua API Key em código de front-end ou em repositórios públicos. Utilize variáveis de ambiente (`process.env`) para armazená-la de forma segura.

---

## 🚀 2. Guia Rápido: Sua Primeira Assinatura

Este guia mostra o fluxo completo para enviar um documento para assinatura em 4 passos simples.

### Passo 1: Carregar o Documento

Primeiro, envie o documento PDF para a plataforma ForSign.

```typescript
import { FileRequest } from '@forsign/sdk';

// Exemplo de upload a partir de uma URL pública
const fileRequest = await FileRequest.fromUrl(
    'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
    'contrato-exemplo.pdf'
);

// Envia o arquivo para a API
const uploadResponse = await forsignClient.uploadFile(fileRequest);

// O objeto 'fileInfo' é essencial para os próximos passos
const fileInfo = {
  id: uploadResponse.data.id,
  description: uploadResponse.data.fileName,
};

console.log(`Arquivo '${fileInfo.description}' enviado! ID do Arquivo: ${fileInfo.id}`);
```
> **💡 Nota:** Você pode carregar arquivos de `Buffer`, `Stream` ou `URL`. Apenas arquivos **PDF** de até **10 MB** são suportados.

### Passo 2: Definir o Signatário

Um `Signer` representa uma pessoa que irá assinar o documento.

```typescript
import { Signer, EmailNotification, EmailDoubleAuthentication, DefaultSignatureType, SignatureType } from '@forsign/sdk';

const signer = new Signer({
    name: 'João da Silva',
    email: 'joao.silva@exemplo.com',

    // Notificação para assinar
    notificationType: new EmailNotification('joao.silva@exemplo.com'),

    // ✨ RECOMENDADO: Duplo Fator de Autenticação (2FA)
    doubleAuthenticationMethod: new EmailDoubleAuthentication('joao.silva@exemplo.com'),

    // Tipo de assinatura (UserChoice permite que o usuário escolha)
    signatureType: new DefaultSignatureType(SignatureType.UserChoice)
});

// Onde no documento o João deve assinar?
// Página 1, posicionado a 70% da largura e 80% da altura.
signer.addSignatureInPosition(fileInfo, 1, '70%', '80%');
```

### Passo 3: Construir e Criar a Operação

Use o `OperationBuilder` para montar a operação com todas as regras.

```typescript
import { OperationBuilder } from '@forsign/sdk';

const operationRequest = OperationBuilder.initializeWithName('Contrato de Prestação de Serviços')
    .setExpirationDate(new Date(Date.now() + 15 * 24 * 60 * 60 * 1000)) // 15 dias
    .withExternalId('ID-INTERNO-456')
    .withRedirectUrl('https://seusite.com/obrigado?opId={operationId}')
    .addSigner(signer)
    .build();

// Envia a requisição para a API
const operationResponse = await forsignClient.createOperation(operationRequest);
```

### Passo 4: Obter e Usar a URL de Assinatura

A resposta da API contém as URLs de assinatura exclusivas para cada participante.

```typescript
console.log(`Operação criada com sucesso! ID da Operação: ${operationResponse.id}`);

operationResponse.members.forEach(member => {
    console.log(`--- Assinante: ${member.name} ---`);
    console.log(`ID do Membro: ${member.id}`);
    console.log(`URL de Assinatura: ${member.signUrl}`);
    console.log('------------------------------------');
});
```
**O que fazer com a URL?** A URL de assinatura pode ser enviada por e-mail, exibida em um botão na sua aplicação, ou usada para redirecionamento.

---

## 📚 3. Funcionalidades Detalhadas

### 3.1. Formulários Interativos

Colete informações diretamente no documento PDF.

```typescript
import { TextFormField, CheckboxFormField, SelectFormField, FormFieldPosition } from '@forsign/sdk';

// Campo de Texto
const textField = TextFormField.withName('CPF')
    .withInstructions('Digite seu CPF')
    .isRequired()
    .onPosition(new FormFieldPosition(fileInfo, 1, '30%', '40%'));

// Caixa de Seleção
const checkboxField = CheckboxFormField.withName('Aceite dos Termos')
    .isRequired()
    .withOptions(['Sim'])
    .onPosition(new FormFieldPosition(fileInfo, 1, '30%', '50%'));

// Lista Suspensa (Select)
const selectField = SelectFormField.withName('Estado Civil')
    .isRequired()
    .withOptions(['Solteiro(a)', 'Casado(a)', 'Divorciado(a)'])
    .onPosition(new FormFieldPosition(fileInfo, 1, '30%', '60%'));

// Adicione os campos ao Signatário
signer.addFormField(textField);
signer.addFormField(checkboxField);
signer.addFormField(selectField);
```

### 3.2. Solicitando Anexos

Peça ao Signatário para enviar arquivos durante o processo de assinatura.

```typescript
import { Attachment, AttachmentFileType, InputAttachmentType } from '@forsign/sdk';

const idAttachment = new Attachment('Documento de Identidade', 'Envie uma foto do seu RG ou CNH', true);

// Define os tipos de arquivo permitidos
idAttachment
    .permitFileType(AttachmentFileType.PNG)
    .permitFileType(AttachmentFileType.JPEG)
    .permitFileType(AttachmentFileType.PDF);

// Define como o usuário pode enviar o anexo
idAttachment
    .permitAttachmentByInput(InputAttachmentType.UploadFile)
    .permitAttachmentByInput(InputAttachmentType.CameraSideFront)
    .permitAttachmentByInput(InputAttachmentType.CameraSideBack);

// Adiciona a solicitação ao Signatário
signer.requestAttachment(idAttachment);
```

---

## 🎛️ 4. Gerenciando o Ciclo de Vida da Operação

Após a criação, você pode gerenciar a operação usando seu `operationId`.

| Método                               | Descrição                                                                              |
| ------------------------------------ | -------------------------------------------------------------------------------------- |
| `completeOperation`                  | Finaliza uma operação que está aguardando conclusão manual.                              |
| `cancelOperation`                    | Cancela uma operação em andamento.                                                     |
| `downloadOperationZip`               | Baixa um arquivo .zip contendo os documentos assinados e a trilha de auditoria.        |
| `setOperationManualCompletion`       | Muda o modo de finalização de uma operação para manual.                                |
| `setOperationAutomaticCompletion`    | Define uma data/hora para a finalização automática da operação.                        |

### Exemplos

```typescript
import { ForSignApiError } from '@forsign/sdk';
import * as fs from 'fs/promises';

const operationId = 12345;

try {
    // Finalizar uma operação
    const completeResponse = await forsignClient.completeOperation(operationId);
    console.log(completeResponse.message);

    // Cancelar uma operação
    const cancelResponse = await forsignClient.cancelOperation(operationId, 'Cancelado por solicitação.');
    console.log(cancelResponse.message);

    // Baixar o pacote de documentos (ZIP)
    const zipFile = await forsignClient.downloadOperationZip(operationId);
    await fs.writeFile(`${zipFile.name}.zip`, zipFile.content);
    console.log(`Operação baixada e salva em: ${zipFile.name}.zip`);

} catch (error) {
    if (error instanceof ForSignApiError) {
        console.error(`Erro ao gerenciar operação: ${error.statusCode} - ${error.message}`);
    }
}
```

---

## 📂 5. Gerenciando Anexos dos Assinantes

Se sua operação solicita anexos, você pode aprová-los, rejeitá-los ou baixá-los via API.

| Método                       | Descrição                                                                      |
| ---------------------------- | ------------------------------------------------------------------------------ |
| `getMemberAttachments`       | Lista todos os anexos de um membro (participante) da operação.                 |
| `approveAttachments`         | Aprova uma lista de anexos enviados por um membro.                             |
| `rejectAttachments`          | Rejeita anexos, fornecendo um motivo para cada um.                             |
| `downloadAttachment`         | Baixa o conteúdo de um anexo específico.                                       |

### Exemplo

```typescript
const memberId = 56789;

try {
    // 1. Listar anexos
    const attachments = await forsignClient.getMemberAttachments(memberId);
    console.log(`Anexos encontrados: ${attachments.length}`);

    const uploaded = attachments.filter(a => a.isUploaded);
    if (uploaded.length > 0) {
        // 2. Aprovar o primeiro anexo
        await forsignClient.approveAttachments(memberId, [uploaded[0].id]);
        console.log(`Anexo ${uploaded[0].id} aprovado.`);

        // 3. Baixar o anexo aprovado
        const file = await forsignClient.downloadAttachment(uploaded[0].id);
        await fs.writeFile(file.fileName, file.content);
        console.log(`Anexo '${file.fileName}' baixado.`);
    }
} catch (error) {
    if (error instanceof ForSignApiError) {
        console.error(`Erro no gerenciamento de anexos: ${error.statusCode} - ${error.message}`);
    }
}
```

---

## ❓ Solução de Problemas

- **`ForSignApiError`**: Esta é a exceção principal lançada pelo SDK. Inspecione as propriedades `statusCode` e `messages` para obter mais detalhes.
- **`401 Unauthorized`**: Sua `API Key` está incorreta ou expirou.
- **`402 Payment Required`**: Sua conta não possui créditos suficientes.
- **`422 Unprocessable Entity`**: Os dados enviados são inválidos. Verifique a propriedade `messages` na exceção.