@maschinenlesbar.org/nina-warnungen-cli 0.0.1

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.
Files changed (69) hide show
  1. package/CONTRIBUTING.md +25 -0
  2. package/LICENSE +661 -0
  3. package/LICENSING.md +47 -0
  4. package/README.md +227 -0
  5. package/dist/src/cli/commands/misc.d.ts +4 -0
  6. package/dist/src/cli/commands/misc.d.ts.map +1 -0
  7. package/dist/src/cli/commands/misc.js +36 -0
  8. package/dist/src/cli/commands/misc.js.map +1 -0
  9. package/dist/src/cli/commands/warnings.d.ts +4 -0
  10. package/dist/src/cli/commands/warnings.d.ts.map +1 -0
  11. package/dist/src/cli/commands/warnings.js +38 -0
  12. package/dist/src/cli/commands/warnings.js.map +1 -0
  13. package/dist/src/cli/index.d.ts +3 -0
  14. package/dist/src/cli/index.d.ts.map +1 -0
  15. package/dist/src/cli/index.js +6 -0
  16. package/dist/src/cli/index.js.map +1 -0
  17. package/dist/src/cli/io.d.ts +17 -0
  18. package/dist/src/cli/io.d.ts.map +1 -0
  19. package/dist/src/cli/io.js +22 -0
  20. package/dist/src/cli/io.js.map +1 -0
  21. package/dist/src/cli/program.d.ts +7 -0
  22. package/dist/src/cli/program.d.ts.map +1 -0
  23. package/dist/src/cli/program.js +53 -0
  24. package/dist/src/cli/program.js.map +1 -0
  25. package/dist/src/cli/run.d.ts +3 -0
  26. package/dist/src/cli/run.d.ts.map +1 -0
  27. package/dist/src/cli/run.js +56 -0
  28. package/dist/src/cli/run.js.map +1 -0
  29. package/dist/src/cli/shared.d.ts +69 -0
  30. package/dist/src/cli/shared.d.ts.map +1 -0
  31. package/dist/src/cli/shared.js +133 -0
  32. package/dist/src/cli/shared.js.map +1 -0
  33. package/dist/src/client/client.d.ts +45 -0
  34. package/dist/src/client/client.d.ts.map +1 -0
  35. package/dist/src/client/client.js +81 -0
  36. package/dist/src/client/client.js.map +1 -0
  37. package/dist/src/client/engine.d.ts +53 -0
  38. package/dist/src/client/engine.d.ts.map +1 -0
  39. package/dist/src/client/engine.js +105 -0
  40. package/dist/src/client/engine.js.map +1 -0
  41. package/dist/src/client/enums.d.ts +15 -0
  42. package/dist/src/client/enums.d.ts.map +1 -0
  43. package/dist/src/client/enums.js +15 -0
  44. package/dist/src/client/enums.js.map +1 -0
  45. package/dist/src/client/errors.d.ts +36 -0
  46. package/dist/src/client/errors.d.ts.map +1 -0
  47. package/dist/src/client/errors.js +60 -0
  48. package/dist/src/client/errors.js.map +1 -0
  49. package/dist/src/client/http.d.ts +26 -0
  50. package/dist/src/client/http.d.ts.map +1 -0
  51. package/dist/src/client/http.js +107 -0
  52. package/dist/src/client/http.js.map +1 -0
  53. package/dist/src/client/index.d.ts +11 -0
  54. package/dist/src/client/index.d.ts.map +1 -0
  55. package/dist/src/client/index.js +9 -0
  56. package/dist/src/client/index.js.map +1 -0
  57. package/dist/src/client/query.d.ts +9 -0
  58. package/dist/src/client/query.d.ts.map +1 -0
  59. package/dist/src/client/query.js +33 -0
  60. package/dist/src/client/query.js.map +1 -0
  61. package/dist/src/client/types.d.ts +48 -0
  62. package/dist/src/client/types.d.ts.map +1 -0
  63. package/dist/src/client/types.js +7 -0
  64. package/dist/src/client/types.js.map +1 -0
  65. package/dist/src/index.d.ts +2 -0
  66. package/dist/src/index.d.ts.map +1 -0
  67. package/dist/src/index.js +3 -0
  68. package/dist/src/index.js.map +1 -0
  69. package/package.json +67 -0
@@ -0,0 +1,60 @@
1
+ // Error types raised by the client. Kept free of any I/O so they are trivial to
2
+ // construct in tests and to `instanceof`-check by consumers.
3
+ /** Base class for every error originating from this client. */
4
+ export class NinaError extends Error {
5
+ constructor(message, options) {
6
+ super(message, options);
7
+ this.name = new.target.name;
8
+ }
9
+ }
10
+ /**
11
+ * The API responded with a non-2xx status code. `detail` holds a human-readable
12
+ * message extracted from the response body when one is present.
13
+ */
14
+ export class NinaApiError extends NinaError {
15
+ status;
16
+ detail;
17
+ url;
18
+ method;
19
+ body;
20
+ constructor(args) {
21
+ const detailPart = args.detail ? `: ${args.detail}` : "";
22
+ // Surface only the request path in the message, not the full URL: the base
23
+ // URL may carry credentials (userinfo) and is noisy. The complete URL stays
24
+ // available on the `.url` property for programmatic inspection.
25
+ super(`HTTP ${args.status} for ${args.method} ${safeTarget(args.url)}${detailPart}`);
26
+ this.status = args.status;
27
+ this.url = args.url;
28
+ this.method = args.method;
29
+ this.body = args.body;
30
+ this.detail = args.detail;
31
+ }
32
+ /** True for statuses the API documents as transient and retry-able. */
33
+ get isRetryable() {
34
+ return this.status === 429 || this.status === 503;
35
+ }
36
+ }
37
+ /**
38
+ * Reduce a full request URL to a path (+ query) for user-facing messages,
39
+ * dropping the origin and any embedded credentials. Falls back to the raw string
40
+ * if it isn't a parseable absolute URL.
41
+ */
42
+ function safeTarget(url) {
43
+ try {
44
+ const u = new URL(url);
45
+ return `${u.pathname}${u.search}`;
46
+ }
47
+ catch {
48
+ return url;
49
+ }
50
+ }
51
+ /** A transport-level failure (DNS, connection reset, timeout, ...). */
52
+ export class NinaNetworkError extends NinaError {
53
+ }
54
+ /** The response body could not be parsed as the expected JSON shape. */
55
+ export class NinaParseError extends NinaError {
56
+ }
57
+ /** A local I/O failure, e.g. writing the --output file (no such dir, EISDIR). */
58
+ export class NinaIOError extends NinaError {
59
+ }
60
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/client/errors.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,6DAA6D;AAE7D,+DAA+D;AAC/D,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC9B,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,YAAa,SAAQ,SAAS;IAChC,MAAM,CAAS;IACf,MAAM,CAAqB;IAC3B,GAAG,CAAS;IACZ,MAAM,CAAS;IACf,IAAI,CAAS;IAEtB,YAAY,IAMX;QACC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,2EAA2E;QAC3E,4EAA4E;QAC5E,gEAAgE;QAChE,KAAK,CAAC,QAAQ,IAAI,CAAC,MAAM,QAAQ,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,UAAU,EAAE,CAAC,CAAC;QACrF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,uEAAuE;IACvE,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC;IACpD,CAAC;CACF;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,MAAM,OAAO,gBAAiB,SAAQ,SAAS;CAAG;AAElD,wEAAwE;AACxE,MAAM,OAAO,cAAe,SAAQ,SAAS;CAAG;AAEhD,iFAAiF;AACjF,MAAM,OAAO,WAAY,SAAQ,SAAS;CAAG"}
@@ -0,0 +1,26 @@
1
+ import http from "node:http";
2
+ export interface HttpRequest {
3
+ method: string;
4
+ /** Fully-qualified absolute URL. */
5
+ url: string;
6
+ headers?: Record<string, string>;
7
+ /** Optional request body (already serialised). */
8
+ body?: string | Buffer;
9
+ /** Per-request timeout in milliseconds. */
10
+ timeoutMs?: number;
11
+ /** Hard cap on the response body size in bytes; the request aborts if exceeded. */
12
+ maxResponseBytes?: number;
13
+ }
14
+ export interface HttpResponse {
15
+ status: number;
16
+ headers: http.IncomingHttpHeaders;
17
+ body: Buffer;
18
+ }
19
+ export type Transport = (request: HttpRequest) => Promise<HttpResponse>;
20
+ /**
21
+ * Default transport. Resolves with the raw response (including non-2xx) — status
22
+ * interpretation is the client's job. Rejects only on transport-level failures
23
+ * (connection errors, timeouts, malformed URLs).
24
+ */
25
+ export declare const nodeHttpTransport: Transport;
26
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/client/http.ts"],"names":[],"mappings":"AAQA,OAAO,IAAI,MAAM,WAAW,CAAC;AAyB7B,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAExE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,SA6E5B,CAAC"}
@@ -0,0 +1,107 @@
1
+ // HTTP transport built on Node's built-in `http`/`https` modules — no axios,
2
+ // no fetch polyfill, no third-party HTTP client.
3
+ //
4
+ // The transport is a plain function so it can be trivially swapped out in tests
5
+ // (inject a `mock.fn()` returning a canned HttpResponse) without touching the
6
+ // network. The default implementation below is exercised against a real local
7
+ // `http.createServer` in the test-suite.
8
+ import http from "node:http";
9
+ import https from "node:https";
10
+ import { NinaNetworkError } from "./errors.js";
11
+ /**
12
+ * Turn an opaque Node transport error into a message that points at the likely
13
+ * cause (usually a wrong/unreachable --base-url) instead of just echoing the raw
14
+ * resolver/socket string. Keeps the original text for context.
15
+ */
16
+ function describeNetworkError(err, host) {
17
+ switch (err.code) {
18
+ case "ECONNREFUSED":
19
+ return `Could not connect to ${host} (connection refused). Check the host/port and --base-url.`;
20
+ case "ENOTFOUND":
21
+ case "EAI_AGAIN":
22
+ return `Could not resolve host ${host}. Check the --base-url and your network/DNS.`;
23
+ case "ECONNRESET":
24
+ return `Connection to ${host} was reset.`;
25
+ case "ETIMEDOUT":
26
+ return `Connection to ${host} timed out.`;
27
+ default:
28
+ return err.message;
29
+ }
30
+ }
31
+ /**
32
+ * Default transport. Resolves with the raw response (including non-2xx) — status
33
+ * interpretation is the client's job. Rejects only on transport-level failures
34
+ * (connection errors, timeouts, malformed URLs).
35
+ */
36
+ export const nodeHttpTransport = (request) => new Promise((resolve, reject) => {
37
+ let url;
38
+ try {
39
+ url = new URL(request.url);
40
+ }
41
+ catch {
42
+ reject(new NinaNetworkError(`Invalid URL: ${request.url}`));
43
+ return;
44
+ }
45
+ // Only http/https are supported. Reject anything else up front with a clear,
46
+ // typed error instead of letting Node throw an opaque ERR_INVALID_PROTOCOL
47
+ // (and so this never reaches the file:/ftp:/etc. drivers).
48
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
49
+ reject(new NinaNetworkError(`Unsupported protocol "${url.protocol}" in URL: ${request.url}`));
50
+ return;
51
+ }
52
+ const isHttps = url.protocol === "https:";
53
+ const driver = isHttps ? https : http;
54
+ const maxBytes = request.maxResponseBytes;
55
+ const req = driver.request(url, {
56
+ method: request.method,
57
+ headers: request.headers,
58
+ }, (res) => {
59
+ const chunks = [];
60
+ let received = 0;
61
+ let aborted = false;
62
+ res.on("data", (chunk) => {
63
+ if (aborted)
64
+ return;
65
+ received += chunk.length;
66
+ if (maxBytes !== undefined && received > maxBytes) {
67
+ aborted = true;
68
+ res.destroy();
69
+ reject(new NinaNetworkError(`Response exceeded maxResponseBytes (${maxBytes})`));
70
+ return;
71
+ }
72
+ chunks.push(chunk);
73
+ });
74
+ res.on("end", () => {
75
+ if (aborted)
76
+ return;
77
+ resolve({
78
+ status: res.statusCode ?? 0,
79
+ headers: res.headers,
80
+ body: Buffer.concat(chunks),
81
+ });
82
+ });
83
+ res.on("error", (err) => {
84
+ if (aborted)
85
+ return; // we already rejected with the size-cap error
86
+ reject(new NinaNetworkError(`Response stream error: ${err.message}`, { cause: err }));
87
+ });
88
+ });
89
+ if (request.timeoutMs && request.timeoutMs > 0) {
90
+ req.setTimeout(request.timeoutMs, () => {
91
+ req.destroy(new NinaNetworkError(`Request timed out after ${request.timeoutMs}ms`));
92
+ });
93
+ }
94
+ req.on("error", (err) => {
95
+ // A timeout destroy already passes an NinaNetworkError; don't double-wrap.
96
+ if (err instanceof NinaNetworkError) {
97
+ reject(err);
98
+ return;
99
+ }
100
+ const message = describeNetworkError(err, url.host);
101
+ reject(new NinaNetworkError(message, { cause: err }));
102
+ });
103
+ if (request.body !== undefined)
104
+ req.write(request.body);
105
+ req.end();
106
+ });
107
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/client/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export { NinaClient } from "./client.js";
2
+ export { RequestEngine, DEFAULT_BASE_URL } from "./engine.js";
3
+ export type { EngineOptions, RawResponse } from "./engine.js";
4
+ export { nodeHttpTransport } from "./http.js";
5
+ export type { Transport, HttpRequest, HttpResponse } from "./http.js";
6
+ export { buildQueryString } from "./query.js";
7
+ export type { QueryParams, QueryValue } from "./query.js";
8
+ export { NinaError, NinaApiError, NinaNetworkError, NinaParseError } from "./errors.js";
9
+ export * from "./enums.js";
10
+ export * from "./types.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAExF,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,9 @@
1
+ // Public entry point for the API client library.
2
+ export { NinaClient } from "./client.js";
3
+ export { RequestEngine, DEFAULT_BASE_URL } from "./engine.js";
4
+ export { nodeHttpTransport } from "./http.js";
5
+ export { buildQueryString } from "./query.js";
6
+ export { NinaError, NinaApiError, NinaNetworkError, NinaParseError } from "./errors.js";
7
+ export * from "./enums.js";
8
+ export * from "./types.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAExF,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type QueryPrimitive = string | number | boolean | Date | null | undefined;
2
+ export type QueryValue = QueryPrimitive | QueryPrimitive[];
3
+ export type QueryParams = Record<string, QueryValue>;
4
+ /**
5
+ * Build a query string (without a leading `?`) from a params object.
6
+ * Returns an empty string when no parameters survive filtering.
7
+ */
8
+ export declare function buildQueryString(params: QueryParams): string;
9
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/client/query.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;AACjF,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,cAAc,EAAE,CAAC;AAC3D,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAQrD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAe5D"}
@@ -0,0 +1,33 @@
1
+ // Tiny, dependency-free query-string builder.
2
+ // - `undefined` / `null` values are omitted entirely
3
+ // - arrays are serialised as repeated keys (`?id=a&id=b`)
4
+ // - booleans become the strings "true"/"false"
5
+ // - Date values become full ISO-8601 strings
6
+ // - everything else is coerced with String()
7
+ function serializeScalar(value) {
8
+ if (value instanceof Date)
9
+ return value.toISOString();
10
+ if (typeof value === "boolean")
11
+ return value ? "true" : "false";
12
+ return String(value);
13
+ }
14
+ /**
15
+ * Build a query string (without a leading `?`) from a params object.
16
+ * Returns an empty string when no parameters survive filtering.
17
+ */
18
+ export function buildQueryString(params) {
19
+ const search = new URLSearchParams();
20
+ for (const [key, raw] of Object.entries(params)) {
21
+ if (raw === undefined || raw === null)
22
+ continue;
23
+ const values = Array.isArray(raw) ? raw : [raw];
24
+ for (const value of values) {
25
+ if (value === undefined || value === null)
26
+ continue;
27
+ search.append(key, serializeScalar(value));
28
+ }
29
+ }
30
+ // URLSearchParams encodes spaces as "+"; "%20" is more broadly interoperable.
31
+ return search.toString().replace(/\+/g, "%20");
32
+ }
33
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/client/query.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,uDAAuD;AACvD,4DAA4D;AAC5D,iDAAiD;AACjD,+CAA+C;AAC/C,+CAA+C;AAM/C,SAAS,eAAe,CAAC,KAAgD;IACvE,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IACtD,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAmB;IAClD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IAErC,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI;YAAE,SAAS;QAEhD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;gBAAE,SAAS;YACpD,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,48 @@
1
+ import type { Severity } from "./enums.js";
2
+ export type JsonValue = string | number | boolean | null | JsonValue[] | {
3
+ [key: string]: JsonValue;
4
+ };
5
+ export type JsonObject = {
6
+ [key: string]: JsonValue;
7
+ };
8
+ /** A localised title map, e.g. `{ "de": "Hochwasser" }`. */
9
+ export type I18nText = {
10
+ [languageCode: string]: string;
11
+ };
12
+ /** One entry of a `/{source}/mapData.json` listing — a warning summary. */
13
+ export interface MapWarning {
14
+ id: string;
15
+ version: number;
16
+ startDate: string;
17
+ /** Some sources also carry an expiry. */
18
+ expiresDate?: string;
19
+ severity: Severity | string;
20
+ /** CAP message type, e.g. "Alert", "Update", "Cancel". */
21
+ type?: string;
22
+ i18nTitle: I18nText;
23
+ transKeys?: {
24
+ event?: string;
25
+ };
26
+ }
27
+ /** One entry of a `/dashboard/{ARS}.json` listing. */
28
+ export interface DashboardEntry {
29
+ id: string;
30
+ payload: JsonObject;
31
+ i18nTitle?: I18nText;
32
+ sent?: string;
33
+ }
34
+ /** One entry of an archive `…-mapping.json` history list. */
35
+ export interface ArchiveMappingEntry {
36
+ identifier: string;
37
+ msgType?: string;
38
+ sent?: string;
39
+ headline?: string;
40
+ }
41
+ export interface ArchiveMapping {
42
+ history: ArchiveMappingEntry[];
43
+ }
44
+ export type WarningDetail = JsonObject;
45
+ export type Notfalltipps = JsonObject;
46
+ export type EventCodes = JsonObject;
47
+ export type DataVersion = JsonObject;
48
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/client/types.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AACjC,MAAM,MAAM,UAAU,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEtD,4DAA4D;AAC5D,MAAM,MAAM,QAAQ,GAAG;IAAE,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAE1D,2EAA2E;AAC3E,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC5B,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,QAAQ,CAAC;IACpB,SAAS,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAChC;AAED,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,UAAU,CAAC;IACpB,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,6DAA6D;AAC7D,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC;AAGD,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC;AACvC,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC;AACtC,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC;AACpC,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC"}
@@ -0,0 +1,7 @@
1
+ // Domain types for the NINA API (warnung.bund.de).
2
+ //
3
+ // The map-data listings have a stable, well-documented summary shape, typed
4
+ // precisely below. Full single-warning payloads are CAP-derived and deeply
5
+ // nested, so they are returned as faithful raw `JsonObject`s.
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/client/types.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,8DAA8D"}
@@ -0,0 +1,2 @@
1
+ export * from "./client/index.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,3 @@
1
+ // Library root. Import from here when using nina-warnungen-cli as a dependency.
2
+ export * from "./client/index.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,cAAc,mBAAmB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@maschinenlesbar.org/nina-warnungen-cli",
3
+ "version": "0.0.1",
4
+ "description": "TypeScript API client and CLI for the open NINA civil-protection warning API (warnung.bund.de)",
5
+ "type": "module",
6
+ "bin": {
7
+ "nina": "dist/src/cli/index.js"
8
+ },
9
+ "main": "dist/src/index.js",
10
+ "types": "dist/src/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/src/index.d.ts",
14
+ "import": "./dist/src/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist/src",
19
+ "LICENSING.md",
20
+ "CONTRIBUTING.md"
21
+ ],
22
+ "engines": {
23
+ "node": ">=20"
24
+ },
25
+ "scripts": {
26
+ "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
27
+ "build": "tsc -p tsconfig.json",
28
+ "prepack": "npm run build",
29
+ "typecheck": "tsc -p tsconfig.json --noEmit",
30
+ "pretest": "npm run build",
31
+ "test": "node --test dist/test/*.test.js",
32
+ "docs": "typedoc src/index.ts --out out",
33
+ "start": "node dist/src/cli/index.js"
34
+ },
35
+ "keywords": [
36
+ "nina",
37
+ "warnung",
38
+ "bbk",
39
+ "mowas",
40
+ "katwarn",
41
+ "civil-protection",
42
+ "germany",
43
+ "cli",
44
+ "api-client"
45
+ ],
46
+ "author": "Sebastian Schürmann <sebs@2xs.org>",
47
+ "license": "AGPL-3.0-or-later",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/maschinenlesbar-org/nina-warnungen-cli.git"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/maschinenlesbar-org/nina-warnungen-cli/issues"
54
+ },
55
+ "homepage": "https://github.com/maschinenlesbar-org/nina-warnungen-cli#readme",
56
+ "publishConfig": {
57
+ "access": "public"
58
+ },
59
+ "dependencies": {
60
+ "commander": "15.0.0"
61
+ },
62
+ "devDependencies": {
63
+ "@types/node": "^22.19.19",
64
+ "typedoc": "0.28.19",
65
+ "typescript": "6.0.3"
66
+ }
67
+ }