SDK - TypeScript / Node.js
@naprawksef/sdk - zero runtime dependencies, działa w Node ≥18, Bun, Deno i edge runtime.
Instalacja
bash
npm install @naprawksef/sdk
# lub
pnpm add @naprawksef/sdk
# lub
yarn add @naprawksef/sdkWymaga Node.js 18+. Korzysta z wbudowanego fetch i node:crypto - żadnych zewnętrznych pakietów.
Inicjalizacja
typescript
import { NaprawKsef } from "@naprawksef/sdk";
const client = new NaprawKsef({
apiKey: process.env.NAPRAW_KSEF_API_KEY!, // nk_live_... lub nk_test_...
appName: "trawers-erp/7.4.2", // dorzucamy do User-Agent
timeoutMs: 30_000,
maxRetries: 3, // 0 = bez retries
});Konstruktor waliduje format klucza - błąd konfiguracji wykryjesz przed pierwszym networkiem.
Walidacja XML
typescript
import { readFileSync } from "node:fs";
const result = await client.validate.run({
xml: readFileSync("faktura.xml", "utf8"),
filename: "faktura.xml",
idempotencyKey: "invoice-42-v1", // opcjonalne, SDK generuje UUID jeśli brak
});
if (!result.valid) {
for (const issue of result.issues) {
console.error(`[${issue.severity}] ${issue.code}: ${issue.message}`);
}
}Analiza pod korekty FA(3)
typescript
const analysis = await client.correction.analyze({
xml: readFileSync("faktura.xml", "utf8"),
});
console.log(analysis.analysis.totals); // metadata
console.log(analysis.suggestions); // top 5 scenariuszy
console.log(analysis.lines_jpk); // sugestie pól JPK_V7MWebhooks - CRUD i test
typescript
const created = await client.webhooks.create({
name: "Production receiver",
url: "https://my-app.com/webhooks/napraw-ksef",
events: ["validation.completed", "correction.created"],
});
// Plaintext sekret jest dostępny TYLKO RAZ:
console.log(created.secret);
const list = await client.webhooks.list();
const deliveries = await client.webhooks.listDeliveries(created.webhook.id);
await client.webhooks.sendTest(created.webhook.id); // smoke test
await client.webhooks.update(created.webhook.id, { is_active: false });
await client.webhooks.delete(created.webhook.id);Weryfikacja podpisu webhooka
Można importować osobny entrypoint, jeśli endpoint webhookowy nie potrzebuje całego klienta:
typescript
import { verifyWebhookSignature } from "@naprawksef/sdk/webhooks";
export async function POST(req: Request) {
const rawBody = await req.text();
const result = verifyWebhookSignature({
secret: process.env.NAPRAW_KSEF_WEBHOOK_SECRET!,
rawBody,
header: req.headers.get("x-nk-signature"),
});
if (!result.ok) return new Response(result.reason, { status: 401 });
// …
return new Response("ok");
}Więcej w przewodniku Webhooks.
Typowane wyjątki
typescript
import {
NaprawKsefRateLimitError,
NaprawKsefAuthError,
NaprawKsefValidationError,
} from "@naprawksef/sdk";
try {
await client.validate.run({ xml });
} catch (e) {
if (e instanceof NaprawKsefRateLimitError) {
await sleep((e.retryAfterSeconds ?? 60) * 1000);
} else if (e instanceof NaprawKsefAuthError) {
rotateKey();
} else if (e instanceof NaprawKsefValidationError) {
showFieldErrors(e.details);
} else {
throw e;
}
}Obserwowalność
typescript
const client = new NaprawKsef({
apiKey,
hooks: {
onResponse: ({ method, url, status, durationMs, requestId }) => {
log.info({ method, url, status, durationMs, requestId }, "nk.api");
},
onRetry: ({ url, attempt, delayMs, reason }) => {
log.warn({ url, attempt, delayMs, reason }, "nk.api.retry");
},
},
});Pełny README
Pełna dokumentacja, lista typów wyjątków i przykłady receiver'ów Next.js / Express żyją w paczce na npm: npmjs.com/package/@naprawksef/sdk.