rutter-ts 0.1.0 → 0.2.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,188 @@
1
+ # rutter-ts
2
+
3
+ TypeScript SDK for the [Rutter API](https://docs.rutter.com). Includes a lightweight HTTP client, typed API wrappers with Zod response validation, and auto-generated types from the Rutter OpenAPI spec.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install rutter-ts zod
9
+ # or
10
+ bun add rutter-ts zod
11
+ ```
12
+
13
+ `zod` is a peer dependency (`>=3.23.0 || >=4.0.0`).
14
+
15
+ ## Entry Points
16
+
17
+ The package is split into three entry points to support tree-shaking and bundle-size-sensitive environments (e.g. Convex, Cloudflare Workers):
18
+
19
+ | Entry | What | Size |
20
+ |---|---|---|
21
+ | `rutter-ts` | Client, errors, types, constants | ~3KB |
22
+ | `rutter-ts/api` | `RutterConnectionsApi`, `RutterAccountingApi` | ~5KB + generated |
23
+ | `rutter-ts/generated` | All generated Zod validators + TypeScript types | ~500KB |
24
+
25
+ If you're in a serverless environment with strict bundle limits, import the lightweight `rutter-ts` entry for queries/mutations and only import `rutter-ts/api` in contexts that allow larger bundles (e.g. Node.js actions).
26
+
27
+ ## Quick Start
28
+
29
+ ```typescript
30
+ import { RutterClient, RUTTER_SANDBOX_BASE_URL } from 'rutter-ts'
31
+ import { RutterConnectionsApi, RutterAccountingApi } from 'rutter-ts/api'
32
+
33
+ const client = new RutterClient(
34
+ RUTTER_SANDBOX_BASE_URL,
35
+ process.env.RUTTER_CLIENT_ID,
36
+ process.env.RUTTER_CLIENT_SECRET,
37
+ )
38
+
39
+ const connections = new RutterConnectionsApi(client)
40
+ const accounting = new RutterAccountingApi(client)
41
+ ```
42
+
43
+ ## Connections API
44
+
45
+ ```typescript
46
+ // Create a connection
47
+ const { connection } = await connections.create({ platform: 'QUICKBOOKS' })
48
+ console.log(connection.link_url) // Rutter Link URL for the user
49
+
50
+ // Exchange a public token for an access token
51
+ const { access_token } = await connections.exchangeToken({
52
+ public_token: 'pt_...',
53
+ })
54
+
55
+ // List all connections
56
+ const { connections: list } = await connections.list()
57
+
58
+ // Get connection details by access token
59
+ const { connection: details } = await connections.get(access_token)
60
+
61
+ // Delete a connection
62
+ await connections.delete(access_token)
63
+ ```
64
+
65
+ ## Accounting API
66
+
67
+ ```typescript
68
+ // Get company info
69
+ const { company_info } = await accounting.getCompanyInfo(accessToken)
70
+
71
+ // List accounts (with pagination)
72
+ const { accounts, next_cursor } = await accounting.listAccounts(accessToken, {
73
+ cursor: 'cur_...',
74
+ })
75
+
76
+ // Get a single account
77
+ const { account } = await accounting.getAccount(accessToken, accountId)
78
+
79
+ // List invoices
80
+ const { invoices } = await accounting.listInvoices(accessToken)
81
+
82
+ // Get a single invoice
83
+ const { invoice } = await accounting.getInvoice(accessToken, invoiceId)
84
+
85
+ // Create an invoice (with idempotency key)
86
+ const { invoice: created } = await accounting.createInvoice(
87
+ accessToken,
88
+ {
89
+ customer_id: 'cust_...',
90
+ issue_date: '2024-07-01',
91
+ currency_code: 'USD',
92
+ line_items: [{ description: 'Consulting', total_amount: 5000 }],
93
+ },
94
+ 'idem_unique_key',
95
+ )
96
+ ```
97
+
98
+ ## Error Handling
99
+
100
+ All API methods throw typed errors:
101
+
102
+ ```typescript
103
+ import { RutterError, RutterSchemaMismatchError } from 'rutter-ts'
104
+
105
+ try {
106
+ await connections.create({ platform: 'QUICKBOOKS' })
107
+ } catch (e) {
108
+ if (e instanceof RutterError) {
109
+ console.error(e.status) // HTTP status code
110
+ console.error(e.errorType) // e.g. 'AUTHENTICATION_ERROR'
111
+ console.error(e.errorCode) // e.g. 'invalid_credentials'
112
+ console.error(e.metadata) // Optional error metadata
113
+
114
+ // Helpers
115
+ e.isRateLimited // true for 429 (Rutter) or 452 (platform)
116
+ e.isUserActionable // true for 400, 409, 410, 450
117
+ e.humanReadableMessage // metadata.human_readable ?? message
118
+ }
119
+
120
+ if (e instanceof RutterSchemaMismatchError) {
121
+ console.error(e.endpoint) // Which endpoint had the schema mismatch
122
+ }
123
+ }
124
+ ```
125
+
126
+ ## Using Generated Types
127
+
128
+ Import Zod validators and TypeScript types directly:
129
+
130
+ ```typescript
131
+ import { zPlatform, zConnectionResponse } from 'rutter-ts/generated'
132
+ import type { Invoice, Account, CompanyInfo20240430 } from 'rutter-ts/generated'
133
+ ```
134
+
135
+ ## Low-Level Client
136
+
137
+ Use `RutterClient` directly for endpoints not yet wrapped by the API classes:
138
+
139
+ ```typescript
140
+ import { RutterClient, RUTTER_PRODUCTION_BASE_URL } from 'rutter-ts'
141
+
142
+ const client = new RutterClient(
143
+ RUTTER_PRODUCTION_BASE_URL,
144
+ clientId,
145
+ clientSecret,
146
+ )
147
+
148
+ // GET with query params
149
+ const data = await client.get('/accounting/bills', {
150
+ access_token: 'at_...',
151
+ cursor: 'cur_...',
152
+ })
153
+
154
+ // POST with body and idempotency key
155
+ const result = await client.post(
156
+ '/accounting/invoices?access_token=at_...',
157
+ { customer_id: 'cust_1', line_items: [] },
158
+ { idempotencyKey: 'unique_key' },
159
+ )
160
+
161
+ // PATCH and DELETE
162
+ await client.patch('/some/endpoint', { field: 'value' })
163
+ await client.delete('/connections', { access_token: 'at_...' })
164
+ ```
165
+
166
+ ## Constants
167
+
168
+ ```typescript
169
+ import {
170
+ RUTTER_SANDBOX_BASE_URL, // https://sandbox.rutterapi.com/versioned
171
+ RUTTER_PRODUCTION_BASE_URL, // https://production.rutterapi.com/versioned
172
+ RUTTER_API_VERSION, // 2024-08-31
173
+ } from 'rutter-ts'
174
+ ```
175
+
176
+ ## Regenerating Types
177
+
178
+ The generated types are built from the Rutter OpenAPI spec:
179
+
180
+ ```bash
181
+ bun run generate
182
+ ```
183
+
184
+ This runs `@hey-api/openapi-ts` against `https://docs.rutter.com/rest/2024-08-31/spec` and applies a post-generation fixup script.
185
+
186
+ ## License
187
+
188
+ MIT
package/dist/api.cjs ADDED
@@ -0,0 +1,175 @@
1
+ 'use strict';
2
+
3
+ var chunkLPP3MIOV_cjs = require('./chunk-LPP3MIOV.cjs');
4
+ var chunkJCJXW7AE_cjs = require('./chunk-JCJXW7AE.cjs');
5
+ var z2 = require('zod');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ var z2__default = /*#__PURE__*/_interopDefault(z2);
10
+
11
+ var RutterConnectionsApi = class {
12
+ constructor(client) {
13
+ this.client = client;
14
+ }
15
+ async create(params) {
16
+ const endpoint = "/connections";
17
+ const response = await this.client.post(endpoint, params);
18
+ const result = chunkJCJXW7AE_cjs.zConnectionResponse.safeParse(response);
19
+ if (!result.success) {
20
+ throw new chunkLPP3MIOV_cjs.RutterSchemaMismatchError(
21
+ endpoint,
22
+ z2__default.default.prettifyError(result.error)
23
+ );
24
+ }
25
+ return result.data;
26
+ }
27
+ async list() {
28
+ const endpoint = "/connections";
29
+ const response = await this.client.get(endpoint);
30
+ const result = chunkJCJXW7AE_cjs.zListConnectionsResponse.safeParse(response);
31
+ if (!result.success) {
32
+ throw new chunkLPP3MIOV_cjs.RutterSchemaMismatchError(
33
+ endpoint,
34
+ z2__default.default.prettifyError(result.error)
35
+ );
36
+ }
37
+ return result.data;
38
+ }
39
+ async get(accessToken) {
40
+ const endpoint = "/connections";
41
+ const response = await this.client.get(endpoint, {
42
+ access_token: accessToken
43
+ });
44
+ const result = chunkJCJXW7AE_cjs.zGetAccessTokenConnectionResponse.safeParse(response);
45
+ if (!result.success) {
46
+ throw new chunkLPP3MIOV_cjs.RutterSchemaMismatchError(
47
+ endpoint,
48
+ z2__default.default.prettifyError(result.error)
49
+ );
50
+ }
51
+ return result.data;
52
+ }
53
+ async exchangeToken(params) {
54
+ const endpoint = "/item/public_token/exchange";
55
+ const response = await this.client.post(endpoint, params);
56
+ const result = chunkJCJXW7AE_cjs.zExchangeTokenResponse.safeParse(response);
57
+ if (!result.success) {
58
+ throw new chunkLPP3MIOV_cjs.RutterSchemaMismatchError(
59
+ endpoint,
60
+ z2__default.default.prettifyError(result.error)
61
+ );
62
+ }
63
+ return result.data;
64
+ }
65
+ async delete(accessToken) {
66
+ const endpoint = "/connections";
67
+ const response = await this.client.delete(endpoint, {
68
+ access_token: accessToken
69
+ });
70
+ const result = chunkJCJXW7AE_cjs.zDeleteConnectionResponse.safeParse(response);
71
+ if (!result.success) {
72
+ throw new chunkLPP3MIOV_cjs.RutterSchemaMismatchError(
73
+ endpoint,
74
+ z2__default.default.prettifyError(result.error)
75
+ );
76
+ }
77
+ return result.data;
78
+ }
79
+ };
80
+ var RutterAccountingApi = class {
81
+ constructor(client) {
82
+ this.client = client;
83
+ }
84
+ async getCompanyInfo(accessToken) {
85
+ const endpoint = "/accounting/company_info";
86
+ const response = await this.client.get(endpoint, {
87
+ access_token: accessToken
88
+ });
89
+ const result = chunkJCJXW7AE_cjs.zCompanyInfo20240430ResponseWithConnection.safeParse(response);
90
+ if (!result.success) {
91
+ throw new chunkLPP3MIOV_cjs.RutterSchemaMismatchError(
92
+ endpoint,
93
+ z2__default.default.prettifyError(result.error)
94
+ );
95
+ }
96
+ return result.data;
97
+ }
98
+ async listAccounts(accessToken, params) {
99
+ const endpoint = "/accounting/accounts";
100
+ const response = await this.client.get(endpoint, {
101
+ access_token: accessToken,
102
+ ...params
103
+ });
104
+ const result = chunkJCJXW7AE_cjs.zListAccountResponseWithConnection.safeParse(response);
105
+ if (!result.success) {
106
+ throw new chunkLPP3MIOV_cjs.RutterSchemaMismatchError(
107
+ endpoint,
108
+ z2__default.default.prettifyError(result.error)
109
+ );
110
+ }
111
+ return result.data;
112
+ }
113
+ async getAccount(accessToken, id) {
114
+ const endpoint = `/accounting/accounts/${id}`;
115
+ const response = await this.client.get(endpoint, {
116
+ access_token: accessToken
117
+ });
118
+ const result = chunkJCJXW7AE_cjs.zAccountResponseWithConnection.safeParse(response);
119
+ if (!result.success) {
120
+ throw new chunkLPP3MIOV_cjs.RutterSchemaMismatchError(
121
+ endpoint,
122
+ z2__default.default.prettifyError(result.error)
123
+ );
124
+ }
125
+ return result.data;
126
+ }
127
+ async listInvoices(accessToken, params) {
128
+ const endpoint = "/accounting/invoices";
129
+ const response = await this.client.get(endpoint, {
130
+ access_token: accessToken,
131
+ ...params
132
+ });
133
+ const result = chunkJCJXW7AE_cjs.zListInvoiceResponseWithConnection.safeParse(response);
134
+ if (!result.success) {
135
+ throw new chunkLPP3MIOV_cjs.RutterSchemaMismatchError(
136
+ endpoint,
137
+ z2__default.default.prettifyError(result.error)
138
+ );
139
+ }
140
+ return result.data;
141
+ }
142
+ async getInvoice(accessToken, id) {
143
+ const endpoint = `/accounting/invoices/${id}`;
144
+ const response = await this.client.get(endpoint, {
145
+ access_token: accessToken
146
+ });
147
+ const result = chunkJCJXW7AE_cjs.zInvoiceResponseWithConnection.safeParse(response);
148
+ if (!result.success) {
149
+ throw new chunkLPP3MIOV_cjs.RutterSchemaMismatchError(
150
+ endpoint,
151
+ z2__default.default.prettifyError(result.error)
152
+ );
153
+ }
154
+ return result.data;
155
+ }
156
+ async createInvoice(accessToken, params, idempotencyKey) {
157
+ const endpoint = "/accounting/invoices";
158
+ const response = await this.client.post(
159
+ `${endpoint}?access_token=${encodeURIComponent(accessToken)}`,
160
+ params,
161
+ idempotencyKey ? { idempotencyKey } : void 0
162
+ );
163
+ const result = chunkJCJXW7AE_cjs.zCreateInvoiceResponse.safeParse(response);
164
+ if (!result.success) {
165
+ throw new chunkLPP3MIOV_cjs.RutterSchemaMismatchError(
166
+ endpoint,
167
+ z2__default.default.prettifyError(result.error)
168
+ );
169
+ }
170
+ return result.data;
171
+ }
172
+ };
173
+
174
+ exports.RutterAccountingApi = RutterAccountingApi;
175
+ exports.RutterConnectionsApi = RutterConnectionsApi;
package/dist/api.d.cts ADDED
@@ -0,0 +1,41 @@
1
+ import z__default from 'zod';
2
+ import { b as RutterClient, c as RutterPaginationParams, d as RutterQueryParams } from './client-sPbSz2i_.cjs';
3
+ import { zConnectionResponse, zListConnectionsResponse, zGetAccessTokenConnectionResponse, zExchangeTokenResponse, zDeleteConnectionResponse, zCompanyInfo20240430ResponseWithConnection, zListAccountResponseWithConnection, zAccountResponseWithConnection, zListInvoiceResponseWithConnection, zInvoiceResponseWithConnection, CreateInvoice, zCreateInvoiceResponse } from './generated.cjs';
4
+
5
+ type TConnectionResponse = z__default.infer<typeof zConnectionResponse>;
6
+ type TListConnectionsResponse = z__default.infer<typeof zListConnectionsResponse>;
7
+ type TExchangeTokenResponse = z__default.infer<typeof zExchangeTokenResponse>;
8
+ type TDeleteConnectionResponse = z__default.infer<typeof zDeleteConnectionResponse>;
9
+ type TGetAccessTokenConnectionResponse = z__default.infer<typeof zGetAccessTokenConnectionResponse>;
10
+ declare class RutterConnectionsApi {
11
+ private readonly client;
12
+ constructor(client: RutterClient);
13
+ create(params: {
14
+ platform: string;
15
+ }): Promise<TConnectionResponse>;
16
+ list(): Promise<TListConnectionsResponse>;
17
+ get(accessToken: string): Promise<TGetAccessTokenConnectionResponse>;
18
+ exchangeToken(params: {
19
+ public_token: string;
20
+ }): Promise<TExchangeTokenResponse>;
21
+ delete(accessToken: string): Promise<TDeleteConnectionResponse>;
22
+ }
23
+
24
+ type TCompanyInfoResponse = z__default.infer<typeof zCompanyInfo20240430ResponseWithConnection>;
25
+ type TListAccountsResponse = z__default.infer<typeof zListAccountResponseWithConnection>;
26
+ type TAccountResponse = z__default.infer<typeof zAccountResponseWithConnection>;
27
+ type TListInvoicesResponse = z__default.infer<typeof zListInvoiceResponseWithConnection>;
28
+ type TInvoiceResponse = z__default.infer<typeof zInvoiceResponseWithConnection>;
29
+ type TCreateInvoiceResponse = z__default.infer<typeof zCreateInvoiceResponse>;
30
+ declare class RutterAccountingApi {
31
+ private readonly client;
32
+ constructor(client: RutterClient);
33
+ getCompanyInfo(accessToken: string): Promise<TCompanyInfoResponse>;
34
+ listAccounts(accessToken: string, params?: RutterPaginationParams & RutterQueryParams): Promise<TListAccountsResponse>;
35
+ getAccount(accessToken: string, id: string): Promise<TAccountResponse>;
36
+ listInvoices(accessToken: string, params?: RutterPaginationParams & RutterQueryParams): Promise<TListInvoicesResponse>;
37
+ getInvoice(accessToken: string, id: string): Promise<TInvoiceResponse>;
38
+ createInvoice(accessToken: string, params: CreateInvoice, idempotencyKey?: string): Promise<TCreateInvoiceResponse>;
39
+ }
40
+
41
+ export { RutterAccountingApi, RutterConnectionsApi };
package/dist/api.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ import z__default from 'zod';
2
+ import { b as RutterClient, c as RutterPaginationParams, d as RutterQueryParams } from './client-sPbSz2i_.js';
3
+ import { zConnectionResponse, zListConnectionsResponse, zGetAccessTokenConnectionResponse, zExchangeTokenResponse, zDeleteConnectionResponse, zCompanyInfo20240430ResponseWithConnection, zListAccountResponseWithConnection, zAccountResponseWithConnection, zListInvoiceResponseWithConnection, zInvoiceResponseWithConnection, CreateInvoice, zCreateInvoiceResponse } from './generated.js';
4
+
5
+ type TConnectionResponse = z__default.infer<typeof zConnectionResponse>;
6
+ type TListConnectionsResponse = z__default.infer<typeof zListConnectionsResponse>;
7
+ type TExchangeTokenResponse = z__default.infer<typeof zExchangeTokenResponse>;
8
+ type TDeleteConnectionResponse = z__default.infer<typeof zDeleteConnectionResponse>;
9
+ type TGetAccessTokenConnectionResponse = z__default.infer<typeof zGetAccessTokenConnectionResponse>;
10
+ declare class RutterConnectionsApi {
11
+ private readonly client;
12
+ constructor(client: RutterClient);
13
+ create(params: {
14
+ platform: string;
15
+ }): Promise<TConnectionResponse>;
16
+ list(): Promise<TListConnectionsResponse>;
17
+ get(accessToken: string): Promise<TGetAccessTokenConnectionResponse>;
18
+ exchangeToken(params: {
19
+ public_token: string;
20
+ }): Promise<TExchangeTokenResponse>;
21
+ delete(accessToken: string): Promise<TDeleteConnectionResponse>;
22
+ }
23
+
24
+ type TCompanyInfoResponse = z__default.infer<typeof zCompanyInfo20240430ResponseWithConnection>;
25
+ type TListAccountsResponse = z__default.infer<typeof zListAccountResponseWithConnection>;
26
+ type TAccountResponse = z__default.infer<typeof zAccountResponseWithConnection>;
27
+ type TListInvoicesResponse = z__default.infer<typeof zListInvoiceResponseWithConnection>;
28
+ type TInvoiceResponse = z__default.infer<typeof zInvoiceResponseWithConnection>;
29
+ type TCreateInvoiceResponse = z__default.infer<typeof zCreateInvoiceResponse>;
30
+ declare class RutterAccountingApi {
31
+ private readonly client;
32
+ constructor(client: RutterClient);
33
+ getCompanyInfo(accessToken: string): Promise<TCompanyInfoResponse>;
34
+ listAccounts(accessToken: string, params?: RutterPaginationParams & RutterQueryParams): Promise<TListAccountsResponse>;
35
+ getAccount(accessToken: string, id: string): Promise<TAccountResponse>;
36
+ listInvoices(accessToken: string, params?: RutterPaginationParams & RutterQueryParams): Promise<TListInvoicesResponse>;
37
+ getInvoice(accessToken: string, id: string): Promise<TInvoiceResponse>;
38
+ createInvoice(accessToken: string, params: CreateInvoice, idempotencyKey?: string): Promise<TCreateInvoiceResponse>;
39
+ }
40
+
41
+ export { RutterAccountingApi, RutterConnectionsApi };
package/dist/api.js ADDED
@@ -0,0 +1,168 @@
1
+ import { RutterSchemaMismatchError } from './chunk-LLGYUOGX.js';
2
+ import { zConnectionResponse, zListConnectionsResponse, zGetAccessTokenConnectionResponse, zExchangeTokenResponse, zDeleteConnectionResponse, zCompanyInfo20240430ResponseWithConnection, zListAccountResponseWithConnection, zAccountResponseWithConnection, zListInvoiceResponseWithConnection, zInvoiceResponseWithConnection, zCreateInvoiceResponse } from './chunk-HSUL4OZU.js';
3
+ import z2 from 'zod';
4
+
5
+ var RutterConnectionsApi = class {
6
+ constructor(client) {
7
+ this.client = client;
8
+ }
9
+ async create(params) {
10
+ const endpoint = "/connections";
11
+ const response = await this.client.post(endpoint, params);
12
+ const result = zConnectionResponse.safeParse(response);
13
+ if (!result.success) {
14
+ throw new RutterSchemaMismatchError(
15
+ endpoint,
16
+ z2.prettifyError(result.error)
17
+ );
18
+ }
19
+ return result.data;
20
+ }
21
+ async list() {
22
+ const endpoint = "/connections";
23
+ const response = await this.client.get(endpoint);
24
+ const result = zListConnectionsResponse.safeParse(response);
25
+ if (!result.success) {
26
+ throw new RutterSchemaMismatchError(
27
+ endpoint,
28
+ z2.prettifyError(result.error)
29
+ );
30
+ }
31
+ return result.data;
32
+ }
33
+ async get(accessToken) {
34
+ const endpoint = "/connections";
35
+ const response = await this.client.get(endpoint, {
36
+ access_token: accessToken
37
+ });
38
+ const result = zGetAccessTokenConnectionResponse.safeParse(response);
39
+ if (!result.success) {
40
+ throw new RutterSchemaMismatchError(
41
+ endpoint,
42
+ z2.prettifyError(result.error)
43
+ );
44
+ }
45
+ return result.data;
46
+ }
47
+ async exchangeToken(params) {
48
+ const endpoint = "/item/public_token/exchange";
49
+ const response = await this.client.post(endpoint, params);
50
+ const result = zExchangeTokenResponse.safeParse(response);
51
+ if (!result.success) {
52
+ throw new RutterSchemaMismatchError(
53
+ endpoint,
54
+ z2.prettifyError(result.error)
55
+ );
56
+ }
57
+ return result.data;
58
+ }
59
+ async delete(accessToken) {
60
+ const endpoint = "/connections";
61
+ const response = await this.client.delete(endpoint, {
62
+ access_token: accessToken
63
+ });
64
+ const result = zDeleteConnectionResponse.safeParse(response);
65
+ if (!result.success) {
66
+ throw new RutterSchemaMismatchError(
67
+ endpoint,
68
+ z2.prettifyError(result.error)
69
+ );
70
+ }
71
+ return result.data;
72
+ }
73
+ };
74
+ var RutterAccountingApi = class {
75
+ constructor(client) {
76
+ this.client = client;
77
+ }
78
+ async getCompanyInfo(accessToken) {
79
+ const endpoint = "/accounting/company_info";
80
+ const response = await this.client.get(endpoint, {
81
+ access_token: accessToken
82
+ });
83
+ const result = zCompanyInfo20240430ResponseWithConnection.safeParse(response);
84
+ if (!result.success) {
85
+ throw new RutterSchemaMismatchError(
86
+ endpoint,
87
+ z2.prettifyError(result.error)
88
+ );
89
+ }
90
+ return result.data;
91
+ }
92
+ async listAccounts(accessToken, params) {
93
+ const endpoint = "/accounting/accounts";
94
+ const response = await this.client.get(endpoint, {
95
+ access_token: accessToken,
96
+ ...params
97
+ });
98
+ const result = zListAccountResponseWithConnection.safeParse(response);
99
+ if (!result.success) {
100
+ throw new RutterSchemaMismatchError(
101
+ endpoint,
102
+ z2.prettifyError(result.error)
103
+ );
104
+ }
105
+ return result.data;
106
+ }
107
+ async getAccount(accessToken, id) {
108
+ const endpoint = `/accounting/accounts/${id}`;
109
+ const response = await this.client.get(endpoint, {
110
+ access_token: accessToken
111
+ });
112
+ const result = zAccountResponseWithConnection.safeParse(response);
113
+ if (!result.success) {
114
+ throw new RutterSchemaMismatchError(
115
+ endpoint,
116
+ z2.prettifyError(result.error)
117
+ );
118
+ }
119
+ return result.data;
120
+ }
121
+ async listInvoices(accessToken, params) {
122
+ const endpoint = "/accounting/invoices";
123
+ const response = await this.client.get(endpoint, {
124
+ access_token: accessToken,
125
+ ...params
126
+ });
127
+ const result = zListInvoiceResponseWithConnection.safeParse(response);
128
+ if (!result.success) {
129
+ throw new RutterSchemaMismatchError(
130
+ endpoint,
131
+ z2.prettifyError(result.error)
132
+ );
133
+ }
134
+ return result.data;
135
+ }
136
+ async getInvoice(accessToken, id) {
137
+ const endpoint = `/accounting/invoices/${id}`;
138
+ const response = await this.client.get(endpoint, {
139
+ access_token: accessToken
140
+ });
141
+ const result = zInvoiceResponseWithConnection.safeParse(response);
142
+ if (!result.success) {
143
+ throw new RutterSchemaMismatchError(
144
+ endpoint,
145
+ z2.prettifyError(result.error)
146
+ );
147
+ }
148
+ return result.data;
149
+ }
150
+ async createInvoice(accessToken, params, idempotencyKey) {
151
+ const endpoint = "/accounting/invoices";
152
+ const response = await this.client.post(
153
+ `${endpoint}?access_token=${encodeURIComponent(accessToken)}`,
154
+ params,
155
+ idempotencyKey ? { idempotencyKey } : void 0
156
+ );
157
+ const result = zCreateInvoiceResponse.safeParse(response);
158
+ if (!result.success) {
159
+ throw new RutterSchemaMismatchError(
160
+ endpoint,
161
+ z2.prettifyError(result.error)
162
+ );
163
+ }
164
+ return result.data;
165
+ }
166
+ };
167
+
168
+ export { RutterAccountingApi, RutterConnectionsApi };
@@ -0,0 +1,36 @@
1
+ // src/errors.ts
2
+ var RutterError = class extends Error {
3
+ status;
4
+ errorType;
5
+ errorCode;
6
+ metadata;
7
+ constructor(body, status) {
8
+ super(body.error_message);
9
+ this.name = "RutterError";
10
+ this.status = status;
11
+ this.errorType = body.error_type;
12
+ this.errorCode = body.error_code;
13
+ this.metadata = body.error_metadata;
14
+ }
15
+ get isRateLimited() {
16
+ return this.status === 429 || this.status === 452;
17
+ }
18
+ get isUserActionable() {
19
+ return this.status === 400 || this.status === 409 || this.status === 410 || this.status === 450;
20
+ }
21
+ get humanReadableMessage() {
22
+ return this.metadata?.human_readable ?? this.message;
23
+ }
24
+ };
25
+ var RutterSchemaMismatchError = class extends Error {
26
+ endpoint;
27
+ constructor(endpoint, issues) {
28
+ super(
29
+ `Rutter response from ${endpoint} failed schema validation: ${issues}`
30
+ );
31
+ this.name = "RutterSchemaMismatchError";
32
+ this.endpoint = endpoint;
33
+ }
34
+ };
35
+
36
+ export { RutterError, RutterSchemaMismatchError };
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ // src/errors.ts
4
+ var RutterError = class extends Error {
5
+ status;
6
+ errorType;
7
+ errorCode;
8
+ metadata;
9
+ constructor(body, status) {
10
+ super(body.error_message);
11
+ this.name = "RutterError";
12
+ this.status = status;
13
+ this.errorType = body.error_type;
14
+ this.errorCode = body.error_code;
15
+ this.metadata = body.error_metadata;
16
+ }
17
+ get isRateLimited() {
18
+ return this.status === 429 || this.status === 452;
19
+ }
20
+ get isUserActionable() {
21
+ return this.status === 400 || this.status === 409 || this.status === 410 || this.status === 450;
22
+ }
23
+ get humanReadableMessage() {
24
+ return this.metadata?.human_readable ?? this.message;
25
+ }
26
+ };
27
+ var RutterSchemaMismatchError = class extends Error {
28
+ endpoint;
29
+ constructor(endpoint, issues) {
30
+ super(
31
+ `Rutter response from ${endpoint} failed schema validation: ${issues}`
32
+ );
33
+ this.name = "RutterSchemaMismatchError";
34
+ this.endpoint = endpoint;
35
+ }
36
+ };
37
+
38
+ exports.RutterError = RutterError;
39
+ exports.RutterSchemaMismatchError = RutterSchemaMismatchError;