@kreiseck/kasseneck-api 0.6.7
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/LICENSE +201 -0
- package/NOTICE +2 -0
- package/README.md +206 -0
- package/dist/cjs/client/api.d.ts +75 -0
- package/dist/cjs/client/api.js +40 -0
- package/dist/cjs/client/auth.d.ts +52 -0
- package/dist/cjs/client/auth.js +72 -0
- package/dist/cjs/client/cashregisters.d.ts +21 -0
- package/dist/cjs/client/cashregisters.js +36 -0
- package/dist/cjs/client/errors.d.ts +159 -0
- package/dist/cjs/client/errors.js +226 -0
- package/dist/cjs/client/index.d.ts +8 -0
- package/dist/cjs/client/index.js +44 -0
- package/dist/cjs/client/receipts.d.ts +245 -0
- package/dist/cjs/client/receipts.js +452 -0
- package/dist/cjs/client/reports.d.ts +43 -0
- package/dist/cjs/client/reports.js +73 -0
- package/dist/cjs/client/status.d.ts +43 -0
- package/dist/cjs/client/status.js +47 -0
- package/dist/cjs/client/transport.d.ts +117 -0
- package/dist/cjs/client/transport.js +312 -0
- package/dist/cjs/enums/credit-card-provider.d.ts +22 -0
- package/dist/cjs/enums/credit-card-provider.js +23 -0
- package/dist/cjs/enums/define-enum.d.ts +15 -0
- package/dist/cjs/enums/define-enum.js +16 -0
- package/dist/cjs/enums/index.d.ts +7 -0
- package/dist/cjs/enums/index.js +17 -0
- package/dist/cjs/enums/keck-payment-method.d.ts +57 -0
- package/dist/cjs/enums/keck-payment-method.js +23 -0
- package/dist/cjs/enums/receipt-type.d.ts +41 -0
- package/dist/cjs/enums/receipt-type.js +18 -0
- package/dist/cjs/enums/stripe-link-mode.d.ts +17 -0
- package/dist/cjs/enums/stripe-link-mode.js +18 -0
- package/dist/cjs/enums/vat-rate.d.ts +40 -0
- package/dist/cjs/enums/vat-rate.js +19 -0
- package/dist/cjs/enums/voucher-action.d.ts +10 -0
- package/dist/cjs/enums/voucher-action.js +11 -0
- package/dist/cjs/enums/voucher-type.d.ts +9 -0
- package/dist/cjs/enums/voucher-type.js +10 -0
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.js +97 -0
- package/dist/cjs/kasse/artikel.d.ts +83 -0
- package/dist/cjs/kasse/artikel.js +79 -0
- package/dist/cjs/kasse/client.d.ts +10 -0
- package/dist/cjs/kasse/client.js +38 -0
- package/dist/cjs/kasse/drucker.d.ts +54 -0
- package/dist/cjs/kasse/drucker.js +41 -0
- package/dist/cjs/kasse/index.d.ts +11 -0
- package/dist/cjs/kasse/index.js +38 -0
- package/dist/cjs/kasse/settings.d.ts +115 -0
- package/dist/cjs/kasse/settings.js +62 -0
- package/dist/cjs/models/cancellation.d.ts +51 -0
- package/dist/cjs/models/cancellation.js +45 -0
- package/dist/cjs/models/cashregister.d.ts +77 -0
- package/dist/cjs/models/cashregister.js +53 -0
- package/dist/cjs/models/enum-payload.d.ts +26 -0
- package/dist/cjs/models/enum-payload.js +50 -0
- package/dist/cjs/models/hobex-receipt.d.ts +63 -0
- package/dist/cjs/models/hobex-receipt.js +86 -0
- package/dist/cjs/models/index.d.ts +10 -0
- package/dist/cjs/models/index.js +46 -0
- package/dist/cjs/models/receipt-company.d.ts +71 -0
- package/dist/cjs/models/receipt-company.js +52 -0
- package/dist/cjs/models/receipt-item.d.ts +100 -0
- package/dist/cjs/models/receipt-item.js +108 -0
- package/dist/cjs/models/receipt-summary.d.ts +92 -0
- package/dist/cjs/models/receipt-summary.js +54 -0
- package/dist/cjs/models/receipt.d.ts +108 -0
- package/dist/cjs/models/receipt.js +119 -0
- package/dist/cjs/models/report-month.d.ts +32 -0
- package/dist/cjs/models/report-month.js +65 -0
- package/dist/cjs/models/stripe-url-session.d.ts +18 -0
- package/dist/cjs/models/stripe-url-session.js +20 -0
- package/dist/cjs/models/voucher.d.ts +41 -0
- package/dist/cjs/models/voucher.js +56 -0
- package/dist/cjs/money.d.ts +23 -0
- package/dist/cjs/money.js +35 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/payments/hobex.d.ts +87 -0
- package/dist/cjs/payments/hobex.js +167 -0
- package/dist/cjs/payments/index.d.ts +33 -0
- package/dist/cjs/payments/index.js +42 -0
- package/dist/cjs/payments/stripe.d.ts +61 -0
- package/dist/cjs/payments/stripe.js +157 -0
- package/dist/cjs/printing/escpos.d.ts +219 -0
- package/dist/cjs/printing/escpos.js +636 -0
- package/dist/cjs/printing/index.d.ts +3 -0
- package/dist/cjs/printing/index.js +33 -0
- package/dist/cjs/printing/printable.d.ts +27 -0
- package/dist/cjs/printing/printable.js +90 -0
- package/dist/cjs/printing/webusb.d.ts +89 -0
- package/dist/cjs/printing/webusb.js +110 -0
- package/dist/cjs/react/index.d.ts +46 -0
- package/dist/cjs/react/index.js +51 -0
- package/dist/cjs/receipt/discount.d.ts +12 -0
- package/dist/cjs/receipt/discount.js +54 -0
- package/dist/cjs/receipt/epos.d.ts +53 -0
- package/dist/cjs/receipt/epos.js +95 -0
- package/dist/cjs/receipt/grid.d.ts +47 -0
- package/dist/cjs/receipt/grid.js +122 -0
- package/dist/cjs/receipt/index.d.ts +4 -0
- package/dist/cjs/receipt/index.js +29 -0
- package/dist/cjs/receipt/layout-escpos.d.ts +35 -0
- package/dist/cjs/receipt/layout-escpos.js +67 -0
- package/dist/cjs/receipt/layout.d.ts +180 -0
- package/dist/cjs/receipt/layout.js +594 -0
- package/dist/cjs/register/index.d.ts +51 -0
- package/dist/cjs/register/index.js +61 -0
- package/dist/cjs/register/pairing.d.ts +248 -0
- package/dist/cjs/register/pairing.js +279 -0
- package/dist/cjs/register/session.d.ts +37 -0
- package/dist/cjs/register/session.js +52 -0
- package/dist/cjs/vienna-time.d.ts +23 -0
- package/dist/cjs/vienna-time.js +114 -0
- package/dist/esm/client/api.d.ts +75 -0
- package/dist/esm/client/api.js +37 -0
- package/dist/esm/client/auth.d.ts +52 -0
- package/dist/esm/client/auth.js +68 -0
- package/dist/esm/client/cashregisters.d.ts +21 -0
- package/dist/esm/client/cashregisters.js +33 -0
- package/dist/esm/client/errors.d.ts +159 -0
- package/dist/esm/client/errors.js +212 -0
- package/dist/esm/client/index.d.ts +8 -0
- package/dist/esm/client/index.js +8 -0
- package/dist/esm/client/receipts.d.ts +245 -0
- package/dist/esm/client/receipts.js +438 -0
- package/dist/esm/client/reports.d.ts +43 -0
- package/dist/esm/client/reports.js +69 -0
- package/dist/esm/client/status.d.ts +43 -0
- package/dist/esm/client/status.js +43 -0
- package/dist/esm/client/transport.d.ts +117 -0
- package/dist/esm/client/transport.js +307 -0
- package/dist/esm/enums/credit-card-provider.d.ts +22 -0
- package/dist/esm/enums/credit-card-provider.js +20 -0
- package/dist/esm/enums/define-enum.d.ts +15 -0
- package/dist/esm/enums/define-enum.js +13 -0
- package/dist/esm/enums/index.d.ts +7 -0
- package/dist/esm/enums/index.js +7 -0
- package/dist/esm/enums/keck-payment-method.d.ts +57 -0
- package/dist/esm/enums/keck-payment-method.js +20 -0
- package/dist/esm/enums/receipt-type.d.ts +41 -0
- package/dist/esm/enums/receipt-type.js +15 -0
- package/dist/esm/enums/stripe-link-mode.d.ts +17 -0
- package/dist/esm/enums/stripe-link-mode.js +15 -0
- package/dist/esm/enums/vat-rate.d.ts +40 -0
- package/dist/esm/enums/vat-rate.js +16 -0
- package/dist/esm/enums/voucher-action.d.ts +10 -0
- package/dist/esm/enums/voucher-action.js +8 -0
- package/dist/esm/enums/voucher-type.d.ts +9 -0
- package/dist/esm/enums/voucher-type.js +7 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/kasse/artikel.d.ts +83 -0
- package/dist/esm/kasse/artikel.js +70 -0
- package/dist/esm/kasse/client.d.ts +10 -0
- package/dist/esm/kasse/client.js +33 -0
- package/dist/esm/kasse/drucker.d.ts +54 -0
- package/dist/esm/kasse/drucker.js +36 -0
- package/dist/esm/kasse/index.d.ts +11 -0
- package/dist/esm/kasse/index.js +13 -0
- package/dist/esm/kasse/settings.d.ts +115 -0
- package/dist/esm/kasse/settings.js +58 -0
- package/dist/esm/models/cancellation.d.ts +51 -0
- package/dist/esm/models/cancellation.js +40 -0
- package/dist/esm/models/cashregister.d.ts +77 -0
- package/dist/esm/models/cashregister.js +50 -0
- package/dist/esm/models/enum-payload.d.ts +26 -0
- package/dist/esm/models/enum-payload.js +44 -0
- package/dist/esm/models/hobex-receipt.d.ts +63 -0
- package/dist/esm/models/hobex-receipt.js +80 -0
- package/dist/esm/models/index.d.ts +10 -0
- package/dist/esm/models/index.js +10 -0
- package/dist/esm/models/receipt-company.d.ts +71 -0
- package/dist/esm/models/receipt-company.js +48 -0
- package/dist/esm/models/receipt-item.d.ts +100 -0
- package/dist/esm/models/receipt-item.js +101 -0
- package/dist/esm/models/receipt-summary.d.ts +92 -0
- package/dist/esm/models/receipt-summary.js +49 -0
- package/dist/esm/models/receipt.d.ts +108 -0
- package/dist/esm/models/receipt.js +113 -0
- package/dist/esm/models/report-month.d.ts +32 -0
- package/dist/esm/models/report-month.js +58 -0
- package/dist/esm/models/stripe-url-session.d.ts +18 -0
- package/dist/esm/models/stripe-url-session.js +16 -0
- package/dist/esm/models/voucher.d.ts +41 -0
- package/dist/esm/models/voucher.js +51 -0
- package/dist/esm/money.d.ts +23 -0
- package/dist/esm/money.js +31 -0
- package/dist/esm/payments/hobex.d.ts +87 -0
- package/dist/esm/payments/hobex.js +162 -0
- package/dist/esm/payments/index.d.ts +33 -0
- package/dist/esm/payments/index.js +33 -0
- package/dist/esm/payments/stripe.d.ts +61 -0
- package/dist/esm/payments/stripe.js +153 -0
- package/dist/esm/printing/escpos.d.ts +219 -0
- package/dist/esm/printing/escpos.js +616 -0
- package/dist/esm/printing/index.d.ts +3 -0
- package/dist/esm/printing/index.js +3 -0
- package/dist/esm/printing/printable.d.ts +27 -0
- package/dist/esm/printing/printable.js +87 -0
- package/dist/esm/printing/webusb.d.ts +89 -0
- package/dist/esm/printing/webusb.js +101 -0
- package/dist/esm/react/index.d.ts +46 -0
- package/dist/esm/react/index.js +47 -0
- package/dist/esm/receipt/discount.d.ts +12 -0
- package/dist/esm/receipt/discount.js +51 -0
- package/dist/esm/receipt/epos.d.ts +53 -0
- package/dist/esm/receipt/epos.js +86 -0
- package/dist/esm/receipt/grid.d.ts +47 -0
- package/dist/esm/receipt/grid.js +116 -0
- package/dist/esm/receipt/index.d.ts +4 -0
- package/dist/esm/receipt/index.js +4 -0
- package/dist/esm/receipt/layout-escpos.d.ts +35 -0
- package/dist/esm/receipt/layout-escpos.js +64 -0
- package/dist/esm/receipt/layout.d.ts +180 -0
- package/dist/esm/receipt/layout.js +583 -0
- package/dist/esm/register/index.d.ts +51 -0
- package/dist/esm/register/index.js +51 -0
- package/dist/esm/register/pairing.d.ts +248 -0
- package/dist/esm/register/pairing.js +270 -0
- package/dist/esm/register/session.d.ts +37 -0
- package/dist/esm/register/session.js +48 -0
- package/dist/esm/vienna-time.d.ts +23 -0
- package/dist/esm/vienna-time.js +110 -0
- package/fixtures/belege/langer-artikelname.json +43 -0
- package/fixtures/belege/null-ausfall.json +41 -0
- package/fixtures/belege/null-jahr.json +41 -0
- package/fixtures/belege/null-monat.json +41 -0
- package/fixtures/belege/null-pruef.json +41 -0
- package/fixtures/belege/null-schluss.json +41 -0
- package/fixtures/belege/null-start.json +40 -0
- package/fixtures/belege/rabattzeilen.json +61 -0
- package/fixtures/belege/signaturausfall-verkauf.json +49 -0
- package/fixtures/belege/storno-teil.json +48 -0
- package/fixtures/belege/storno-voll.json +54 -0
- package/fixtures/belege/testkasse-verkauf.json +50 -0
- package/fixtures/belege/testsignatur-verkauf.json +50 -0
- package/fixtures/belege/training.json +49 -0
- package/fixtures/belege/verkauf-bar.json +49 -0
- package/fixtures/belege/verkauf-karte.json +49 -0
- package/fixtures/belege/verkauf-kleinunternehmer.json +42 -0
- package/fixtures/erwartet/langer-artikelname.grid32.txt +25 -0
- package/fixtures/erwartet/langer-artikelname.grid48.txt +24 -0
- package/fixtures/erwartet/langer-artikelname.lines.json +216 -0
- package/fixtures/erwartet/null-ausfall.grid32.txt +28 -0
- package/fixtures/erwartet/null-ausfall.grid48.txt +25 -0
- package/fixtures/erwartet/null-ausfall.lines.json +220 -0
- package/fixtures/erwartet/null-jahr.grid32.txt +29 -0
- package/fixtures/erwartet/null-jahr.grid48.txt +25 -0
- package/fixtures/erwartet/null-jahr.lines.json +220 -0
- package/fixtures/erwartet/null-monat.grid32.txt +28 -0
- package/fixtures/erwartet/null-monat.grid48.txt +25 -0
- package/fixtures/erwartet/null-monat.lines.json +220 -0
- package/fixtures/erwartet/null-pruef.grid32.txt +28 -0
- package/fixtures/erwartet/null-pruef.grid48.txt +25 -0
- package/fixtures/erwartet/null-pruef.lines.json +220 -0
- package/fixtures/erwartet/null-schluss.grid32.txt +28 -0
- package/fixtures/erwartet/null-schluss.grid48.txt +25 -0
- package/fixtures/erwartet/null-schluss.lines.json +220 -0
- package/fixtures/erwartet/null-start.grid32.txt +28 -0
- package/fixtures/erwartet/null-start.grid48.txt +25 -0
- package/fixtures/erwartet/null-start.lines.json +220 -0
- package/fixtures/erwartet/rabattzeilen.grid32.txt +27 -0
- package/fixtures/erwartet/rabattzeilen.grid48.txt +26 -0
- package/fixtures/erwartet/rabattzeilen.lines.json +286 -0
- package/fixtures/erwartet/signaturausfall-verkauf.grid32.txt +28 -0
- package/fixtures/erwartet/signaturausfall-verkauf.grid48.txt +26 -0
- package/fixtures/erwartet/signaturausfall-verkauf.lines.json +266 -0
- package/fixtures/erwartet/storno-teil.grid32.txt +27 -0
- package/fixtures/erwartet/storno-teil.grid48.txt +26 -0
- package/fixtures/erwartet/storno-teil.lines.json +237 -0
- package/fixtures/erwartet/storno-voll.grid32.txt +29 -0
- package/fixtures/erwartet/storno-voll.grid48.txt +28 -0
- package/fixtures/erwartet/storno-voll.lines.json +277 -0
- package/fixtures/erwartet/testkasse-verkauf.grid32.txt +28 -0
- package/fixtures/erwartet/testkasse-verkauf.grid48.txt +27 -0
- package/fixtures/erwartet/testkasse-verkauf.lines.json +270 -0
- package/fixtures/erwartet/testsignatur-verkauf.grid32.txt +30 -0
- package/fixtures/erwartet/testsignatur-verkauf.grid48.txt +27 -0
- package/fixtures/erwartet/testsignatur-verkauf.lines.json +270 -0
- package/fixtures/erwartet/training.grid32.txt +33 -0
- package/fixtures/erwartet/training.grid48.txt +30 -0
- package/fixtures/erwartet/training.lines.json +277 -0
- package/fixtures/erwartet/verkauf-bar.grid32.txt +25 -0
- package/fixtures/erwartet/verkauf-bar.grid48.txt +24 -0
- package/fixtures/erwartet/verkauf-bar.lines.json +256 -0
- package/fixtures/erwartet/verkauf-karte.grid32.txt +25 -0
- package/fixtures/erwartet/verkauf-karte.grid48.txt +24 -0
- package/fixtures/erwartet/verkauf-karte.lines.json +256 -0
- package/fixtures/erwartet/verkauf-kleinunternehmer.grid32.txt +26 -0
- package/fixtures/erwartet/verkauf-kleinunternehmer.grid48.txt +25 -0
- package/fixtures/erwartet/verkauf-kleinunternehmer.lines.json +226 -0
- package/fixtures/manifest.json +107 -0
- package/package.json +135 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { KasseneckAuth } from './auth.js';
|
|
2
|
+
/**
|
|
3
|
+
* Transport zum Kasseneck-Backend: ein Aufruf ist ein POST an
|
|
4
|
+
* `<basis>/<funktionsname>` mit dem JSON-Rumpf `{ "params": { … } }` — wie im
|
|
5
|
+
* Flutter-Zwilling `kasseneck_api`.
|
|
6
|
+
*
|
|
7
|
+
* Der Transport macht drei Dinge und sonst nichts: Anfrage bauen (Kopfzeilen
|
|
8
|
+
* von der Anmeldung, Nutzlast aus Auth-Parametern und Aufruferparametern),
|
|
9
|
+
* Zeitlimit ueberwachen, und die Antworthuelle aufloesen. Er kennt keine
|
|
10
|
+
* einzelne Backend-Funktion und keine Firebase-Details.
|
|
11
|
+
*
|
|
12
|
+
* Es gibt **zwei Einstiegspunkte** auf demselben Kern: [createTransport] fuer
|
|
13
|
+
* die JSON-Aufrufe und [createBinaryTransport] fuer die beiden Bericht-
|
|
14
|
+
* Downloads, die ein PDF liefern. Anmeldung, Zeitlimit, Rumpfaufbau und die
|
|
15
|
+
* Fehlerarten sind bei beiden dieselben; sie unterscheiden sich nur darin, wie
|
|
16
|
+
* der Antwortrumpf gelesen und ausgewertet wird.
|
|
17
|
+
*
|
|
18
|
+
* **Kein Wiederholen fehlgeschlagener Aufrufe.** Ein Beleg ist nicht folgenlos
|
|
19
|
+
* wiederholbar; ohne entschiedene Idempotenz waere ein automatischer zweiter
|
|
20
|
+
* Versuch ein zweiter Beleg.
|
|
21
|
+
*/
|
|
22
|
+
/** Basis-URL der Produktion. */
|
|
23
|
+
export declare const DEFAULT_BASE_URL = "https://api.kasseneck.at/v1";
|
|
24
|
+
/**
|
|
25
|
+
* Zeitlimit je Aufruf (wie im Flutter-Zwilling). Ohne Zeitlimit bleibt eine
|
|
26
|
+
* haengende Anfrage fuer immer offen — der Aufrufer bekaeme weder Ergebnis
|
|
27
|
+
* noch Fehler.
|
|
28
|
+
*/
|
|
29
|
+
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
30
|
+
/**
|
|
31
|
+
* Der Teil einer `fetch`-Antwort, den dieser Transport braucht. Bewusst
|
|
32
|
+
* minimal, damit Tests ohne echtes Netz eine Antwort stellen koennen; das
|
|
33
|
+
* globale `fetch` erfuellt diese Form.
|
|
34
|
+
*/
|
|
35
|
+
export interface HttpResponseLike {
|
|
36
|
+
status: number;
|
|
37
|
+
headers: {
|
|
38
|
+
get(name: string): string | null;
|
|
39
|
+
};
|
|
40
|
+
text(): Promise<string>;
|
|
41
|
+
/**
|
|
42
|
+
* Rohe Bytes der Antwort — der Binaerweg ([createBinaryTransport]) liest
|
|
43
|
+
* ausschliesslich sie. Bewusst **verpflichtend**: jede `fetch`-Antwort bringt
|
|
44
|
+
* die Methode mit, betroffen sind nur Attrappen — und eine Attrappe ohne
|
|
45
|
+
* Bytes bringt einen Test dazu, den Binaerweg nie zu erreichen und trotzdem
|
|
46
|
+
* gruen zu melden. Dieser Fehler gehoert an die Bauzeit, nicht in die
|
|
47
|
+
* Laufzeit.
|
|
48
|
+
*/
|
|
49
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
50
|
+
}
|
|
51
|
+
export interface HttpRequestInit {
|
|
52
|
+
method: string;
|
|
53
|
+
headers: Record<string, string>;
|
|
54
|
+
body: string;
|
|
55
|
+
signal: AbortSignal;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Austauschbare `fetch`-Umsetzung. Vorgabe ist das globale `fetch` (Node
|
|
59
|
+
* >= 20.18 und jeder Browser bringen es mit) — dieses Paket haengt an keiner
|
|
60
|
+
* HTTP-Bibliothek.
|
|
61
|
+
*/
|
|
62
|
+
export type FetchLike = (url: string, init: HttpRequestInit) => Promise<HttpResponseLike>;
|
|
63
|
+
export interface TransportOptions {
|
|
64
|
+
/** Anmeldung; wird pro Aufruf befragt. */
|
|
65
|
+
auth: KasseneckAuth;
|
|
66
|
+
/** Abweichende Basis-URL (z. B. eigene Rewrites der Browser-Kasse). */
|
|
67
|
+
baseUrl?: string;
|
|
68
|
+
/** Zeitlimit je Aufruf in Millisekunden. */
|
|
69
|
+
timeoutMs?: number;
|
|
70
|
+
/** Eigene `fetch`-Umsetzung (Tests, Proxys). */
|
|
71
|
+
fetch?: FetchLike;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Ruft eine Backend-Funktion auf und liefert deren Nutzlast **ohne Huelle**.
|
|
75
|
+
* Ein Verbraucher prueft nie selbst auf `status`: Misserfolg kommt als
|
|
76
|
+
* geworfener Fehler.
|
|
77
|
+
*
|
|
78
|
+
* `extraBodyFields` legt zusaetzliche Felder **neben** `params` auf die oberste
|
|
79
|
+
* Rumpfebene. Genau ein Endpunkt braucht das: `financeWebService` erwartet
|
|
80
|
+
* seine `method` neben `params` und nicht darin (siehe Flutter-Vorbild
|
|
81
|
+
* `_financeWebServicePostRequest`). Fuer alle anderen Aufrufe bleibt der Rumpf
|
|
82
|
+
* unveraendert `{params:{…}}`.
|
|
83
|
+
*
|
|
84
|
+
* `secretParams` nennt Werte, die dieser Aufruf in der **Nutzlast** sendet und
|
|
85
|
+
* die in keinem Fehler auftauchen duerfen. Die gesendeten Kopfzeilen sind
|
|
86
|
+
* ohnehin geschuetzt (siehe unten); PIN, Geraetegeheimnis und Kopplungs-Code
|
|
87
|
+
* der Kassen-Anmeldung reisen dagegen im Rumpf, und ein Geraetegeheimnis ist
|
|
88
|
+
* bezeichner-foermig genug, um durch die Ursachen-Verdichtung zu kommen. Wer
|
|
89
|
+
* ein Geheimnis im Rumpf sendet, nennt es hier — sonst gilt es als
|
|
90
|
+
* unbedenklich.
|
|
91
|
+
*
|
|
92
|
+
* Der Typ nennt darum genau dieses eine Feld und ist kein offener Beutel:
|
|
93
|
+
* ein `params` von aussen wuerde die Nutzlast samt Auth-Parametern
|
|
94
|
+
* ueberschreiben — mit `registerUserAuth` verschwaende dabei still die
|
|
95
|
+
* Kassenbindung. Zusaetzlich setzt der Rumpfaufbau `params` als letztes, damit
|
|
96
|
+
* auch ein Verbraucher ohne Typen nicht daran vorbeikommt.
|
|
97
|
+
*/
|
|
98
|
+
export interface TransportBodyFields {
|
|
99
|
+
/** Vorgangsart von `financeWebService` (z. B. `status_cashbox`). */
|
|
100
|
+
method?: string;
|
|
101
|
+
}
|
|
102
|
+
export type KasseneckTransport = <T = unknown>(functionName: string, params?: Record<string, unknown>, extraBodyFields?: TransportBodyFields, secretParams?: readonly string[]) => Promise<T>;
|
|
103
|
+
/**
|
|
104
|
+
* Ruft eine Backend-Funktion auf, die **Binaerdaten** liefert (die beiden
|
|
105
|
+
* Bericht-PDFs), und gibt sie als `Uint8Array` zurueck.
|
|
106
|
+
*/
|
|
107
|
+
export type KasseneckBinaryTransport = (functionName: string, params?: Record<string, unknown>) => Promise<Uint8Array>;
|
|
108
|
+
export declare function createTransport(options: TransportOptions): KasseneckTransport;
|
|
109
|
+
/**
|
|
110
|
+
* Zweiter Einstiegspunkt fuer die Bericht-Downloads. Er liest die Antwort als
|
|
111
|
+
* Bytes und **nie** als Zeichenkette: ein PDF ist keine UTF-8-Folge, und eine
|
|
112
|
+
* Textdeutung ersetzt jedes Byte ueber 0x7F durch U+FFFD — die Datei waere
|
|
113
|
+
* kaputt, ohne dass es jemand merkt. (Das Flutter-Vorbild nimmt hier
|
|
114
|
+
* `response.body.codeUnits`; das ist eine bewusste Abweichung, siehe
|
|
115
|
+
* reports.ts.)
|
|
116
|
+
*/
|
|
117
|
+
export declare function createBinaryTransport(options: TransportOptions): KasseneckBinaryTransport;
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_BASE_URL = void 0;
|
|
4
|
+
exports.createTransport = createTransport;
|
|
5
|
+
exports.createBinaryTransport = createBinaryTransport;
|
|
6
|
+
const errors_js_1 = require("./errors.js");
|
|
7
|
+
/**
|
|
8
|
+
* Transport zum Kasseneck-Backend: ein Aufruf ist ein POST an
|
|
9
|
+
* `<basis>/<funktionsname>` mit dem JSON-Rumpf `{ "params": { … } }` — wie im
|
|
10
|
+
* Flutter-Zwilling `kasseneck_api`.
|
|
11
|
+
*
|
|
12
|
+
* Der Transport macht drei Dinge und sonst nichts: Anfrage bauen (Kopfzeilen
|
|
13
|
+
* von der Anmeldung, Nutzlast aus Auth-Parametern und Aufruferparametern),
|
|
14
|
+
* Zeitlimit ueberwachen, und die Antworthuelle aufloesen. Er kennt keine
|
|
15
|
+
* einzelne Backend-Funktion und keine Firebase-Details.
|
|
16
|
+
*
|
|
17
|
+
* Es gibt **zwei Einstiegspunkte** auf demselben Kern: [createTransport] fuer
|
|
18
|
+
* die JSON-Aufrufe und [createBinaryTransport] fuer die beiden Bericht-
|
|
19
|
+
* Downloads, die ein PDF liefern. Anmeldung, Zeitlimit, Rumpfaufbau und die
|
|
20
|
+
* Fehlerarten sind bei beiden dieselben; sie unterscheiden sich nur darin, wie
|
|
21
|
+
* der Antwortrumpf gelesen und ausgewertet wird.
|
|
22
|
+
*
|
|
23
|
+
* **Kein Wiederholen fehlgeschlagener Aufrufe.** Ein Beleg ist nicht folgenlos
|
|
24
|
+
* wiederholbar; ohne entschiedene Idempotenz waere ein automatischer zweiter
|
|
25
|
+
* Versuch ein zweiter Beleg.
|
|
26
|
+
*/
|
|
27
|
+
/** Basis-URL der Produktion. */
|
|
28
|
+
exports.DEFAULT_BASE_URL = 'https://api.kasseneck.at/v1';
|
|
29
|
+
/**
|
|
30
|
+
* Zeitlimit je Aufruf (wie im Flutter-Zwilling). Ohne Zeitlimit bleibt eine
|
|
31
|
+
* haengende Anfrage fuer immer offen — der Aufrufer bekaeme weder Ergebnis
|
|
32
|
+
* noch Fehler.
|
|
33
|
+
*/
|
|
34
|
+
exports.DEFAULT_TIMEOUT_MS = 30_000;
|
|
35
|
+
function createTransport(options) {
|
|
36
|
+
const kern = createCore(options);
|
|
37
|
+
return (functionName, params, extraBodyFields, secretParams) => kern(functionName, params, extraBodyFields, secretParams, alsText, jsonAuswerten);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Zweiter Einstiegspunkt fuer die Bericht-Downloads. Er liest die Antwort als
|
|
41
|
+
* Bytes und **nie** als Zeichenkette: ein PDF ist keine UTF-8-Folge, und eine
|
|
42
|
+
* Textdeutung ersetzt jedes Byte ueber 0x7F durch U+FFFD — die Datei waere
|
|
43
|
+
* kaputt, ohne dass es jemand merkt. (Das Flutter-Vorbild nimmt hier
|
|
44
|
+
* `response.body.codeUnits`; das ist eine bewusste Abweichung, siehe
|
|
45
|
+
* reports.ts.)
|
|
46
|
+
*/
|
|
47
|
+
function createBinaryTransport(options) {
|
|
48
|
+
const kern = createCore(options);
|
|
49
|
+
return (functionName, params) => kern(functionName, params, undefined, undefined, alsBytes, pdfAuswerten);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Gemeinsamer Kern beider Einstiegspunkte: Anmeldung, Zeitlimit, Anfrage und
|
|
53
|
+
* HTTP-Status. Was danach mit dem Rumpf geschieht, entscheiden `lesen` und
|
|
54
|
+
* `auswerten`.
|
|
55
|
+
*/
|
|
56
|
+
function createCore(options) {
|
|
57
|
+
const basis = (options.baseUrl ?? exports.DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
58
|
+
const zeitlimitMs = options.timeoutMs ?? exports.DEFAULT_TIMEOUT_MS;
|
|
59
|
+
const holen = options.fetch ?? globalesFetch();
|
|
60
|
+
return async function aufrufen(functionName, params = {}, extraBodyFields, secretParams, lesen, auswerten) {
|
|
61
|
+
// Die URL nennt die Backend-Funktion, die Fehler nennen den **Vorgang**:
|
|
62
|
+
// `financeWebService` fuehrt ein Dutzend verschiedener Vorgaenge unter einem
|
|
63
|
+
// Endpunkt, und ein Fehler, der nur "financeWebService" sagt, verschweigt
|
|
64
|
+
// dem Aufrufer, welcher davon scheiterte.
|
|
65
|
+
const fehlerName = extraBodyFields?.method ? `${functionName}/${extraBodyFields.method}` : functionName;
|
|
66
|
+
// Das Zeitlimit laeuft ab HIER — es deckt die Anmeldung mit ab. Haengt die
|
|
67
|
+
// Token-Erneuerung auf flauem Netz, haette der Aufruf sonst weder Ergebnis
|
|
68
|
+
// noch Fehler, und die Kasse stuende still.
|
|
69
|
+
const abbruch = new AbortController();
|
|
70
|
+
const wecker = setTimeout(() => abbruch.abort(), zeitlimitMs);
|
|
71
|
+
try {
|
|
72
|
+
// Die Anmeldung wird bei JEDEM Aufruf befragt — nichts wird beim Anlegen
|
|
73
|
+
// des Transports gemerkt (Ablaufzeiten siehe auth.ts).
|
|
74
|
+
let anmeldung;
|
|
75
|
+
try {
|
|
76
|
+
const ergebnis = await Promise.race([Promise.resolve(options.auth()), abbruchAlsAblehnung(abbruch.signal)]);
|
|
77
|
+
anmeldung = gepruefteAnmeldung(ergebnis);
|
|
78
|
+
}
|
|
79
|
+
catch (ursache) {
|
|
80
|
+
if (abbruch.signal.aborted) {
|
|
81
|
+
throw new errors_js_1.KasseneckNetworkError(fehlerName, true, zeitlimitMs);
|
|
82
|
+
}
|
|
83
|
+
// Eigene Pruefungen tragen ihren geheimnisfreien Grund weiter; von einer
|
|
84
|
+
// fremden Ursache (Firebase & Co.) bleibt nichts uebrig — weder Meldung
|
|
85
|
+
// noch Verdichtung, siehe Klassenkommentar zu KasseneckAuthError.
|
|
86
|
+
const grund = ursache instanceof errors_js_1.KasseneckAuthError ? ursache.reason : 'Anmeldung fehlgeschlagen';
|
|
87
|
+
throw new errors_js_1.KasseneckAuthError(grund, { functionName: fehlerName });
|
|
88
|
+
}
|
|
89
|
+
// Was wir gleich senden, darf spaeter in keiner Fehlermeldung auftauchen:
|
|
90
|
+
// die Kopfzeilen der Anmeldung — und die Werte, die dieser Aufruf als
|
|
91
|
+
// Geheimnis der Nutzlast benannt hat (Kassen-Anmeldung: Kopplungs-Code,
|
|
92
|
+
// Geraetegeheimnis, PIN). Ohne die zweite Haelfte greift die Zusage genau
|
|
93
|
+
// dort nicht, wo es gar keine Kopfzeilen gibt.
|
|
94
|
+
const geheimnisse = [...Object.values(anmeldung.headers), ...(secretParams ?? [])];
|
|
95
|
+
const url = `${basis}/${encodeURIComponent(functionName)}`;
|
|
96
|
+
// `params` steht ZULETZT: so kann kein Zusatzfeld die Nutzlast (und mit
|
|
97
|
+
// ihr die Kassenbindung aus der Anmeldung) verdraengen — auch nicht von
|
|
98
|
+
// einem Verbraucher, der ohne Typen an TransportBodyFields vorbeikommt.
|
|
99
|
+
const rumpf = JSON.stringify({ ...extraBodyFields, params: nutzlast(anmeldung.params, params) });
|
|
100
|
+
let antwort;
|
|
101
|
+
let koerper;
|
|
102
|
+
try {
|
|
103
|
+
// Auch der Aufruf laeuft gegen den Abbruch — nicht nur die Anmeldung.
|
|
104
|
+
// Das `AbortSignal` geht zwar mit, aber ob eine fetch-Umsetzung es
|
|
105
|
+
// beachtet, ist keine Zusage dieses Pakets: `options.fetch` ist ein
|
|
106
|
+
// dokumentierter Erweiterungspunkt fuer Proxys, und eine Umsetzung,
|
|
107
|
+
// die das Signal ignoriert, liesse den Aufruf sonst fuer immer offen —
|
|
108
|
+
// weder Ergebnis noch Fehler. Das Lesen des Rumpfs haengt genauso mit
|
|
109
|
+
// darunter: eine Gegenstelle kann die Kopfzeilen schicken und den
|
|
110
|
+
// Rumpf offen lassen.
|
|
111
|
+
antwort = await Promise.race([
|
|
112
|
+
holen(url, {
|
|
113
|
+
method: 'POST',
|
|
114
|
+
headers: { 'Content-Type': 'application/json', ...anmeldung.headers },
|
|
115
|
+
body: rumpf,
|
|
116
|
+
signal: abbruch.signal,
|
|
117
|
+
}),
|
|
118
|
+
abbruchAlsAblehnung(abbruch.signal),
|
|
119
|
+
]);
|
|
120
|
+
koerper = await Promise.race([lesen(antwort, fehlerName), abbruchAlsAblehnung(abbruch.signal)]);
|
|
121
|
+
}
|
|
122
|
+
catch (ursache) {
|
|
123
|
+
// Ein Formfehler des Pakets ist kein Netzfehler und behaelt seine Art
|
|
124
|
+
// (der Binaerweg wirft ihn, wenn die fetch-Antwort keine Bytes liefert).
|
|
125
|
+
if (ursache instanceof errors_js_1.KasseneckValidationError) {
|
|
126
|
+
throw ursache;
|
|
127
|
+
}
|
|
128
|
+
// Bis hierher kam keine verwertbare Antwort: Netz weg oder Zeitlimit.
|
|
129
|
+
throw new errors_js_1.KasseneckNetworkError(fehlerName, abbruch.signal.aborted, zeitlimitMs, (0, errors_js_1.causeDigest)(ursache, geheimnisse));
|
|
130
|
+
}
|
|
131
|
+
const inhaltstyp = antwort.headers.get('content-type') ?? undefined;
|
|
132
|
+
// Das Backend antwortet auf jeden fachlichen Ausgang mit HTTP 200; alles
|
|
133
|
+
// andere kommt nicht von ihm (Proxy, Rewrite-Luecke, Infrastruktur).
|
|
134
|
+
if (antwort.status !== 200) {
|
|
135
|
+
throw new errors_js_1.KasseneckHttpError(fehlerName, antwort.status, inhaltstyp, 'server-error');
|
|
136
|
+
}
|
|
137
|
+
return auswerten(koerper, fehlerName, antwort.status, inhaltstyp);
|
|
138
|
+
}
|
|
139
|
+
finally {
|
|
140
|
+
// Ohne Abraeumen haelt der Wecker den Node-Prozess bis zum Zeitlimit wach.
|
|
141
|
+
clearTimeout(wecker);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/** JSON-Weg: der Rumpf ist Text. */
|
|
146
|
+
const alsText = (antwort) => antwort.text();
|
|
147
|
+
/**
|
|
148
|
+
* Binaerweg: der Rumpf sind Bytes. `text()` wird hier bewusst **nicht**
|
|
149
|
+
* angefasst — es wuerde die Bytes als UTF-8 deuten.
|
|
150
|
+
*/
|
|
151
|
+
const alsBytes = async (antwort, functionName) => {
|
|
152
|
+
if (typeof antwort.arrayBuffer !== 'function') {
|
|
153
|
+
// Der Typ verlangt die Methode; diese Pruefung gilt dem Verbraucher ohne
|
|
154
|
+
// Typen, der eine eigene fetch-Umsetzung mitbringt. Lieber laut scheitern
|
|
155
|
+
// als still auf text() ausweichen — das waere genau der Bytefehler, den
|
|
156
|
+
// dieser Weg verhindern soll.
|
|
157
|
+
throw new errors_js_1.KasseneckValidationError(functionName, 'Die fetch-Antwort liefert keine Bytes (arrayBuffer fehlt)', 'response');
|
|
158
|
+
}
|
|
159
|
+
return new Uint8Array(await antwort.arrayBuffer());
|
|
160
|
+
};
|
|
161
|
+
/** Auswertung des JSON-Wegs: Huelle aufloesen, Nutzlast zurueckgeben. */
|
|
162
|
+
function jsonAuswerten(text, functionName, statusCode, inhaltstyp) {
|
|
163
|
+
if (!text.trim()) {
|
|
164
|
+
throw new errors_js_1.KasseneckHttpError(functionName, statusCode, inhaltstyp, 'empty-body');
|
|
165
|
+
}
|
|
166
|
+
let roh;
|
|
167
|
+
try {
|
|
168
|
+
roh = JSON.parse(text);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// Typischer Fall: der Aufruf landete mangels Rewrite auf der HTML-Seite
|
|
172
|
+
// der Single-Page-App — HTTP 200, aber kein JSON.
|
|
173
|
+
throw new errors_js_1.KasseneckHttpError(functionName, statusCode, inhaltstyp, 'not-json');
|
|
174
|
+
}
|
|
175
|
+
const huelle = alsHuelle(roh);
|
|
176
|
+
if (huelle === null) {
|
|
177
|
+
throw new errors_js_1.KasseneckHttpError(functionName, statusCode, inhaltstyp, 'missing-status');
|
|
178
|
+
}
|
|
179
|
+
if (huelle.status === 'success') {
|
|
180
|
+
return huelle.data;
|
|
181
|
+
}
|
|
182
|
+
// Alles, was nicht ausdruecklich Erfolg ist, gilt als fachlicher Fehler —
|
|
183
|
+
// ein unbekannter Statuswert darf nie stillschweigend als Erfolg durchgehen.
|
|
184
|
+
throw fachfehler(functionName, huelle.message);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Auswertung des Binaerwegs. Der Kern der Zusage: **ein Aufrufer bekommt nie
|
|
188
|
+
* ein "PDF", das in Wahrheit eine Fehlermeldung ist.** Das Backend antwortet
|
|
189
|
+
* auch im Fehlerfall mit HTTP 200 und schickt dann seine JSON-Huelle statt des
|
|
190
|
+
* PDF; wer die Bytes ungeprueft durchreicht, gibt dem Kassier eine kaputte
|
|
191
|
+
* Datei ohne jeden Hinweis.
|
|
192
|
+
*
|
|
193
|
+
* Entschieden wird an den **ersten Bytes**, nicht am Inhaltstyp: der Inhaltstyp
|
|
194
|
+
* ist die Aussage der Gegenstelle (oder eines Proxys davor) und kann fehlen
|
|
195
|
+
* oder falsch sein, die PDF-Kennung `%PDF` steht dagegen in jeder Datei, die
|
|
196
|
+
* das Backend hier erzeugt (pdf-lib). Alles, was nicht so anfaengt, ist kein
|
|
197
|
+
* Bericht — und wird dann daraufhin angesehen, ob es die Fehlerhuelle ist.
|
|
198
|
+
*/
|
|
199
|
+
function pdfAuswerten(bytes, functionName, statusCode, inhaltstyp) {
|
|
200
|
+
if (bytes.length === 0) {
|
|
201
|
+
throw new errors_js_1.KasseneckHttpError(functionName, statusCode, inhaltstyp, 'empty-body');
|
|
202
|
+
}
|
|
203
|
+
if (istPdf(bytes)) {
|
|
204
|
+
return bytes;
|
|
205
|
+
}
|
|
206
|
+
// Ab hier ist nichts mehr zu retten; die Bytes werden nur noch **zur
|
|
207
|
+
// Fehlerdeutung** als Text gelesen, nie als Ergebnis zurueckgegeben. Die
|
|
208
|
+
// Gruende sind dieselben wie auf dem JSON-Weg und heissen auch so: "kein
|
|
209
|
+
// JSON" ist betrieblich der fehlende Rewrite (die Antwort ist die HTML-Seite
|
|
210
|
+
// der Single-Page-App), "kein Statusfeld" ein geaenderter Backend-Vertrag.
|
|
211
|
+
// Ein eigener Sammelgrund fuer den Binaerweg wuerde die beiden verschmelzen.
|
|
212
|
+
let roh;
|
|
213
|
+
try {
|
|
214
|
+
roh = JSON.parse(new TextDecoder('utf-8').decode(bytes));
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
throw new errors_js_1.KasseneckHttpError(functionName, statusCode, inhaltstyp, 'not-json');
|
|
218
|
+
}
|
|
219
|
+
const huelle = alsHuelle(roh);
|
|
220
|
+
if (huelle === null) {
|
|
221
|
+
throw new errors_js_1.KasseneckHttpError(functionName, statusCode, inhaltstyp, 'missing-status');
|
|
222
|
+
}
|
|
223
|
+
if (huelle.status === 'success') {
|
|
224
|
+
// Erfolg gemeldet, aber kein PDF geliefert: die Antwort traegt nicht, was
|
|
225
|
+
// der Aufruf zusagt.
|
|
226
|
+
throw new errors_js_1.KasseneckValidationError(functionName, 'Antwort ist ein Erfolgsrumpf statt eines PDF', 'response');
|
|
227
|
+
}
|
|
228
|
+
// Derselbe fachliche Fehler wie auf dem JSON-Weg — fuer den Aufrufer macht
|
|
229
|
+
// es keinen Unterschied, ob er ein PDF oder eine Nutzlast erwartet hat.
|
|
230
|
+
throw fachfehler(functionName, huelle.message);
|
|
231
|
+
}
|
|
232
|
+
/** `%PDF` am Anfang — die Kennung jeder PDF-Datei. */
|
|
233
|
+
function istPdf(bytes) {
|
|
234
|
+
return bytes.length >= 4 && bytes[0] === 0x25 && bytes[1] === 0x50 && bytes[2] === 0x44 && bytes[3] === 0x46;
|
|
235
|
+
}
|
|
236
|
+
/** Antworthuelle `{status, message, data}` — oder `null`, wenn es keine ist. */
|
|
237
|
+
function alsHuelle(wert) {
|
|
238
|
+
if (typeof wert !== 'object' || wert === null || !('status' in wert)) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
return wert;
|
|
242
|
+
}
|
|
243
|
+
function fachfehler(functionName, message) {
|
|
244
|
+
const meldung = typeof message === 'string' && message.trim() ? message : 'Unbekannter Fehler';
|
|
245
|
+
return new errors_js_1.KasseneckApiError(functionName, meldung);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Nutzlast aus Auth- und Aufruferparametern. Auth-Parameter bilden die
|
|
249
|
+
* Grundlage; ein ausdruecklich gesetzter Aufruferwert sticht (der Server prueft
|
|
250
|
+
* ihn ohnehin gegen die Sitzung). Ein **anwesender, aber undefinierter**
|
|
251
|
+
* Schluessel sticht dagegen nicht: `{ …, cashregisterId: opts.cashregisterId }`
|
|
252
|
+
* ist in der Endpunkt-Schicht das natuerlichste Muster der Welt, und ein reines
|
|
253
|
+
* Spread wuerde die Kassenbindung damit still loeschen (`JSON.stringify` wirft
|
|
254
|
+
* undefined danach weg). `null` bleibt erhalten — das ist eine Aussage.
|
|
255
|
+
*/
|
|
256
|
+
function nutzlast(authParams, params) {
|
|
257
|
+
const zusammen = { ...authParams };
|
|
258
|
+
for (const [schluessel, wert] of Object.entries(params)) {
|
|
259
|
+
if (wert !== undefined) {
|
|
260
|
+
zusammen[schluessel] = wert;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return zusammen;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Prueft, was eine Anmeldung geliefert hat. Die Typen verlangen
|
|
267
|
+
* `{headers, params}` — `auth()` ist aber der Erweiterungspunkt fuer fremden
|
|
268
|
+
* Code, und zur Laufzeit kommt an, was ankommt. Ohne diese Pruefung flogen
|
|
269
|
+
* `undefined`, ein String oder ein Objekt ohne `headers` als roher `TypeError`
|
|
270
|
+
* an allen Fehlerarten dieses Pakets vorbei, waehrend ein fehlendes `params`
|
|
271
|
+
* still durchlief. Der gelieferte Wert selbst taucht in der Meldung **nicht**
|
|
272
|
+
* auf — er kann der api_key sein.
|
|
273
|
+
*/
|
|
274
|
+
function gepruefteAnmeldung(wert) {
|
|
275
|
+
if (typeof wert !== 'object' || wert === null) {
|
|
276
|
+
throw new errors_js_1.KasseneckAuthError('Anmeldung lieferte keine Zugangsdaten');
|
|
277
|
+
}
|
|
278
|
+
const { headers, params } = wert;
|
|
279
|
+
if (!istKopfzeilen(headers)) {
|
|
280
|
+
throw new errors_js_1.KasseneckAuthError('Anmeldung lieferte keine brauchbaren Kopfzeilen');
|
|
281
|
+
}
|
|
282
|
+
if (typeof params !== 'object' || params === null || Array.isArray(params)) {
|
|
283
|
+
throw new errors_js_1.KasseneckAuthError('Anmeldung lieferte keine brauchbaren Zusatzparameter');
|
|
284
|
+
}
|
|
285
|
+
return { headers, params: params };
|
|
286
|
+
}
|
|
287
|
+
function istKopfzeilen(wert) {
|
|
288
|
+
if (typeof wert !== 'object' || wert === null || Array.isArray(wert)) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
return Object.values(wert).every((eintrag) => typeof eintrag === 'string');
|
|
292
|
+
}
|
|
293
|
+
/** Lehnt ab, sobald das Zeitlimit die Anfrage abbricht. */
|
|
294
|
+
function abbruchAlsAblehnung(signal) {
|
|
295
|
+
return new Promise((_erfuellen, ablehnen) => {
|
|
296
|
+
if (signal.aborted) {
|
|
297
|
+
ablehnen(new Error('abgebrochen'));
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
signal.addEventListener('abort', () => ablehnen(new Error('abgebrochen')), { once: true });
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
/** Das globale `fetch`; fehlt es, faellt das sofort und deutlich auf. */
|
|
304
|
+
function globalesFetch() {
|
|
305
|
+
const umgebung = globalThis;
|
|
306
|
+
if (typeof umgebung.fetch !== 'function') {
|
|
307
|
+
throw new Error('createTransport: kein globales fetch vorhanden — Node >= 20.18 verwenden oder eine fetch-Umsetzung uebergeben');
|
|
308
|
+
}
|
|
309
|
+
// Ueber das Umgebungsobjekt aufrufen: manche Browser verlangen `globalThis`
|
|
310
|
+
// als Empfaenger und werfen bei einem losgeloesten fetch.
|
|
311
|
+
return (url, init) => umgebung.fetch(url, init);
|
|
312
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kartenanbieter — Zwilling von `CreditCardProvider` in
|
|
3
|
+
* kasseneck_api/lib/enums/credit_card_provider.dart.
|
|
4
|
+
*
|
|
5
|
+
* `hobexHps`, `sumup` und `myposPro` bleiben Teil des Enums: Das Backend kennt sie,
|
|
6
|
+
* und Belege aus der Flutter-App tragen sie weiterhin. Nur die Anbindung im
|
|
7
|
+
* Browser-Paket fehlt bewusst — Hobex HPS spricht lokal per TCP mit dem Terminal,
|
|
8
|
+
* myPOS und SumUp sind Android-SDKs. Ein Browser kann das nicht, und kein Bundler
|
|
9
|
+
* aendert daran etwas.
|
|
10
|
+
*/
|
|
11
|
+
export declare const CreditCardProvider: {
|
|
12
|
+
readonly gpTomAndroid: "gpTomAndroid";
|
|
13
|
+
readonly gpTomIos: "gpTomIos";
|
|
14
|
+
readonly hobexCloudApi: "hobexCloudApi";
|
|
15
|
+
readonly hobexHps: "hobexHps";
|
|
16
|
+
readonly sumup: "sumup";
|
|
17
|
+
readonly myposPro: "myposPro";
|
|
18
|
+
readonly stripe: "stripe";
|
|
19
|
+
readonly custom: "custom";
|
|
20
|
+
};
|
|
21
|
+
export type CreditCardProviderKey = keyof typeof CreditCardProvider;
|
|
22
|
+
export type CreditCardProvider = (typeof CreditCardProvider)[CreditCardProviderKey];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CreditCardProvider = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Kartenanbieter — Zwilling von `CreditCardProvider` in
|
|
6
|
+
* kasseneck_api/lib/enums/credit_card_provider.dart.
|
|
7
|
+
*
|
|
8
|
+
* `hobexHps`, `sumup` und `myposPro` bleiben Teil des Enums: Das Backend kennt sie,
|
|
9
|
+
* und Belege aus der Flutter-App tragen sie weiterhin. Nur die Anbindung im
|
|
10
|
+
* Browser-Paket fehlt bewusst — Hobex HPS spricht lokal per TCP mit dem Terminal,
|
|
11
|
+
* myPOS und SumUp sind Android-SDKs. Ein Browser kann das nicht, und kein Bundler
|
|
12
|
+
* aendert daran etwas.
|
|
13
|
+
*/
|
|
14
|
+
exports.CreditCardProvider = {
|
|
15
|
+
gpTomAndroid: 'gpTomAndroid',
|
|
16
|
+
gpTomIos: 'gpTomIos',
|
|
17
|
+
hobexCloudApi: 'hobexCloudApi',
|
|
18
|
+
hobexHps: 'hobexHps',
|
|
19
|
+
sumup: 'sumup',
|
|
20
|
+
myposPro: 'myposPro',
|
|
21
|
+
stripe: 'stripe',
|
|
22
|
+
custom: 'custom',
|
|
23
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bindet bei Enums mit Zusatzfeldern das `value`-Feld zur Bauzeit an den eigenen
|
|
3
|
+
* Objekt-Schluessel — `vat20: { value: 'vat20', ... }` kompiliert, `vat20: { value:
|
|
4
|
+
* 'vat2O', ... }` nicht. `value` ist die Nutzlast, die an das Backend geht: ein
|
|
5
|
+
* Tippfehler dort erzeugt sonst erst in Produktion einen Beleg mit unbekanntem
|
|
6
|
+
* Steuersatz bzw. Belegtyp.
|
|
7
|
+
*
|
|
8
|
+
* `const T` erhaelt die Literal-Typen (wie `as const`), ohne dass der Aufrufer
|
|
9
|
+
* `as const` selbst schreiben muss.
|
|
10
|
+
*/
|
|
11
|
+
export declare function defineEnum<const T extends {
|
|
12
|
+
[K in keyof T]: {
|
|
13
|
+
value: K;
|
|
14
|
+
} & Record<string, unknown>;
|
|
15
|
+
}>(eintraege: T): T;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defineEnum = defineEnum;
|
|
4
|
+
/**
|
|
5
|
+
* Bindet bei Enums mit Zusatzfeldern das `value`-Feld zur Bauzeit an den eigenen
|
|
6
|
+
* Objekt-Schluessel — `vat20: { value: 'vat20', ... }` kompiliert, `vat20: { value:
|
|
7
|
+
* 'vat2O', ... }` nicht. `value` ist die Nutzlast, die an das Backend geht: ein
|
|
8
|
+
* Tippfehler dort erzeugt sonst erst in Produktion einen Beleg mit unbekanntem
|
|
9
|
+
* Steuersatz bzw. Belegtyp.
|
|
10
|
+
*
|
|
11
|
+
* `const T` erhaelt die Literal-Typen (wie `as const`), ohne dass der Aufrufer
|
|
12
|
+
* `as const` selbst schreiben muss.
|
|
13
|
+
*/
|
|
14
|
+
function defineEnum(eintraege) {
|
|
15
|
+
return eintraege;
|
|
16
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ReceiptType, type ReceiptTypeKey } from './receipt-type.js';
|
|
2
|
+
export { VatRate, type VatRateKey } from './vat-rate.js';
|
|
3
|
+
export { KeckPaymentMethod, type KeckPaymentMethodKey } from './keck-payment-method.js';
|
|
4
|
+
export { CreditCardProvider, type CreditCardProviderKey } from './credit-card-provider.js';
|
|
5
|
+
export { VoucherType, type VoucherTypeKey } from './voucher-type.js';
|
|
6
|
+
export { VoucherAction, type VoucherActionKey } from './voucher-action.js';
|
|
7
|
+
export { StripeLinkMode, type StripeLinkModeKey } from './stripe-link-mode.js';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StripeLinkMode = exports.VoucherAction = exports.VoucherType = exports.CreditCardProvider = exports.KeckPaymentMethod = exports.VatRate = exports.ReceiptType = void 0;
|
|
4
|
+
var receipt_type_js_1 = require("./receipt-type.js");
|
|
5
|
+
Object.defineProperty(exports, "ReceiptType", { enumerable: true, get: function () { return receipt_type_js_1.ReceiptType; } });
|
|
6
|
+
var vat_rate_js_1 = require("./vat-rate.js");
|
|
7
|
+
Object.defineProperty(exports, "VatRate", { enumerable: true, get: function () { return vat_rate_js_1.VatRate; } });
|
|
8
|
+
var keck_payment_method_js_1 = require("./keck-payment-method.js");
|
|
9
|
+
Object.defineProperty(exports, "KeckPaymentMethod", { enumerable: true, get: function () { return keck_payment_method_js_1.KeckPaymentMethod; } });
|
|
10
|
+
var credit_card_provider_js_1 = require("./credit-card-provider.js");
|
|
11
|
+
Object.defineProperty(exports, "CreditCardProvider", { enumerable: true, get: function () { return credit_card_provider_js_1.CreditCardProvider; } });
|
|
12
|
+
var voucher_type_js_1 = require("./voucher-type.js");
|
|
13
|
+
Object.defineProperty(exports, "VoucherType", { enumerable: true, get: function () { return voucher_type_js_1.VoucherType; } });
|
|
14
|
+
var voucher_action_js_1 = require("./voucher-action.js");
|
|
15
|
+
Object.defineProperty(exports, "VoucherAction", { enumerable: true, get: function () { return voucher_action_js_1.VoucherAction; } });
|
|
16
|
+
var stripe_link_mode_js_1 = require("./stripe-link-mode.js");
|
|
17
|
+
Object.defineProperty(exports, "StripeLinkMode", { enumerable: true, get: function () { return stripe_link_mode_js_1.StripeLinkMode; } });
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zahlungsart — Zwilling von `KeckPaymentMethod` in
|
|
3
|
+
* kasseneck_api/lib/enums/keck_payment_method.dart.
|
|
4
|
+
*
|
|
5
|
+
* `label` ist das deutsche Anzeige-Label fuer die Zahlungsart-Zeile auf dem Beleg.
|
|
6
|
+
* Muss 1:1 mit dem Backend-Mapping `paymentMethodToString` (functions/helper.js)
|
|
7
|
+
* uebereinstimmen.
|
|
8
|
+
*/
|
|
9
|
+
export declare const KeckPaymentMethod: {
|
|
10
|
+
readonly cash: {
|
|
11
|
+
readonly value: "cash";
|
|
12
|
+
readonly needsCreditCard: false;
|
|
13
|
+
readonly label: "Barzahlung";
|
|
14
|
+
};
|
|
15
|
+
readonly creditCard: {
|
|
16
|
+
readonly value: "creditCard";
|
|
17
|
+
readonly needsCreditCard: true;
|
|
18
|
+
readonly label: "Kartenzahlung";
|
|
19
|
+
};
|
|
20
|
+
readonly online: {
|
|
21
|
+
readonly value: "online";
|
|
22
|
+
readonly needsCreditCard: false;
|
|
23
|
+
readonly label: "Onlinezahlung";
|
|
24
|
+
};
|
|
25
|
+
readonly uberApp: {
|
|
26
|
+
readonly value: "uberApp";
|
|
27
|
+
readonly needsCreditCard: false;
|
|
28
|
+
readonly label: "Uber App";
|
|
29
|
+
};
|
|
30
|
+
readonly uberCash: {
|
|
31
|
+
readonly value: "uberCash";
|
|
32
|
+
readonly needsCreditCard: false;
|
|
33
|
+
readonly label: "Uber Cash";
|
|
34
|
+
};
|
|
35
|
+
readonly uberCard: {
|
|
36
|
+
readonly value: "uberCard";
|
|
37
|
+
readonly needsCreditCard: true;
|
|
38
|
+
readonly label: "Uber Card";
|
|
39
|
+
};
|
|
40
|
+
readonly boltApp: {
|
|
41
|
+
readonly value: "boltApp";
|
|
42
|
+
readonly needsCreditCard: false;
|
|
43
|
+
readonly label: "Bolt App";
|
|
44
|
+
};
|
|
45
|
+
readonly boltCash: {
|
|
46
|
+
readonly value: "boltCash";
|
|
47
|
+
readonly needsCreditCard: false;
|
|
48
|
+
readonly label: "Bolt Cash";
|
|
49
|
+
};
|
|
50
|
+
readonly boltCard: {
|
|
51
|
+
readonly value: "boltCard";
|
|
52
|
+
readonly needsCreditCard: true;
|
|
53
|
+
readonly label: "Bolt Card";
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
export type KeckPaymentMethodKey = keyof typeof KeckPaymentMethod;
|
|
57
|
+
export type KeckPaymentMethod = (typeof KeckPaymentMethod)[KeckPaymentMethodKey];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KeckPaymentMethod = void 0;
|
|
4
|
+
const define_enum_js_1 = require("./define-enum.js");
|
|
5
|
+
/**
|
|
6
|
+
* Zahlungsart — Zwilling von `KeckPaymentMethod` in
|
|
7
|
+
* kasseneck_api/lib/enums/keck_payment_method.dart.
|
|
8
|
+
*
|
|
9
|
+
* `label` ist das deutsche Anzeige-Label fuer die Zahlungsart-Zeile auf dem Beleg.
|
|
10
|
+
* Muss 1:1 mit dem Backend-Mapping `paymentMethodToString` (functions/helper.js)
|
|
11
|
+
* uebereinstimmen.
|
|
12
|
+
*/
|
|
13
|
+
exports.KeckPaymentMethod = (0, define_enum_js_1.defineEnum)({
|
|
14
|
+
cash: { value: 'cash', needsCreditCard: false, label: 'Barzahlung' },
|
|
15
|
+
creditCard: { value: 'creditCard', needsCreditCard: true, label: 'Kartenzahlung' },
|
|
16
|
+
online: { value: 'online', needsCreditCard: false, label: 'Onlinezahlung' },
|
|
17
|
+
uberApp: { value: 'uberApp', needsCreditCard: false, label: 'Uber App' },
|
|
18
|
+
uberCash: { value: 'uberCash', needsCreditCard: false, label: 'Uber Cash' },
|
|
19
|
+
uberCard: { value: 'uberCard', needsCreditCard: true, label: 'Uber Card' },
|
|
20
|
+
boltApp: { value: 'boltApp', needsCreditCard: false, label: 'Bolt App' },
|
|
21
|
+
boltCash: { value: 'boltCash', needsCreditCard: false, label: 'Bolt Cash' },
|
|
22
|
+
boltCard: { value: 'boltCard', needsCreditCard: true, label: 'Bolt Card' },
|
|
23
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Belegtyp — Zwilling von `ReceiptType` in kasseneck_api/lib/enums/receipt_type.dart.
|
|
3
|
+
*
|
|
4
|
+
* needsItems: Positionen sind fuer diesen Typ Pflicht.
|
|
5
|
+
* isZero: RKSV-Nullbeleg (Start-/Monats-/Jahresbeleg-Signaturkette-Marker).
|
|
6
|
+
* allowsVouchers: Gutscheine duerfen auf Belegen dieses Typs erscheinen.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ReceiptType: {
|
|
9
|
+
readonly start: {
|
|
10
|
+
readonly value: "start";
|
|
11
|
+
readonly needsItems: false;
|
|
12
|
+
readonly isZero: true;
|
|
13
|
+
readonly allowsVouchers: false;
|
|
14
|
+
};
|
|
15
|
+
readonly standard: {
|
|
16
|
+
readonly value: "standard";
|
|
17
|
+
readonly needsItems: true;
|
|
18
|
+
readonly isZero: false;
|
|
19
|
+
readonly allowsVouchers: true;
|
|
20
|
+
};
|
|
21
|
+
readonly zero: {
|
|
22
|
+
readonly value: "zero";
|
|
23
|
+
readonly needsItems: false;
|
|
24
|
+
readonly isZero: true;
|
|
25
|
+
readonly allowsVouchers: false;
|
|
26
|
+
};
|
|
27
|
+
readonly cancellation: {
|
|
28
|
+
readonly value: "cancellation";
|
|
29
|
+
readonly needsItems: true;
|
|
30
|
+
readonly isZero: false;
|
|
31
|
+
readonly allowsVouchers: true;
|
|
32
|
+
};
|
|
33
|
+
readonly training: {
|
|
34
|
+
readonly value: "training";
|
|
35
|
+
readonly needsItems: true;
|
|
36
|
+
readonly isZero: false;
|
|
37
|
+
readonly allowsVouchers: true;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
export type ReceiptTypeKey = keyof typeof ReceiptType;
|
|
41
|
+
export type ReceiptType = (typeof ReceiptType)[ReceiptTypeKey];
|