@frihet/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,131 @@
1
+ # @frihet/sdk
2
+
3
+ Official TypeScript SDK for the [Frihet](https://frihet.io) API. AI-native business management.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @frihet/sdk
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```typescript
14
+ import Frihet from '@frihet/sdk';
15
+
16
+ const frihet = new Frihet({ apiKey: 'fri_...' });
17
+
18
+ // Create an invoice
19
+ const invoice = await frihet.invoices.create({
20
+ clientName: 'Acme Corp',
21
+ items: [{ description: 'Consulting', quantity: 10, unitPrice: 150 }],
22
+ });
23
+
24
+ // List overdue invoices
25
+ const overdue = await frihet.invoices.list({ status: 'overdue' });
26
+
27
+ // Mark as paid
28
+ await frihet.invoices.markPaid(invoice.id);
29
+
30
+ // Send by email
31
+ await frihet.invoices.send(invoice.id, { recipientEmail: 'billing@acme.com' });
32
+
33
+ // Download PDF
34
+ const pdf = await frihet.invoices.pdf(invoice.id);
35
+ ```
36
+
37
+ ## Resources
38
+
39
+ | Resource | Methods |
40
+ |----------|---------|
41
+ | `frihet.invoices` | `list`, `retrieve`, `create`, `update`, `del`, `search`, `markPaid`, `send`, `pdf`, `createBatch` |
42
+ | `frihet.expenses` | `list`, `retrieve`, `create`, `update`, `del`, `search`, `createBatch` |
43
+ | `frihet.clients` | `list`, `retrieve`, `create`, `update`, `del`, `search` |
44
+ | `frihet.vendors` | `list`, `retrieve`, `create`, `update`, `del`, `search` |
45
+ | `frihet.products` | `list`, `retrieve`, `create`, `update`, `del`, `search` |
46
+ | `frihet.quotes` | `list`, `retrieve`, `create`, `update`, `del`, `search`, `send`, `pdf` |
47
+ | `frihet.webhooks` | `list`, `retrieve`, `create`, `update`, `del` |
48
+ | `frihet.intelligence` | `context`, `summary`, `monthly`, `quarterly` |
49
+
50
+ ## Intelligence
51
+
52
+ ```typescript
53
+ // Full business context (one call for AI agents)
54
+ const ctx = await frihet.intelligence.context();
55
+
56
+ // Monthly P&L with tax liability
57
+ const march = await frihet.intelligence.monthly('2026-03');
58
+
59
+ // Quarterly tax prep (Modelo 303/130)
60
+ const q1 = await frihet.intelligence.quarterly('2026-Q1');
61
+
62
+ // Financial summary with date range
63
+ const ytd = await frihet.intelligence.summary({ from: '2026-01-01', to: '2026-12-31' });
64
+ ```
65
+
66
+ ## Error handling
67
+
68
+ ```typescript
69
+ import Frihet, { RateLimitError, NotFoundError, ValidationError } from '@frihet/sdk';
70
+
71
+ try {
72
+ await frihet.invoices.retrieve('nonexistent');
73
+ } catch (err) {
74
+ if (err instanceof NotFoundError) {
75
+ console.log('Invoice not found');
76
+ } else if (err instanceof RateLimitError) {
77
+ console.log(`Retry after ${err.retryAfter}s`);
78
+ } else if (err instanceof ValidationError) {
79
+ console.log('Validation:', err.details);
80
+ }
81
+ }
82
+ ```
83
+
84
+ ## Webhook verification
85
+
86
+ ```typescript
87
+ import { Webhooks } from '@frihet/sdk';
88
+
89
+ const isValid = Webhooks.verifySignature(
90
+ rawBody,
91
+ req.headers['x-frihet-signature'],
92
+ webhookSecret,
93
+ );
94
+ ```
95
+
96
+ ## Configuration
97
+
98
+ ```typescript
99
+ const frihet = new Frihet({
100
+ apiKey: 'fri_...',
101
+ baseUrl: 'https://api.frihet.io/v1', // default
102
+ timeout: 30000, // 30s default
103
+ });
104
+
105
+ // Per-request options
106
+ await frihet.invoices.create(data, {
107
+ idempotencyKey: 'unique-key-123',
108
+ timeout: 60000,
109
+ });
110
+ ```
111
+
112
+ ## Features
113
+
114
+ - Full TypeScript types with autocompletion
115
+ - Automatic retry on rate limits (429) and server errors (5xx)
116
+ - Exponential backoff with configurable retries
117
+ - Idempotency key support for safe retries
118
+ - Dual CJS/ESM output
119
+ - Zero runtime dependencies
120
+ - Request ID tracking on errors
121
+ - HMAC webhook signature verification
122
+
123
+ ## Links
124
+
125
+ - [API Documentation](https://docs.frihet.io/desarrolladores/api-rest)
126
+ - [MCP Server](https://www.npmjs.com/package/@frihet/mcp-server)
127
+ - [CLI](https://www.npmjs.com/package/frihet)
128
+
129
+ ## License
130
+
131
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,542 @@
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
+ Clients: () => Clients,
26
+ Expenses: () => Expenses,
27
+ Frihet: () => Frihet,
28
+ FrihetError: () => FrihetError,
29
+ Intelligence: () => Intelligence,
30
+ Invoices: () => Invoices,
31
+ NotFoundError: () => NotFoundError,
32
+ Products: () => Products,
33
+ Quotes: () => Quotes,
34
+ RateLimitError: () => RateLimitError,
35
+ TimeoutError: () => TimeoutError,
36
+ ValidationError: () => ValidationError,
37
+ Vendors: () => Vendors,
38
+ Webhooks: () => Webhooks,
39
+ default: () => index_default
40
+ });
41
+ module.exports = __toCommonJS(index_exports);
42
+
43
+ // src/error.ts
44
+ var FrihetError = class extends Error {
45
+ constructor(message) {
46
+ super(message);
47
+ this.name = "FrihetError";
48
+ }
49
+ };
50
+ var APIError = class extends FrihetError {
51
+ status;
52
+ code;
53
+ requestId;
54
+ constructor(status, code, message, requestId) {
55
+ super(message);
56
+ this.name = "APIError";
57
+ this.status = status;
58
+ this.code = code;
59
+ this.requestId = requestId;
60
+ }
61
+ };
62
+ var AuthenticationError = class extends APIError {
63
+ constructor(message = "Invalid or missing API key") {
64
+ super(401, "authentication_error", message);
65
+ this.name = "AuthenticationError";
66
+ }
67
+ };
68
+ var NotFoundError = class extends APIError {
69
+ constructor(message = "Resource not found") {
70
+ super(404, "not_found", message);
71
+ this.name = "NotFoundError";
72
+ }
73
+ };
74
+ var ValidationError = class extends APIError {
75
+ details;
76
+ constructor(message, details) {
77
+ super(400, "validation_error", message);
78
+ this.name = "ValidationError";
79
+ this.details = details;
80
+ }
81
+ };
82
+ var RateLimitError = class extends APIError {
83
+ retryAfter;
84
+ constructor(retryAfter) {
85
+ super(429, "rate_limit_exceeded", "Rate limit exceeded. Please retry later.");
86
+ this.name = "RateLimitError";
87
+ this.retryAfter = retryAfter;
88
+ }
89
+ };
90
+ var TimeoutError = class extends FrihetError {
91
+ constructor(timeoutMs) {
92
+ super(`Request timed out after ${timeoutMs}ms`);
93
+ this.name = "TimeoutError";
94
+ }
95
+ };
96
+
97
+ // src/client.ts
98
+ var DEFAULT_BASE_URL = "https://api.frihet.io/v1";
99
+ var DEFAULT_TIMEOUT_MS = 3e4;
100
+ var MAX_RETRIES = 3;
101
+ var BASE_RETRY_DELAY_MS = 1e3;
102
+ var SDK_VERSION = "1.0.0";
103
+ var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
104
+ var HttpClient = class {
105
+ apiKey;
106
+ baseUrl;
107
+ timeout;
108
+ constructor(opts) {
109
+ if (!opts.apiKey) {
110
+ throw new Error("apiKey is required. Get one at https://app.frihet.io/settings/security");
111
+ }
112
+ this.apiKey = opts.apiKey;
113
+ this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
114
+ this.timeout = opts.timeout ?? DEFAULT_TIMEOUT_MS;
115
+ }
116
+ get defaultHeaders() {
117
+ return {
118
+ "X-API-Key": this.apiKey,
119
+ "Content-Type": "application/json",
120
+ "Accept": "application/json",
121
+ "User-Agent": `@frihet/sdk/${SDK_VERSION} (node)`
122
+ };
123
+ }
124
+ async get(path, query, opts) {
125
+ return this.request("GET", path, void 0, query, opts);
126
+ }
127
+ async post(path, body, opts) {
128
+ return this.request("POST", path, body, void 0, opts);
129
+ }
130
+ async patch(path, body, opts) {
131
+ return this.request("PATCH", path, body, void 0, opts);
132
+ }
133
+ async del(path, opts) {
134
+ return this.request("DELETE", path, void 0, void 0, opts);
135
+ }
136
+ async getPage(path, query, opts) {
137
+ const raw = await this.requestRaw("GET", path, void 0, query, opts);
138
+ const body = await raw.json();
139
+ const page = this.extractPageFromEnvelope(body);
140
+ if (!page) {
141
+ throw new APIError(200, "invalid_response", "Expected paginated response with data array", this.extractRequestId(raw));
142
+ }
143
+ return page;
144
+ }
145
+ async getRaw(path, opts) {
146
+ const response = await this.requestRaw("GET", path, void 0, void 0, opts);
147
+ return response.arrayBuffer();
148
+ }
149
+ async request(method, path, body, query, opts) {
150
+ const response = await this.requestRaw(method, path, body, query, opts);
151
+ if (response.status === 204) {
152
+ return void 0;
153
+ }
154
+ const json = await response.json();
155
+ return this.unwrapEnvelope(json);
156
+ }
157
+ async requestRaw(method, path, body, query, opts, retryCount = 0) {
158
+ const url = new URL(`${this.baseUrl}${path}`);
159
+ if (query) {
160
+ for (const [key, value] of Object.entries(query)) {
161
+ if (value !== void 0) url.searchParams.set(key, String(value));
162
+ }
163
+ }
164
+ const headers = { ...this.defaultHeaders };
165
+ if (opts?.idempotencyKey) {
166
+ headers["Idempotency-Key"] = opts.idempotencyKey;
167
+ }
168
+ const controller = new AbortController();
169
+ const timeoutMs = opts?.timeout ?? this.timeout;
170
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
171
+ let response;
172
+ try {
173
+ response = await fetch(url.toString(), {
174
+ method,
175
+ headers,
176
+ body: body ? JSON.stringify(body) : void 0,
177
+ signal: opts?.signal ?? controller.signal
178
+ });
179
+ } catch (err) {
180
+ if (err instanceof Error && err.name === "AbortError") {
181
+ throw new TimeoutError(timeoutMs);
182
+ }
183
+ if (retryCount < MAX_RETRIES) {
184
+ const delayMs = BASE_RETRY_DELAY_MS * Math.pow(2, retryCount);
185
+ await new Promise((r) => setTimeout(r, delayMs));
186
+ return this.requestRaw(method, path, body, query, opts, retryCount + 1);
187
+ }
188
+ throw err;
189
+ } finally {
190
+ clearTimeout(timeoutId);
191
+ }
192
+ if (RETRYABLE_STATUS_CODES.has(response.status) && retryCount < MAX_RETRIES) {
193
+ if (response.status === 429) {
194
+ const retryAfter = response.headers.get("Retry-After");
195
+ const delayMs = retryAfter ? parseInt(retryAfter, 10) * 1e3 : BASE_RETRY_DELAY_MS * Math.pow(2, retryCount);
196
+ await new Promise((r) => setTimeout(r, delayMs));
197
+ } else {
198
+ const delayMs = BASE_RETRY_DELAY_MS * Math.pow(2, retryCount);
199
+ await new Promise((r) => setTimeout(r, delayMs));
200
+ }
201
+ return this.requestRaw(method, path, body, query, opts, retryCount + 1);
202
+ }
203
+ if (response.status === 429) {
204
+ const retryAfter = response.headers.get("Retry-After");
205
+ throw new RateLimitError(retryAfter ? parseInt(retryAfter, 10) : void 0);
206
+ }
207
+ if (!response.ok) {
208
+ const requestId = this.extractRequestId(response);
209
+ let errorBody;
210
+ try {
211
+ const json = await response.json();
212
+ errorBody = json.error ? json : json.data ?? json;
213
+ } catch {
214
+ errorBody = { error: `http_${response.status}`, message: response.statusText };
215
+ }
216
+ throw this.buildError(response.status, errorBody, requestId);
217
+ }
218
+ return response;
219
+ }
220
+ /**
221
+ * Unwrap the API response envelope.
222
+ * API returns: { data: T, meta: {...} } for single resources
223
+ * { data: T[], total, limit, offset, meta: {...} } for lists
224
+ */
225
+ unwrapEnvelope(json) {
226
+ if (json && typeof json === "object" && "data" in json) {
227
+ const obj = json;
228
+ if ("total" in obj && "limit" in obj) {
229
+ return json;
230
+ }
231
+ return obj.data;
232
+ }
233
+ return json;
234
+ }
235
+ extractPageFromEnvelope(json) {
236
+ if (!json || typeof json !== "object") return null;
237
+ const obj = json;
238
+ if (Array.isArray(obj.data) && "total" in obj) {
239
+ return { data: obj.data, total: obj.total, limit: obj.limit, offset: obj.offset };
240
+ }
241
+ return null;
242
+ }
243
+ extractRequestId(response) {
244
+ return response.headers.get("X-Request-Id") ?? void 0;
245
+ }
246
+ buildError(status, body, requestId) {
247
+ switch (status) {
248
+ case 401:
249
+ return new AuthenticationError(body.message);
250
+ case 404:
251
+ return new NotFoundError(body.message);
252
+ case 400:
253
+ case 422:
254
+ return new ValidationError(body.message ?? body.error, body.details);
255
+ case 429:
256
+ return new RateLimitError();
257
+ default:
258
+ return new APIError(status, body.error, body.message ?? body.error, requestId);
259
+ }
260
+ }
261
+ };
262
+
263
+ // src/resources/invoices.ts
264
+ var enc = encodeURIComponent;
265
+ var Invoices = class {
266
+ constructor(_client) {
267
+ this._client = _client;
268
+ }
269
+ list(params, opts) {
270
+ return this._client.getPage("/invoices", params, opts);
271
+ }
272
+ retrieve(id, opts) {
273
+ return this._client.get(`/invoices/${enc(id)}`, void 0, opts);
274
+ }
275
+ create(params, opts) {
276
+ return this._client.post("/invoices", params, opts);
277
+ }
278
+ update(id, params, opts) {
279
+ return this._client.patch(`/invoices/${enc(id)}`, params, opts);
280
+ }
281
+ del(id, opts) {
282
+ return this._client.del(`/invoices/${enc(id)}`, opts);
283
+ }
284
+ search(query, params, opts) {
285
+ return this._client.getPage("/invoices", { q: query, ...params }, opts);
286
+ }
287
+ markPaid(id, paidDate, opts) {
288
+ return this._client.post(`/invoices/${enc(id)}/paid`, paidDate ? { paidDate } : void 0, opts);
289
+ }
290
+ send(id, params, opts) {
291
+ return this._client.post(`/invoices/${enc(id)}/send`, params, opts);
292
+ }
293
+ pdf(id, opts) {
294
+ return this._client.getRaw(`/invoices/${enc(id)}/pdf`, opts);
295
+ }
296
+ createBatch(items, opts) {
297
+ return this._client.post("/invoices/batch", items, opts);
298
+ }
299
+ };
300
+
301
+ // src/resources/expenses.ts
302
+ var enc2 = encodeURIComponent;
303
+ var Expenses = class {
304
+ constructor(_client) {
305
+ this._client = _client;
306
+ }
307
+ list(params, opts) {
308
+ return this._client.getPage("/expenses", params, opts);
309
+ }
310
+ retrieve(id, opts) {
311
+ return this._client.get(`/expenses/${enc2(id)}`, void 0, opts);
312
+ }
313
+ create(params, opts) {
314
+ return this._client.post("/expenses", params, opts);
315
+ }
316
+ update(id, params, opts) {
317
+ return this._client.patch(`/expenses/${enc2(id)}`, params, opts);
318
+ }
319
+ del(id, opts) {
320
+ return this._client.del(`/expenses/${enc2(id)}`, opts);
321
+ }
322
+ search(query, params, opts) {
323
+ return this._client.getPage("/expenses", { q: query, ...params }, opts);
324
+ }
325
+ createBatch(items, opts) {
326
+ return this._client.post("/expenses/batch", items, opts);
327
+ }
328
+ };
329
+
330
+ // src/resources/clients.ts
331
+ var enc3 = encodeURIComponent;
332
+ var Clients = class {
333
+ constructor(_client) {
334
+ this._client = _client;
335
+ }
336
+ list(params, opts) {
337
+ return this._client.getPage("/clients", params, opts);
338
+ }
339
+ retrieve(id, opts) {
340
+ return this._client.get(`/clients/${enc3(id)}`, void 0, opts);
341
+ }
342
+ create(params, opts) {
343
+ return this._client.post("/clients", params, opts);
344
+ }
345
+ update(id, params, opts) {
346
+ return this._client.patch(`/clients/${enc3(id)}`, params, opts);
347
+ }
348
+ del(id, opts) {
349
+ return this._client.del(`/clients/${enc3(id)}`, opts);
350
+ }
351
+ search(query, params, opts) {
352
+ return this._client.getPage("/clients", { q: query, ...params }, opts);
353
+ }
354
+ };
355
+
356
+ // src/resources/products.ts
357
+ var enc4 = encodeURIComponent;
358
+ var Products = class {
359
+ constructor(_client) {
360
+ this._client = _client;
361
+ }
362
+ list(params, opts) {
363
+ return this._client.getPage("/products", params, opts);
364
+ }
365
+ retrieve(id, opts) {
366
+ return this._client.get(`/products/${enc4(id)}`, void 0, opts);
367
+ }
368
+ create(params, opts) {
369
+ return this._client.post("/products", params, opts);
370
+ }
371
+ update(id, params, opts) {
372
+ return this._client.patch(`/products/${enc4(id)}`, params, opts);
373
+ }
374
+ del(id, opts) {
375
+ return this._client.del(`/products/${enc4(id)}`, opts);
376
+ }
377
+ search(query, params, opts) {
378
+ return this._client.getPage("/products", { q: query, ...params }, opts);
379
+ }
380
+ };
381
+
382
+ // src/resources/quotes.ts
383
+ var enc5 = encodeURIComponent;
384
+ var Quotes = class {
385
+ constructor(_client) {
386
+ this._client = _client;
387
+ }
388
+ list(params, opts) {
389
+ return this._client.getPage("/quotes", params, opts);
390
+ }
391
+ retrieve(id, opts) {
392
+ return this._client.get(`/quotes/${enc5(id)}`, void 0, opts);
393
+ }
394
+ create(params, opts) {
395
+ return this._client.post("/quotes", params, opts);
396
+ }
397
+ update(id, params, opts) {
398
+ return this._client.patch(`/quotes/${enc5(id)}`, params, opts);
399
+ }
400
+ del(id, opts) {
401
+ return this._client.del(`/quotes/${enc5(id)}`, opts);
402
+ }
403
+ search(query, params, opts) {
404
+ return this._client.getPage("/quotes", { q: query, ...params }, opts);
405
+ }
406
+ pdf(id, opts) {
407
+ return this._client.getRaw(`/quotes/${enc5(id)}/pdf`, opts);
408
+ }
409
+ send(id, params, opts) {
410
+ return this._client.post(`/quotes/${enc5(id)}/send`, params, opts);
411
+ }
412
+ };
413
+
414
+ // src/resources/vendors.ts
415
+ var enc6 = encodeURIComponent;
416
+ var Vendors = class {
417
+ constructor(_client) {
418
+ this._client = _client;
419
+ }
420
+ list(params, opts) {
421
+ return this._client.getPage("/vendors", params, opts);
422
+ }
423
+ retrieve(id, opts) {
424
+ return this._client.get(`/vendors/${enc6(id)}`, void 0, opts);
425
+ }
426
+ create(params, opts) {
427
+ return this._client.post("/vendors", params, opts);
428
+ }
429
+ update(id, params, opts) {
430
+ return this._client.patch(`/vendors/${enc6(id)}`, params, opts);
431
+ }
432
+ del(id, opts) {
433
+ return this._client.del(`/vendors/${enc6(id)}`, opts);
434
+ }
435
+ search(query, params, opts) {
436
+ return this._client.getPage("/vendors", { q: query, ...params }, opts);
437
+ }
438
+ };
439
+
440
+ // src/resources/webhooks.ts
441
+ var import_node_crypto = require("crypto");
442
+ var enc7 = encodeURIComponent;
443
+ var Webhooks = class {
444
+ constructor(_client) {
445
+ this._client = _client;
446
+ }
447
+ list(params, opts) {
448
+ return this._client.getPage("/webhooks", params, opts);
449
+ }
450
+ retrieve(id, opts) {
451
+ return this._client.get(`/webhooks/${enc7(id)}`, void 0, opts);
452
+ }
453
+ create(params, opts) {
454
+ return this._client.post("/webhooks", params, opts);
455
+ }
456
+ update(id, params, opts) {
457
+ return this._client.patch(`/webhooks/${enc7(id)}`, params, opts);
458
+ }
459
+ del(id, opts) {
460
+ return this._client.del(`/webhooks/${enc7(id)}`, opts);
461
+ }
462
+ /**
463
+ * Verify a webhook signature. Use this in your webhook handler to confirm
464
+ * the payload was sent by Frihet.
465
+ *
466
+ * @param payload - Raw request body (string or Buffer)
467
+ * @param signature - Value of the X-Frihet-Signature header
468
+ * @param secret - Your webhook secret
469
+ */
470
+ static verifySignature(payload, signature, secret) {
471
+ const expected = `sha256=${(0, import_node_crypto.createHmac)("sha256", secret).update(payload).digest("hex")}`;
472
+ if (expected.length !== signature.length) return false;
473
+ let mismatch = 0;
474
+ for (let i = 0; i < expected.length; i++) {
475
+ mismatch |= expected.charCodeAt(i) ^ signature.charCodeAt(i);
476
+ }
477
+ return mismatch === 0;
478
+ }
479
+ };
480
+
481
+ // src/resources/intelligence.ts
482
+ var Intelligence = class {
483
+ constructor(_client) {
484
+ this._client = _client;
485
+ }
486
+ context(opts) {
487
+ return this._client.get("/context", void 0, opts);
488
+ }
489
+ summary(params, opts) {
490
+ return this._client.get("/summary", params, opts);
491
+ }
492
+ monthly(month, opts) {
493
+ return this._client.get("/monthly", month ? { month } : void 0, opts);
494
+ }
495
+ quarterly(quarter, opts) {
496
+ return this._client.get("/quarterly", quarter ? { quarter } : void 0, opts);
497
+ }
498
+ };
499
+
500
+ // src/index.ts
501
+ var Frihet = class {
502
+ invoices;
503
+ expenses;
504
+ clients;
505
+ vendors;
506
+ products;
507
+ quotes;
508
+ webhooks;
509
+ intelligence;
510
+ constructor(opts) {
511
+ const client = new HttpClient(opts);
512
+ this.invoices = new Invoices(client);
513
+ this.expenses = new Expenses(client);
514
+ this.clients = new Clients(client);
515
+ this.vendors = new Vendors(client);
516
+ this.products = new Products(client);
517
+ this.quotes = new Quotes(client);
518
+ this.webhooks = new Webhooks(client);
519
+ this.intelligence = new Intelligence(client);
520
+ }
521
+ };
522
+ var index_default = Frihet;
523
+ // Annotate the CommonJS export names for ESM import in node:
524
+ 0 && (module.exports = {
525
+ APIError,
526
+ AuthenticationError,
527
+ Clients,
528
+ Expenses,
529
+ Frihet,
530
+ FrihetError,
531
+ Intelligence,
532
+ Invoices,
533
+ NotFoundError,
534
+ Products,
535
+ Quotes,
536
+ RateLimitError,
537
+ TimeoutError,
538
+ ValidationError,
539
+ Vendors,
540
+ Webhooks
541
+ });
542
+ //# sourceMappingURL=index.cjs.map