@substrat-run/connector-fortnox 0.2.0 → 0.4.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/dist/mock.d.ts CHANGED
@@ -4,13 +4,13 @@ import type { FetchLike } from '@substrat-run/kernel';
4
4
  * whole sweep without a provider account.
5
5
  *
6
6
  * **What a mock proves:** that our shape works — the client-credentials mint, the
7
- * latin1 decode, the year-overlap pick, the paging, the unchanged-hash skip.
7
+ * PC8/CP437 decode, the year-overlap pick, the paging, the unchanged-hash skip.
8
8
  * **What it cannot prove:** that our reading of Fortnox's API is correct. The mock IS
9
9
  * our reading. Green here means *ready to check against a real company*, which is what
10
10
  * `test/live.test.ts` does when a credential is present.
11
11
  *
12
12
  * The one thing it models with real bytes rather than a convenient string is the SIE
13
- * response: {@link FortnoxMock.sieBytes} encodes to ISO-8859-1, so a connector that
13
+ * response: {@link FortnoxMock.sieBytes} encodes to PC8/CP437, so a connector that
14
14
  * forgot to decode explicitly fails here rather than in production with mangled
15
15
  * account names.
16
16
  */
@@ -32,9 +32,27 @@ export interface FortnoxMockOptions {
32
32
  sie?: Record<number, string>;
33
33
  /** Seconds a minted token claims to live. */
34
34
  expiresIn?: number;
35
+ /**
36
+ * The one-time consent code the authorization-code exchange accepts — what a
37
+ * consent-flow test (`completeFortnoxConsent`) presents. SINGLE-use, as Fortnox's
38
+ * is: the second exchange of the same code answers `invalid_grant`, which is the
39
+ * reloaded-callback-tab case a connect flow must survive.
40
+ */
41
+ consentCode?: string;
35
42
  }
36
- /** Encode to ISO-8859-1. Any code point above 0xff becomes `?`, exactly as Fortnox would. */
37
- export declare function latin1Bytes(text: string): Uint8Array;
43
+ /**
44
+ * Encode to PC8 (code page 437) — the charset a real Fortnox SIE export declares in
45
+ * `#FORMAT` and actually sends.
46
+ *
47
+ * This used to encode ISO-8859-1, and that single wrong premise is what let a wrong
48
+ * decoder pass every test in this package: the mock encoded latin1, the reader decoded
49
+ * latin1, and the two agreed with each other while disagreeing with Fortnox. Only the
50
+ * live suite could see it. Encoding here the way the provider really does is what makes
51
+ * the mock evidence about Fortnox rather than about our own assumption.
52
+ *
53
+ * A code point with no CP437 representation becomes `?`, exactly as Fortnox would.
54
+ */
55
+ export declare function pc8Bytes(text: string): Uint8Array;
38
56
  export declare class FortnoxMock {
39
57
  readonly apiBase = "https://api.fortnox.test/3";
40
58
  readonly oauthBase = "https://apps.fortnox.test/oauth-v1";
@@ -45,6 +63,8 @@ export declare class FortnoxMock {
45
63
  private readonly years;
46
64
  private readonly sie;
47
65
  private readonly expiresIn;
66
+ /** Spends to `undefined` on the first successful exchange. */
67
+ private consentCode;
48
68
  /** Every token this mock has minted — a test asserts the mint happened exactly once. */
49
69
  readonly mints: string[];
50
70
  /** Every REST path fetched, in order. */
@@ -1 +1 @@
1
- {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAMtD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,cAAc,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpE,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,6FAA6F;AAC7F,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAOpD;AAED,qBAAa,WAAW;IACtB,QAAQ,CAAC,OAAO,gCAAgC;IAChD,QAAQ,CAAC,SAAS,wCAAwC;IAE1D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6C;IACrE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoD;IAC1E,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAM;IAC9B,yCAAyC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAM;IAE9B,YAAY,OAAO,GAAE,kBAAuB,EAe3C;IAED,iFAAiF;IACjF,MAAM,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAElD;IAED,OAAO,CAAC,IAAI;IAUZ,yCAAyC;IACzC,QAAQ,CAAC,KAAK,EAAE,SAAS,CA0DvB;CACH"}
1
+ {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAQtD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,cAAc,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpE,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAejD;AAED,qBAAa,WAAW;IACtB,QAAQ,CAAC,OAAO,gCAAgC;IAChD,QAAQ,CAAC,SAAS,wCAAwC;IAE1D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6C;IACrE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoD;IAC1E,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,8DAA8D;IAC9D,OAAO,CAAC,WAAW,CAAqB;IAExC,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAM;IAC9B,yCAAyC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAM;IAE9B,YAAY,OAAO,GAAE,kBAAuB,EAgB3C;IAED,iFAAiF;IACjF,MAAM,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAElD;IAED,OAAO,CAAC,IAAI;IAUZ,yCAAyC;IACzC,QAAQ,CAAC,KAAK,EAAE,SAAS,CA2EvB;CACH"}
package/dist/mock.js CHANGED
@@ -1,11 +1,31 @@
1
- /** Encode to ISO-8859-1. Any code point above 0xff becomes `?`, exactly as Fortnox would. */
2
- export function latin1Bytes(text) {
3
- const out = new Uint8Array(text.length);
4
- for (let i = 0; i < text.length; i += 1) {
5
- const code = text.charCodeAt(i);
6
- out[i] = code <= 0xff ? code : 0x3f;
1
+ import { CP437_HIGH } from './sie4.js';
2
+ /**
3
+ * Encode to PC8 (code page 437) — the charset a real Fortnox SIE export declares in
4
+ * `#FORMAT` and actually sends.
5
+ *
6
+ * This used to encode ISO-8859-1, and that single wrong premise is what let a wrong
7
+ * decoder pass every test in this package: the mock encoded latin1, the reader decoded
8
+ * latin1, and the two agreed with each other while disagreeing with Fortnox. Only the
9
+ * live suite could see it. Encoding here the way the provider really does is what makes
10
+ * the mock evidence about Fortnox rather than about our own assumption.
11
+ *
12
+ * A code point with no CP437 representation becomes `?`, exactly as Fortnox would.
13
+ */
14
+ export function pc8Bytes(text) {
15
+ // `for...of` iterates CODE POINTS; `text[i]` would hand back UTF-16 code units, so an
16
+ // astral character (an emoji in a voucher text, say) would split into two surrogate
17
+ // halves and emit two `?` bytes where the contract above promises one.
18
+ const out = [];
19
+ for (const ch of text) {
20
+ const code = ch.codePointAt(0) ?? 0x3f;
21
+ if (code < 0x80) {
22
+ out.push(code);
23
+ continue;
24
+ }
25
+ const high = CP437_HIGH.indexOf(ch);
26
+ out.push(high === -1 ? 0x3f : 0x80 + high);
7
27
  }
8
- return out;
28
+ return new Uint8Array(out);
9
29
  }
10
30
  export class FortnoxMock {
11
31
  apiBase = 'https://api.fortnox.test/3';
@@ -17,6 +37,8 @@ export class FortnoxMock {
17
37
  years;
18
38
  sie;
19
39
  expiresIn;
40
+ /** Spends to `undefined` on the first successful exchange. */
41
+ consentCode;
20
42
  /** Every token this mock has minted — a test asserts the mint happened exactly once. */
21
43
  mints = [];
22
44
  /** Every REST path fetched, in order. */
@@ -36,6 +58,7 @@ export class FortnoxMock {
36
58
  ];
37
59
  this.sie = options.sie ?? {};
38
60
  this.expiresIn = options.expiresIn ?? 3600;
61
+ this.consentCode = options.consentCode;
39
62
  }
40
63
  /** Replace one year's SIE payload — how a test simulates "the books changed". */
41
64
  setSie(financialYearId, text) {
@@ -47,7 +70,7 @@ export class FortnoxMock {
47
70
  ok: status >= 200 && status < 300,
48
71
  status,
49
72
  text: async () => text,
50
- arrayBuffer: async () => latin1Bytes(text).buffer,
73
+ arrayBuffer: async () => pc8Bytes(text).buffer,
51
74
  };
52
75
  }
53
76
  /** The `fetch` a connector is handed. */
@@ -61,6 +84,23 @@ export class FortnoxMock {
61
84
  if (auth !== expected) {
62
85
  return this.json({ error: 'invalid_client', error_description: 'bad client credentials' }, 401);
63
86
  }
87
+ // The consent flow's one-time exchange: no TenantId header (the exchange is what
88
+ // DISCOVERS the company), and the code spends on first use.
89
+ if (String(init?.body ?? '').includes('grant_type=authorization_code')) {
90
+ const code = new URLSearchParams(String(init?.body ?? '')).get('code') ?? undefined;
91
+ if (this.consentCode === undefined || code !== this.consentCode) {
92
+ return this.json({ error: 'invalid_grant', error_description: 'code spent or unknown' }, 400);
93
+ }
94
+ this.consentCode = undefined;
95
+ const token = `consent-token-${this.mints.length + 1}`;
96
+ this.mints.push(token);
97
+ return this.json({
98
+ access_token: token,
99
+ token_type: 'bearer',
100
+ expires_in: this.expiresIn,
101
+ scope: 'bookkeeping companyinformation',
102
+ });
103
+ }
64
104
  if ((headers['TenantId'] ?? '') !== this.tenantId) {
65
105
  // Fortnox answers 400 here, not 404 — a wrong TenantId reads like a bad client
66
106
  // pair unless the message is surfaced, which is why the connector surfaces it.
@@ -97,7 +137,7 @@ export class FortnoxMock {
97
137
  if (text === undefined) {
98
138
  return this.json({ ErrorInformation: { message: 'no such financial year' } }, 404);
99
139
  }
100
- const bytes = latin1Bytes(text);
140
+ const bytes = pc8Bytes(text);
101
141
  return {
102
142
  ok: true,
103
143
  status: 200,
package/dist/mock.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mock.js","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mock.js","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAyCvC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,sFAAsF;IACtF,oFAAoF;IACpF,uEAAuE;IACvE,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QACvC,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC;YAChB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,OAAO,WAAW;IACb,OAAO,GAAG,4BAA4B,CAAC;IACvC,SAAS,GAAG,oCAAoC,CAAC;IAEzC,QAAQ,CAAS;IACjB,YAAY,CAAS;IACrB,QAAQ,CAAS;IACjB,OAAO,CAA6C;IACpD,KAAK,CAAoD;IACzD,GAAG,CAAyB;IAC5B,SAAS,CAAS;IACnC,8DAA8D;IACtD,WAAW,CAAqB;IAExC,wFAAwF;IAC/E,KAAK,GAAa,EAAE,CAAC;IAC9B,yCAAyC;IAChC,KAAK,GAAa,EAAE,CAAC;IAE9B,YAAY,OAAO,GAAuB,EAAE;QAC1C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,WAAW,CAAC;QAChD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,eAAe,CAAC;QAC5D,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC;QAC7C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI;YAChC,WAAW,EAAE,gBAAgB;YAC7B,kBAAkB,EAAE,aAAa;YACjC,cAAc,EAAE,MAAM;SACvB,CAAC;QACF,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,cAAc,IAAI;YACrC,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE;YACvD,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE;SACxD,CAAC;QACF,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;QAC3C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACzC,CAAC;IAED,iFAAiF;IACjF,MAAM,CAAC,eAAuB,EAAE,IAAY;QAC1C,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC;IACnC,CAAC;IAEO,IAAI,CAAC,IAAa,EAAE,MAAM,GAAG,GAAG;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClC,OAAO;YACL,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG;YACjC,MAAM;YACN,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;YACtB,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAqB;SAC5B,CAAC;IACtC,CAAC;IAED,yCAAyC;IAChC,KAAK,GAAc,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAChD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC;QAEvC,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAA2B,CAAC;YAChE,MAAM,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,SAAS,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC;YAC1E,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,EAAE,GAAG,CAAC,CAAC;YAClG,CAAC;YACD,iFAAiF;YACjF,4DAA4D;YAC5D,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC,EAAE,CAAC;gBACvE,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;gBACpF,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;oBAChE,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,EAAE,GAAG,CAAC,CAAC;gBAChG,CAAC;gBACD,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;gBAC7B,MAAM,KAAK,GAAG,iBAAiB,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACvB,OAAO,IAAI,CAAC,IAAI,CAAC;oBACf,YAAY,EAAE,KAAK;oBACnB,UAAU,EAAE,QAAQ;oBACpB,UAAU,EAAE,IAAI,CAAC,SAAS;oBAC1B,KAAK,EAAE,gCAAgC;iBACxC,CAAC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClD,+EAA+E;gBAC/E,+EAA+E;gBAC/E,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,EAAE,GAAG,CAAC,CAAC;YAC3F,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC,EAAE,CAAC;gBACxE,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,EAAE,GAAG,CAAC,CAAC;YAC7D,CAAC;YACD,MAAM,KAAK,GAAG,SAAS,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC,IAAI,CAAC;gBACf,YAAY,EAAE,KAAK;gBACnB,UAAU,EAAE,QAAQ;gBACpB,UAAU,EAAE,IAAI,CAAC,SAAS;gBAC1B,KAAK,EAAE,gCAAgC;aACxC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAA2B,CAAC;QAChE,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtB,IAAI,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,QAAQ,GAAG,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,EAAE,OAAO,EAAE,wBAAwB,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;YACrF,CAAC;YACD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC7B,OAAO;gBACL,EAAE,EAAE,IAAI;gBACR,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;gBACtB,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,MAAqB;aACnB,CAAC;QACtC,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,EAAE,OAAO,EAAE,iBAAiB,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IACpF,CAAC,CAAC;CACH"}
package/dist/sie4.d.ts CHANGED
@@ -4,7 +4,8 @@
4
4
  * per-voucher REST endpoints.
5
5
  *
6
6
  * Deliberately a parser over a *text* input, with no I/O of its own: the decoding
7
- * from ISO-8859-1 happens at the seam that owns the bytes ({@link FortnoxApi.sieFile}),
7
+ * from PC8/CP437 happens in {@link decodeSie} below, called at the seam that owns the
8
+ * bytes ({@link FortnoxApi.sieFile}),
8
9
  * so this file is pure and testable against a fixture, and a caller reading SIE from
9
10
  * somewhere else (an upload, an archive) can use it unchanged.
10
11
  *
@@ -22,6 +23,39 @@
22
23
  * ignored rather than fatal: SIE files carry vendor extensions, and refusing a
23
24
  * file over a post we do not read would break on a Fortnox release that adds one.
24
25
  */
26
+ /**
27
+ * Bytes 0x80–0xFF of code page 437, in order — the half of PC8 that is not ASCII.
28
+ *
29
+ * Generated from the code page, not typed from memory. Only the Swedish letters are
30
+ * load-bearing here (0x84 ä, 0x86 å, 0x8E Ä, 0x8F Å, 0x94 ö, 0x99 Ö), but a partial
31
+ * table would silently mangle everything else, so the whole upper half is present.
32
+ */
33
+ export declare const CP437_HIGH: string;
34
+ /**
35
+ * Decode a SIE file's bytes, honouring the charset it declares in `#FORMAT`.
36
+ *
37
+ * ## Why this is not `TextDecoder`
38
+ *
39
+ * SIE4 files are **PC8, which is code page 437** — an MS-DOS charset that predates the
40
+ * standard and is NOT in the WHATWG Encoding registry, so `new TextDecoder('cp437')`
41
+ * throws `RangeError` in every runtime. There is no web-standard decoder to reach for,
42
+ * which is why the table above exists rather than an import.
43
+ *
44
+ * ## Why the wrong decoder was invisible
45
+ *
46
+ * This previously decoded as `iso-8859-1`, and nothing complained — twice over. Every
47
+ * byte 0x00–0xFF is a valid latin1 code point, so a mis-decode can never produce U+FFFD
48
+ * and the "no replacement character" check that guarded this could not fail by
49
+ * construction. And `TextDecoder('iso-8859-1')` is really **windows-1252**, so Fortnox's
50
+ * `0x94` ö arrived as `”`. The result was correct-looking Swedish account names with the
51
+ * wrong letters in them — wrong data on a screen, never a throw. Confirmed against
52
+ * api.fortnox.se 2026-09-03, whose export declares `#FORMAT PC8`.
53
+ *
54
+ * A file declaring any other charset is REFUSED rather than decoded on a guess: PC8 is
55
+ * what SIE4 mandates and what every Fortnox export observed so far sends, and a wrong
56
+ * guess is invisible rather than loud.
57
+ */
58
+ export declare function decodeSie(bytes: ArrayBuffer | Uint8Array): string;
25
59
  /** A parsed `#KONTO` — the chart of accounts. */
26
60
  export interface SieAccount {
27
61
  number: string;
@@ -1 +1 @@
1
- {"version":3,"file":"sie4.d.ts","sourceRoot":"","sources":["../src/sie4.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,iDAAiD;AACjD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,mFAAmF;AACnF,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,cAAc,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3C,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA0DnD;AAgBD,4EAA4E;AAC5E,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAiBzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAkGjD"}
1
+ {"version":3,"file":"sie4.d.ts","sourceRoot":"","sources":["../src/sie4.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,QAQ6E,CAAC;AAErG;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,MAAM,CAuBjE;AAED,iDAAiD;AACjD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,mFAAmF;AACnF,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,cAAc,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3C,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA0DnD;AAgBD,4EAA4E;AAC5E,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAiBzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAkGjD"}
package/dist/sie4.js CHANGED
@@ -4,7 +4,8 @@
4
4
  * per-voucher REST endpoints.
5
5
  *
6
6
  * Deliberately a parser over a *text* input, with no I/O of its own: the decoding
7
- * from ISO-8859-1 happens at the seam that owns the bytes ({@link FortnoxApi.sieFile}),
7
+ * from PC8/CP437 happens in {@link decodeSie} below, called at the seam that owns the
8
+ * bytes ({@link FortnoxApi.sieFile}),
8
9
  * so this file is pure and testable against a fixture, and a caller reading SIE from
9
10
  * somewhere else (an upload, an archive) can use it unchanged.
10
11
  *
@@ -22,6 +23,65 @@
22
23
  * ignored rather than fatal: SIE files carry vendor extensions, and refusing a
23
24
  * file over a post we do not read would break on a Fortnox release that adds one.
24
25
  */
26
+ /**
27
+ * Bytes 0x80–0xFF of code page 437, in order — the half of PC8 that is not ASCII.
28
+ *
29
+ * Generated from the code page, not typed from memory. Only the Swedish letters are
30
+ * load-bearing here (0x84 ä, 0x86 å, 0x8E Ä, 0x8F Å, 0x94 ö, 0x99 Ö), but a partial
31
+ * table would silently mangle everything else, so the whole upper half is present.
32
+ */
33
+ export const CP437_HIGH = '\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5' +
34
+ '\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00a2\u00a3\u00a5\u20a7\u0192' +
35
+ '\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb' +
36
+ '\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510' +
37
+ '\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567' +
38
+ '\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580' +
39
+ '\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u00b5\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229' +
40
+ '\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u00a0';
41
+ /**
42
+ * Decode a SIE file's bytes, honouring the charset it declares in `#FORMAT`.
43
+ *
44
+ * ## Why this is not `TextDecoder`
45
+ *
46
+ * SIE4 files are **PC8, which is code page 437** — an MS-DOS charset that predates the
47
+ * standard and is NOT in the WHATWG Encoding registry, so `new TextDecoder('cp437')`
48
+ * throws `RangeError` in every runtime. There is no web-standard decoder to reach for,
49
+ * which is why the table above exists rather than an import.
50
+ *
51
+ * ## Why the wrong decoder was invisible
52
+ *
53
+ * This previously decoded as `iso-8859-1`, and nothing complained — twice over. Every
54
+ * byte 0x00–0xFF is a valid latin1 code point, so a mis-decode can never produce U+FFFD
55
+ * and the "no replacement character" check that guarded this could not fail by
56
+ * construction. And `TextDecoder('iso-8859-1')` is really **windows-1252**, so Fortnox's
57
+ * `0x94` ö arrived as `”`. The result was correct-looking Swedish account names with the
58
+ * wrong letters in them — wrong data on a screen, never a throw. Confirmed against
59
+ * api.fortnox.se 2026-09-03, whose export declares `#FORMAT PC8`.
60
+ *
61
+ * A file declaring any other charset is REFUSED rather than decoded on a guess: PC8 is
62
+ * what SIE4 mandates and what every Fortnox export observed so far sends, and a wrong
63
+ * guess is invisible rather than loud.
64
+ */
65
+ export function decodeSie(bytes) {
66
+ const view = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
67
+ // `#FORMAT` is ASCII and sits in the header, so it can be read before the charset is
68
+ // known — the one thing safe to decode without having decided first.
69
+ const header = String.fromCharCode(...view.subarray(0, 512));
70
+ const declared = /^#FORMAT\s+"?([A-Za-z0-9-]+)"?/m.exec(header)?.[1]?.toUpperCase();
71
+ if (declared !== undefined && declared !== 'PC8') {
72
+ // Refusing beats guessing. Reading a charset wrong does not throw anywhere
73
+ // downstream — it yields plausible Swedish account names with the wrong letters,
74
+ // which is precisely the failure that survived a year of green tests here.
75
+ throw new Error(`SIE #FORMAT ${declared} is not supported — this reader implements PC8 (CP437) only`);
76
+ }
77
+ let out = '';
78
+ for (const byte of view) {
79
+ // The index is provably in range (0x00–0x7F took the other branch), so the
80
+ // fallback is unreachable; it is here only because the compiler cannot see that.
81
+ out += byte < 0x80 ? String.fromCharCode(byte) : (CP437_HIGH[byte - 0x80] ?? '\ufffd');
82
+ }
83
+ return out;
84
+ }
25
85
  /**
26
86
  * Split one SIE line into fields, honouring quoting and object lists.
27
87
  *
package/dist/sie4.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sie4.js","sourceRoot":"","sources":["../src/sie4.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sie4.js","sourceRoot":"","sources":["../src/sie4.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@substrat-run/connector-fortnox",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Substrat connector: Fortnox accounting (Swedish). Reads a company's bookkeeping as SIE4 on a poll and lands it into a scope through the vertical's own operation. Auth is OAuth2 client-credentials against a service consent, so there is no refresh token to rotate. Host code — swept on a ScopeHost, never module code.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
@@ -24,22 +24,22 @@
24
24
  "default": "./dist/index.js"
25
25
  }
26
26
  },
27
- "scripts": {
28
- "build": "tsc -p tsconfig.json",
29
- "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
30
- "test": "vitest run"
31
- },
32
27
  "dependencies": {
33
- "@substrat-run/contracts": "workspace:^",
34
- "@substrat-run/kernel": "workspace:^"
28
+ "@substrat-run/contracts": "^0.98.1",
29
+ "@substrat-run/kernel": "^0.98.1"
35
30
  },
36
31
  "devDependencies": {
37
- "@substrat-run/adapter-sqlite": "workspace:^",
38
- "typescript": "catalog:",
39
- "vitest": "catalog:",
40
- "zod": "catalog:"
32
+ "typescript": "^7.0.0",
33
+ "vitest": "^3.2.7",
34
+ "zod": "^4.4.3",
35
+ "@substrat-run/adapter-sqlite": "^0.98.1"
41
36
  },
42
37
  "peerDependencies": {
43
38
  "zod": "^4.4.0"
39
+ },
40
+ "scripts": {
41
+ "build": "tsc -p tsconfig.json",
42
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
43
+ "test": "vitest run"
44
44
  }
45
- }
45
+ }