Ir para o conteúdo principal
PPDF123

@pdf123/sdk: o SDK TypeScript do PDF123

@pdf123/sdk é o SDK TypeScript da API de PDF do PDF123. Ele executa 95 ferramentas, como juntar, dividir, comprimir e OCR, tipa as opções de cada ferramenta e acrescenta lotes, pipelines, tratamento de senhas e erros tipados. É um módulo ES sem dependências em tempo de execução.

@pdf123/sdkNode 20.3 ou mais recente, ou Bun

Instalação

npm install @pdf123/sdk
Nesta página

Como instalo o SDK?

Instale o pacote com o seu gerenciador de pacotes. É necessário Node 20.3 ou mais recente, Bun ou um bundler. Os tipos TypeScript já vêm incluídos e @types/node não é necessário.

Instalaçãobash
npm install @pdf123/sdk

bun add @pdf123/sdk e pnpm add @pdf123/sdk funcionam da mesma forma.

Como junto dois PDFs?

Crie um cliente, execute a ferramenta merge em dois arquivos e salve o resultado. Sem opções, o cliente fala com a API pública de forma anônima.

Juntar e salvarts
import { Pdf123Client } from "@pdf123/sdk";
import { readFileInput, saveResult } from "@pdf123/sdk/node";

const client = new Pdf123Client();
const result = await client.run("merge", {
  input: [await readFileInput("a.pdf"), await readFileInput("b.pdf")],
});
const path = await saveResult(result, { output: "merged.pdf" });
console.log(path);

O resultado traz os bytes em data, o contentType, o filename dado pelo servidor e json para ferramentas que devolvem um relatório. A mesma operação está disponível no site como Juntar PDF.

Qual ponto de entrada devo importar?

Ponto de entradaRequerFornece
@pdf123/sdkApenas fetchPdf123Client, TOOLS, getTool, Pdf123Error e os auxiliares do catálogo
@pdf123/sdk/nodeNode ou BunreadFileInput, fileSource, saveResult, checkOutput e clientFromEnv

Importe do ponto de entrada raiz em navegadores e runtimes de borda, e acrescente o ponto node apenas onde você lê ou grava arquivos.

Quais métodos o cliente tem?

MétodoO que faz
run(tool, { input, params })Executa uma ferramenta e resolve com um resultado
runBatch(tool, inputs, options)Executa uma ferramenta de arquivo único em várias entradas e resolve com um item por entrada
pipeline(steps, input, options)Executa várias ferramentas em uma única requisição
call(target, files, fields)Envia uma requisição bruta para um id de ferramenta, um id de operação ou um caminho /api/...
upload(file)Envia um arquivo pela API de upload em partes e devolve o id dele

Os auxiliares do catálogo são funções simples: TOOLS lista todas as ferramentas, getTool(id) devolve os campos, os valores padrão e os tipos de arquivo aceitos por uma ferramenta, e toolGroup, toolSummary, matchesQuery e suggestTools ajudam a montar seletores de ferramentas. A linha de comando imprime o mesmo catálogo com pdfx list e pdfx describe.

Como passo opções para uma ferramenta?

params é tipado por ferramenta. Aceita apenas os campos dela, e campos de escolha aceitam apenas os valores permitidos. Campos numéricos são verificados contra o mínimo e o máximo, e o arquivo é verificado contra os tipos aceitos, antes de qualquer envio. Os valores padrão de que o servidor precisa são preenchidos.

Marca d'água com opçõests
const marked = await client.run("watermark", {
  input: await readFileInput("a.pdf"),
  params: { watermarkText: "DRAFT", fontSize: 40, rotation: -45 },
});
await saveResult(marked, { output: "draft.pdf" });

Uma string vazia significa “não definido”, então vale o valor padrão. Veja Marca d'água em PDF para saber o que cada opção faz.

Como processo muitos arquivos?

runBatch executa uma ferramenta de arquivo único, como Comprimir, Girar ou Proteger, em cada entrada com as mesmas opções. Por padrão processa dois arquivos por vez. Um arquivo com problema nunca interrompe os demais.

Lote com cancelamentots
import { fileSource, saveResult } from "@pdf123/sdk/node";

const controller = new AbortController();
const entries = await client.runBatch("compress", [fileSource("a.pdf"), fileSource("b.pdf")], {
  concurrency: 2,
  signal: controller.signal,
  onResult: async (entry, index) => {
    if (entry.ok) await saveResult(entry.result, { output: "compressed/" });
  },
});
console.log(entries.map((entry) => entry.ok));
  • fileSource(path) é uma fonte preguiçosa, lida só quando um processo de trabalho a pega, então muitos arquivos grandes nunca ficam juntos na memória.
  • onResult recebe cada resultado assim que ele termina. Salve-o ali e, se você cancelar no arquivo 50 de 100, os 49 primeiros ficam salvos. Com retainData: false, o array devolvido não guarda os bytes.
  • Qualquer chamada aceita timeoutMs e um signal para cancelá-la.
  • idempotencyKey vira <key>:<index> para cada arquivo.

Ferramentas de filtro (ids que começam com filter-) resolvem com matched: false em vez de lançar um erro quando a condição delas não é atendida. Em um lote, esse arquivo ainda conta como ok.

Como encadeio ferramentas em uma requisição?

pipeline envia uma lista de etapas e uma ou mais entradas. O servidor passa a saída de cada etapa para a seguinte.

Juntar, marca d'água, comprimirts
const piped = await client.pipeline(
  [{ tool: "merge" }, { tool: "watermark", params: { watermarkText: "DRAFT" } }, { tool: "compress" }],
  [await readFileInput("a.pdf"), await readFileInput("b.pdf")],
);
await saveResult(piped, { output: "out.pdf" });

Os pipelines aceitam as mesmas opções de senha que run.

Como trabalho com PDFs criptografados?

Passe password para run para abrir antes uma entrada criptografada. O desbloqueio e a ferramenta rodam em uma única requisição. Para ferramentas que recebem vários arquivos, como Juntar, passe passwords com um item por entrada, usando uma string vazia para um arquivo aberto. Cada arquivo é desbloqueado separadamente.

Senhasts
await client.run("compress", { input: await readFileInput("locked.pdf"), password: "secret" });
await client.run("merge", {
  input: [await readFileInput("locked.pdf"), await readFileInput("open.pdf")],
  passwords: ["secret", ""],
});

Em um lote, passwordFor(file, index) devolve a senha de cada entrada. Para remover a proteção de forma permanente, use a ferramenta Desbloquear.

Como funcionam os erros?

As falhas lançam Pdf123Error. Ele tem status (undefined quando não houve resposta), code, reason com a causa detalhada, como password_required, e problem com os detalhes do problema enviados pelo servidor, que incluem hint quando existe. Os erros de validação são lançados antes de qualquer envio.

Tratar um errots
import { Pdf123Error } from "@pdf123/sdk";

try {
  await client.run("compress", { input: await readFileInput("locked.pdf") });
} catch (error) {
  if (error instanceof Pdf123Error) {
    console.error(error.status, error.code, error.reason, error.problem?.hint);
  } else {
    throw error;
  }
}

Os códigos do servidor estão em Códigos de erro. O cliente acrescenta estes códigos próprios:

CódigoSignificado
network_errorA requisição não recebeu resposta
timeoutUma requisição excedeu timeoutMs
cancelledSeu signal abortou a chamada
input_unreadableNão foi possível ler um caminho local
output_unwritableNão foi possível salvar o resultado no caminho indicado
output_mismatchsaveResult se recusou a gravar um ZIP com nome .pdf
unsupported_file_typeA ferramenta não aceita esse tipo de arquivo
unknown_toolO id da ferramenta não existe; a mensagem sugere ids parecidos
invalid_targetcall recusou um caminho /api/... com segmentos .., . ou vazios
no_contentA ferramenta não tinha nada para devolver (HTTP 204)

saveResult nunca sobrescreve um arquivo dentro de um diretório. Chame antes checkOutput(output, { several }) para descobrir, antes do envio, se um caminho pode ser gravado.

Quais configurações de TypeScript e de módulos funcionam?

Os tipos são resolvidos com as configurações de moduleResolution nodenext, node16, bundler e a mais antiga node10, incluindo o subcaminho @pdf123/sdk/node. O pacote é um módulo ES, então import funciona em qualquer lugar. require("@pdf123/sdk") a partir de CommonJS funciona no Node 22.12 ou mais recente e não está disponível no Node 20.

Como configuro o cliente?

OpçãoVariável de ambientePadrão
baseUrlPDFX_API_BASEhttps://pdf123.xyz
apiKeyPDFX_API_KEYnenhum, anônimo
timeoutMsnenhuma300000

new Pdf123Client() nunca lê o ambiente. clientFromEnv(), de @pdf123/sdk/node, lê as duas variáveis, e as opções que você passar têm prioridade. A chave é enviada no cabeçalho X-API-KEY; veja Autenticação.

Para usar o seu próprio servidor, defina baseUrl com o endereço dele, por exemplo http://localhost:8080. Veja Self-host.

Posso usar o SDK em um navegador?

Sim. O ponto de entrada raiz @pdf123/sdk só precisa de fetch e não tem dependências do Node. Monte você mesmo os objetos FileInput a partir de um File ou de um Uint8Array, porque os auxiliares de arquivo ficam no ponto de entrada node. Não inclua uma chave de API em código de navegador que outras pessoas possam ler.

FAQ

O SDK precisa de uma chave de API?

Não. Um cliente criado sem opções chama a API pública de forma anônima. Passe apiKey para enviar o cabeçalho X-API-KEY.

Qual versão do Node o SDK exige?

Node 20.3 ou mais recente, ou Bun. O ponto de entrada raiz só precisa de fetch, então também roda em navegadores e bundlers.

Como uso uma ferramenta mais nova que o SDK?

Use client.call. Ele recebe um id de ferramenta, um id de operação como general/merge-pdfs ou um caminho /api/..., além de arquivos e campos. Nada é validado nem preenchido com valores padrão localmente.

Qual o tamanho máximo de arquivo que posso enviar?

Entradas com mais de 95 MB no total passam automaticamente pela API de upload em partes. O corpo de uma requisição direta é limitado a 100 MiB.

Por que minha chamada lançou um erro para um PDF sem tabelas?

Ferramentas como pdf-to-csv e pdf-to-xlsx respondem sem conteúdo quando o PDF não tem nenhuma tabela detectável. O SDK lança Pdf123Error com o código no_content em vez de devolver um arquivo vazio. Verifique esse código se um resultado vazio for aceitável para você.