@maschinenlesbar.org/marktstammdatenregister-cli 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -4
- package/dist/src/cli/commands/units.d.ts.map +1 -1
- package/dist/src/cli/commands/units.js +21 -14
- package/dist/src/cli/commands/units.js.map +1 -1
- package/dist/src/cli/program.d.ts.map +1 -1
- package/dist/src/cli/program.js +1 -1
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/cli/shared.d.ts +9 -3
- package/dist/src/cli/shared.d.ts.map +1 -1
- package/dist/src/cli/shared.js +28 -4
- package/dist/src/cli/shared.js.map +1 -1
- package/dist/src/client/client.d.ts +15 -2
- package/dist/src/client/client.d.ts.map +1 -1
- package/dist/src/client/client.js +84 -18
- package/dist/src/client/client.js.map +1 -1
- package/dist/src/client/engine.d.ts +59 -12
- package/dist/src/client/engine.d.ts.map +1 -1
- package/dist/src/client/engine.js +113 -25
- package/dist/src/client/engine.js.map +1 -1
- package/dist/src/client/errors.d.ts +10 -1
- package/dist/src/client/errors.d.ts.map +1 -1
- package/dist/src/client/errors.js +27 -3
- package/dist/src/client/errors.js.map +1 -1
- package/dist/src/client/filter.d.ts +57 -0
- package/dist/src/client/filter.d.ts.map +1 -0
- package/dist/src/client/filter.js +145 -0
- package/dist/src/client/filter.js.map +1 -0
- package/dist/src/client/http.js +2 -2
- package/dist/src/client/http.js.map +1 -1
- package/dist/src/client/index.d.ts +5 -3
- package/dist/src/client/index.d.ts.map +1 -1
- package/dist/src/client/index.js +4 -3
- package/dist/src/client/index.js.map +1 -1
- package/dist/src/client/types.d.ts +27 -11
- package/dist/src/client/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,11 +42,15 @@ mastr filters stromerzeugung # the filterable columns + d
|
|
|
42
42
|
|
|
43
43
|
Categories: `stromerzeugung`, `stromverbrauch`, `gaserzeugung`, `gasverbrauch`.
|
|
44
44
|
|
|
45
|
-
**Filtering** uses the register's own syntax — `FilterName~op~'value'~
|
|
45
|
+
**Filtering** uses the register's own syntax — `FilterName~op~'value'~and~…`
|
|
46
46
|
(ops `eq|neq|sw|ct|nct|ew|null|nn`, plus the strict `gt`/`lt` for numbers and dates);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
there is **no working `~or~`** (the register drops everything after it, so the CLI
|
|
48
|
+
rejects it) — for several codes of one dropdown, list them in one value:
|
|
49
|
+
`Energieträger~eq~'2497,2498'`. Discover the German field names and dropdown codes with `mastr filters <category>`. A
|
|
50
|
+
**wrong `FilterName` is silently ignored** (you get the unfiltered set), and a **wrong
|
|
51
|
+
`--sort` key returns 0 rows**; a malformed spec or an unknown operator (e.g. `gte`) is
|
|
52
|
+
rejected before any request (exit 2), because the register would answer it with a wrong
|
|
53
|
+
count. Verify filter names
|
|
50
54
|
with `mastr filters` and sanity-check with `--total`; sort keys are record field names
|
|
51
55
|
(`Bruttoleistung`), not FilterNames — list them with
|
|
52
56
|
`mastr stromerzeugung --page-size 1 --compact | jq '.data[0] | keys'`. **Dates** come as Microsoft
|
|
@@ -66,6 +70,21 @@ solar.total; // total matching units
|
|
|
66
70
|
parseMsDate(String(solar.data[0]?.EinheitRegistrierungsdatum)); // Date | null
|
|
67
71
|
```
|
|
68
72
|
|
|
73
|
+
Build filters from user input with `buildFilter`, not string interpolation: a filter
|
|
74
|
+
value cannot contain `~` (the register splits on it and has no escape), so
|
|
75
|
+
`` `Ort~eq~'${input}'` `` lets an input like `Münster'~and~Energieträger~eq~'2497` add a
|
|
76
|
+
condition. `buildFilter` quotes each value and throws `MastrValidationError` for a `~`:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { buildFilter } from "@maschinenlesbar.org/marktstammdatenregister-cli";
|
|
80
|
+
|
|
81
|
+
const filter = buildFilter([
|
|
82
|
+
{ name: "Ort", op: "eq", value: town }, // quoted, ~ refused
|
|
83
|
+
{ name: "Energieträger", op: "eq", value: ["2497", "2498"] }, // comma list = any of
|
|
84
|
+
]);
|
|
85
|
+
await mastr.stromerzeugung({ filter, pageSize: 1 });
|
|
86
|
+
```
|
|
87
|
+
|
|
69
88
|
## Documentation
|
|
70
89
|
|
|
71
90
|
- [Usage.md](Usage.md) — commands, filter syntax, exit codes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"units.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/units.ts"],"names":[],"mappings":"AAIA,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"units.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/units.ts"],"names":[],"mappings":"AAIA,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAmCxC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CA6DtE"}
|
|
@@ -2,12 +2,16 @@
|
|
|
2
2
|
// gas × generation / consumption), each a paged, optionally-filtered search, plus a
|
|
3
3
|
// `filters` command to discover the filterable columns and their dropdown codes.
|
|
4
4
|
import { Argument } from "commander";
|
|
5
|
-
import {
|
|
5
|
+
import { MAX_PAGE, MAX_PAGE_SIZE } from "../../client/client.js";
|
|
6
|
+
import { action, parseBoundedInt, parseFilter, parseNonEmpty, renderJson } from "../shared.js";
|
|
7
|
+
// `sortKey` is a record field that exists in that category's rows (live 2026-09-26):
|
|
8
|
+
// only stromerzeugung rows carry Bruttoleistung/Nettonennleistung, so the stderr hint
|
|
9
|
+
// must not suggest it for the other three.
|
|
6
10
|
const CATEGORIES = [
|
|
7
|
-
{ name: "stromerzeugung", desc: "Electricity-generation units (Stromerzeugung)" },
|
|
8
|
-
{ name: "stromverbrauch", desc: "Electricity-consumption units (Stromverbrauch)" },
|
|
9
|
-
{ name: "gaserzeugung", desc: "Gas-generation units (Gaserzeugung)" },
|
|
10
|
-
{ name: "gasverbrauch", desc: "Gas-consumption units (Gasverbrauch)" },
|
|
11
|
+
{ name: "stromerzeugung", desc: "Electricity-generation units (Stromerzeugung)", sortKey: "Bruttoleistung" },
|
|
12
|
+
{ name: "stromverbrauch", desc: "Electricity-consumption units (Stromverbrauch)", sortKey: "InbetriebnahmeDatum" },
|
|
13
|
+
{ name: "gaserzeugung", desc: "Gas-generation units (Gaserzeugung)", sortKey: "Erzeugungsleistung" },
|
|
14
|
+
{ name: "gasverbrauch", desc: "Gas-consumption units (Gasverbrauch)", sortKey: "MaximaleGasbezugsLeistung" },
|
|
11
15
|
];
|
|
12
16
|
const RUN = {
|
|
13
17
|
stromerzeugung: (c, q) => c.stromerzeugung(q),
|
|
@@ -37,12 +41,13 @@ export function registerCommands(program, deps) {
|
|
|
37
41
|
program
|
|
38
42
|
.command(cat.name)
|
|
39
43
|
.description(cat.desc)
|
|
40
|
-
.option("--page <n>", "1-based page number", parseBoundedInt(1,
|
|
41
|
-
.option("--page-size <n>",
|
|
44
|
+
.option("--page <n>", "1-based page number", parseBoundedInt(1, MAX_PAGE), 1)
|
|
45
|
+
.option("--page-size <n>", `rows per page (1..${MAX_PAGE_SIZE})`, parseBoundedInt(1, MAX_PAGE_SIZE), 25)
|
|
42
46
|
.option("--sort <spec>", "sort: FieldKey-asc | FieldKey-desc, where FieldKey is a record field name, not a " +
|
|
43
|
-
|
|
44
|
-
.option("--filter <spec>", "filter: FilterName~op~'value'~
|
|
45
|
-
"gt/lt strict;
|
|
47
|
+
`FilterName (e.g. ${cat.sortKey}-desc)`, parseNonEmpty)
|
|
48
|
+
.option("--filter <spec>", "filter: FilterName~op~'value'~and~… (see `filters`; ops eq|neq|sw|ct|nct|ew|null|nn|gt|lt, " +
|
|
49
|
+
"gt/lt strict; null/nn take ''). A malformed spec or unknown op is rejected. No ~or~: " +
|
|
50
|
+
"for several dropdown codes use one comma list, e.g. Energieträger~eq~'2497,2498'", parseFilter)
|
|
46
51
|
.option("--total", "print only the total match count, not the rows")
|
|
47
52
|
.action(action(deps, async ({ client, global, opts }) => {
|
|
48
53
|
const page = await RUN[cat.name](client, buildQuery(opts));
|
|
@@ -52,14 +57,16 @@ export function registerCommands(program, deps) {
|
|
|
52
57
|
// the FilterNames from `mastr filters` ("Bruttoleistung der Einheit") don't sort.
|
|
53
58
|
if (page.total === 0 && typeof opts["sort"] === "string") {
|
|
54
59
|
deps.io.err("Note: 0 results with --sort set. If you expected matches, an unknown sort " +
|
|
55
|
-
|
|
60
|
+
`key returns 0 rows. Sort keys are record field names (e.g. ${cat.sortKey}), ` +
|
|
56
61
|
"not the FilterNames from `mastr filters`; list them with " +
|
|
57
62
|
`\`mastr ${cat.name} --page-size 1 --compact | jq '.data[0] | keys'\`.`);
|
|
58
63
|
}
|
|
64
|
+
// An unknown operator is already a usage error (filterProblem); what is left
|
|
65
|
+
// that silently gives 0 rows is a value the register can't match.
|
|
59
66
|
if (page.total === 0 && typeof opts["filter"] === "string") {
|
|
60
|
-
deps.io.err("Note: 0 results with --filter set. If you expected matches, check the
|
|
61
|
-
"
|
|
62
|
-
"
|
|
67
|
+
deps.io.err("Note: 0 results with --filter set. If you expected matches, check the values: a " +
|
|
68
|
+
"dropdown takes its code (the Value from `mastr filters`), not its label, decimals " +
|
|
69
|
+
"take a point ('4999.999'), and gt/lt are strict.");
|
|
63
70
|
}
|
|
64
71
|
renderJson(deps, global, opts["total"] === true ? page.total : page);
|
|
65
72
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"units.js","sourceRoot":"","sources":["../../../../src/cli/commands/units.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,oFAAoF;AACpF,iFAAiF;AAEjF,OAAO,EAAE,QAAQ,EAAgB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"units.js","sourceRoot":"","sources":["../../../../src/cli/commands/units.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../../src/cli/program.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAuBvC,eAAO,MAAM,OAAO,QAAgB,CAAC;AAErC,8DAA8D;AAC9D,eAAO,MAAM,WAAW,EAAE,OAGzB,CAAC;AAEF,wBAAgB,YAAY,CAAC,IAAI,GAAE,OAAqB,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../../src/cli/program.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAuBvC,eAAO,MAAM,OAAO,QAAgB,CAAC;AAErC,8DAA8D;AAC9D,eAAO,MAAM,WAAW,EAAE,OAGzB,CAAC;AAEF,wBAAgB,YAAY,CAAC,IAAI,GAAE,OAAqB,GAAG,OAAO,CA0CjE"}
|
package/dist/src/cli/program.js
CHANGED
|
@@ -44,7 +44,7 @@ export function buildProgram(deps = defaultDeps) {
|
|
|
44
44
|
.option("--base-url <url>", "API base URL (http/https only)", parseBaseUrl, "https://www.marktstammdatenregister.de/MaStR")
|
|
45
45
|
.option("--timeout <ms>", "time limit per request in ms, whole response included (0 = no timeout)", parseBoundedInt(0, MAX_TIMEOUT_MS))
|
|
46
46
|
.option("--user-agent <ua>", "User-Agent header value", parseHeaderValue)
|
|
47
|
-
.option("--max-retries <n>", "retries for transient 429/503 responses (0..10)", parseBoundedInt(0, 10))
|
|
47
|
+
.option("--max-retries <n>", "retries for transient 429/503 responses (0..10; each waits the server's Retry-After, up to 30 s)", parseBoundedInt(0, 10))
|
|
48
48
|
.option("--max-response-bytes <n>", "cap response body size in bytes (0 = unlimited; default 100 MiB)", parseIntArg)
|
|
49
49
|
.option("--compact", "print JSON on a single line instead of pretty-printed")
|
|
50
50
|
.option("--iso-dates", "rewrite MaStR /Date(ms)/ timestamps to ISO-8601")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"program.js","sourceRoot":"","sources":["../../../src/cli/program.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,4EAA4E;AAC5E,mBAAmB;AAEnB,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;GAKG;AACH,SAAS,WAAW;IAClB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,uBAAuB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAyB,CAAC;QAC5F,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;AAErC,8DAA8D;AAC9D,MAAM,CAAC,MAAM,WAAW,GAAY;IAClC,EAAE,EAAE,SAAS;IACb,YAAY,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC;CACpD,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,IAAI,GAAY,WAAW;IACtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,OAAO,CAAC;SACb,WAAW,CACV,iFAAiF;QAC/E,gFAAgF;QAChF,mFAAmF;QACnF,gFAAgF;QAChF,oFAAoF,CACvF;SACA,OAAO,CAAC,OAAO,CAAC;SAChB,MAAM,CACL,kBAAkB,EAClB,gCAAgC,EAChC,YAAY,EACZ,8CAA8C,CAC/C;SACA,MAAM,CACL,gBAAgB,EAChB,wEAAwE,EACxE,eAAe,CAAC,CAAC,EAAE,cAAc,CAAC,CACnC;SACA,MAAM,CAAC,mBAAmB,EAAE,yBAAyB,EAAE,gBAAgB,CAAC;SACxE,MAAM,
|
|
1
|
+
{"version":3,"file":"program.js","sourceRoot":"","sources":["../../../src/cli/program.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,4EAA4E;AAC5E,mBAAmB;AAEnB,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;GAKG;AACH,SAAS,WAAW;IAClB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,uBAAuB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAyB,CAAC;QAC5F,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;AAErC,8DAA8D;AAC9D,MAAM,CAAC,MAAM,WAAW,GAAY;IAClC,EAAE,EAAE,SAAS;IACb,YAAY,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC;CACpD,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,IAAI,GAAY,WAAW;IACtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,OAAO,CAAC;SACb,WAAW,CACV,iFAAiF;QAC/E,gFAAgF;QAChF,mFAAmF;QACnF,gFAAgF;QAChF,oFAAoF,CACvF;SACA,OAAO,CAAC,OAAO,CAAC;SAChB,MAAM,CACL,kBAAkB,EAClB,gCAAgC,EAChC,YAAY,EACZ,8CAA8C,CAC/C;SACA,MAAM,CACL,gBAAgB,EAChB,wEAAwE,EACxE,eAAe,CAAC,CAAC,EAAE,cAAc,CAAC,CACnC;SACA,MAAM,CAAC,mBAAmB,EAAE,yBAAyB,EAAE,gBAAgB,CAAC;SACxE,MAAM,CACL,mBAAmB,EACnB,kGAAkG,EAClG,eAAe,CAAC,CAAC,EAAE,EAAE,CAAC,CACvB;SACA,MAAM,CACL,0BAA0B,EAC1B,kEAAkE,EAClE,WAAW,CACZ;SACA,MAAM,CAAC,WAAW,EAAE,uDAAuD,CAAC;SAC5E,MAAM,CAAC,aAAa,EAAE,iDAAiD,CAAC;SACxE,kBAAkB,EAAE,CAAC;IAExB,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAEhC,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/src/cli/shared.d.ts
CHANGED
|
@@ -10,6 +10,11 @@ import type { MastrClientOptions } from "../client/client.js";
|
|
|
10
10
|
export declare function parseIntArg(value: string): number;
|
|
11
11
|
/** commander value-parser: a non-empty (after trimming) string. */
|
|
12
12
|
export declare function parseNonEmpty(value: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* commander value-parser for `--filter`: non-blank, and not a spec the register would
|
|
15
|
+
* misread (see `filterProblem`), so it becomes a usage error before any request.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseFilter(value: string): string;
|
|
13
18
|
/**
|
|
14
19
|
* commander value-parser for `--base-url`: non-empty and http/https-only.
|
|
15
20
|
*
|
|
@@ -41,9 +46,10 @@ export interface GlobalOptions {
|
|
|
41
46
|
/** Translate resolved global CLI options into client options. */
|
|
42
47
|
export declare function toEngineOptions(global: GlobalOptions): MastrClientOptions;
|
|
43
48
|
/**
|
|
44
|
-
* Escape the
|
|
45
|
-
* ESC) but not DEL
|
|
46
|
-
*
|
|
49
|
+
* Escape the characters JSON.stringify leaves raw although a terminal acts on them.
|
|
50
|
+
* It escapes C0 (including ESC) but not DEL, the C1 range U+0080–U+009F (U+009B is
|
|
51
|
+
* the 8-bit form of CSI) or the bidi formatting characters (isBidiControl), which
|
|
52
|
+
* reorder the text that follows. The output is server data, so escape them; the
|
|
47
53
|
* result is equivalent, valid JSON (these characters only occur inside strings).
|
|
48
54
|
* Checked by char code so the source stays free of control bytes.
|
|
49
55
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/cli/shared.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/cli/shared.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAM9D;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASjD;AAED,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKnD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAyBlD;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAOnF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQtD;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,kBAAkB,CAQzE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWvD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAgBrF;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IAC5C,MAAM,EAAE,aAAa,CAAC;IACtB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,OAAO,EACb,EAAE,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAC/D,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAQvC"}
|
package/dist/src/cli/shared.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import { InvalidArgumentError } from "commander";
|
|
4
4
|
import { isoifyDates } from "../client/client.js";
|
|
5
5
|
import { MastrParseError } from "../client/errors.js";
|
|
6
|
+
import { filterProblem } from "../client/filter.js";
|
|
7
|
+
import { isBidiControl } from "../client/engine.js";
|
|
6
8
|
/**
|
|
7
9
|
* commander value-parser: a plain base-10 non-negative integer.
|
|
8
10
|
*
|
|
@@ -27,6 +29,17 @@ export function parseNonEmpty(value) {
|
|
|
27
29
|
}
|
|
28
30
|
return value;
|
|
29
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* commander value-parser for `--filter`: non-blank, and not a spec the register would
|
|
34
|
+
* misread (see `filterProblem`), so it becomes a usage error before any request.
|
|
35
|
+
*/
|
|
36
|
+
export function parseFilter(value) {
|
|
37
|
+
parseNonEmpty(value);
|
|
38
|
+
const problem = filterProblem(value);
|
|
39
|
+
if (problem !== undefined)
|
|
40
|
+
throw new InvalidArgumentError(problem);
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
30
43
|
/**
|
|
31
44
|
* commander value-parser for `--base-url`: non-empty and http/https-only.
|
|
32
45
|
*
|
|
@@ -51,6 +64,16 @@ export function parseBaseUrl(value) {
|
|
|
51
64
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
52
65
|
throw new InvalidArgumentError("Only http and https URLs are supported.");
|
|
53
66
|
}
|
|
67
|
+
// Paths are appended to the base URL as a string, so a query or fragment would
|
|
68
|
+
// swallow every request path ("http://h/#f" requests "/" for every command).
|
|
69
|
+
if (/[?#]/.test(value)) {
|
|
70
|
+
throw new InvalidArgumentError("A base URL cannot have a query (?) or fragment (#).");
|
|
71
|
+
}
|
|
72
|
+
// new URL() trims surrounding whitespace silently; the raw value is what the
|
|
73
|
+
// engine uses, so reject it rather than guess.
|
|
74
|
+
if (value !== value.trim()) {
|
|
75
|
+
throw new InvalidArgumentError("A base URL cannot have surrounding whitespace.");
|
|
76
|
+
}
|
|
54
77
|
return value;
|
|
55
78
|
}
|
|
56
79
|
/** Build a commander value-parser for an integer constrained to [min, max]. */
|
|
@@ -95,9 +118,10 @@ export function toEngineOptions(global) {
|
|
|
95
118
|
return options;
|
|
96
119
|
}
|
|
97
120
|
/**
|
|
98
|
-
* Escape the
|
|
99
|
-
* ESC) but not DEL
|
|
100
|
-
*
|
|
121
|
+
* Escape the characters JSON.stringify leaves raw although a terminal acts on them.
|
|
122
|
+
* It escapes C0 (including ESC) but not DEL, the C1 range U+0080–U+009F (U+009B is
|
|
123
|
+
* the 8-bit form of CSI) or the bidi formatting characters (isBidiControl), which
|
|
124
|
+
* reorder the text that follows. The output is server data, so escape them; the
|
|
101
125
|
* result is equivalent, valid JSON (these characters only occur inside strings).
|
|
102
126
|
* Checked by char code so the source stays free of control bytes.
|
|
103
127
|
*/
|
|
@@ -106,7 +130,7 @@ export function escapeControlChars(json) {
|
|
|
106
130
|
let from = 0;
|
|
107
131
|
for (let i = 0; i < json.length; i++) {
|
|
108
132
|
const c = json.charCodeAt(i);
|
|
109
|
-
if (c >= 0x7f && c <= 0x9f) {
|
|
133
|
+
if ((c >= 0x7f && c <= 0x9f) || isBidiControl(c)) {
|
|
110
134
|
result += json.slice(from, i) + "\\u" + c.toString(16).padStart(4, "0");
|
|
111
135
|
from = i + 1;
|
|
112
136
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/cli/shared.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wEAAwE;AAGxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/cli/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { type EngineOptions } from "./engine.js";
|
|
2
2
|
import type { FilterColumn, UnitCategory, UnitPage, UnitQuery } from "./types.js";
|
|
3
|
+
/** Largest `page` the client (and the CLI's `--page`) accepts. */
|
|
4
|
+
export declare const MAX_PAGE = 1000000;
|
|
5
|
+
/** Largest `pageSize` the client (and the CLI's `--page-size`) accepts. */
|
|
6
|
+
export declare const MAX_PAGE_SIZE = 5000;
|
|
3
7
|
/** Options for the MaStR client (engine options only — the API needs no auth). */
|
|
4
8
|
export type MastrClientOptions = EngineOptions;
|
|
5
9
|
/**
|
|
6
10
|
* Parse a MaStR Microsoft-AJAX date string (`"/Date(1548979200000)/"`) into a Date.
|
|
7
|
-
*
|
|
11
|
+
* The offset form `"/Date(1548979200000+0100)/"` is accepted too; its milliseconds
|
|
12
|
+
* are UTC already, the offset only names the sender's zone. Returns null if the
|
|
13
|
+
* string is not in that format or the value is outside the Date range.
|
|
8
14
|
*/
|
|
9
15
|
export declare function parseMsDate(value: string): Date | null;
|
|
10
16
|
/**
|
|
@@ -19,6 +25,9 @@ export declare class MastrClient {
|
|
|
19
25
|
* Fetch one page of units for a category. Sends the full Kendo param set —
|
|
20
26
|
* `sort`, `page`, `pageSize`, `group`, `filter` — always, because the server
|
|
21
27
|
* rejects a request with `group`/`filter` missing ("Die Anfrage ist Null.").
|
|
28
|
+
* An unknown category, a `page` outside 1..`MAX_PAGE`, a `pageSize` outside
|
|
29
|
+
* 1..`MAX_PAGE_SIZE` or a filter the register would misread (e.g. `~or~`, see
|
|
30
|
+
* {@link validateFilter}) is rejected with a `MastrValidationError` before any request.
|
|
22
31
|
*/
|
|
23
32
|
units(category: UnitCategory, query?: UnitQuery): Promise<UnitPage>;
|
|
24
33
|
/** Electricity-generation units (`Stromerzeugung`). */
|
|
@@ -29,7 +38,11 @@ export declare class MastrClient {
|
|
|
29
38
|
gaserzeugung(query?: UnitQuery): Promise<UnitPage>;
|
|
30
39
|
/** Gas-consumption units (`Gasverbrauch`). */
|
|
31
40
|
gasverbrauch(query?: UnitQuery): Promise<UnitPage>;
|
|
32
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* The filterable columns (names, types, dropdown codes) for a category. An `Errors`
|
|
43
|
+
* envelope throws `MastrApiError`, any other non-array reply `MastrParseError` —
|
|
44
|
+
* never an empty list, which would read as "this category has no filters".
|
|
45
|
+
*/
|
|
33
46
|
filterColumns(category: UnitCategory): Promise<FilterColumn[]>;
|
|
34
47
|
}
|
|
35
48
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/client/client.ts"],"names":[],"mappings":"AAYA,OAAO,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/client/client.ts"],"names":[],"mappings":"AAYA,OAAO,EAAsC,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAIrF,OAAO,KAAK,EAAE,YAAY,EAAa,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAc7F,kEAAkE;AAClE,eAAO,MAAM,QAAQ,UAAY,CAAC;AAClC,2EAA2E;AAC3E,eAAO,MAAM,aAAa,OAAO,CAAC;AAsBlC,kFAAkF;AAClF,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAKtD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAqB1C;AAWD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IAEvC,YAAY,OAAO,GAAE,kBAAuB,EAE3C;IAED;;;;;;;OAOG;IACG,KAAK,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,GAAE,SAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,CAoC5E;IAED,uDAAuD;IACvD,cAAc,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEnD;IACD,wDAAwD;IACxD,cAAc,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEnD;IACD,6CAA6C;IAC7C,YAAY,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEjD;IACD,8CAA8C;IAC9C,YAAY,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEjD;IAED;;;;OAIG;IACG,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAenE;CACF"}
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
// const c = new MastrClient();
|
|
10
10
|
// const page = await c.stromerzeugung({ pageSize: 10, filter: "Energieträger~eq~'2495'" });
|
|
11
11
|
// page.total; // total solar units
|
|
12
|
-
import { RequestEngine,
|
|
13
|
-
import { MastrApiError } from "./errors.js";
|
|
12
|
+
import { RequestEngine, describeMastrErrors } from "./engine.js";
|
|
13
|
+
import { MastrApiError, MastrParseError, MastrValidationError } from "./errors.js";
|
|
14
|
+
import { validateFilter } from "./filter.js";
|
|
14
15
|
const SERVICE = "/Einheit/EinheitJson";
|
|
15
16
|
/** Map a category to the PascalCase suffix used in the endpoint names. */
|
|
16
17
|
const CATEGORY_SUFFIX = {
|
|
@@ -21,15 +22,37 @@ const CATEGORY_SUFFIX = {
|
|
|
21
22
|
};
|
|
22
23
|
const DEFAULT_PAGE = 1;
|
|
23
24
|
const DEFAULT_PAGE_SIZE = 25;
|
|
25
|
+
/** Largest `page` the client (and the CLI's `--page`) accepts. */
|
|
26
|
+
export const MAX_PAGE = 1_000_000;
|
|
27
|
+
/** Largest `pageSize` the client (and the CLI's `--page-size`) accepts. */
|
|
28
|
+
export const MAX_PAGE_SIZE = 5000;
|
|
29
|
+
/** The category's endpoint suffix; an unknown category (from plain JS) throws. */
|
|
30
|
+
function categorySuffix(category) {
|
|
31
|
+
if (typeof category !== "string" || !Object.hasOwn(CATEGORY_SUFFIX, category)) {
|
|
32
|
+
throw new MastrValidationError(`Invalid category: expected one of ${Object.keys(CATEGORY_SUFFIX).join(", ")}, got ${JSON.stringify(category)}.`);
|
|
33
|
+
}
|
|
34
|
+
return CATEGORY_SUFFIX[category];
|
|
35
|
+
}
|
|
36
|
+
/** Check an optional integer paging option against 1..max. */
|
|
37
|
+
function checkPaging(name, value, max) {
|
|
38
|
+
if (value === undefined)
|
|
39
|
+
return;
|
|
40
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1 || value > max) {
|
|
41
|
+
throw new MastrValidationError(`Invalid ${name}: expected an integer from 1 to ${max}, got ${typeof value === "string" ? JSON.stringify(value) : String(value)}.`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
24
44
|
/**
|
|
25
45
|
* Parse a MaStR Microsoft-AJAX date string (`"/Date(1548979200000)/"`) into a Date.
|
|
26
|
-
*
|
|
46
|
+
* The offset form `"/Date(1548979200000+0100)/"` is accepted too; its milliseconds
|
|
47
|
+
* are UTC already, the offset only names the sender's zone. Returns null if the
|
|
48
|
+
* string is not in that format or the value is outside the Date range.
|
|
27
49
|
*/
|
|
28
50
|
export function parseMsDate(value) {
|
|
29
|
-
const m = /^\/Date\((-?\d+)\)\/$/.exec(value);
|
|
51
|
+
const m = /^\/Date\((-?\d+)(?:[+-]\d{4})?\)\/$/.exec(value);
|
|
30
52
|
if (!m)
|
|
31
53
|
return null;
|
|
32
|
-
|
|
54
|
+
const date = new Date(Number(m[1]));
|
|
55
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
33
56
|
}
|
|
34
57
|
/**
|
|
35
58
|
* Recursively rewrite every `"/Date(ms)/"` string in a value to an ISO-8601 string,
|
|
@@ -37,10 +60,10 @@ export function parseMsDate(value) {
|
|
|
37
60
|
*/
|
|
38
61
|
export function isoifyDates(value) {
|
|
39
62
|
if (typeof value === "string") {
|
|
63
|
+
// parseMsDate returns null for an out-of-range value, so `.toISOString()` never
|
|
64
|
+
// throws; such a string is left as-is.
|
|
40
65
|
const d = parseMsDate(value);
|
|
41
|
-
|
|
42
|
-
// guard against it so `.toISOString()` never throws — leave the string as-is.
|
|
43
|
-
return (d && !Number.isNaN(d.getTime()) ? d.toISOString() : value);
|
|
66
|
+
return (d ? d.toISOString() : value);
|
|
44
67
|
}
|
|
45
68
|
if (Array.isArray(value)) {
|
|
46
69
|
return value.map((v) => isoifyDates(v));
|
|
@@ -58,6 +81,13 @@ export function isoifyDates(value) {
|
|
|
58
81
|
}
|
|
59
82
|
return value;
|
|
60
83
|
}
|
|
84
|
+
/** True for a JSON object (not null, not an array). */
|
|
85
|
+
function isObject(value) {
|
|
86
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
87
|
+
}
|
|
88
|
+
function shapeError(path, expected) {
|
|
89
|
+
return new MastrParseError(`Unexpected response shape from ${path}: expected ${expected}.`);
|
|
90
|
+
}
|
|
61
91
|
export class MastrClient {
|
|
62
92
|
engine;
|
|
63
93
|
constructor(options = {}) {
|
|
@@ -67,8 +97,16 @@ export class MastrClient {
|
|
|
67
97
|
* Fetch one page of units for a category. Sends the full Kendo param set —
|
|
68
98
|
* `sort`, `page`, `pageSize`, `group`, `filter` — always, because the server
|
|
69
99
|
* rejects a request with `group`/`filter` missing ("Die Anfrage ist Null.").
|
|
100
|
+
* An unknown category, a `page` outside 1..`MAX_PAGE`, a `pageSize` outside
|
|
101
|
+
* 1..`MAX_PAGE_SIZE` or a filter the register would misread (e.g. `~or~`, see
|
|
102
|
+
* {@link validateFilter}) is rejected with a `MastrValidationError` before any request.
|
|
70
103
|
*/
|
|
71
104
|
async units(category, query = {}) {
|
|
105
|
+
const suffix = categorySuffix(category);
|
|
106
|
+
checkPaging("page", query.page, MAX_PAGE);
|
|
107
|
+
checkPaging("pageSize", query.pageSize, MAX_PAGE_SIZE);
|
|
108
|
+
if (query.filter !== undefined)
|
|
109
|
+
validateFilter(query.filter);
|
|
72
110
|
const params = {
|
|
73
111
|
sort: query.sort ?? "",
|
|
74
112
|
page: query.page ?? DEFAULT_PAGE,
|
|
@@ -76,20 +114,33 @@ export class MastrClient {
|
|
|
76
114
|
group: "",
|
|
77
115
|
filter: query.filter ?? "",
|
|
78
116
|
};
|
|
79
|
-
const path = `${SERVICE}/GetErweiterteOeffentlicheEinheit${
|
|
117
|
+
const path = `${SERVICE}/GetErweiterteOeffentlicheEinheit${suffix}`;
|
|
80
118
|
const res = await this.engine.getJson(path, params);
|
|
81
|
-
if (res
|
|
119
|
+
if (!isObject(res))
|
|
120
|
+
throw shapeError(path, "a JSON object with Data and Total");
|
|
121
|
+
// MaStR answers HTTP 200 with a logical error in `Errors`: a string such as "Die
|
|
122
|
+
// Anfrage ist Null.", or a Kendo ModelState object. Anything but null is an error
|
|
123
|
+
// (a broken reply must not read as "no matches"). The text is server-controlled
|
|
124
|
+
// and reaches stderr, so describeMastrErrors sanitises it.
|
|
125
|
+
if (res["Errors"] !== undefined && res["Errors"] !== null) {
|
|
82
126
|
throw new MastrApiError({
|
|
83
127
|
url: this.engine.buildUrl(path, params),
|
|
84
128
|
method: "GET",
|
|
85
129
|
body: JSON.stringify(res),
|
|
86
|
-
|
|
87
|
-
// controlled and reaches stderr, so strip control characters to prevent
|
|
88
|
-
// terminal escape-sequence injection.
|
|
89
|
-
detail: sanitizeServerText(res.Errors),
|
|
130
|
+
detail: describeMastrErrors(res["Errors"]),
|
|
90
131
|
});
|
|
91
132
|
}
|
|
92
|
-
|
|
133
|
+
const total = res["Total"];
|
|
134
|
+
if (typeof total !== "number" || !Number.isSafeInteger(total) || total < 0) {
|
|
135
|
+
throw shapeError(path, "a numeric Total");
|
|
136
|
+
}
|
|
137
|
+
const data = res["Data"];
|
|
138
|
+
// A reply with no matches may carry `Data: null`; with a positive Total it must be an array.
|
|
139
|
+
if (data === null && total === 0)
|
|
140
|
+
return { total, data: [] };
|
|
141
|
+
if (!Array.isArray(data))
|
|
142
|
+
throw shapeError(path, "a Data array");
|
|
143
|
+
return { total, data: data };
|
|
93
144
|
}
|
|
94
145
|
/** Electricity-generation units (`Stromerzeugung`). */
|
|
95
146
|
stromerzeugung(query) {
|
|
@@ -107,11 +158,26 @@ export class MastrClient {
|
|
|
107
158
|
gasverbrauch(query) {
|
|
108
159
|
return this.units("gasverbrauch", query);
|
|
109
160
|
}
|
|
110
|
-
/**
|
|
161
|
+
/**
|
|
162
|
+
* The filterable columns (names, types, dropdown codes) for a category. An `Errors`
|
|
163
|
+
* envelope throws `MastrApiError`, any other non-array reply `MastrParseError` —
|
|
164
|
+
* never an empty list, which would read as "this category has no filters".
|
|
165
|
+
*/
|
|
111
166
|
async filterColumns(category) {
|
|
112
|
-
const path = `${SERVICE}/GetFilterColumnsErweiterteOeffentlicheEinheit${
|
|
167
|
+
const path = `${SERVICE}/GetFilterColumnsErweiterteOeffentlicheEinheit${categorySuffix(category)}`;
|
|
113
168
|
const res = await this.engine.getJson(path);
|
|
114
|
-
|
|
169
|
+
if (isObject(res) && res["Errors"] !== undefined && res["Errors"] !== null) {
|
|
170
|
+
throw new MastrApiError({
|
|
171
|
+
url: this.engine.buildUrl(path),
|
|
172
|
+
method: "GET",
|
|
173
|
+
body: JSON.stringify(res),
|
|
174
|
+
detail: describeMastrErrors(res["Errors"]),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
if (!Array.isArray(res) || !res.every(isObject)) {
|
|
178
|
+
throw shapeError(path, "a JSON array of filter columns");
|
|
179
|
+
}
|
|
180
|
+
return res;
|
|
115
181
|
}
|
|
116
182
|
}
|
|
117
183
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/client/client.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,kFAAkF;AAClF,sFAAsF;AACtF,EAAE;AACF,kFAAkF;AAClF,iFAAiF;AACjF,gEAAgE;AAChE,EAAE;AACF,iCAAiC;AACjC,8FAA8F;AAC9F,qCAAqC;AAErC,OAAO,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/client/client.ts"],"names":[],"mappings":"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"}
|