@unifetch/fortnox 1.0.0 → 2.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 +181 -0
- package/dist/create-fortnox-BRQXlzrc.cjs +1723 -0
- package/dist/create-fortnox-BRQXlzrc.cjs.map +1 -0
- package/dist/create-fortnox-CIWMiQTF.d.mts +1698 -0
- package/dist/create-fortnox-CIWMiQTF.d.mts.map +1 -0
- package/dist/create-fortnox-CSULrMkm.mjs +1717 -0
- package/dist/create-fortnox-CSULrMkm.mjs.map +1 -0
- package/dist/create-fortnox-D9a-YhJ-.d.cts +1698 -0
- package/dist/create-fortnox-D9a-YhJ-.d.cts.map +1 -0
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/{official-routes-CO9qO54b.d.mts → official-COyUx9dP.d.cts} +20 -4
- package/dist/official-COyUx9dP.d.cts.map +1 -0
- package/dist/{official-routes-UGPWNmls.d.cts → official-Lpmk8gr7.d.mts} +20 -4
- package/dist/official-Lpmk8gr7.d.mts.map +1 -0
- package/dist/official.cjs +2 -70
- package/dist/official.cjs.map +1 -1
- package/dist/official.d.cts +2 -57
- package/dist/official.d.mts +2 -57
- package/dist/official.mjs +3 -70
- package/dist/official.mjs.map +1 -1
- package/dist/patched.cjs +2 -70
- package/dist/patched.cjs.map +1 -1
- package/dist/patched.d.cts +12388 -51
- package/dist/patched.d.cts.map +1 -1
- package/dist/patched.d.mts +12388 -51
- package/dist/patched.d.mts.map +1 -1
- package/dist/patched.mjs +3 -70
- package/dist/patched.mjs.map +1 -1
- package/package.json +3 -2
- package/dist/official-routes-CO9qO54b.d.mts.map +0 -1
- package/dist/official-routes-UGPWNmls.d.cts.map +0 -1
- package/dist/official.d.cts.map +0 -1
- package/dist/official.d.mts.map +0 -1
package/README.md
CHANGED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# @unifetch/fortnox
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for the [Fortnox API](https://api.fortnox.se/apidocs), fully typed from the official OpenAPI specification — with corrections applied where the spec has incorrect or overly permissive types.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @unifetch/fortnox
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @unifetch/fortnox
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Initialization
|
|
14
|
+
|
|
15
|
+
There are two ways to initialize the client.
|
|
16
|
+
|
|
17
|
+
### 1. Access token
|
|
18
|
+
|
|
19
|
+
Use this if you manage your own oAuth flow and already have a Fortnox access token.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { initFortnox } from "@unifetch/fortnox";
|
|
23
|
+
|
|
24
|
+
const fortnox = initFortnox({
|
|
25
|
+
accessToken: "your-access-token",
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 2. Proxy via unifetch.dev
|
|
30
|
+
|
|
31
|
+
[unifetch.dev](https://unifetch.dev) acts as a proxy layer that internally handles OAuth and token rotation, removing the need to manage credentials yourself.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { initFortnox } from "@unifetch/fortnox";
|
|
35
|
+
|
|
36
|
+
const fortnox = initFortnox({
|
|
37
|
+
proxy: {
|
|
38
|
+
baseUrl: "https://proxy.unifetch.dev/fortnox",
|
|
39
|
+
apiKey: "your-api-key", // You generate it on unifetch.dev dashboard
|
|
40
|
+
tenantId: "your-tenant-id", // Your company's unique fortnox id. You can see it on unifetch.dev dashboard.
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
Every response is a discriminated union of `{ error: null; data: T }` or `{ error: ErrorResponse; data: null }`. Once you handle (or narrow) the error branch, TypeScript automatically infers that `data` is non-null.
|
|
48
|
+
|
|
49
|
+
There are two ways to call the API.
|
|
50
|
+
|
|
51
|
+
### Resource-based API (recommended)
|
|
52
|
+
|
|
53
|
+
Access resources by name and call operations by their ID. Both the resource name and operation ID are autocompleted by TypeScript.
|
|
54
|
+
|
|
55
|
+
> **Note:** The operation names (e.g. `getList`, `create`, `bookkeep`) are **manually curated** and are not derived from the official Fortnox OpenAPI specification. The official spec uses operation ids that are inconsistent and ambiguous across endpoints. The names used here follow a consistent, human-readable convention defined in [`overrides/operation-ids.json`](overrides/operation-ids.json).
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const { data, error } = await fortnox.invoices.getList();
|
|
59
|
+
|
|
60
|
+
if (error) {
|
|
61
|
+
console.error(error.ErrorInformation.message);
|
|
62
|
+
} else {
|
|
63
|
+
// data is non-null here — TypeScript knows this after the error check
|
|
64
|
+
console.log(data.Invoices);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### With query parameters
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
const { data, error } = await fortnox.invoices.getList({
|
|
72
|
+
query: { fromdate: "2024-01-01", todate: "2024-12-31" },
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (error) throw error;
|
|
76
|
+
|
|
77
|
+
for (const invoice of data.Invoices) {
|
|
78
|
+
console.log(invoice.DocumentNumber, invoice.Total);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
#### Creating a resource
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const { data, error } = await fortnox.invoices.create({
|
|
86
|
+
body: {
|
|
87
|
+
Invoice: {
|
|
88
|
+
CustomerNumber: "1",
|
|
89
|
+
InvoiceRows: [
|
|
90
|
+
{ ArticleNumber: "A1", DeliveredQuantity: 2 },
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
if (error) throw error;
|
|
97
|
+
|
|
98
|
+
console.log(data.Invoice.DocumentNumber);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### Fetching a single resource by ID
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
const { data, error } = await fortnox.invoices.get({
|
|
105
|
+
params: { DocumentNumber: "100" },
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
if (error) throw error;
|
|
109
|
+
|
|
110
|
+
console.log(data.Invoice.CustomerName);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### Calling an action on a resource
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
const { data, error } = await fortnox.invoices.bookkeep({
|
|
117
|
+
params: { DocumentNumber: "100" },
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Path-based API
|
|
122
|
+
|
|
123
|
+
If you want to access an endpoint directly by its raw path, use `fortnox.path()`. This is equivalent to the resource-based API under the hood. The path and all the parameters are fully typed.
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
const { data, error } = await fortnox.path("/3/invoices").get();
|
|
127
|
+
|
|
128
|
+
if (error) throw error;
|
|
129
|
+
|
|
130
|
+
console.log(data.Invoices);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
const { data, error } = await fortnox.path("/3/invoices/{DocumentNumber}").get({
|
|
135
|
+
params: { DocumentNumber: "100" },
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Type definitions
|
|
140
|
+
|
|
141
|
+
### `@unifetch/fortnox` (default) — patched types
|
|
142
|
+
|
|
143
|
+
The default import uses **patched type definitions**. Fortnox's official OpenAPI spec has a number of incorrect or missing type constraints (e.g. response wrapper properties marked as optional when they are always present). This package fixes those issues so the types accurately reflect real API behavior. But some of the "patched" types can still be incorrect since we do not have clear documentation.
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { initFortnox } from "@unifetch/fortnox";
|
|
147
|
+
// or equivalently:
|
|
148
|
+
import { initFortnox } from "@unifetch/fortnox/patched";
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `@unifetch/fortnox/official` — unmodified types
|
|
152
|
+
|
|
153
|
+
If you need the raw types exactly as they appear in Fortnox's official OpenAPI specification, import from the `/official` subpath.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { initFortnox } from "@unifetch/fortnox/official";
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
> **Note:** The official types may include inaccuracies inherited from the upstream spec. Prefer the default (patched) import unless you have a specific reason to use the unmodified types.
|
|
160
|
+
|
|
161
|
+
## Error handling
|
|
162
|
+
|
|
163
|
+
The error object has the following shape:
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
type ErrorResponse = {
|
|
167
|
+
ErrorSource: "fortnox" | "unknown";
|
|
168
|
+
ErrorInformation: {
|
|
169
|
+
error: number;
|
|
170
|
+
message: string;
|
|
171
|
+
code: number;
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
- `ErrorSource: "fortnox"` — the Fortnox API returned a non-2xx response.
|
|
177
|
+
- `ErrorSource: "unknown"` — a network or unexpected error occurred.
|
|
178
|
+
|
|
179
|
+
## License
|
|
180
|
+
|
|
181
|
+
ISC
|