@abby-inc/node

中文文档
2.9.0发布于 2026/11/04MITTypeScriptESM + CJS构建来源已验证近 30 天下载 1932

Node.js, Bun, and Deno library for the Abby API

原始使用文档
文档目录21 节
  1. Table of Contents
  2. Installation
  3. Requirements
  4. Usage
  5. Initialization
  6. Services
  7. Basic Example
  8. Configuration
  9. Custom Fetch & Proxy Support
  10. Error Handling
  11. Event Listeners
  12. Interceptors
  13. Raw Requests
  14. Validation
  15. Automatic Validation
  16. Using Zod Schemas Directly
  17. TypeScript Support
  18. Versioning
  19. Development
  20. Support
  21. License

Abby Node.js, Bun & Deno SDK

npm version npm downloads CI codecov License: MIT

The official Node.js, Bun, and Deno library for the Abby API. Abby is an all-in-one business management platform for freelancers and micro-enterprises.

Table of Contents

Installation

Install the package using your preferred package manager:

npm install @abby-inc/node
# or
yarn add @abby-inc/node
# or
pnpm add @abby-inc/node
# or
bun add @abby-inc/node

For Deno, you can import directly from npm:

import Abby from 'npm:@abby-inc/node';

Requirements

  • Node.js 22.13.0 or higher (CI: 22, 24, 26), Bun 1.0.0 or higher, or Deno 2.0.0 or higher
  • An Abby account with an API key

Usage

Initialization

Get your API key from the Abby settings.

import Abby from '@abby-inc/node';

const abby = new Abby('your_api_key');

Services

The SDK provides several services to interact with different parts of the Abby API:

  • abby.company: Current company info and preferences.
  • abby.invoice: Create and manage invoices.
  • abby.estimate: Create and manage estimates (quotes).
  • abby.contact: Manage your contacts (customers).
  • abby.organization: Manage organizations.
  • abby.billing: Shared billing utilities (PDFs, emails).
  • abby.opportunity: CRM and opportunities management.
  • abby.asset: Manage business assets.
  • abby.advance: Manage advance payments.
  • abby.customerPortal: Customer portal payments and billing themes.

Basic Example

import Abby from '@abby-inc/node';

const abby = new Abby('your_api_key');

async function main() {
  // Get current company information
  const { data: me } = await abby.company.getMe();
  console.log(`Welcome back, ${me.user.firstname}!`);

  // List all contacts
  const { data: contacts } = await abby.contact.retrieveContacts({
    query: { limit: 10 },
  });

  console.log(`Found ${contacts.docs.length} contacts.`);
}

main().catch(console.error);

Configuration

You can pass optional configuration settings when initializing the SDK:

import Abby from '@abby-inc/node';

const abby = new Abby('your_api_key', {
  baseUrl: 'https://api.app-abby.com',
  timeout: 30000,
  headers: {
    'X-Custom-Header': 'value',
  },
});
OptionDefaultDescription
baseUrl'https://api.app-abby.com'Base URL for the Abby API.
timeout30000Request timeout in milliseconds.
headersundefinedAdditional headers to include in every request.
fetchglobalThis.fetchCustom fetch implementation for proxies, logging, or testing. See Custom Fetch & Proxy Support.

Custom Fetch & Proxy Support

The SDK allows you to provide a custom fetch implementation for advanced use cases like proxies, custom logging, or testing.

Using a Proxy

With undici (recommended for Node.js):

import Abby from '@abby-inc/node';
import { fetch as undiciFetch, ProxyAgent } from 'undici';

const proxyAgent = new ProxyAgent('http://proxy.example.com:8080');

const abby = new Abby('your_api_key', {
  fetch: (url, init) =>
    undiciFetch(url, {
      ...init,
      dispatcher: proxyAgent,
    }),
});

With node-fetch and https-proxy-agent:

import Abby from '@abby-inc/node';
import fetch from 'node-fetch';
import { HttpsProxyAgent } from 'https-proxy-agent';

const proxyAgent = new HttpsProxyAgent('http://proxy.example.com:8080');

const abby = new Abby('your_api_key', {
  fetch: (url, init) =>
    fetch(url, {
      ...init,
      agent: proxyAgent,
    }) as Promise<Response>,
});

Custom Logging

const abby = new Abby('your_api_key', {
  fetch: async (url, init) => {
    console.log(`[Abby SDK] ${init?.method ?? 'GET'} ${url}`);
    const start = Date.now();

    const response = await globalThis.fetch(url, init);

    console.log(`[Abby SDK] ${response.status} in ${Date.now() - start}ms`);
    return response;
  },
});

Testing with Mock Fetch

import { vi } from 'vitest';

const mockFetch = vi.fn(
  async () =>
    new Response(JSON.stringify({ success: true }), {
      status: 200,
      headers: { 'Content-Type': 'application/json' },
    })
);

const abby = new Abby('your_api_key', {
  fetch: mockFetch,
});

Error Handling

The SDK throws descriptive errors when a request fails. You can catch these errors to handle different failure scenarios:

try {
  const { data } = await abby.invoice.getInvoice({
    path: { invoiceId: 'inv_invalid' },
  });
} catch (error) {
  if (error.status === 404) {
    console.error('Invoice not found');
  } else if (error.status === 401) {
    console.error('Invalid API key');
  } else {
    console.error('An unexpected error occurred:', error.message);
  }
}

Event Listeners

The SDK provides an event emitter pattern for global error handling and logging. This is useful for integrating with error tracking services like Sentry or for centralized logging.

Listening for Errors

Subscribe to all API errors across your application:

import Abby from '@abby-inc/node';

const abby = new Abby('your_api_key');

// Global error handler - fires on any 4xx/5xx response
abby.on('error', (error) => {
  console.error(`API Error: ${error.status} ${error.statusText}`);
  console.error(`URL: ${error.method} ${error.url}`);
  console.error(`Message: ${error.message}`);
  console.error(`Duration: ${error.duration}ms`);

  // Send to error tracking service
  Sentry.captureException(new Error(error.message), {
    extra: {
      status: error.status,
      url: error.url,
      requestId: error.requestId,
      body: error.body,
    },
  });
});

Listening for All Responses

Subscribe to all API responses (both successful and failed):

// Log all API calls for debugging/monitoring
abby.on('response', (response) => {
  console.log(`${response.method} ${response.url} - ${response.status} (${response.duration}ms)`);
});

Removing Listeners

Use off() to remove a listener:

const errorHandler = (error) => console.error(error);

// Add listener
abby.on('error', errorHandler);

// Remove listener later
abby.off('error', errorHandler);

Event Types

EventDescriptionPayload Type
errorFires on 4xx/5xx responsesAbbyErrorEvent
responseFires on all responsesAbbyResponseEvent

AbbyErrorEvent properties:

PropertyTypeDescription
statusnumberHTTP status code (4xx or 5xx)
statusTextstringHTTP status text
urlstringRequest URL
methodstringHTTP method (GET, POST, etc.)
durationnumberRequest duration in milliseconds
messagestring?Error message from response body, if available
bodyunknown?Response body, if available
requestIdstring?X-Request-Id header, if available

AbbyResponseEvent properties:

PropertyTypeDescription
statusnumberHTTP status code
urlstringRequest URL
methodstringHTTP method (GET, POST, etc.)
durationnumberRequest duration in milliseconds
okbooleanWhether the response was successful (2xx)

Interceptors

Interceptors allow you to hook into the request/response lifecycle:

const client = abby.getClient();

// Request Interceptor: Add a custom header to every request
client.interceptors.request.use((request) => {
  request.headers.set('X-Request-ID', crypto.randomUUID());
  return request;
});

// Response Interceptor: Log every response status
client.interceptors.response.use((response) => {
  console.log(`API Response: ${response.status}`);
  return response;
});

Raw Requests

If you need to call an endpoint that isn't covered by the SDK, or prefer to specify request details directly, you can use the underlying HTTP client:

import Abby from '@abby-inc/node';

const abby = new Abby('your_api_key');
const client = abby.getClient();

// GET request
const { data } = await client.get({
  url: '/v2/some/endpoint',
});

// POST request with body
const { data: result } = await client.post({
  url: '/v2/some/endpoint',
  body: {
    field: 'value',
  },
});

// Other methods available: put, patch, delete, head, options

The client automatically includes your API key and SDK headers in all requests.

Validation

The SDK includes built-in Zod validation for API requests, catching malformed payloads before they leave your process.

Automatic Validation

All SDK methods automatically validate request data: parameters, query strings, and request bodies are checked before sending.

Responses are not validated. Response schemas are generated and exported (see below), but the SDK does not run them — a spec/API mismatch would otherwise turn a successful call into a thrown error. Types on responses remain compile-time only; parse with the exported z*Dto schemas yourself if you need a runtime guarantee.

If request validation fails, a ZodError is thrown with detailed information about what went wrong:

import Abby from '@abby-inc/node';
import { ZodError } from 'zod';

const abby = new Abby('your_api_key');

try {
  // This will fail validation if the request body is invalid
  await abby.contact.createContact({
    body: {
      // Missing required fields will trigger a ZodError
    },
  });
} catch (error) {
  if (error instanceof ZodError) {
    console.error('Validation failed:', error.errors);
  }
}

Using Zod Schemas Directly

All Zod schemas are exported and can be used for your own validation needs:

import Abby, { zCreateContactDto, zReadContactDto } from '@abby-inc/node';

// Validate user input before sending to the API
const userInput = {
  firstname: 'John',
  lastname: 'Doe',
  email: '[email protected]',
};

// Parse and validate (throws ZodError if invalid)
const validatedContact = zCreateContactDto.parse(userInput);

// Or use safeParse for non-throwing validation
const result = zCreateContactDto.safeParse(userInput);
if (result.success) {
  console.log('Valid:', result.data);
} else {
  console.error('Invalid:', result.error.errors);
}

// Infer TypeScript types from schemas
import { z } from 'zod';
type CreateContactInput = z.infer<typeof zCreateContactDto>;

Available schema patterns:

  • z{DtoName} - Schemas for DTOs (e.g., zCreateContactDto, zReadInvoiceDto)
  • z{ControllerMethod}Data - Request data schemas (e.g., zContactControllerCreateContactData)

TypeScript Support

The SDK is written in TypeScript and provides complete type definitions for all API resources and responses.

import Abby, { ReadMeDto } from '@abby-inc/node';

const abby = new Abby('your_api_key');

async function getCompanyData() {
  const { data }: { data: ReadMeDto } = await abby.company.getMe();
  return data;
}

You can also infer types directly from Zod schemas:

import { z } from 'zod';
import { zReadContactDto } from '@abby-inc/node';

// Infer the type from the Zod schema
type Contact = z.infer<typeof zReadContactDto>;

Versioning

This SDK uses independent versioning from the Abby API:

  • SDK version (version in package.json): Follows semver for SDK changes (bug fixes, new features, breaking changes)
  • API version (apiVersion in package.json): Tracks which Abby API version was used to generate the SDK
{
  "version": "1.2.0", // SDK version
  "apiVersion": "1.5.0" // API spec version used to generate
}

This allows the SDK to receive bug fixes and improvements independently from API changes.

SDK update PRs opened automatically by an API spec change are auto-merged and published once CI passes. Manual runs of the Generate SDK workflow need a human merge.

Development

Contributions are welcome! Please see our Contributing Guidelines for more information.

Support

If you encounter any issues or have questions, please check the following resources:

License

MIT License - see LICENSE for details.

版本与发布记录

@abby-inc/node 共发布 12 个版本,首次发布于 2025/12/27;过去 12 个月发布了 12 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.9.0latest2026/11/043 天前
2.8.02026/11/035 天前
2.7.02026/10/1722 天前
2.6.02026/10/1623 天前
2.5.02026/10/1128 天前
2.4.02026/10/0930 天前

关于 @abby-inc/node 的常见问题

@abby-inc/node 是什么?

Node.js, Bun, and Deno library for the Abby API

如何安装 @abby-inc/node?

在项目目录运行 npm install @abby-inc/node,或使用 pnpm add / yarn add / bun add。

@abby-inc/node 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@abby-inc/node 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@abby-inc/node 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.13.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@abby-inc/node 可以商用吗?

@abby-inc/node 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@abby-inc/node 的下载量有多少?

根据 npm 官方下载统计,@abby-inc/node 在 2026/10/05 – 2026/11/03 这 30 天内被下载 1,932 次,日均约 64 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@abby-inc/node 还在维护吗?

最新版本 2.9.0 发布于 2026/11/04(3 天前);至今共发布 12 个版本,其中过去 12 个月发布了 12 个;首次发布于 2025/12/27。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。