@heyinvoice/sdk 1.0.0

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.
package/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # @heyinvoice/sdk
2
+
3
+ > Official Node.js & TypeScript SDK for [HeyInvoice](https://heyinvoice.com).
4
+
5
+ Stripe-like lightweight, fully-typed API client for managing invoices, PEPPOL e-invoicing, and customer billing.
6
+
7
+ ## 📦 Installation
8
+
9
+ ```bash
10
+ # npm
11
+ npm install @heyinvoice/sdk
12
+
13
+ # pnpm
14
+ pnpm add @heyinvoice/sdk
15
+
16
+ # yarn
17
+ yarn add @heyinvoice/sdk
18
+ ```
19
+
20
+ ## 🚀 Quick Start
21
+
22
+ Initialize the SDK with your API key (`sk_live_...` or `sk_test_...`):
23
+
24
+ ```typescript
25
+ import { HeyInvoice } from '@heyinvoice/sdk';
26
+
27
+ // Initialize with API Key string
28
+ const heyinvoice = new HeyInvoice('sk_test_51MzXYZ...');
29
+
30
+ // Or with custom config options
31
+ /*
32
+ const heyinvoice = new HeyInvoice({
33
+ apiKey: 'sk_test_51MzXYZ...',
34
+ apiBase: 'https://api.heyinvoice.com',
35
+ timeout: 10000,
36
+ });
37
+ */
38
+ ```
39
+
40
+ ---
41
+
42
+ ## 🧾 Invoice CRUD Operations
43
+
44
+ ### 1. Create a Draft Invoice
45
+
46
+ ```typescript
47
+ const invoice = await heyinvoice.invoices.create({
48
+ id_customer: 1024,
49
+ invoice_date: '2026-07-26',
50
+ due_date: '2026-08-25',
51
+ currency: 'SGD',
52
+ payment_terms: 30,
53
+ notes: 'Thank you for doing business with us!',
54
+ line_items: [
55
+ {
56
+ description: 'Consulting Services (July 2026)',
57
+ quantity: 10,
58
+ unit_price_cents: 15000, // $150.00
59
+ gst_rate: 9, // 9% GST
60
+ },
61
+ {
62
+ description: 'Software Setup & Configuration',
63
+ quantity: 1,
64
+ unit_price_cents: 50000, // $500.00
65
+ },
66
+ ],
67
+ });
68
+
69
+ console.log('Created invoice:', invoice.id, invoice.total_cents);
70
+ ```
71
+
72
+ ### 2. Retrieve an Invoice
73
+
74
+ ```typescript
75
+ const invoice = await heyinvoice.invoices.retrieve('inv_998123');
76
+ // Or alias:
77
+ // const invoice = await heyinvoice.invoices.get('inv_998123');
78
+ console.log(invoice.invoice_number, invoice.status);
79
+ ```
80
+
81
+ ### 3. Update an Invoice
82
+
83
+ ```typescript
84
+ const updatedInvoice = await heyinvoice.invoices.update('inv_998123', {
85
+ notes: 'Updated payment instructions: Pay via PayNow UEN 123456789W',
86
+ due_date: '2026-09-01',
87
+ });
88
+ ```
89
+
90
+ ### 4. List Invoices with Filtering
91
+
92
+ ```typescript
93
+ const { data: invoices, has_more } = await heyinvoice.invoices.list({
94
+ status: 'draft',
95
+ limit: 20,
96
+ page: 1,
97
+ });
98
+
99
+ for (const inv of invoices) {
100
+ console.log(inv.id, inv.invoice_number, inv.total_cents);
101
+ }
102
+ ```
103
+
104
+ ### 5. Finalize / Send / Void / Delete Invoice
105
+
106
+ ```typescript
107
+ // Send invoice to customer
108
+ await heyinvoice.invoices.send('inv_998123');
109
+
110
+ // Void invoice
111
+ await heyinvoice.invoices.void('inv_998123');
112
+
113
+ // Delete draft invoice
114
+ await heyinvoice.invoices.del('inv_998123');
115
+ ```
116
+
117
+ ---
118
+
119
+ ## ⚠️ Error Handling
120
+
121
+ The SDK throws specialized error classes inherited from `HeyInvoiceError`:
122
+
123
+ ```typescript
124
+ import {
125
+ HeyInvoice,
126
+ AuthenticationError,
127
+ NotFoundError,
128
+ InvalidRequestError,
129
+ HeyInvoiceError,
130
+ } from '@heyinvoice/sdk';
131
+
132
+ try {
133
+ const invoice = await heyinvoice.invoices.retrieve('invalid_id');
134
+ } catch (error) {
135
+ if (error instanceof AuthenticationError) {
136
+ console.error('Invalid API Key provided');
137
+ } else if (error instanceof NotFoundError) {
138
+ console.error('Invoice does not exist');
139
+ } else if (error instanceof InvalidRequestError) {
140
+ console.error('Validation failed:', error.message);
141
+ } else if (error instanceof HeyInvoiceError) {
142
+ console.error(`API Error [${error.statusCode}]: ${error.message}`);
143
+ } else {
144
+ console.error('Unexpected error:', error);
145
+ }
146
+ }
147
+ ```
148
+
149
+ ---
150
+
151
+ ## 🛠 Deploying & Publishing to NPM
152
+
153
+ ### 1. Build package locally
154
+
155
+ ```bash
156
+ pnpm --filter=@heyinvoice/sdk build
157
+ ```
158
+
159
+ ### 2. Perform a dry-run publish
160
+
161
+ ```bash
162
+ cd packages/sdk
163
+ npm publish --dry-run
164
+ ```
165
+
166
+ ### 3. Publish to NPM Registry
167
+
168
+ Ensure you are logged into your npm account (`npm login`), then publish with public access:
169
+
170
+ ```bash
171
+ npm publish --access public
172
+ ```
173
+
174
+ ---
175
+
176
+ ## 📄 License
177
+
178
+ MIT © [HeyInvoice](https://heyinvoice.com)
@@ -0,0 +1,223 @@
1
+ interface ClientConfig {
2
+ /**
3
+ * HeyInvoice API Key (e.g. sk_live_... or sk_test_...)
4
+ */
5
+ apiKey: string;
6
+ /**
7
+ * Base URL of the HeyInvoice API server.
8
+ * @default 'https://api.heyinvoice.com'
9
+ */
10
+ apiBase?: string;
11
+ /**
12
+ * Request timeout in milliseconds.
13
+ * @default 30000
14
+ */
15
+ timeout?: number;
16
+ /**
17
+ * Maximum number of automatic retries on rate limits or server errors.
18
+ * @default 2
19
+ */
20
+ maxRetries?: number;
21
+ /**
22
+ * Custom HTTP headers to include with every request.
23
+ */
24
+ headers?: Record<string, string>;
25
+ }
26
+ type InvoiceStatus = 'draft' | 'final' | 'void' | 'paid' | 'overdue';
27
+ interface InvoiceLineItem {
28
+ id?: string;
29
+ description: string;
30
+ quantity?: number;
31
+ unit_price_cents: number;
32
+ gst_rate?: number;
33
+ amount_cents?: number;
34
+ }
35
+ interface Invoice {
36
+ id: string;
37
+ object: 'invoice';
38
+ id_customer: number | string;
39
+ invoice_number: string;
40
+ status: InvoiceStatus;
41
+ invoice_date?: string;
42
+ due_date?: string;
43
+ currency?: string;
44
+ payment_type?: 'one_time' | 'recurring';
45
+ payment_terms?: number;
46
+ subtotal_cents?: number;
47
+ gst_amount_cents?: number;
48
+ total_cents?: number;
49
+ notes?: string;
50
+ internal_notes?: string;
51
+ line_items?: InvoiceLineItem[];
52
+ created_at?: string;
53
+ updated_at?: string;
54
+ [key: string]: unknown;
55
+ }
56
+ interface CreateInvoiceParams {
57
+ id_customer: number | string;
58
+ invoice_date?: string;
59
+ due_date?: string;
60
+ currency?: string;
61
+ payment_type?: 'one_time' | 'recurring';
62
+ payment_terms?: number;
63
+ notes?: string;
64
+ internal_notes?: string;
65
+ line_items: Array<{
66
+ description: string;
67
+ quantity?: number;
68
+ unit_price_cents: number;
69
+ gst_rate?: number;
70
+ }>;
71
+ }
72
+ interface UpdateInvoiceParams {
73
+ id_customer?: number | string;
74
+ invoice_date?: string;
75
+ due_date?: string;
76
+ currency?: string;
77
+ notes?: string;
78
+ internal_notes?: string;
79
+ status?: InvoiceStatus;
80
+ line_items?: Array<{
81
+ id?: string;
82
+ description: string;
83
+ quantity?: number;
84
+ unit_price_cents: number;
85
+ gst_rate?: number;
86
+ }>;
87
+ }
88
+ interface ListInvoicesParams {
89
+ limit?: number;
90
+ page?: number;
91
+ status?: InvoiceStatus;
92
+ customer_id?: number | string;
93
+ date_from?: string;
94
+ date_to?: string;
95
+ }
96
+ interface PaginatedList<T> {
97
+ object: 'list';
98
+ data: T[];
99
+ has_more: boolean;
100
+ total_count?: number;
101
+ }
102
+ interface DeletedResource {
103
+ id: string;
104
+ object: string;
105
+ deleted: true;
106
+ }
107
+
108
+ interface RequestOptions {
109
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
110
+ path: string;
111
+ query?: Record<string, string | number | boolean | undefined>;
112
+ body?: unknown;
113
+ headers?: Record<string, string>;
114
+ }
115
+ declare class HttpClient {
116
+ private readonly apiKey;
117
+ private readonly apiBase;
118
+ private readonly timeout;
119
+ private readonly maxRetries;
120
+ private readonly customHeaders;
121
+ constructor(config: ClientConfig);
122
+ request<T>(options: RequestOptions): Promise<T>;
123
+ private buildUrl;
124
+ private buildHeaders;
125
+ private delay;
126
+ }
127
+
128
+ declare abstract class Resource {
129
+ protected readonly client: HttpClient;
130
+ constructor(client: HttpClient);
131
+ }
132
+
133
+ declare class Invoices extends Resource {
134
+ /**
135
+ * Create a new invoice draft.
136
+ */
137
+ create(params: CreateInvoiceParams): Promise<Invoice>;
138
+ /**
139
+ * Retrieve an existing invoice by ID.
140
+ */
141
+ retrieve(id: string): Promise<Invoice>;
142
+ /**
143
+ * Alias for retrieve.
144
+ */
145
+ get(id: string): Promise<Invoice>;
146
+ /**
147
+ * Update an existing invoice.
148
+ */
149
+ update(id: string, params: UpdateInvoiceParams): Promise<Invoice>;
150
+ /**
151
+ * List invoices with optional pagination and filtering.
152
+ */
153
+ list(params?: ListInvoicesParams): Promise<PaginatedList<Invoice>>;
154
+ /**
155
+ * Delete or void an invoice.
156
+ */
157
+ del(id: string): Promise<DeletedResource>;
158
+ /**
159
+ * Finalize/Send a draft invoice.
160
+ */
161
+ send(id: string): Promise<Invoice>;
162
+ /**
163
+ * Void an invoice.
164
+ */
165
+ void(id: string): Promise<Invoice>;
166
+ }
167
+
168
+ declare class HeyInvoice {
169
+ private readonly httpClient;
170
+ readonly invoices: Invoices;
171
+ /**
172
+ * Initializes a new HeyInvoice SDK client.
173
+ *
174
+ * @param apiKeyOrConfig API Key string or full ClientConfig object
175
+ * @param options Additional client options if first parameter is an API Key string
176
+ *
177
+ * @example
178
+ * ```ts
179
+ * // String initialization
180
+ * const heyinvoice = new HeyInvoice('sk_live_xyz123');
181
+ *
182
+ * // Object initialization
183
+ * const heyinvoice = new HeyInvoice({
184
+ * apiKey: 'sk_live_xyz123',
185
+ * apiBase: 'https://api.heyinvoice.com',
186
+ * });
187
+ * ```
188
+ */
189
+ constructor(apiKeyOrConfig: string | ClientConfig, options?: Omit<ClientConfig, 'apiKey'>);
190
+ }
191
+
192
+ interface HeyInvoiceErrorOptions {
193
+ type?: string;
194
+ statusCode?: number;
195
+ code?: string;
196
+ requestId?: string;
197
+ raw?: unknown;
198
+ }
199
+ declare class HeyInvoiceError extends Error {
200
+ readonly type: string;
201
+ readonly statusCode?: number;
202
+ readonly code?: string;
203
+ readonly requestId?: string;
204
+ readonly raw?: unknown;
205
+ constructor(message: string, options?: HeyInvoiceErrorOptions);
206
+ }
207
+ declare class AuthenticationError extends HeyInvoiceError {
208
+ constructor(message?: string, options?: Omit<HeyInvoiceErrorOptions, 'type'>);
209
+ }
210
+ declare class InvalidRequestError extends HeyInvoiceError {
211
+ constructor(message?: string, options?: Omit<HeyInvoiceErrorOptions, 'type'>);
212
+ }
213
+ declare class NotFoundError extends HeyInvoiceError {
214
+ constructor(message?: string, options?: Omit<HeyInvoiceErrorOptions, 'type'>);
215
+ }
216
+ declare class APIError extends HeyInvoiceError {
217
+ constructor(message?: string, options?: Omit<HeyInvoiceErrorOptions, 'type'>);
218
+ }
219
+ declare class ConnectionError extends HeyInvoiceError {
220
+ constructor(message?: string, options?: Omit<HeyInvoiceErrorOptions, 'type'>);
221
+ }
222
+
223
+ export { APIError, AuthenticationError, type ClientConfig, ConnectionError, type CreateInvoiceParams, type DeletedResource, HeyInvoice, HeyInvoiceError, type HeyInvoiceErrorOptions, InvalidRequestError, type Invoice, type InvoiceLineItem, type InvoiceStatus, Invoices, type ListInvoicesParams, NotFoundError, type PaginatedList, Resource, type UpdateInvoiceParams, HeyInvoice as default };
@@ -0,0 +1,223 @@
1
+ interface ClientConfig {
2
+ /**
3
+ * HeyInvoice API Key (e.g. sk_live_... or sk_test_...)
4
+ */
5
+ apiKey: string;
6
+ /**
7
+ * Base URL of the HeyInvoice API server.
8
+ * @default 'https://api.heyinvoice.com'
9
+ */
10
+ apiBase?: string;
11
+ /**
12
+ * Request timeout in milliseconds.
13
+ * @default 30000
14
+ */
15
+ timeout?: number;
16
+ /**
17
+ * Maximum number of automatic retries on rate limits or server errors.
18
+ * @default 2
19
+ */
20
+ maxRetries?: number;
21
+ /**
22
+ * Custom HTTP headers to include with every request.
23
+ */
24
+ headers?: Record<string, string>;
25
+ }
26
+ type InvoiceStatus = 'draft' | 'final' | 'void' | 'paid' | 'overdue';
27
+ interface InvoiceLineItem {
28
+ id?: string;
29
+ description: string;
30
+ quantity?: number;
31
+ unit_price_cents: number;
32
+ gst_rate?: number;
33
+ amount_cents?: number;
34
+ }
35
+ interface Invoice {
36
+ id: string;
37
+ object: 'invoice';
38
+ id_customer: number | string;
39
+ invoice_number: string;
40
+ status: InvoiceStatus;
41
+ invoice_date?: string;
42
+ due_date?: string;
43
+ currency?: string;
44
+ payment_type?: 'one_time' | 'recurring';
45
+ payment_terms?: number;
46
+ subtotal_cents?: number;
47
+ gst_amount_cents?: number;
48
+ total_cents?: number;
49
+ notes?: string;
50
+ internal_notes?: string;
51
+ line_items?: InvoiceLineItem[];
52
+ created_at?: string;
53
+ updated_at?: string;
54
+ [key: string]: unknown;
55
+ }
56
+ interface CreateInvoiceParams {
57
+ id_customer: number | string;
58
+ invoice_date?: string;
59
+ due_date?: string;
60
+ currency?: string;
61
+ payment_type?: 'one_time' | 'recurring';
62
+ payment_terms?: number;
63
+ notes?: string;
64
+ internal_notes?: string;
65
+ line_items: Array<{
66
+ description: string;
67
+ quantity?: number;
68
+ unit_price_cents: number;
69
+ gst_rate?: number;
70
+ }>;
71
+ }
72
+ interface UpdateInvoiceParams {
73
+ id_customer?: number | string;
74
+ invoice_date?: string;
75
+ due_date?: string;
76
+ currency?: string;
77
+ notes?: string;
78
+ internal_notes?: string;
79
+ status?: InvoiceStatus;
80
+ line_items?: Array<{
81
+ id?: string;
82
+ description: string;
83
+ quantity?: number;
84
+ unit_price_cents: number;
85
+ gst_rate?: number;
86
+ }>;
87
+ }
88
+ interface ListInvoicesParams {
89
+ limit?: number;
90
+ page?: number;
91
+ status?: InvoiceStatus;
92
+ customer_id?: number | string;
93
+ date_from?: string;
94
+ date_to?: string;
95
+ }
96
+ interface PaginatedList<T> {
97
+ object: 'list';
98
+ data: T[];
99
+ has_more: boolean;
100
+ total_count?: number;
101
+ }
102
+ interface DeletedResource {
103
+ id: string;
104
+ object: string;
105
+ deleted: true;
106
+ }
107
+
108
+ interface RequestOptions {
109
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
110
+ path: string;
111
+ query?: Record<string, string | number | boolean | undefined>;
112
+ body?: unknown;
113
+ headers?: Record<string, string>;
114
+ }
115
+ declare class HttpClient {
116
+ private readonly apiKey;
117
+ private readonly apiBase;
118
+ private readonly timeout;
119
+ private readonly maxRetries;
120
+ private readonly customHeaders;
121
+ constructor(config: ClientConfig);
122
+ request<T>(options: RequestOptions): Promise<T>;
123
+ private buildUrl;
124
+ private buildHeaders;
125
+ private delay;
126
+ }
127
+
128
+ declare abstract class Resource {
129
+ protected readonly client: HttpClient;
130
+ constructor(client: HttpClient);
131
+ }
132
+
133
+ declare class Invoices extends Resource {
134
+ /**
135
+ * Create a new invoice draft.
136
+ */
137
+ create(params: CreateInvoiceParams): Promise<Invoice>;
138
+ /**
139
+ * Retrieve an existing invoice by ID.
140
+ */
141
+ retrieve(id: string): Promise<Invoice>;
142
+ /**
143
+ * Alias for retrieve.
144
+ */
145
+ get(id: string): Promise<Invoice>;
146
+ /**
147
+ * Update an existing invoice.
148
+ */
149
+ update(id: string, params: UpdateInvoiceParams): Promise<Invoice>;
150
+ /**
151
+ * List invoices with optional pagination and filtering.
152
+ */
153
+ list(params?: ListInvoicesParams): Promise<PaginatedList<Invoice>>;
154
+ /**
155
+ * Delete or void an invoice.
156
+ */
157
+ del(id: string): Promise<DeletedResource>;
158
+ /**
159
+ * Finalize/Send a draft invoice.
160
+ */
161
+ send(id: string): Promise<Invoice>;
162
+ /**
163
+ * Void an invoice.
164
+ */
165
+ void(id: string): Promise<Invoice>;
166
+ }
167
+
168
+ declare class HeyInvoice {
169
+ private readonly httpClient;
170
+ readonly invoices: Invoices;
171
+ /**
172
+ * Initializes a new HeyInvoice SDK client.
173
+ *
174
+ * @param apiKeyOrConfig API Key string or full ClientConfig object
175
+ * @param options Additional client options if first parameter is an API Key string
176
+ *
177
+ * @example
178
+ * ```ts
179
+ * // String initialization
180
+ * const heyinvoice = new HeyInvoice('sk_live_xyz123');
181
+ *
182
+ * // Object initialization
183
+ * const heyinvoice = new HeyInvoice({
184
+ * apiKey: 'sk_live_xyz123',
185
+ * apiBase: 'https://api.heyinvoice.com',
186
+ * });
187
+ * ```
188
+ */
189
+ constructor(apiKeyOrConfig: string | ClientConfig, options?: Omit<ClientConfig, 'apiKey'>);
190
+ }
191
+
192
+ interface HeyInvoiceErrorOptions {
193
+ type?: string;
194
+ statusCode?: number;
195
+ code?: string;
196
+ requestId?: string;
197
+ raw?: unknown;
198
+ }
199
+ declare class HeyInvoiceError extends Error {
200
+ readonly type: string;
201
+ readonly statusCode?: number;
202
+ readonly code?: string;
203
+ readonly requestId?: string;
204
+ readonly raw?: unknown;
205
+ constructor(message: string, options?: HeyInvoiceErrorOptions);
206
+ }
207
+ declare class AuthenticationError extends HeyInvoiceError {
208
+ constructor(message?: string, options?: Omit<HeyInvoiceErrorOptions, 'type'>);
209
+ }
210
+ declare class InvalidRequestError extends HeyInvoiceError {
211
+ constructor(message?: string, options?: Omit<HeyInvoiceErrorOptions, 'type'>);
212
+ }
213
+ declare class NotFoundError extends HeyInvoiceError {
214
+ constructor(message?: string, options?: Omit<HeyInvoiceErrorOptions, 'type'>);
215
+ }
216
+ declare class APIError extends HeyInvoiceError {
217
+ constructor(message?: string, options?: Omit<HeyInvoiceErrorOptions, 'type'>);
218
+ }
219
+ declare class ConnectionError extends HeyInvoiceError {
220
+ constructor(message?: string, options?: Omit<HeyInvoiceErrorOptions, 'type'>);
221
+ }
222
+
223
+ export { APIError, AuthenticationError, type ClientConfig, ConnectionError, type CreateInvoiceParams, type DeletedResource, HeyInvoice, HeyInvoiceError, type HeyInvoiceErrorOptions, InvalidRequestError, type Invoice, type InvoiceLineItem, type InvoiceStatus, Invoices, type ListInvoicesParams, NotFoundError, type PaginatedList, Resource, type UpdateInvoiceParams, HeyInvoice as default };
package/dist/index.js ADDED
@@ -0,0 +1,322 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ APIError: () => APIError,
24
+ AuthenticationError: () => AuthenticationError,
25
+ ConnectionError: () => ConnectionError,
26
+ HeyInvoice: () => HeyInvoice,
27
+ HeyInvoiceError: () => HeyInvoiceError,
28
+ InvalidRequestError: () => InvalidRequestError,
29
+ Invoices: () => Invoices,
30
+ NotFoundError: () => NotFoundError,
31
+ Resource: () => Resource,
32
+ default: () => index_default
33
+ });
34
+ module.exports = __toCommonJS(index_exports);
35
+
36
+ // src/errors/index.ts
37
+ var HeyInvoiceError = class extends Error {
38
+ type;
39
+ statusCode;
40
+ code;
41
+ requestId;
42
+ raw;
43
+ constructor(message, options) {
44
+ super(message);
45
+ this.name = this.constructor.name;
46
+ this.type = options?.type || "api_error";
47
+ this.statusCode = options?.statusCode;
48
+ this.code = options?.code;
49
+ this.requestId = options?.requestId;
50
+ this.raw = options?.raw;
51
+ Object.setPrototypeOf(this, new.target.prototype);
52
+ }
53
+ };
54
+ var AuthenticationError = class extends HeyInvoiceError {
55
+ constructor(message = "Invalid API key or unauthorized request", options) {
56
+ super(message, { ...options, type: "authentication_error", statusCode: options?.statusCode || 401 });
57
+ }
58
+ };
59
+ var InvalidRequestError = class extends HeyInvoiceError {
60
+ constructor(message = "Invalid request parameters", options) {
61
+ super(message, { ...options, type: "invalid_request_error", statusCode: options?.statusCode || 400 });
62
+ }
63
+ };
64
+ var NotFoundError = class extends HeyInvoiceError {
65
+ constructor(message = "Resource not found", options) {
66
+ super(message, { ...options, type: "not_found_error", statusCode: options?.statusCode || 404 });
67
+ }
68
+ };
69
+ var APIError = class extends HeyInvoiceError {
70
+ constructor(message = "An error occurred on HeyInvoice servers", options) {
71
+ super(message, { ...options, type: "api_error", statusCode: options?.statusCode || 500 });
72
+ }
73
+ };
74
+ var ConnectionError = class extends HeyInvoiceError {
75
+ constructor(message = "Failed to connect to HeyInvoice API", options) {
76
+ super(message, { ...options, type: "connection_error" });
77
+ }
78
+ };
79
+
80
+ // src/http/httpClient.ts
81
+ var HttpClient = class {
82
+ apiKey;
83
+ apiBase;
84
+ timeout;
85
+ maxRetries;
86
+ customHeaders;
87
+ constructor(config) {
88
+ if (!config.apiKey || typeof config.apiKey !== "string" || !config.apiKey.trim()) {
89
+ throw new AuthenticationError("API Key is required to instantiate HeyInvoice SDK");
90
+ }
91
+ this.apiKey = config.apiKey.trim();
92
+ this.apiBase = (config.apiBase || "https://api.heyinvoice.com").replace(/\/+$/, "");
93
+ this.timeout = config.timeout ?? 3e4;
94
+ this.maxRetries = config.maxRetries ?? 2;
95
+ this.customHeaders = config.headers || {};
96
+ }
97
+ async request(options) {
98
+ const url = this.buildUrl(options.path, options.query);
99
+ const headers = this.buildHeaders(options.headers);
100
+ let attempt = 0;
101
+ while (true) {
102
+ attempt++;
103
+ try {
104
+ const controller = new AbortController();
105
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
106
+ const response = await fetch(url, {
107
+ method: options.method,
108
+ headers,
109
+ body: options.body ? JSON.stringify(options.body) : void 0,
110
+ signal: controller.signal
111
+ });
112
+ clearTimeout(timeoutId);
113
+ const requestId = response.headers.get("x-request-id") || void 0;
114
+ let responseData;
115
+ const contentType = response.headers.get("content-type") || "";
116
+ if (contentType.includes("application/json")) {
117
+ responseData = await response.json();
118
+ } else {
119
+ responseData = await response.text();
120
+ }
121
+ if (response.ok) {
122
+ return responseData;
123
+ }
124
+ const errorMessage = typeof responseData === "object" && responseData?.message || typeof responseData === "string" && responseData || `HTTP Error ${response.status} ${response.statusText}`;
125
+ const code = typeof responseData === "object" ? responseData?.code : void 0;
126
+ if (response.status === 401 || response.status === 403) {
127
+ throw new AuthenticationError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });
128
+ }
129
+ if (response.status === 404) {
130
+ throw new NotFoundError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });
131
+ }
132
+ if (response.status === 400 || response.status === 422) {
133
+ throw new InvalidRequestError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });
134
+ }
135
+ if (response.status >= 500) {
136
+ if (attempt <= this.maxRetries) {
137
+ await this.delay(attempt * 500);
138
+ continue;
139
+ }
140
+ throw new APIError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });
141
+ }
142
+ throw new HeyInvoiceError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });
143
+ } catch (err) {
144
+ if (err instanceof HeyInvoiceError) {
145
+ throw err;
146
+ }
147
+ if (err.name === "AbortError") {
148
+ throw new ConnectionError(`Request timed out after ${this.timeout}ms`);
149
+ }
150
+ if (attempt <= this.maxRetries && err.name !== "AbortError") {
151
+ await this.delay(attempt * 500);
152
+ continue;
153
+ }
154
+ throw new ConnectionError(err.message || "Network communication failure", { raw: err });
155
+ }
156
+ }
157
+ }
158
+ buildUrl(path, query) {
159
+ const formattedPath = path.startsWith("/") ? path : `/${path}`;
160
+ const url = new URL(`${this.apiBase}${formattedPath}`);
161
+ if (query) {
162
+ Object.entries(query).forEach(([key, value]) => {
163
+ if (value !== void 0 && value !== null) {
164
+ url.searchParams.append(key, String(value));
165
+ }
166
+ });
167
+ }
168
+ return url.toString();
169
+ }
170
+ buildHeaders(extraHeaders) {
171
+ return {
172
+ "Authorization": `Bearer ${this.apiKey}`,
173
+ "Content-Type": "application/json",
174
+ "Accept": "application/json",
175
+ "User-Agent": "HeyInvoice/v1 NodeSDK/1.0.0",
176
+ ...this.customHeaders,
177
+ ...extraHeaders
178
+ };
179
+ }
180
+ delay(ms) {
181
+ return new Promise((resolve) => setTimeout(resolve, ms));
182
+ }
183
+ };
184
+
185
+ // src/resources/resource.ts
186
+ var Resource = class {
187
+ client;
188
+ constructor(client) {
189
+ this.client = client;
190
+ }
191
+ };
192
+
193
+ // src/resources/invoices.ts
194
+ var Invoices = class extends Resource {
195
+ /**
196
+ * Create a new invoice draft.
197
+ */
198
+ async create(params) {
199
+ return this.client.request({
200
+ method: "POST",
201
+ path: "/v1/invoices",
202
+ body: params
203
+ });
204
+ }
205
+ /**
206
+ * Retrieve an existing invoice by ID.
207
+ */
208
+ async retrieve(id) {
209
+ return this.client.request({
210
+ method: "GET",
211
+ path: `/v1/invoices/${encodeURIComponent(id)}`
212
+ });
213
+ }
214
+ /**
215
+ * Alias for retrieve.
216
+ */
217
+ async get(id) {
218
+ return this.retrieve(id);
219
+ }
220
+ /**
221
+ * Update an existing invoice.
222
+ */
223
+ async update(id, params) {
224
+ return this.client.request({
225
+ method: "PATCH",
226
+ path: `/v1/invoices/${encodeURIComponent(id)}`,
227
+ body: params
228
+ });
229
+ }
230
+ /**
231
+ * List invoices with optional pagination and filtering.
232
+ */
233
+ async list(params) {
234
+ return this.client.request({
235
+ method: "GET",
236
+ path: "/v1/invoices",
237
+ query: params
238
+ });
239
+ }
240
+ /**
241
+ * Delete or void an invoice.
242
+ */
243
+ async del(id) {
244
+ return this.client.request({
245
+ method: "DELETE",
246
+ path: `/v1/invoices/${encodeURIComponent(id)}`
247
+ });
248
+ }
249
+ /**
250
+ * Finalize/Send a draft invoice.
251
+ */
252
+ async send(id) {
253
+ return this.client.request({
254
+ method: "POST",
255
+ path: `/v1/invoices/${encodeURIComponent(id)}/send`
256
+ });
257
+ }
258
+ /**
259
+ * Void an invoice.
260
+ */
261
+ async void(id) {
262
+ return this.client.request({
263
+ method: "POST",
264
+ path: `/v1/invoices/${encodeURIComponent(id)}/void`
265
+ });
266
+ }
267
+ };
268
+
269
+ // src/client.ts
270
+ var HeyInvoice = class {
271
+ httpClient;
272
+ invoices;
273
+ /**
274
+ * Initializes a new HeyInvoice SDK client.
275
+ *
276
+ * @param apiKeyOrConfig API Key string or full ClientConfig object
277
+ * @param options Additional client options if first parameter is an API Key string
278
+ *
279
+ * @example
280
+ * ```ts
281
+ * // String initialization
282
+ * const heyinvoice = new HeyInvoice('sk_live_xyz123');
283
+ *
284
+ * // Object initialization
285
+ * const heyinvoice = new HeyInvoice({
286
+ * apiKey: 'sk_live_xyz123',
287
+ * apiBase: 'https://api.heyinvoice.com',
288
+ * });
289
+ * ```
290
+ */
291
+ constructor(apiKeyOrConfig, options) {
292
+ let config;
293
+ if (typeof apiKeyOrConfig === "string") {
294
+ config = {
295
+ apiKey: apiKeyOrConfig,
296
+ ...options
297
+ };
298
+ } else if (apiKeyOrConfig && typeof apiKeyOrConfig === "object") {
299
+ config = apiKeyOrConfig;
300
+ } else {
301
+ throw new Error("Invalid constructor arguments: API key string or config object expected");
302
+ }
303
+ this.httpClient = new HttpClient(config);
304
+ this.invoices = new Invoices(this.httpClient);
305
+ }
306
+ };
307
+
308
+ // src/index.ts
309
+ var index_default = HeyInvoice;
310
+ // Annotate the CommonJS export names for ESM import in node:
311
+ 0 && (module.exports = {
312
+ APIError,
313
+ AuthenticationError,
314
+ ConnectionError,
315
+ HeyInvoice,
316
+ HeyInvoiceError,
317
+ InvalidRequestError,
318
+ Invoices,
319
+ NotFoundError,
320
+ Resource
321
+ });
322
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/errors/index.ts","../src/http/httpClient.ts","../src/resources/resource.ts","../src/resources/invoices.ts","../src/client.ts"],"sourcesContent":["import { HeyInvoice } from './client';\n\nexport { HeyInvoice };\nexport default HeyInvoice;\n\nexport * from './types';\nexport * from './errors';\nexport * from './resources/invoices';\nexport * from './resources/resource';\n","export interface HeyInvoiceErrorOptions {\n type?: string;\n statusCode?: number;\n code?: string;\n requestId?: string;\n raw?: unknown;\n}\n\nexport class HeyInvoiceError extends Error {\n readonly type: string;\n readonly statusCode?: number;\n readonly code?: string;\n readonly requestId?: string;\n readonly raw?: unknown;\n\n constructor(message: string, options?: HeyInvoiceErrorOptions) {\n super(message);\n this.name = this.constructor.name;\n this.type = options?.type || 'api_error';\n this.statusCode = options?.statusCode;\n this.code = options?.code;\n this.requestId = options?.requestId;\n this.raw = options?.raw;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class AuthenticationError extends HeyInvoiceError {\n constructor(message = 'Invalid API key or unauthorized request', options?: Omit<HeyInvoiceErrorOptions, 'type'>) {\n super(message, { ...options, type: 'authentication_error', statusCode: options?.statusCode || 401 });\n }\n}\n\nexport class InvalidRequestError extends HeyInvoiceError {\n constructor(message = 'Invalid request parameters', options?: Omit<HeyInvoiceErrorOptions, 'type'>) {\n super(message, { ...options, type: 'invalid_request_error', statusCode: options?.statusCode || 400 });\n }\n}\n\nexport class NotFoundError extends HeyInvoiceError {\n constructor(message = 'Resource not found', options?: Omit<HeyInvoiceErrorOptions, 'type'>) {\n super(message, { ...options, type: 'not_found_error', statusCode: options?.statusCode || 404 });\n }\n}\n\nexport class APIError extends HeyInvoiceError {\n constructor(message = 'An error occurred on HeyInvoice servers', options?: Omit<HeyInvoiceErrorOptions, 'type'>) {\n super(message, { ...options, type: 'api_error', statusCode: options?.statusCode || 500 });\n }\n}\n\nexport class ConnectionError extends HeyInvoiceError {\n constructor(message = 'Failed to connect to HeyInvoice API', options?: Omit<HeyInvoiceErrorOptions, 'type'>) {\n super(message, { ...options, type: 'connection_error' });\n }\n}\n","import { ClientConfig } from '../types';\nimport {\n HeyInvoiceError,\n AuthenticationError,\n InvalidRequestError,\n NotFoundError,\n APIError,\n ConnectionError,\n} from '../errors';\n\nexport interface RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n path: string;\n query?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n headers?: Record<string, string>;\n}\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly apiBase: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n private readonly customHeaders: Record<string, string>;\n\n constructor(config: ClientConfig) {\n if (!config.apiKey || typeof config.apiKey !== 'string' || !config.apiKey.trim()) {\n throw new AuthenticationError('API Key is required to instantiate HeyInvoice SDK');\n }\n this.apiKey = config.apiKey.trim();\n this.apiBase = (config.apiBase || 'https://api.heyinvoice.com').replace(/\\/+$/, '');\n this.timeout = config.timeout ?? 30000;\n this.maxRetries = config.maxRetries ?? 2;\n this.customHeaders = config.headers || {};\n }\n\n async request<T>(options: RequestOptions): Promise<T> {\n const url = this.buildUrl(options.path, options.query);\n const headers = this.buildHeaders(options.headers);\n\n let attempt = 0;\n while (true) {\n attempt++;\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(url, {\n method: options.method,\n headers,\n body: options.body ? JSON.stringify(options.body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const requestId = response.headers.get('x-request-id') || undefined;\n let responseData: any;\n const contentType = response.headers.get('content-type') || '';\n\n if (contentType.includes('application/json')) {\n responseData = await response.json();\n } else {\n responseData = await response.text();\n }\n\n if (response.ok) {\n return responseData as T;\n }\n\n const errorMessage =\n (typeof responseData === 'object' && responseData?.message) ||\n (typeof responseData === 'string' && responseData) ||\n `HTTP Error ${response.status} ${response.statusText}`;\n\n const code = typeof responseData === 'object' ? responseData?.code : undefined;\n\n if (response.status === 401 || response.status === 403) {\n throw new AuthenticationError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });\n }\n if (response.status === 404) {\n throw new NotFoundError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });\n }\n if (response.status === 400 || response.status === 422) {\n throw new InvalidRequestError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });\n }\n\n if (response.status >= 500) {\n if (attempt <= this.maxRetries) {\n await this.delay(attempt * 500);\n continue;\n }\n throw new APIError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });\n }\n\n throw new HeyInvoiceError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });\n } catch (err: any) {\n if (err instanceof HeyInvoiceError) {\n throw err;\n }\n\n if (err.name === 'AbortError') {\n throw new ConnectionError(`Request timed out after ${this.timeout}ms`);\n }\n\n if (attempt <= this.maxRetries && err.name !== 'AbortError') {\n await this.delay(attempt * 500);\n continue;\n }\n\n throw new ConnectionError(err.message || 'Network communication failure', { raw: err });\n }\n }\n }\n\n private buildUrl(path: string, query?: Record<string, string | number | boolean | undefined>): string {\n const formattedPath = path.startsWith('/') ? path : `/${path}`;\n const url = new URL(`${this.apiBase}${formattedPath}`);\n\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n });\n }\n\n return url.toString();\n }\n\n private buildHeaders(extraHeaders?: Record<string, string>): Record<string, string> {\n return {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'User-Agent': 'HeyInvoice/v1 NodeSDK/1.0.0',\n ...this.customHeaders,\n ...extraHeaders,\n };\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { HttpClient } from '../http/httpClient';\n\nexport abstract class Resource {\n protected readonly client: HttpClient;\n\n constructor(client: HttpClient) {\n this.client = client;\n }\n}\n","import { Resource } from './resource';\nimport {\n Invoice,\n CreateInvoiceParams,\n UpdateInvoiceParams,\n ListInvoicesParams,\n PaginatedList,\n DeletedResource,\n} from '../types';\n\nexport class Invoices extends Resource {\n /**\n * Create a new invoice draft.\n */\n async create(params: CreateInvoiceParams): Promise<Invoice> {\n return this.client.request<Invoice>({\n method: 'POST',\n path: '/v1/invoices',\n body: params,\n });\n }\n\n /**\n * Retrieve an existing invoice by ID.\n */\n async retrieve(id: string): Promise<Invoice> {\n return this.client.request<Invoice>({\n method: 'GET',\n path: `/v1/invoices/${encodeURIComponent(id)}`,\n });\n }\n\n /**\n * Alias for retrieve.\n */\n async get(id: string): Promise<Invoice> {\n return this.retrieve(id);\n }\n\n /**\n * Update an existing invoice.\n */\n async update(id: string, params: UpdateInvoiceParams): Promise<Invoice> {\n return this.client.request<Invoice>({\n method: 'PATCH',\n path: `/v1/invoices/${encodeURIComponent(id)}`,\n body: params,\n });\n }\n\n /**\n * List invoices with optional pagination and filtering.\n */\n async list(params?: ListInvoicesParams): Promise<PaginatedList<Invoice>> {\n return this.client.request<PaginatedList<Invoice>>({\n method: 'GET',\n path: '/v1/invoices',\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Delete or void an invoice.\n */\n async del(id: string): Promise<DeletedResource> {\n return this.client.request<DeletedResource>({\n method: 'DELETE',\n path: `/v1/invoices/${encodeURIComponent(id)}`,\n });\n }\n\n /**\n * Finalize/Send a draft invoice.\n */\n async send(id: string): Promise<Invoice> {\n return this.client.request<Invoice>({\n method: 'POST',\n path: `/v1/invoices/${encodeURIComponent(id)}/send`,\n });\n }\n\n /**\n * Void an invoice.\n */\n async void(id: string): Promise<Invoice> {\n return this.client.request<Invoice>({\n method: 'POST',\n path: `/v1/invoices/${encodeURIComponent(id)}/void`,\n });\n }\n}\n","import { ClientConfig } from './types';\nimport { HttpClient } from './http/httpClient';\nimport { Invoices } from './resources/invoices';\n\nexport class HeyInvoice {\n private readonly httpClient: HttpClient;\n readonly invoices: Invoices;\n\n /**\n * Initializes a new HeyInvoice SDK client.\n * \n * @param apiKeyOrConfig API Key string or full ClientConfig object\n * @param options Additional client options if first parameter is an API Key string\n * \n * @example\n * ```ts\n * // String initialization\n * const heyinvoice = new HeyInvoice('sk_live_xyz123');\n * \n * // Object initialization\n * const heyinvoice = new HeyInvoice({\n * apiKey: 'sk_live_xyz123',\n * apiBase: 'https://api.heyinvoice.com',\n * });\n * ```\n */\n constructor(apiKeyOrConfig: string | ClientConfig, options?: Omit<ClientConfig, 'apiKey'>) {\n let config: ClientConfig;\n\n if (typeof apiKeyOrConfig === 'string') {\n config = {\n apiKey: apiKeyOrConfig,\n ...options,\n };\n } else if (apiKeyOrConfig && typeof apiKeyOrConfig === 'object') {\n config = apiKeyOrConfig;\n } else {\n throw new Error('Invalid constructor arguments: API key string or config object expected');\n }\n\n this.httpClient = new HttpClient(config);\n this.invoices = new Invoices(this.httpClient);\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,287 @@
1
+ // src/errors/index.ts
2
+ var HeyInvoiceError = class extends Error {
3
+ type;
4
+ statusCode;
5
+ code;
6
+ requestId;
7
+ raw;
8
+ constructor(message, options) {
9
+ super(message);
10
+ this.name = this.constructor.name;
11
+ this.type = options?.type || "api_error";
12
+ this.statusCode = options?.statusCode;
13
+ this.code = options?.code;
14
+ this.requestId = options?.requestId;
15
+ this.raw = options?.raw;
16
+ Object.setPrototypeOf(this, new.target.prototype);
17
+ }
18
+ };
19
+ var AuthenticationError = class extends HeyInvoiceError {
20
+ constructor(message = "Invalid API key or unauthorized request", options) {
21
+ super(message, { ...options, type: "authentication_error", statusCode: options?.statusCode || 401 });
22
+ }
23
+ };
24
+ var InvalidRequestError = class extends HeyInvoiceError {
25
+ constructor(message = "Invalid request parameters", options) {
26
+ super(message, { ...options, type: "invalid_request_error", statusCode: options?.statusCode || 400 });
27
+ }
28
+ };
29
+ var NotFoundError = class extends HeyInvoiceError {
30
+ constructor(message = "Resource not found", options) {
31
+ super(message, { ...options, type: "not_found_error", statusCode: options?.statusCode || 404 });
32
+ }
33
+ };
34
+ var APIError = class extends HeyInvoiceError {
35
+ constructor(message = "An error occurred on HeyInvoice servers", options) {
36
+ super(message, { ...options, type: "api_error", statusCode: options?.statusCode || 500 });
37
+ }
38
+ };
39
+ var ConnectionError = class extends HeyInvoiceError {
40
+ constructor(message = "Failed to connect to HeyInvoice API", options) {
41
+ super(message, { ...options, type: "connection_error" });
42
+ }
43
+ };
44
+
45
+ // src/http/httpClient.ts
46
+ var HttpClient = class {
47
+ apiKey;
48
+ apiBase;
49
+ timeout;
50
+ maxRetries;
51
+ customHeaders;
52
+ constructor(config) {
53
+ if (!config.apiKey || typeof config.apiKey !== "string" || !config.apiKey.trim()) {
54
+ throw new AuthenticationError("API Key is required to instantiate HeyInvoice SDK");
55
+ }
56
+ this.apiKey = config.apiKey.trim();
57
+ this.apiBase = (config.apiBase || "https://api.heyinvoice.com").replace(/\/+$/, "");
58
+ this.timeout = config.timeout ?? 3e4;
59
+ this.maxRetries = config.maxRetries ?? 2;
60
+ this.customHeaders = config.headers || {};
61
+ }
62
+ async request(options) {
63
+ const url = this.buildUrl(options.path, options.query);
64
+ const headers = this.buildHeaders(options.headers);
65
+ let attempt = 0;
66
+ while (true) {
67
+ attempt++;
68
+ try {
69
+ const controller = new AbortController();
70
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
71
+ const response = await fetch(url, {
72
+ method: options.method,
73
+ headers,
74
+ body: options.body ? JSON.stringify(options.body) : void 0,
75
+ signal: controller.signal
76
+ });
77
+ clearTimeout(timeoutId);
78
+ const requestId = response.headers.get("x-request-id") || void 0;
79
+ let responseData;
80
+ const contentType = response.headers.get("content-type") || "";
81
+ if (contentType.includes("application/json")) {
82
+ responseData = await response.json();
83
+ } else {
84
+ responseData = await response.text();
85
+ }
86
+ if (response.ok) {
87
+ return responseData;
88
+ }
89
+ const errorMessage = typeof responseData === "object" && responseData?.message || typeof responseData === "string" && responseData || `HTTP Error ${response.status} ${response.statusText}`;
90
+ const code = typeof responseData === "object" ? responseData?.code : void 0;
91
+ if (response.status === 401 || response.status === 403) {
92
+ throw new AuthenticationError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });
93
+ }
94
+ if (response.status === 404) {
95
+ throw new NotFoundError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });
96
+ }
97
+ if (response.status === 400 || response.status === 422) {
98
+ throw new InvalidRequestError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });
99
+ }
100
+ if (response.status >= 500) {
101
+ if (attempt <= this.maxRetries) {
102
+ await this.delay(attempt * 500);
103
+ continue;
104
+ }
105
+ throw new APIError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });
106
+ }
107
+ throw new HeyInvoiceError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });
108
+ } catch (err) {
109
+ if (err instanceof HeyInvoiceError) {
110
+ throw err;
111
+ }
112
+ if (err.name === "AbortError") {
113
+ throw new ConnectionError(`Request timed out after ${this.timeout}ms`);
114
+ }
115
+ if (attempt <= this.maxRetries && err.name !== "AbortError") {
116
+ await this.delay(attempt * 500);
117
+ continue;
118
+ }
119
+ throw new ConnectionError(err.message || "Network communication failure", { raw: err });
120
+ }
121
+ }
122
+ }
123
+ buildUrl(path, query) {
124
+ const formattedPath = path.startsWith("/") ? path : `/${path}`;
125
+ const url = new URL(`${this.apiBase}${formattedPath}`);
126
+ if (query) {
127
+ Object.entries(query).forEach(([key, value]) => {
128
+ if (value !== void 0 && value !== null) {
129
+ url.searchParams.append(key, String(value));
130
+ }
131
+ });
132
+ }
133
+ return url.toString();
134
+ }
135
+ buildHeaders(extraHeaders) {
136
+ return {
137
+ "Authorization": `Bearer ${this.apiKey}`,
138
+ "Content-Type": "application/json",
139
+ "Accept": "application/json",
140
+ "User-Agent": "HeyInvoice/v1 NodeSDK/1.0.0",
141
+ ...this.customHeaders,
142
+ ...extraHeaders
143
+ };
144
+ }
145
+ delay(ms) {
146
+ return new Promise((resolve) => setTimeout(resolve, ms));
147
+ }
148
+ };
149
+
150
+ // src/resources/resource.ts
151
+ var Resource = class {
152
+ client;
153
+ constructor(client) {
154
+ this.client = client;
155
+ }
156
+ };
157
+
158
+ // src/resources/invoices.ts
159
+ var Invoices = class extends Resource {
160
+ /**
161
+ * Create a new invoice draft.
162
+ */
163
+ async create(params) {
164
+ return this.client.request({
165
+ method: "POST",
166
+ path: "/v1/invoices",
167
+ body: params
168
+ });
169
+ }
170
+ /**
171
+ * Retrieve an existing invoice by ID.
172
+ */
173
+ async retrieve(id) {
174
+ return this.client.request({
175
+ method: "GET",
176
+ path: `/v1/invoices/${encodeURIComponent(id)}`
177
+ });
178
+ }
179
+ /**
180
+ * Alias for retrieve.
181
+ */
182
+ async get(id) {
183
+ return this.retrieve(id);
184
+ }
185
+ /**
186
+ * Update an existing invoice.
187
+ */
188
+ async update(id, params) {
189
+ return this.client.request({
190
+ method: "PATCH",
191
+ path: `/v1/invoices/${encodeURIComponent(id)}`,
192
+ body: params
193
+ });
194
+ }
195
+ /**
196
+ * List invoices with optional pagination and filtering.
197
+ */
198
+ async list(params) {
199
+ return this.client.request({
200
+ method: "GET",
201
+ path: "/v1/invoices",
202
+ query: params
203
+ });
204
+ }
205
+ /**
206
+ * Delete or void an invoice.
207
+ */
208
+ async del(id) {
209
+ return this.client.request({
210
+ method: "DELETE",
211
+ path: `/v1/invoices/${encodeURIComponent(id)}`
212
+ });
213
+ }
214
+ /**
215
+ * Finalize/Send a draft invoice.
216
+ */
217
+ async send(id) {
218
+ return this.client.request({
219
+ method: "POST",
220
+ path: `/v1/invoices/${encodeURIComponent(id)}/send`
221
+ });
222
+ }
223
+ /**
224
+ * Void an invoice.
225
+ */
226
+ async void(id) {
227
+ return this.client.request({
228
+ method: "POST",
229
+ path: `/v1/invoices/${encodeURIComponent(id)}/void`
230
+ });
231
+ }
232
+ };
233
+
234
+ // src/client.ts
235
+ var HeyInvoice = class {
236
+ httpClient;
237
+ invoices;
238
+ /**
239
+ * Initializes a new HeyInvoice SDK client.
240
+ *
241
+ * @param apiKeyOrConfig API Key string or full ClientConfig object
242
+ * @param options Additional client options if first parameter is an API Key string
243
+ *
244
+ * @example
245
+ * ```ts
246
+ * // String initialization
247
+ * const heyinvoice = new HeyInvoice('sk_live_xyz123');
248
+ *
249
+ * // Object initialization
250
+ * const heyinvoice = new HeyInvoice({
251
+ * apiKey: 'sk_live_xyz123',
252
+ * apiBase: 'https://api.heyinvoice.com',
253
+ * });
254
+ * ```
255
+ */
256
+ constructor(apiKeyOrConfig, options) {
257
+ let config;
258
+ if (typeof apiKeyOrConfig === "string") {
259
+ config = {
260
+ apiKey: apiKeyOrConfig,
261
+ ...options
262
+ };
263
+ } else if (apiKeyOrConfig && typeof apiKeyOrConfig === "object") {
264
+ config = apiKeyOrConfig;
265
+ } else {
266
+ throw new Error("Invalid constructor arguments: API key string or config object expected");
267
+ }
268
+ this.httpClient = new HttpClient(config);
269
+ this.invoices = new Invoices(this.httpClient);
270
+ }
271
+ };
272
+
273
+ // src/index.ts
274
+ var index_default = HeyInvoice;
275
+ export {
276
+ APIError,
277
+ AuthenticationError,
278
+ ConnectionError,
279
+ HeyInvoice,
280
+ HeyInvoiceError,
281
+ InvalidRequestError,
282
+ Invoices,
283
+ NotFoundError,
284
+ Resource,
285
+ index_default as default
286
+ };
287
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors/index.ts","../src/http/httpClient.ts","../src/resources/resource.ts","../src/resources/invoices.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["export interface HeyInvoiceErrorOptions {\n type?: string;\n statusCode?: number;\n code?: string;\n requestId?: string;\n raw?: unknown;\n}\n\nexport class HeyInvoiceError extends Error {\n readonly type: string;\n readonly statusCode?: number;\n readonly code?: string;\n readonly requestId?: string;\n readonly raw?: unknown;\n\n constructor(message: string, options?: HeyInvoiceErrorOptions) {\n super(message);\n this.name = this.constructor.name;\n this.type = options?.type || 'api_error';\n this.statusCode = options?.statusCode;\n this.code = options?.code;\n this.requestId = options?.requestId;\n this.raw = options?.raw;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class AuthenticationError extends HeyInvoiceError {\n constructor(message = 'Invalid API key or unauthorized request', options?: Omit<HeyInvoiceErrorOptions, 'type'>) {\n super(message, { ...options, type: 'authentication_error', statusCode: options?.statusCode || 401 });\n }\n}\n\nexport class InvalidRequestError extends HeyInvoiceError {\n constructor(message = 'Invalid request parameters', options?: Omit<HeyInvoiceErrorOptions, 'type'>) {\n super(message, { ...options, type: 'invalid_request_error', statusCode: options?.statusCode || 400 });\n }\n}\n\nexport class NotFoundError extends HeyInvoiceError {\n constructor(message = 'Resource not found', options?: Omit<HeyInvoiceErrorOptions, 'type'>) {\n super(message, { ...options, type: 'not_found_error', statusCode: options?.statusCode || 404 });\n }\n}\n\nexport class APIError extends HeyInvoiceError {\n constructor(message = 'An error occurred on HeyInvoice servers', options?: Omit<HeyInvoiceErrorOptions, 'type'>) {\n super(message, { ...options, type: 'api_error', statusCode: options?.statusCode || 500 });\n }\n}\n\nexport class ConnectionError extends HeyInvoiceError {\n constructor(message = 'Failed to connect to HeyInvoice API', options?: Omit<HeyInvoiceErrorOptions, 'type'>) {\n super(message, { ...options, type: 'connection_error' });\n }\n}\n","import { ClientConfig } from '../types';\nimport {\n HeyInvoiceError,\n AuthenticationError,\n InvalidRequestError,\n NotFoundError,\n APIError,\n ConnectionError,\n} from '../errors';\n\nexport interface RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n path: string;\n query?: Record<string, string | number | boolean | undefined>;\n body?: unknown;\n headers?: Record<string, string>;\n}\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly apiBase: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n private readonly customHeaders: Record<string, string>;\n\n constructor(config: ClientConfig) {\n if (!config.apiKey || typeof config.apiKey !== 'string' || !config.apiKey.trim()) {\n throw new AuthenticationError('API Key is required to instantiate HeyInvoice SDK');\n }\n this.apiKey = config.apiKey.trim();\n this.apiBase = (config.apiBase || 'https://api.heyinvoice.com').replace(/\\/+$/, '');\n this.timeout = config.timeout ?? 30000;\n this.maxRetries = config.maxRetries ?? 2;\n this.customHeaders = config.headers || {};\n }\n\n async request<T>(options: RequestOptions): Promise<T> {\n const url = this.buildUrl(options.path, options.query);\n const headers = this.buildHeaders(options.headers);\n\n let attempt = 0;\n while (true) {\n attempt++;\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(url, {\n method: options.method,\n headers,\n body: options.body ? JSON.stringify(options.body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const requestId = response.headers.get('x-request-id') || undefined;\n let responseData: any;\n const contentType = response.headers.get('content-type') || '';\n\n if (contentType.includes('application/json')) {\n responseData = await response.json();\n } else {\n responseData = await response.text();\n }\n\n if (response.ok) {\n return responseData as T;\n }\n\n const errorMessage =\n (typeof responseData === 'object' && responseData?.message) ||\n (typeof responseData === 'string' && responseData) ||\n `HTTP Error ${response.status} ${response.statusText}`;\n\n const code = typeof responseData === 'object' ? responseData?.code : undefined;\n\n if (response.status === 401 || response.status === 403) {\n throw new AuthenticationError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });\n }\n if (response.status === 404) {\n throw new NotFoundError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });\n }\n if (response.status === 400 || response.status === 422) {\n throw new InvalidRequestError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });\n }\n\n if (response.status >= 500) {\n if (attempt <= this.maxRetries) {\n await this.delay(attempt * 500);\n continue;\n }\n throw new APIError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });\n }\n\n throw new HeyInvoiceError(errorMessage, { statusCode: response.status, code, requestId, raw: responseData });\n } catch (err: any) {\n if (err instanceof HeyInvoiceError) {\n throw err;\n }\n\n if (err.name === 'AbortError') {\n throw new ConnectionError(`Request timed out after ${this.timeout}ms`);\n }\n\n if (attempt <= this.maxRetries && err.name !== 'AbortError') {\n await this.delay(attempt * 500);\n continue;\n }\n\n throw new ConnectionError(err.message || 'Network communication failure', { raw: err });\n }\n }\n }\n\n private buildUrl(path: string, query?: Record<string, string | number | boolean | undefined>): string {\n const formattedPath = path.startsWith('/') ? path : `/${path}`;\n const url = new URL(`${this.apiBase}${formattedPath}`);\n\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n });\n }\n\n return url.toString();\n }\n\n private buildHeaders(extraHeaders?: Record<string, string>): Record<string, string> {\n return {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'User-Agent': 'HeyInvoice/v1 NodeSDK/1.0.0',\n ...this.customHeaders,\n ...extraHeaders,\n };\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { HttpClient } from '../http/httpClient';\n\nexport abstract class Resource {\n protected readonly client: HttpClient;\n\n constructor(client: HttpClient) {\n this.client = client;\n }\n}\n","import { Resource } from './resource';\nimport {\n Invoice,\n CreateInvoiceParams,\n UpdateInvoiceParams,\n ListInvoicesParams,\n PaginatedList,\n DeletedResource,\n} from '../types';\n\nexport class Invoices extends Resource {\n /**\n * Create a new invoice draft.\n */\n async create(params: CreateInvoiceParams): Promise<Invoice> {\n return this.client.request<Invoice>({\n method: 'POST',\n path: '/v1/invoices',\n body: params,\n });\n }\n\n /**\n * Retrieve an existing invoice by ID.\n */\n async retrieve(id: string): Promise<Invoice> {\n return this.client.request<Invoice>({\n method: 'GET',\n path: `/v1/invoices/${encodeURIComponent(id)}`,\n });\n }\n\n /**\n * Alias for retrieve.\n */\n async get(id: string): Promise<Invoice> {\n return this.retrieve(id);\n }\n\n /**\n * Update an existing invoice.\n */\n async update(id: string, params: UpdateInvoiceParams): Promise<Invoice> {\n return this.client.request<Invoice>({\n method: 'PATCH',\n path: `/v1/invoices/${encodeURIComponent(id)}`,\n body: params,\n });\n }\n\n /**\n * List invoices with optional pagination and filtering.\n */\n async list(params?: ListInvoicesParams): Promise<PaginatedList<Invoice>> {\n return this.client.request<PaginatedList<Invoice>>({\n method: 'GET',\n path: '/v1/invoices',\n query: params as Record<string, string | number | boolean | undefined>,\n });\n }\n\n /**\n * Delete or void an invoice.\n */\n async del(id: string): Promise<DeletedResource> {\n return this.client.request<DeletedResource>({\n method: 'DELETE',\n path: `/v1/invoices/${encodeURIComponent(id)}`,\n });\n }\n\n /**\n * Finalize/Send a draft invoice.\n */\n async send(id: string): Promise<Invoice> {\n return this.client.request<Invoice>({\n method: 'POST',\n path: `/v1/invoices/${encodeURIComponent(id)}/send`,\n });\n }\n\n /**\n * Void an invoice.\n */\n async void(id: string): Promise<Invoice> {\n return this.client.request<Invoice>({\n method: 'POST',\n path: `/v1/invoices/${encodeURIComponent(id)}/void`,\n });\n }\n}\n","import { ClientConfig } from './types';\nimport { HttpClient } from './http/httpClient';\nimport { Invoices } from './resources/invoices';\n\nexport class HeyInvoice {\n private readonly httpClient: HttpClient;\n readonly invoices: Invoices;\n\n /**\n * Initializes a new HeyInvoice SDK client.\n * \n * @param apiKeyOrConfig API Key string or full ClientConfig object\n * @param options Additional client options if first parameter is an API Key string\n * \n * @example\n * ```ts\n * // String initialization\n * const heyinvoice = new HeyInvoice('sk_live_xyz123');\n * \n * // Object initialization\n * const heyinvoice = new HeyInvoice({\n * apiKey: 'sk_live_xyz123',\n * apiBase: 'https://api.heyinvoice.com',\n * });\n * ```\n */\n constructor(apiKeyOrConfig: string | ClientConfig, options?: Omit<ClientConfig, 'apiKey'>) {\n let config: ClientConfig;\n\n if (typeof apiKeyOrConfig === 'string') {\n config = {\n apiKey: apiKeyOrConfig,\n ...options,\n };\n } else if (apiKeyOrConfig && typeof apiKeyOrConfig === 'object') {\n config = apiKeyOrConfig;\n } else {\n throw new Error('Invalid constructor arguments: API key string or config object expected');\n }\n\n this.httpClient = new HttpClient(config);\n this.invoices = new Invoices(this.httpClient);\n }\n}\n","import { HeyInvoice } from './client';\n\nexport { HeyInvoice };\nexport default HeyInvoice;\n\nexport * from './types';\nexport * from './errors';\nexport * from './resources/invoices';\nexport * from './resources/resource';\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@heyinvoice/sdk",
3
+ "version": "1.0.0",
4
+ "description": "Official Node.js and TypeScript SDK for HeyInvoice API",
5
+ "author": "HeyInvoice",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "heyinvoice",
9
+ "invoice",
10
+ "peppol",
11
+ "sdk",
12
+ "stripe-like",
13
+ "api-client"
14
+ ],
15
+ "main": "./dist/index.js",
16
+ "module": "./dist/index.mjs",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "import": {
21
+ "types": "./dist/index.d.ts",
22
+ "default": "./dist/index.mjs"
23
+ },
24
+ "require": {
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
+ }
28
+ }
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "README.md"
33
+ ],
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "scripts": {
38
+ "build": "npx --cache /tmp/npm-cache -p tsup -p typescript@5.7.3 tsup",
39
+ "dev": "npx --cache /tmp/npm-cache -p tsup -p typescript@5.7.3 tsup --watch",
40
+ "check-types": "tsc --noEmit",
41
+ "prepublishOnly": "npm run build"
42
+ },
43
+ "devDependencies": {
44
+ "@repo/typescript-config": "workspace:*",
45
+ "tsup": "^8.3.6",
46
+ "typescript": "5.9.2"
47
+ },
48
+ "engines": {
49
+ "node": ">=18.0.0"
50
+ }
51
+ }