@kreiseck/kasseneck-api 1.3.0 → 1.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/CHANGELOG.md +68 -0
- package/README.md +112 -1
- package/dist/cjs/client/aufrufe.d.ts +2 -2
- package/dist/cjs/client/aufrufe.js +30 -0
- package/dist/cjs/inventory/api.d.ts +45 -0
- package/dist/cjs/inventory/api.js +38 -0
- package/dist/cjs/inventory/auth.d.ts +17 -0
- package/dist/cjs/inventory/auth.js +27 -0
- package/dist/cjs/inventory/endpunkte.d.ts +71 -0
- package/dist/cjs/inventory/endpunkte.js +285 -0
- package/dist/cjs/inventory/fehler.d.ts +33 -0
- package/dist/cjs/inventory/fehler.js +47 -0
- package/dist/cjs/inventory/index.d.ts +19 -0
- package/dist/cjs/inventory/index.js +64 -0
- package/dist/cjs/inventory/lesen.d.ts +38 -0
- package/dist/cjs/inventory/lesen.js +294 -0
- package/dist/cjs/inventory/typen.d.ts +319 -0
- package/dist/cjs/inventory/typen.js +14 -0
- package/dist/cjs/inventory/vertrag.d.ts +76 -0
- package/dist/cjs/inventory/vertrag.js +166 -0
- package/dist/cjs/inventory/webhook.d.ts +50 -0
- package/dist/cjs/inventory/webhook.js +110 -0
- package/dist/cjs/stored/vokabular.d.ts +1 -1
- package/dist/cjs/stored/vokabular.js +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/client/aufrufe.d.ts +2 -2
- package/dist/esm/client/aufrufe.js +30 -0
- package/dist/esm/inventory/api.d.ts +45 -0
- package/dist/esm/inventory/api.js +35 -0
- package/dist/esm/inventory/auth.d.ts +17 -0
- package/dist/esm/inventory/auth.js +24 -0
- package/dist/esm/inventory/endpunkte.d.ts +71 -0
- package/dist/esm/inventory/endpunkte.js +266 -0
- package/dist/esm/inventory/fehler.d.ts +33 -0
- package/dist/esm/inventory/fehler.js +40 -0
- package/dist/esm/inventory/index.d.ts +19 -0
- package/dist/esm/inventory/index.js +18 -0
- package/dist/esm/inventory/lesen.d.ts +38 -0
- package/dist/esm/inventory/lesen.js +278 -0
- package/dist/esm/inventory/typen.d.ts +319 -0
- package/dist/esm/inventory/typen.js +13 -0
- package/dist/esm/inventory/vertrag.d.ts +76 -0
- package/dist/esm/inventory/vertrag.js +163 -0
- package/dist/esm/inventory/webhook.d.ts +50 -0
- package/dist/esm/inventory/webhook.js +101 -0
- package/dist/esm/stored/vokabular.d.ts +1 -1
- package/dist/esm/stored/vokabular.js +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/fixtures/hobex-hps-codes.json +1 -1
- package/fixtures/invoice-api.schema.json +1 -1
- package/fixtures/invoice-texts.json +1 -1
- package/fixtures/pos-texts.json +1 -1
- package/fixtures/surface.json +161 -3
- package/fixtures/v3/README.md +9 -1
- package/fixtures/v3/antworten/belege.json +2 -2
- package/fixtures/v3/antworten/belegmail.json +2 -2
- package/fixtures/v3/antworten/kasse-belege.json +2 -2
- package/fixtures/v3/antworten/kasse.json +3 -3
- package/fixtures/v3/antworten/lager.json +1520 -0
- package/fixtures/v3/antworten/rechnungen.json +2 -2
- package/fixtures/v3/antworten/storno.json +2 -2
- package/fixtures/v3/stored/belege.json +2 -2
- package/fixtures/v3/stored/kasse.json +404 -4
- package/fixtures/v3/stored/rechnungen.json +2 -2
- package/fixtures/v3/v3-vokabular.json +423 -6
- package/fixtures/v3/zahlbetrag-faelle.json +2 -2
- package/package.json +14 -2
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Die Aufrufe der Lager-API: Artikel, Standorte, Bestand und Bewegungen
|
|
4
|
+
* lesen, Konto-Webhooks verwalten (Backend Stufe 5a).
|
|
5
|
+
*
|
|
6
|
+
* Jede Funktion nimmt den Transport als ersten Parameter und ist einzeln
|
|
7
|
+
* importierbar; die Fassade [createInventoryClient] bindet ihn nur einmal.
|
|
8
|
+
*
|
|
9
|
+
* **Geprueft wird hier nur, was ohne Netz sicher falsch ist** (leere Kennung,
|
|
10
|
+
* `limit` ausserhalb 1–200, eine Aenderung ohne Feld). Alles Fachliche prueft
|
|
11
|
+
* der Server und meldet es als `validation` mit `errors[]`; zwei Pruefungen
|
|
12
|
+
* hiessen zwei Wahrheiten.
|
|
13
|
+
*
|
|
14
|
+
* Lesen hat keine Wirkung: nach einem Zeitlimit darf derselbe Aufruf
|
|
15
|
+
* wiederholt werden. Bei `rate_limited` vorher `retryAfterSec` warten
|
|
16
|
+
* ([inventoryRetryAfterSec]).
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.getArticle = getArticle;
|
|
20
|
+
exports.listArticles = listArticles;
|
|
21
|
+
exports.iterateArticles = iterateArticles;
|
|
22
|
+
exports.lookupArticleByCode = lookupArticleByCode;
|
|
23
|
+
exports.listLocations = listLocations;
|
|
24
|
+
exports.getStock = getStock;
|
|
25
|
+
exports.listStock = listStock;
|
|
26
|
+
exports.iterateStock = iterateStock;
|
|
27
|
+
exports.listStockMovements = listStockMovements;
|
|
28
|
+
exports.iterateStockMovements = iterateStockMovements;
|
|
29
|
+
exports.createWebhook = createWebhook;
|
|
30
|
+
exports.updateWebhook = updateWebhook;
|
|
31
|
+
exports.deleteWebhook = deleteWebhook;
|
|
32
|
+
exports.listWebhooks = listWebhooks;
|
|
33
|
+
exports.rotateWebhookSecret = rotateWebhookSecret;
|
|
34
|
+
exports.sendWebhookTest = sendWebhookTest;
|
|
35
|
+
exports.listWebhookDeliveries = listWebhookDeliveries;
|
|
36
|
+
const errors_js_1 = require("../client/errors.js");
|
|
37
|
+
const lesen_js_1 = require("./lesen.js");
|
|
38
|
+
const vertrag_js_1 = require("./vertrag.js");
|
|
39
|
+
function anfragefehler(name, grund) {
|
|
40
|
+
return new errors_js_1.KasseneckValidationError(name, grund, 'request');
|
|
41
|
+
}
|
|
42
|
+
/** Eine Kennung, die gesendet werden muss: Text mit mindestens einem Zeichen ausser Leerraum. */
|
|
43
|
+
function kennung(name, feld, wert) {
|
|
44
|
+
if (typeof wert !== 'string' || wert.trim() === '')
|
|
45
|
+
throw anfragefehler(name, `${feld} fehlt`);
|
|
46
|
+
return wert;
|
|
47
|
+
}
|
|
48
|
+
/** Felder, die einen Zeitpunkt tragen: ein `Date` geht als ISO 8601 UTC hinaus. */
|
|
49
|
+
const ZEITFELDER = new Set(['updatedSince', 'changedSince', 'from', 'to']);
|
|
50
|
+
/**
|
|
51
|
+
* Die Abfrage einer Liste als Parameter. Unbekannte Felder gehen unveraendert
|
|
52
|
+
* hinaus (der Server weist sie mit `validation` ab), `undefined` faellt weg.
|
|
53
|
+
*/
|
|
54
|
+
function abfrage(name, query) {
|
|
55
|
+
if (query === undefined || query === null)
|
|
56
|
+
return {};
|
|
57
|
+
if (typeof query !== 'object' || Array.isArray(query))
|
|
58
|
+
throw anfragefehler(name, 'Abfrage muss ein Objekt sein');
|
|
59
|
+
const raus = {};
|
|
60
|
+
for (const [feld, w] of Object.entries(query)) {
|
|
61
|
+
if (w === undefined)
|
|
62
|
+
continue;
|
|
63
|
+
if (ZEITFELDER.has(feld) && w instanceof Date) {
|
|
64
|
+
if (Number.isNaN(w.getTime()))
|
|
65
|
+
throw anfragefehler(name, `${feld} ist kein gueltiger Zeitpunkt`);
|
|
66
|
+
raus[feld] = w.toISOString();
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
raus[feld] = w;
|
|
70
|
+
}
|
|
71
|
+
if (raus.limit !== undefined) {
|
|
72
|
+
const limit = raus.limit;
|
|
73
|
+
if (typeof limit !== 'number' || !Number.isInteger(limit) || limit < 1 || limit > vertrag_js_1.INVENTORY_LIST_LIMIT_MAX) {
|
|
74
|
+
throw anfragefehler(name, `limit muss eine ganze Zahl von 1 bis ${vertrag_js_1.INVENTORY_LIST_LIMIT_MAX} sein`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (raus.cursor !== undefined)
|
|
78
|
+
kennung(name, 'cursor', raus.cursor);
|
|
79
|
+
return raus;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Blaettert ueber alle Seiten, Eintrag fuer Eintrag. Derselbe Cursor zweimal
|
|
83
|
+
* waere eine Endlosschleife: dann endet die Schleife mit einem Antwortfehler.
|
|
84
|
+
*/
|
|
85
|
+
async function* seitenweise(name, start, seite) {
|
|
86
|
+
const gesehen = new Set();
|
|
87
|
+
// Auch der Startcursor zaehlt: nennt die erste Antwort ihn wieder, waere es dieselbe Seite.
|
|
88
|
+
if (start)
|
|
89
|
+
gesehen.add(start);
|
|
90
|
+
let cursor = start;
|
|
91
|
+
for (;;) {
|
|
92
|
+
const { eintraege, nextCursor } = await seite(cursor);
|
|
93
|
+
yield* eintraege;
|
|
94
|
+
if (nextCursor === null)
|
|
95
|
+
return;
|
|
96
|
+
if (gesehen.has(nextCursor))
|
|
97
|
+
throw (0, lesen_js_1.antwortfehler)(name, 'Antwort nennt denselben nextCursor zweimal');
|
|
98
|
+
gesehen.add(nextCursor);
|
|
99
|
+
cursor = nextCursor;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// ---- Artikel ------------------------------------------------------------------
|
|
103
|
+
async function getArticle(transport, articleId) {
|
|
104
|
+
const name = 'getArticle';
|
|
105
|
+
const daten = await transport(name, { articleId: kennung(name, 'articleId', articleId) });
|
|
106
|
+
return (0, lesen_js_1.artikel)({ name, pfad: 'article' }, (0, lesen_js_1.objekt)(daten)?.article);
|
|
107
|
+
}
|
|
108
|
+
async function listArticles(transport, query) {
|
|
109
|
+
const name = 'listArticles';
|
|
110
|
+
const daten = await transport(name, abfrage(name, query));
|
|
111
|
+
return { articles: (0, lesen_js_1.liste)(name, daten, 'articles', lesen_js_1.artikel), nextCursor: (0, lesen_js_1.naechsterCursor)(name, daten) };
|
|
112
|
+
}
|
|
113
|
+
/** Alle Artikel der Abfrage, Seite fuer Seite ueber `nextCursor`. */
|
|
114
|
+
function iterateArticles(transport, query) {
|
|
115
|
+
const { cursor, ...rest } = query ?? {};
|
|
116
|
+
return seitenweise('listArticles', cursor, async (c) => {
|
|
117
|
+
const s = await listArticles(transport, { ...rest, cursor: c });
|
|
118
|
+
return { eintraege: s.articles, nextCursor: s.nextCursor };
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Ein aktiver Artikel per Code (`number`, `ean` oder `internalCode`) oder per
|
|
123
|
+
* eigener Kennung aus `externalIds` (`{ externalSystem: 'shop', externalId: '4711' }`).
|
|
124
|
+
* Ein stillgelegter Artikel gilt als nicht gefunden (`article_not_found`).
|
|
125
|
+
*/
|
|
126
|
+
async function lookupArticleByCode(transport, lookup) {
|
|
127
|
+
const name = 'lookupArticleByCode';
|
|
128
|
+
let params;
|
|
129
|
+
if (typeof lookup === 'string') {
|
|
130
|
+
params = { code: kennung(name, 'code', lookup) };
|
|
131
|
+
}
|
|
132
|
+
else if (lookup !== null && typeof lookup === 'object' && !Array.isArray(lookup)) {
|
|
133
|
+
const l = lookup;
|
|
134
|
+
const extern = l.externalSystem !== undefined || l.externalId !== undefined;
|
|
135
|
+
if (l.code !== undefined && extern)
|
|
136
|
+
throw anfragefehler(name, 'entweder code oder externalSystem mit externalId');
|
|
137
|
+
params = extern
|
|
138
|
+
? { externalSystem: kennung(name, 'externalSystem', l.externalSystem), externalId: kennung(name, 'externalId', l.externalId) }
|
|
139
|
+
: { code: kennung(name, 'code', l.code) };
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
throw anfragefehler(name, 'Code als Text oder { code } bzw. { externalSystem, externalId } erwartet');
|
|
143
|
+
}
|
|
144
|
+
const daten = await transport(name, params);
|
|
145
|
+
return (0, lesen_js_1.artikel)({ name, pfad: 'article' }, (0, lesen_js_1.objekt)(daten)?.article);
|
|
146
|
+
}
|
|
147
|
+
// ---- Standorte und Bestand -----------------------------------------------------------
|
|
148
|
+
/** Alle Standorte des Kontos, samt aufgeloesten (`active: false`) und dem Hauptstandort. */
|
|
149
|
+
async function listLocations(transport) {
|
|
150
|
+
const name = 'listLocations';
|
|
151
|
+
return (0, lesen_js_1.liste)(name, await transport(name, {}), 'locations', lesen_js_1.standort);
|
|
152
|
+
}
|
|
153
|
+
/** Die Werte (`values`): fehlt das Feld, fehlt das Recht `costs` -> `null`, nie `[]`. */
|
|
154
|
+
function werte(name, daten) {
|
|
155
|
+
const roh = (0, lesen_js_1.objekt)(daten)?.values;
|
|
156
|
+
if (roh === undefined || roh === null)
|
|
157
|
+
return null;
|
|
158
|
+
return (0, lesen_js_1.liste)(name, daten, 'values', lesen_js_1.wert);
|
|
159
|
+
}
|
|
160
|
+
/** Bestand eines Artikels je Standort. */
|
|
161
|
+
async function getStock(transport, articleId) {
|
|
162
|
+
const name = 'getStock';
|
|
163
|
+
const daten = await transport(name, { articleId: kennung(name, 'articleId', articleId) });
|
|
164
|
+
return { stock: (0, lesen_js_1.liste)(name, daten, 'stock', lesen_js_1.bestand), values: werte(name, daten) };
|
|
165
|
+
}
|
|
166
|
+
async function listStock(transport, query) {
|
|
167
|
+
const name = 'listStock';
|
|
168
|
+
const daten = await transport(name, abfrage(name, query));
|
|
169
|
+
return { stock: (0, lesen_js_1.liste)(name, daten, 'stock', lesen_js_1.bestand), values: werte(name, daten), nextCursor: (0, lesen_js_1.naechsterCursor)(name, daten) };
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Alle Bestandszeilen der Abfrage, Seite fuer Seite. Die Werte (`values`)
|
|
173
|
+
* stehen je Seite in [listStock]; der Iterator liefert nur die Zeilen.
|
|
174
|
+
*/
|
|
175
|
+
function iterateStock(transport, query) {
|
|
176
|
+
const { cursor, ...rest } = query ?? {};
|
|
177
|
+
return seitenweise('listStock', cursor, async (c) => {
|
|
178
|
+
const s = await listStock(transport, { ...rest, cursor: c });
|
|
179
|
+
return { eintraege: s.stock, nextCursor: s.nextCursor };
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/** Das Lagerprotokoll, neueste zuerst. */
|
|
183
|
+
async function listStockMovements(transport, query) {
|
|
184
|
+
const name = 'listStockMovements';
|
|
185
|
+
const daten = await transport(name, abfrage(name, query));
|
|
186
|
+
return { movements: (0, lesen_js_1.liste)(name, daten, 'movements', lesen_js_1.bewegung), nextCursor: (0, lesen_js_1.naechsterCursor)(name, daten) };
|
|
187
|
+
}
|
|
188
|
+
function iterateStockMovements(transport, query) {
|
|
189
|
+
const { cursor, ...rest } = query ?? {};
|
|
190
|
+
return seitenweise('listStockMovements', cursor, async (c) => {
|
|
191
|
+
const s = await listStockMovements(transport, { ...rest, cursor: c });
|
|
192
|
+
return { eintraege: s.movements, nextCursor: s.nextCursor };
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
// ---- Webhooks ------------------------------------------------------------------
|
|
196
|
+
function mitSecret(name, daten) {
|
|
197
|
+
const o = (0, lesen_js_1.objekt)(daten);
|
|
198
|
+
const secret = o?.secret;
|
|
199
|
+
if (typeof secret !== 'string' || secret === '') {
|
|
200
|
+
throw (0, lesen_js_1.antwortfehler)(name, 'Antwort enthaelt kein secret; ohne es laesst sich keine Zustellung pruefen');
|
|
201
|
+
}
|
|
202
|
+
return { webhook: (0, lesen_js_1.webhook)({ name, pfad: 'webhook' }, o?.webhook), secret };
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Legt einen Webhook an (hoechstens 5 je Konto, `webhook_limit`).
|
|
206
|
+
* **Das Secret in der Antwort kommt nur dieses eine Mal**; sofort dorthin
|
|
207
|
+
* schreiben, wo der Empfaenger es liest, nicht in ein Protokoll.
|
|
208
|
+
*/
|
|
209
|
+
async function createWebhook(transport, options) {
|
|
210
|
+
const name = 'createWebhook';
|
|
211
|
+
const url = kennung(name, 'url', options?.url);
|
|
212
|
+
if (!Array.isArray(options.events) || options.events.length === 0) {
|
|
213
|
+
throw anfragefehler(name, 'events ist leer; ein Webhook ohne Ereignis bekaeme nie etwas');
|
|
214
|
+
}
|
|
215
|
+
const params = { url, events: options.events };
|
|
216
|
+
if (options.description !== undefined)
|
|
217
|
+
params.description = options.description;
|
|
218
|
+
return mitSecret(name, await transport(name, params));
|
|
219
|
+
}
|
|
220
|
+
/** Aendert nur die genannten Felder; `description: null` loescht die Beschreibung. */
|
|
221
|
+
async function updateWebhook(transport, webhookId, patch) {
|
|
222
|
+
const name = 'updateWebhook';
|
|
223
|
+
const id = kennung(name, 'webhookId', webhookId);
|
|
224
|
+
if (patch === null || typeof patch !== 'object' || Array.isArray(patch))
|
|
225
|
+
throw anfragefehler(name, 'patch muss ein Objekt sein');
|
|
226
|
+
const params = { webhookId: id };
|
|
227
|
+
for (const [feld, w] of Object.entries(patch))
|
|
228
|
+
if (w !== undefined)
|
|
229
|
+
params[feld] = w;
|
|
230
|
+
if (Object.keys(params).length === 1)
|
|
231
|
+
throw anfragefehler(name, 'patch nennt keine Aenderung');
|
|
232
|
+
const daten = await transport(name, params);
|
|
233
|
+
return (0, lesen_js_1.webhook)({ name, pfad: 'webhook' }, (0, lesen_js_1.objekt)(daten)?.webhook);
|
|
234
|
+
}
|
|
235
|
+
async function deleteWebhook(transport, webhookId) {
|
|
236
|
+
const name = 'deleteWebhook';
|
|
237
|
+
const id = kennung(name, 'webhookId', webhookId);
|
|
238
|
+
const o = (0, lesen_js_1.objekt)(await transport(name, { webhookId: id }));
|
|
239
|
+
return { webhookId: typeof o?.webhookId === 'string' && o.webhookId ? o.webhookId : id, deleted: o?.deleted === true };
|
|
240
|
+
}
|
|
241
|
+
/** Die Webhooks des Kontos und die Ereignisse, die es abonnieren kann. */
|
|
242
|
+
async function listWebhooks(transport) {
|
|
243
|
+
const name = 'listWebhooks';
|
|
244
|
+
const daten = await transport(name, {});
|
|
245
|
+
const ereignisse = (0, lesen_js_1.objekt)(daten)?.events;
|
|
246
|
+
return {
|
|
247
|
+
webhooks: (0, lesen_js_1.liste)(name, daten, 'webhooks', lesen_js_1.webhook),
|
|
248
|
+
events: Array.isArray(ereignisse) ? ereignisse.filter((e) => typeof e === 'string') : [],
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Ein neues Secret fuer denselben Webhook. Ab der Antwort gilt nur noch das
|
|
253
|
+
* neue (keine Uebergangsfrist): erst speichern, dann weiterarbeiten.
|
|
254
|
+
*/
|
|
255
|
+
async function rotateWebhookSecret(transport, webhookId) {
|
|
256
|
+
const name = 'rotateWebhookSecret';
|
|
257
|
+
return mitSecret(name, await transport(name, { webhookId: kennung(name, 'webhookId', webhookId) }));
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Eine Probe genau dieses Ereignisses an genau diesen Webhook, mit erfundener
|
|
261
|
+
* Nutzlast und `test: true` in der Huelle. Der Webhook muss das Ereignis
|
|
262
|
+
* abonnieren (`event_not_subscribed`) und aktiv sein (`webhook_inactive`).
|
|
263
|
+
*/
|
|
264
|
+
async function sendWebhookTest(transport, webhookId, event) {
|
|
265
|
+
const name = 'sendWebhookTest';
|
|
266
|
+
const id = kennung(name, 'webhookId', webhookId);
|
|
267
|
+
const ereignis = kennung(name, 'event', event);
|
|
268
|
+
const daten = await transport(name, { webhookId: id, event: ereignis });
|
|
269
|
+
const o = (0, lesen_js_1.objekt)(daten);
|
|
270
|
+
return {
|
|
271
|
+
eventId: typeof o?.eventId === 'string' ? o.eventId : '',
|
|
272
|
+
event: typeof o?.event === 'string' ? o.event : ereignis,
|
|
273
|
+
deliveries: (0, lesen_js_1.liste)(name, daten, 'deliveries', (ort, e) => (0, lesen_js_1.probeZustellung)(ort, e, id)),
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
/** Die letzten Zustellungen, neueste zuerst; mit `webhookId` nur die eines Webhooks. */
|
|
277
|
+
async function listWebhookDeliveries(transport, options = {}) {
|
|
278
|
+
const name = 'listWebhookDeliveries';
|
|
279
|
+
const params = {};
|
|
280
|
+
if (options.webhookId !== undefined)
|
|
281
|
+
params.webhookId = kennung(name, 'webhookId', options.webhookId);
|
|
282
|
+
if (options.limit !== undefined)
|
|
283
|
+
Object.assign(params, abfrage(name, { limit: options.limit }));
|
|
284
|
+
return (0, lesen_js_1.liste)(name, await transport(name, params), 'deliveries', lesen_js_1.zustellung);
|
|
285
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fehler der Lager-API auswerten: am Code, nie am Text.
|
|
3
|
+
*
|
|
4
|
+
* Es zaehlen die Codes der Lager-Endpunkte ([INVENTORY_ERROR_CODES]) und die,
|
|
5
|
+
* die Anmeldung und Rand auf jedem Aufruf erzeugen koennen
|
|
6
|
+
* ([INVENTORY_REQUEST_ERROR_CODES]). Ein fremder Code ist fuer diese Helfer
|
|
7
|
+
* kein Lager-Fehler: wer darauf verzweigt, tut es bewusst ueber
|
|
8
|
+
* `KasseneckApiError.code`.
|
|
9
|
+
*/
|
|
10
|
+
import type { KasseneckApiError } from '../client/errors.js';
|
|
11
|
+
import { type InventoryErrorCode, type InventoryRequestErrorCode } from './vertrag.js';
|
|
12
|
+
/** Ein Code, den ein Lager-Aufruf liefern kann. */
|
|
13
|
+
export type InventoryApiErrorCode = InventoryErrorCode | InventoryRequestErrorCode;
|
|
14
|
+
export declare function isInventoryErrorCode(value: unknown): value is InventoryApiErrorCode;
|
|
15
|
+
/** Der Fehlercode eines geworfenen Fehlers; `undefined`, wenn es keiner der Lager-API ist. */
|
|
16
|
+
export declare function inventoryErrorCode(error: unknown): InventoryApiErrorCode | undefined;
|
|
17
|
+
/** Kurzform fuer `catch (e) { if (isInventoryError(e, 'article_not_found')) … }`. */
|
|
18
|
+
export declare function isInventoryError(error: unknown, code?: InventoryApiErrorCode): error is KasseneckApiError;
|
|
19
|
+
/** Ein Feldfehler aus `data.errors[]` einer `validation`-Antwort. */
|
|
20
|
+
export interface InventoryFieldError {
|
|
21
|
+
/** Feld der gesendeten Anfrage, z. B. `limit` oder `events`. */
|
|
22
|
+
field: string;
|
|
23
|
+
message: string;
|
|
24
|
+
}
|
|
25
|
+
/** Die Feldfehler einer `validation`-Antwort; leer, wenn es keine sind. */
|
|
26
|
+
export declare function inventoryFieldErrors(error: unknown): InventoryFieldError[];
|
|
27
|
+
/**
|
|
28
|
+
* Wie lange `rate_limited` noch gilt, in Sekunden (`data.retryAfterSec`,
|
|
29
|
+
* dasselbe wie die Kopfzeile `Retry-After`). `undefined`, wenn der Fehler kein
|
|
30
|
+
* `rate_limited` ist oder der Server keine Angabe macht. Die Grenze gilt je
|
|
31
|
+
* Konto (etwa 20 Anfragen je Sekunde, kurze Spitzen bis 40).
|
|
32
|
+
*/
|
|
33
|
+
export declare function inventoryRetryAfterSec(error: unknown): number | undefined;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Fehler der Lager-API auswerten: am Code, nie am Text.
|
|
4
|
+
*
|
|
5
|
+
* Es zaehlen die Codes der Lager-Endpunkte ([INVENTORY_ERROR_CODES]) und die,
|
|
6
|
+
* die Anmeldung und Rand auf jedem Aufruf erzeugen koennen
|
|
7
|
+
* ([INVENTORY_REQUEST_ERROR_CODES]). Ein fremder Code ist fuer diese Helfer
|
|
8
|
+
* kein Lager-Fehler: wer darauf verzweigt, tut es bewusst ueber
|
|
9
|
+
* `KasseneckApiError.code`.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.isInventoryErrorCode = isInventoryErrorCode;
|
|
13
|
+
exports.inventoryErrorCode = inventoryErrorCode;
|
|
14
|
+
exports.isInventoryError = isInventoryError;
|
|
15
|
+
exports.inventoryFieldErrors = inventoryFieldErrors;
|
|
16
|
+
exports.inventoryRetryAfterSec = inventoryRetryAfterSec;
|
|
17
|
+
const fehlercodes_js_1 = require("../client/fehlercodes.js");
|
|
18
|
+
const vertrag_js_1 = require("./vertrag.js");
|
|
19
|
+
const BEKANNT = new Set([...vertrag_js_1.INVENTORY_ERROR_CODES, ...vertrag_js_1.INVENTORY_REQUEST_ERROR_CODES]);
|
|
20
|
+
function isInventoryErrorCode(value) {
|
|
21
|
+
return typeof value === 'string' && BEKANNT.has(value);
|
|
22
|
+
}
|
|
23
|
+
/** Der Fehlercode eines geworfenen Fehlers; `undefined`, wenn es keiner der Lager-API ist. */
|
|
24
|
+
function inventoryErrorCode(error) {
|
|
25
|
+
return (0, fehlercodes_js_1.bekannterCode)(error, BEKANNT);
|
|
26
|
+
}
|
|
27
|
+
/** Kurzform fuer `catch (e) { if (isInventoryError(e, 'article_not_found')) … }`. */
|
|
28
|
+
function isInventoryError(error, code) {
|
|
29
|
+
const gefunden = inventoryErrorCode(error);
|
|
30
|
+
return gefunden !== undefined && (code === undefined || gefunden === code);
|
|
31
|
+
}
|
|
32
|
+
/** Die Feldfehler einer `validation`-Antwort; leer, wenn es keine sind. */
|
|
33
|
+
function inventoryFieldErrors(error) {
|
|
34
|
+
return (0, fehlercodes_js_1.feldfehlerVon)(error);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Wie lange `rate_limited` noch gilt, in Sekunden (`data.retryAfterSec`,
|
|
38
|
+
* dasselbe wie die Kopfzeile `Retry-After`). `undefined`, wenn der Fehler kein
|
|
39
|
+
* `rate_limited` ist oder der Server keine Angabe macht. Die Grenze gilt je
|
|
40
|
+
* Konto (etwa 20 Anfragen je Sekunde, kurze Spitzen bis 40).
|
|
41
|
+
*/
|
|
42
|
+
function inventoryRetryAfterSec(error) {
|
|
43
|
+
if (inventoryErrorCode(error) !== 'rate_limited')
|
|
44
|
+
return undefined;
|
|
45
|
+
const wert = error.details['retryAfterSec'];
|
|
46
|
+
return typeof wert === 'number' && Number.isFinite(wert) && wert >= 0 ? wert : undefined;
|
|
47
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@kreiseck/kasseneck-api/inventory` – die Lager-API: Artikel, Standorte,
|
|
3
|
+
* Bestand und Lagerprotokoll lesen, Konto-Webhooks verwalten und eingehende
|
|
4
|
+
* Zustellungen pruefen (Backend Stufe 5a).
|
|
5
|
+
*
|
|
6
|
+
* Ein eigener Unterpfad wie `invoice`: der `api_key` eines Kontos gehoert auf
|
|
7
|
+
* einen **Server** (etwa das Backend eines Online-Shops) und soll nicht
|
|
8
|
+
* versehentlich in ein Browser-Buendel wandern.
|
|
9
|
+
*
|
|
10
|
+
* Mengen in Tausendstel der Basiseinheit, Geld in Cent, Einkaufspreise in
|
|
11
|
+
* Mikro-Euro; alles Ganzzahlen.
|
|
12
|
+
*/
|
|
13
|
+
export { createInventoryClient, type InventoryClient, type InventoryClientOptions } from './api.js';
|
|
14
|
+
export { inventoryKeyAuth, type InventoryKeyAuthOptions } from './auth.js';
|
|
15
|
+
export { isInventoryError, isInventoryErrorCode, inventoryErrorCode, inventoryFieldErrors, inventoryRetryAfterSec, type InventoryApiErrorCode, type InventoryFieldError, } from './fehler.js';
|
|
16
|
+
export { createWebhook, deleteWebhook, getArticle, getStock, iterateArticles, iterateStock, iterateStockMovements, listArticles, listLocations, listStock, listStockMovements, listWebhookDeliveries, listWebhooks, lookupArticleByCode, rotateWebhookSecret, sendWebhookTest, updateWebhook, } from './endpunkte.js';
|
|
17
|
+
export { verifyInventoryWebhookSignature, parseInventoryWebhookEvent, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_EVENT_HEADER, WEBHOOK_DELIVERY_HEADER, WEBHOOK_TOLERANCE_SEC, type VerifyInventoryWebhookOptions, } from './webhook.js';
|
|
18
|
+
export type { Article, ArticleListQuery, ArticleLookup, ArticlePage, CreateInventoryWebhookOptions, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookEnvelope, InventoryWebhookEvent, InventoryWebhookList, InventoryWebhookPatch, InventoryWebhookTestDelivery, InventoryWebhookTestResult, InventoryWebhookWithSecret, Location, LocationAddress, StockBelowMinimumEventData, StockChangedEventData, StockLevel, StockListQuery, StockMovement, StockMovementLot, StockMovementPage, StockMovementQuery, StockMovementSourceRef, StockPage, StockResult, StockValue, } from './typen.js';
|
|
19
|
+
export { INVENTORY_ENDPOINTS, INVENTORY_ERROR_CODES, INVENTORY_REQUEST_ERROR_CODES, INVENTORY_WEBHOOK_EVENTS, INVENTORY_WEBHOOK_ENVELOPE_FIELDS, INVENTORY_WEBHOOK_LIMIT, INVENTORY_LIST_LIMIT_MAX, LOCATION_TYPES, STOCK_MOVEMENT_TYPES, STOCK_MOVEMENT_SOURCES, STOCK_CONDITIONS, STOCK_CHANGE_CAUSES, WEBHOOK_DELIVERY_STATUSES, type InventoryEndpoint, type InventoryErrorCode, type InventoryRequestErrorCode, type InventoryWebhookEventType, type LocationType, type StockMovementType, type StockMovementSource, type StockCondition, type StockChangeCause, type WebhookDeliveryStatus, } from './vertrag.js';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `@kreiseck/kasseneck-api/inventory` – die Lager-API: Artikel, Standorte,
|
|
4
|
+
* Bestand und Lagerprotokoll lesen, Konto-Webhooks verwalten und eingehende
|
|
5
|
+
* Zustellungen pruefen (Backend Stufe 5a).
|
|
6
|
+
*
|
|
7
|
+
* Ein eigener Unterpfad wie `invoice`: der `api_key` eines Kontos gehoert auf
|
|
8
|
+
* einen **Server** (etwa das Backend eines Online-Shops) und soll nicht
|
|
9
|
+
* versehentlich in ein Browser-Buendel wandern.
|
|
10
|
+
*
|
|
11
|
+
* Mengen in Tausendstel der Basiseinheit, Geld in Cent, Einkaufspreise in
|
|
12
|
+
* Mikro-Euro; alles Ganzzahlen.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.WEBHOOK_DELIVERY_STATUSES = exports.STOCK_CHANGE_CAUSES = exports.STOCK_CONDITIONS = exports.STOCK_MOVEMENT_SOURCES = exports.STOCK_MOVEMENT_TYPES = exports.LOCATION_TYPES = exports.INVENTORY_LIST_LIMIT_MAX = exports.INVENTORY_WEBHOOK_LIMIT = exports.INVENTORY_WEBHOOK_ENVELOPE_FIELDS = exports.INVENTORY_WEBHOOK_EVENTS = exports.INVENTORY_REQUEST_ERROR_CODES = exports.INVENTORY_ERROR_CODES = exports.INVENTORY_ENDPOINTS = exports.WEBHOOK_TOLERANCE_SEC = exports.WEBHOOK_DELIVERY_HEADER = exports.WEBHOOK_EVENT_HEADER = exports.WEBHOOK_SIGNATURE_HEADER = exports.parseInventoryWebhookEvent = exports.verifyInventoryWebhookSignature = exports.updateWebhook = exports.sendWebhookTest = exports.rotateWebhookSecret = exports.lookupArticleByCode = exports.listWebhooks = exports.listWebhookDeliveries = exports.listStockMovements = exports.listStock = exports.listLocations = exports.listArticles = exports.iterateStockMovements = exports.iterateStock = exports.iterateArticles = exports.getStock = exports.getArticle = exports.deleteWebhook = exports.createWebhook = exports.inventoryRetryAfterSec = exports.inventoryFieldErrors = exports.inventoryErrorCode = exports.isInventoryErrorCode = exports.isInventoryError = exports.inventoryKeyAuth = exports.createInventoryClient = void 0;
|
|
16
|
+
var api_js_1 = require("./api.js");
|
|
17
|
+
Object.defineProperty(exports, "createInventoryClient", { enumerable: true, get: function () { return api_js_1.createInventoryClient; } });
|
|
18
|
+
var auth_js_1 = require("./auth.js");
|
|
19
|
+
Object.defineProperty(exports, "inventoryKeyAuth", { enumerable: true, get: function () { return auth_js_1.inventoryKeyAuth; } });
|
|
20
|
+
var fehler_js_1 = require("./fehler.js");
|
|
21
|
+
Object.defineProperty(exports, "isInventoryError", { enumerable: true, get: function () { return fehler_js_1.isInventoryError; } });
|
|
22
|
+
Object.defineProperty(exports, "isInventoryErrorCode", { enumerable: true, get: function () { return fehler_js_1.isInventoryErrorCode; } });
|
|
23
|
+
Object.defineProperty(exports, "inventoryErrorCode", { enumerable: true, get: function () { return fehler_js_1.inventoryErrorCode; } });
|
|
24
|
+
Object.defineProperty(exports, "inventoryFieldErrors", { enumerable: true, get: function () { return fehler_js_1.inventoryFieldErrors; } });
|
|
25
|
+
Object.defineProperty(exports, "inventoryRetryAfterSec", { enumerable: true, get: function () { return fehler_js_1.inventoryRetryAfterSec; } });
|
|
26
|
+
var endpunkte_js_1 = require("./endpunkte.js");
|
|
27
|
+
Object.defineProperty(exports, "createWebhook", { enumerable: true, get: function () { return endpunkte_js_1.createWebhook; } });
|
|
28
|
+
Object.defineProperty(exports, "deleteWebhook", { enumerable: true, get: function () { return endpunkte_js_1.deleteWebhook; } });
|
|
29
|
+
Object.defineProperty(exports, "getArticle", { enumerable: true, get: function () { return endpunkte_js_1.getArticle; } });
|
|
30
|
+
Object.defineProperty(exports, "getStock", { enumerable: true, get: function () { return endpunkte_js_1.getStock; } });
|
|
31
|
+
Object.defineProperty(exports, "iterateArticles", { enumerable: true, get: function () { return endpunkte_js_1.iterateArticles; } });
|
|
32
|
+
Object.defineProperty(exports, "iterateStock", { enumerable: true, get: function () { return endpunkte_js_1.iterateStock; } });
|
|
33
|
+
Object.defineProperty(exports, "iterateStockMovements", { enumerable: true, get: function () { return endpunkte_js_1.iterateStockMovements; } });
|
|
34
|
+
Object.defineProperty(exports, "listArticles", { enumerable: true, get: function () { return endpunkte_js_1.listArticles; } });
|
|
35
|
+
Object.defineProperty(exports, "listLocations", { enumerable: true, get: function () { return endpunkte_js_1.listLocations; } });
|
|
36
|
+
Object.defineProperty(exports, "listStock", { enumerable: true, get: function () { return endpunkte_js_1.listStock; } });
|
|
37
|
+
Object.defineProperty(exports, "listStockMovements", { enumerable: true, get: function () { return endpunkte_js_1.listStockMovements; } });
|
|
38
|
+
Object.defineProperty(exports, "listWebhookDeliveries", { enumerable: true, get: function () { return endpunkte_js_1.listWebhookDeliveries; } });
|
|
39
|
+
Object.defineProperty(exports, "listWebhooks", { enumerable: true, get: function () { return endpunkte_js_1.listWebhooks; } });
|
|
40
|
+
Object.defineProperty(exports, "lookupArticleByCode", { enumerable: true, get: function () { return endpunkte_js_1.lookupArticleByCode; } });
|
|
41
|
+
Object.defineProperty(exports, "rotateWebhookSecret", { enumerable: true, get: function () { return endpunkte_js_1.rotateWebhookSecret; } });
|
|
42
|
+
Object.defineProperty(exports, "sendWebhookTest", { enumerable: true, get: function () { return endpunkte_js_1.sendWebhookTest; } });
|
|
43
|
+
Object.defineProperty(exports, "updateWebhook", { enumerable: true, get: function () { return endpunkte_js_1.updateWebhook; } });
|
|
44
|
+
var webhook_js_1 = require("./webhook.js");
|
|
45
|
+
Object.defineProperty(exports, "verifyInventoryWebhookSignature", { enumerable: true, get: function () { return webhook_js_1.verifyInventoryWebhookSignature; } });
|
|
46
|
+
Object.defineProperty(exports, "parseInventoryWebhookEvent", { enumerable: true, get: function () { return webhook_js_1.parseInventoryWebhookEvent; } });
|
|
47
|
+
Object.defineProperty(exports, "WEBHOOK_SIGNATURE_HEADER", { enumerable: true, get: function () { return webhook_js_1.WEBHOOK_SIGNATURE_HEADER; } });
|
|
48
|
+
Object.defineProperty(exports, "WEBHOOK_EVENT_HEADER", { enumerable: true, get: function () { return webhook_js_1.WEBHOOK_EVENT_HEADER; } });
|
|
49
|
+
Object.defineProperty(exports, "WEBHOOK_DELIVERY_HEADER", { enumerable: true, get: function () { return webhook_js_1.WEBHOOK_DELIVERY_HEADER; } });
|
|
50
|
+
Object.defineProperty(exports, "WEBHOOK_TOLERANCE_SEC", { enumerable: true, get: function () { return webhook_js_1.WEBHOOK_TOLERANCE_SEC; } });
|
|
51
|
+
var vertrag_js_1 = require("./vertrag.js");
|
|
52
|
+
Object.defineProperty(exports, "INVENTORY_ENDPOINTS", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_ENDPOINTS; } });
|
|
53
|
+
Object.defineProperty(exports, "INVENTORY_ERROR_CODES", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_ERROR_CODES; } });
|
|
54
|
+
Object.defineProperty(exports, "INVENTORY_REQUEST_ERROR_CODES", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_REQUEST_ERROR_CODES; } });
|
|
55
|
+
Object.defineProperty(exports, "INVENTORY_WEBHOOK_EVENTS", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_WEBHOOK_EVENTS; } });
|
|
56
|
+
Object.defineProperty(exports, "INVENTORY_WEBHOOK_ENVELOPE_FIELDS", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_WEBHOOK_ENVELOPE_FIELDS; } });
|
|
57
|
+
Object.defineProperty(exports, "INVENTORY_WEBHOOK_LIMIT", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_WEBHOOK_LIMIT; } });
|
|
58
|
+
Object.defineProperty(exports, "INVENTORY_LIST_LIMIT_MAX", { enumerable: true, get: function () { return vertrag_js_1.INVENTORY_LIST_LIMIT_MAX; } });
|
|
59
|
+
Object.defineProperty(exports, "LOCATION_TYPES", { enumerable: true, get: function () { return vertrag_js_1.LOCATION_TYPES; } });
|
|
60
|
+
Object.defineProperty(exports, "STOCK_MOVEMENT_TYPES", { enumerable: true, get: function () { return vertrag_js_1.STOCK_MOVEMENT_TYPES; } });
|
|
61
|
+
Object.defineProperty(exports, "STOCK_MOVEMENT_SOURCES", { enumerable: true, get: function () { return vertrag_js_1.STOCK_MOVEMENT_SOURCES; } });
|
|
62
|
+
Object.defineProperty(exports, "STOCK_CONDITIONS", { enumerable: true, get: function () { return vertrag_js_1.STOCK_CONDITIONS; } });
|
|
63
|
+
Object.defineProperty(exports, "STOCK_CHANGE_CAUSES", { enumerable: true, get: function () { return vertrag_js_1.STOCK_CHANGE_CAUSES; } });
|
|
64
|
+
Object.defineProperty(exports, "WEBHOOK_DELIVERY_STATUSES", { enumerable: true, get: function () { return vertrag_js_1.WEBHOOK_DELIVERY_STATUSES; } });
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Leser der Lager-Antworten: aus dem Draht `/v3` werden die Modelle in
|
|
3
|
+
* `typen.ts`. Paketintern, nicht Teil der Oberflaeche.
|
|
4
|
+
*
|
|
5
|
+
* Regel wie beim Lager an der Kasse (`pos/lager.ts`): eine Menge, ein Betrag
|
|
6
|
+
* oder eine Folgenummer ist eine Ganzzahl, sonst endet der Aufruf mit
|
|
7
|
+
* `KasseneckValidationError` (`scope: 'response'`). Ein Ersatzwert wie `0`
|
|
8
|
+
* waere eine falsche Aussage („kein Bestand“ statt „Antwort kaputt“). Texte
|
|
9
|
+
* sind nachsichtiger: ein fehlender oder fremder Wert wird `null`.
|
|
10
|
+
*
|
|
11
|
+
* Optionale Felder (Einkaufswerte, `externalIds` …) erscheinen im Modell nur,
|
|
12
|
+
* wenn der Server sie sendet: „fehlt“ heisst dort „kein Recht“, nicht „leer“.
|
|
13
|
+
*/
|
|
14
|
+
import { KasseneckValidationError } from '../client/errors.js';
|
|
15
|
+
import type { Article, InventoryWebhook, InventoryWebhookDelivery, InventoryWebhookTestDelivery, Location, StockBelowMinimumEventData, StockChangedEventData, StockLevel, StockMovement, StockValue } from './typen.js';
|
|
16
|
+
type Roh = Record<string, unknown>;
|
|
17
|
+
/** Ein Leser bekommt den Vorgang (fuer die Meldung) und den Pfad im Rumpf. */
|
|
18
|
+
export interface Ort {
|
|
19
|
+
name: string;
|
|
20
|
+
pfad: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function antwortfehler(name: string, grund: string): KasseneckValidationError;
|
|
23
|
+
export declare function objekt(w: unknown): Roh | null;
|
|
24
|
+
export declare function artikel(ort: Ort, w: unknown): Article;
|
|
25
|
+
export declare function standort(ort: Ort, w: unknown): Location;
|
|
26
|
+
export declare function bestand(ort: Ort, w: unknown): StockLevel;
|
|
27
|
+
export declare function wert(ort: Ort, w: unknown): StockValue;
|
|
28
|
+
export declare function bewegung(ort: Ort, w: unknown): StockMovement;
|
|
29
|
+
export declare function webhook(ort: Ort, w: unknown): InventoryWebhook;
|
|
30
|
+
export declare function zustellung(ort: Ort, w: unknown): InventoryWebhookDelivery;
|
|
31
|
+
export declare function probeZustellung(ort: Ort, w: unknown, webhookId: string): InventoryWebhookTestDelivery;
|
|
32
|
+
export declare function bestandGeaendert(ort: Ort, w: unknown): StockChangedEventData;
|
|
33
|
+
export declare function unterMindestbestand(ort: Ort, w: unknown): StockBelowMinimumEventData;
|
|
34
|
+
/** Eine zugesagte Liste `data.<feld>`, Eintrag fuer Eintrag gelesen. */
|
|
35
|
+
export declare function liste<T>(name: string, daten: unknown, feld: string, lesen: (ort: Ort, e: unknown) => T): T[];
|
|
36
|
+
/** Der Cursor der naechsten Seite; `null` am Ende. Etwas anderes als Text oder `null` ist kaputt. */
|
|
37
|
+
export declare function naechsterCursor(name: string, daten: unknown): string | null;
|
|
38
|
+
export {};
|