@maschinenlesbar.org/marktstammdatenregister-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.
- package/CONTRIBUTING.md +25 -0
- package/LICENSE +661 -0
- package/LICENSING.md +47 -0
- package/README.md +72 -0
- package/dist/src/cli/commands/units.d.ts +4 -0
- package/dist/src/cli/commands/units.d.ts.map +1 -0
- package/dist/src/cli/commands/units.js +64 -0
- package/dist/src/cli/commands/units.js.map +1 -0
- package/dist/src/cli/index.d.ts +3 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +11 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/io.d.ts +12 -0
- package/dist/src/cli/io.d.ts.map +1 -0
- package/dist/src/cli/io.js +7 -0
- package/dist/src/cli/io.js.map +1 -0
- package/dist/src/cli/program.d.ts +7 -0
- package/dist/src/cli/program.d.ts.map +1 -0
- package/dist/src/cli/program.js +54 -0
- package/dist/src/cli/program.js.map +1 -0
- package/dist/src/cli/run.d.ts +3 -0
- package/dist/src/cli/run.d.ts.map +1 -0
- package/dist/src/cli/run.js +85 -0
- package/dist/src/cli/run.js.map +1 -0
- package/dist/src/cli/shared.d.ts +53 -0
- package/dist/src/cli/shared.d.ts.map +1 -0
- package/dist/src/cli/shared.js +96 -0
- package/dist/src/cli/shared.js.map +1 -0
- package/dist/src/client/client.d.ts +35 -0
- package/dist/src/client/client.d.ts.map +1 -0
- package/dist/src/client/client.js +109 -0
- package/dist/src/client/client.js.map +1 -0
- package/dist/src/client/engine.d.ts +55 -0
- package/dist/src/client/engine.d.ts.map +1 -0
- package/dist/src/client/engine.js +114 -0
- package/dist/src/client/engine.js.map +1 -0
- package/dist/src/client/errors.d.ts +42 -0
- package/dist/src/client/errors.d.ts.map +1 -0
- package/dist/src/client/errors.js +52 -0
- package/dist/src/client/errors.js.map +1 -0
- package/dist/src/client/http.d.ts +26 -0
- package/dist/src/client/http.d.ts.map +1 -0
- package/dist/src/client/http.js +80 -0
- package/dist/src/client/http.js.map +1 -0
- package/dist/src/client/index.d.ts +11 -0
- package/dist/src/client/index.d.ts.map +1 -0
- package/dist/src/client/index.js +8 -0
- package/dist/src/client/index.js.map +1 -0
- package/dist/src/client/query.d.ts +9 -0
- package/dist/src/client/query.d.ts.map +1 -0
- package/dist/src/client/query.js +33 -0
- package/dist/src/client/query.js.map +1 -0
- package/dist/src/client/types.d.ts +103 -0
- package/dist/src/client/types.d.ts.map +1 -0
- package/dist/src/client/types.js +4 -0
- package/dist/src/client/types.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// MastrClient — a typed client over the Marktstammdatenregister (MaStR) public
|
|
2
|
+
// unit-search API (www.marktstammdatenregister.de/MaStR): the Bundesnetzagentur's
|
|
3
|
+
// register of the German electricity & gas market (~9M generation/consumption units).
|
|
4
|
+
//
|
|
5
|
+
// No auth. Each category is a Kendo UI Grid endpoint; the client ALWAYS sends the
|
|
6
|
+
// full param set (sort/page/pageSize/group/filter) because omitting group/filter
|
|
7
|
+
// makes the server answer `{"Errors":"Die Anfrage ist Null."}`.
|
|
8
|
+
//
|
|
9
|
+
// const c = new MastrClient();
|
|
10
|
+
// const page = await c.stromerzeugung({ pageSize: 10, filter: "Energieträger~eq~'2495'" });
|
|
11
|
+
// page.total; // total solar units
|
|
12
|
+
import { RequestEngine } from "./engine.js";
|
|
13
|
+
import { MastrApiError } from "./errors.js";
|
|
14
|
+
const SERVICE = "/Einheit/EinheitJson";
|
|
15
|
+
/** Map a category to the PascalCase suffix used in the endpoint names. */
|
|
16
|
+
const CATEGORY_SUFFIX = {
|
|
17
|
+
stromerzeugung: "Stromerzeugung",
|
|
18
|
+
stromverbrauch: "Stromverbrauch",
|
|
19
|
+
gaserzeugung: "Gaserzeugung",
|
|
20
|
+
gasverbrauch: "Gasverbrauch",
|
|
21
|
+
};
|
|
22
|
+
const DEFAULT_PAGE = 1;
|
|
23
|
+
const DEFAULT_PAGE_SIZE = 25;
|
|
24
|
+
/**
|
|
25
|
+
* Parse a MaStR Microsoft-AJAX date string (`"/Date(1548979200000)/"`) into a Date.
|
|
26
|
+
* Returns null if the string is not in that format.
|
|
27
|
+
*/
|
|
28
|
+
export function parseMsDate(value) {
|
|
29
|
+
const m = /^\/Date\((-?\d+)\)\/$/.exec(value);
|
|
30
|
+
if (!m)
|
|
31
|
+
return null;
|
|
32
|
+
return new Date(Number(m[1]));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Recursively rewrite every `"/Date(ms)/"` string in a value to an ISO-8601 string,
|
|
36
|
+
* returning a new value. Used by the CLI's `--iso-dates`.
|
|
37
|
+
*/
|
|
38
|
+
export function isoifyDates(value) {
|
|
39
|
+
if (typeof value === "string") {
|
|
40
|
+
const d = parseMsDate(value);
|
|
41
|
+
// An out-of-range milliseconds value yields an Invalid Date (a truthy object);
|
|
42
|
+
// guard against it so `.toISOString()` never throws — leave the string as-is.
|
|
43
|
+
return (d && !Number.isNaN(d.getTime()) ? d.toISOString() : value);
|
|
44
|
+
}
|
|
45
|
+
if (Array.isArray(value)) {
|
|
46
|
+
return value.map((v) => isoifyDates(v));
|
|
47
|
+
}
|
|
48
|
+
if (value && typeof value === "object") {
|
|
49
|
+
const out = {};
|
|
50
|
+
for (const [k, v] of Object.entries(value))
|
|
51
|
+
out[k] = isoifyDates(v);
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
export class MastrClient {
|
|
57
|
+
engine;
|
|
58
|
+
constructor(options = {}) {
|
|
59
|
+
this.engine = new RequestEngine(options);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Fetch one page of units for a category. Sends the full Kendo param set —
|
|
63
|
+
* `sort`, `page`, `pageSize`, `group`, `filter` — always, because the server
|
|
64
|
+
* rejects a request with `group`/`filter` missing ("Die Anfrage ist Null.").
|
|
65
|
+
*/
|
|
66
|
+
async units(category, query = {}) {
|
|
67
|
+
const params = {
|
|
68
|
+
sort: query.sort ?? "",
|
|
69
|
+
page: query.page ?? DEFAULT_PAGE,
|
|
70
|
+
pageSize: query.pageSize ?? DEFAULT_PAGE_SIZE,
|
|
71
|
+
group: "",
|
|
72
|
+
filter: query.filter ?? "",
|
|
73
|
+
};
|
|
74
|
+
const path = `${SERVICE}/GetErweiterteOeffentlicheEinheit${CATEGORY_SUFFIX[category]}`;
|
|
75
|
+
const res = await this.engine.getJson(path, params);
|
|
76
|
+
if (res && typeof res.Errors === "string" && res.Errors.length > 0) {
|
|
77
|
+
throw new MastrApiError({
|
|
78
|
+
url: this.engine.buildUrl(path, params),
|
|
79
|
+
method: "GET",
|
|
80
|
+
body: JSON.stringify(res),
|
|
81
|
+
detail: res.Errors,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return { total: res?.Total ?? 0, data: (res?.Data ?? []) };
|
|
85
|
+
}
|
|
86
|
+
/** Electricity-generation units (`Stromerzeugung`). */
|
|
87
|
+
stromerzeugung(query) {
|
|
88
|
+
return this.units("stromerzeugung", query);
|
|
89
|
+
}
|
|
90
|
+
/** Electricity-consumption units (`Stromverbrauch`). */
|
|
91
|
+
stromverbrauch(query) {
|
|
92
|
+
return this.units("stromverbrauch", query);
|
|
93
|
+
}
|
|
94
|
+
/** Gas-generation units (`Gaserzeugung`). */
|
|
95
|
+
gaserzeugung(query) {
|
|
96
|
+
return this.units("gaserzeugung", query);
|
|
97
|
+
}
|
|
98
|
+
/** Gas-consumption units (`Gasverbrauch`). */
|
|
99
|
+
gasverbrauch(query) {
|
|
100
|
+
return this.units("gasverbrauch", query);
|
|
101
|
+
}
|
|
102
|
+
/** The filterable columns (names, types, dropdown codes) for a category. */
|
|
103
|
+
async filterColumns(category) {
|
|
104
|
+
const path = `${SERVICE}/GetFilterColumnsErweiterteOeffentlicheEinheit${CATEGORY_SUFFIX[category]}`;
|
|
105
|
+
const res = await this.engine.getJson(path);
|
|
106
|
+
return Array.isArray(res) ? res : [];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/client/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type Transport } from "./http.js";
|
|
2
|
+
import { type QueryParams } from "./query.js";
|
|
3
|
+
export declare const DEFAULT_BASE_URL = "https://www.marktstammdatenregister.de/MaStR";
|
|
4
|
+
export interface RawResponse {
|
|
5
|
+
data: Buffer;
|
|
6
|
+
contentType: string;
|
|
7
|
+
status: number;
|
|
8
|
+
}
|
|
9
|
+
export interface EngineOptions {
|
|
10
|
+
/** Base URL of the API. Defaults to the canonical marktstammdatenregister.de base. */
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
/** Swappable transport. Defaults to the built-in node http/https transport. */
|
|
13
|
+
transport?: Transport;
|
|
14
|
+
/** Value of the User-Agent header. */
|
|
15
|
+
userAgent?: string;
|
|
16
|
+
/** Extra headers sent on every request. */
|
|
17
|
+
defaultHeaders?: Record<string, string>;
|
|
18
|
+
/** Per-request timeout in milliseconds (0 disables). */
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
/** Number of automatic retries for transient (429/503) responses. */
|
|
21
|
+
maxRetries?: number;
|
|
22
|
+
/** Base backoff between retries in milliseconds (grows linearly). */
|
|
23
|
+
retryDelayMs?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Hard cap on response body size in bytes (defends against memory exhaustion
|
|
26
|
+
* from a hostile/buggy endpoint). Defaults to 100 MiB; set to 0 for no limit.
|
|
27
|
+
*/
|
|
28
|
+
maxResponseBytes?: number;
|
|
29
|
+
/** Injectable sleep, primarily for deterministic tests. */
|
|
30
|
+
sleep?: (ms: number) => Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export declare class RequestEngine {
|
|
33
|
+
private readonly baseUrl;
|
|
34
|
+
private readonly transport;
|
|
35
|
+
private readonly userAgent;
|
|
36
|
+
private readonly defaultHeaders;
|
|
37
|
+
private readonly timeoutMs;
|
|
38
|
+
private readonly maxRetries;
|
|
39
|
+
private readonly retryDelayMs;
|
|
40
|
+
private readonly maxResponseBytes;
|
|
41
|
+
private readonly sleep;
|
|
42
|
+
constructor(options?: EngineOptions);
|
|
43
|
+
/** Build a fully-qualified URL from a path and optional query parameters. */
|
|
44
|
+
buildUrl(path: string, query?: QueryParams): string;
|
|
45
|
+
/**
|
|
46
|
+
* Perform a GET with Accept negotiation and transient-error retries. Redirects
|
|
47
|
+
* are NOT followed — the canonical host answers directly, so a 3xx (e.g. a bad
|
|
48
|
+
* base URL bouncing to a portal page) surfaces as an error.
|
|
49
|
+
*/
|
|
50
|
+
request(path: string, query?: QueryParams, accept?: string): Promise<RawResponse>;
|
|
51
|
+
/** GET a path with query params and parse the JSON reply into `T`. */
|
|
52
|
+
getJson<T>(path: string, query?: QueryParams): Promise<T>;
|
|
53
|
+
private toApiError;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/client/engine.ts"],"names":[],"mappings":"AAKA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAGhE,eAAO,MAAM,gBAAgB,iDAAiD,CAAC;AAG/E,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAOD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;gBAE1C,OAAO,GAAE,aAAkB;IAYvC,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,MAAM;IAMnD;;;;OAIG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,EAAE,MAAM,SAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;IAsCnG,sEAAsE;IAChE,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAa/D,OAAO,CAAC,UAAU;CAkBnB"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// The request engine: turns logical (path, query) calls into HTTP GET requests via
|
|
2
|
+
// a Transport, applies retry/backoff for transient statuses (429, 503), and decodes
|
|
3
|
+
// JSON responses. MaStR's public search backend is an unauthenticated GET API whose
|
|
4
|
+
// parameters travel in the query string.
|
|
5
|
+
import { nodeHttpTransport } from "./http.js";
|
|
6
|
+
import { buildQueryString } from "./query.js";
|
|
7
|
+
import { MastrApiError, MastrParseError } from "./errors.js";
|
|
8
|
+
export const DEFAULT_BASE_URL = "https://www.marktstammdatenregister.de/MaStR";
|
|
9
|
+
const DEFAULT_USER_AGENT = "marktstammdatenregister-cli";
|
|
10
|
+
const DEFAULT_MAX_RESPONSE_BYTES = 100 * 1024 * 1024;
|
|
11
|
+
const realSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
12
|
+
export class RequestEngine {
|
|
13
|
+
baseUrl;
|
|
14
|
+
transport;
|
|
15
|
+
userAgent;
|
|
16
|
+
defaultHeaders;
|
|
17
|
+
timeoutMs;
|
|
18
|
+
maxRetries;
|
|
19
|
+
retryDelayMs;
|
|
20
|
+
maxResponseBytes;
|
|
21
|
+
sleep;
|
|
22
|
+
constructor(options = {}) {
|
|
23
|
+
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
24
|
+
this.transport = options.transport ?? nodeHttpTransport;
|
|
25
|
+
this.userAgent = options.userAgent ?? DEFAULT_USER_AGENT;
|
|
26
|
+
this.defaultHeaders = options.defaultHeaders ?? {};
|
|
27
|
+
this.timeoutMs = options.timeoutMs ?? 30_000;
|
|
28
|
+
this.maxRetries = options.maxRetries ?? 2;
|
|
29
|
+
this.retryDelayMs = options.retryDelayMs ?? 200;
|
|
30
|
+
this.maxResponseBytes = options.maxResponseBytes ?? DEFAULT_MAX_RESPONSE_BYTES;
|
|
31
|
+
this.sleep = options.sleep ?? realSleep;
|
|
32
|
+
}
|
|
33
|
+
/** Build a fully-qualified URL from a path and optional query parameters. */
|
|
34
|
+
buildUrl(path, query) {
|
|
35
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
36
|
+
const qs = query ? buildQueryString(query) : "";
|
|
37
|
+
return `${this.baseUrl}${normalizedPath}${qs ? `?${qs}` : ""}`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Perform a GET with Accept negotiation and transient-error retries. Redirects
|
|
41
|
+
* are NOT followed — the canonical host answers directly, so a 3xx (e.g. a bad
|
|
42
|
+
* base URL bouncing to a portal page) surfaces as an error.
|
|
43
|
+
*/
|
|
44
|
+
async request(path, query, accept = "application/json") {
|
|
45
|
+
const url = this.buildUrl(path, query);
|
|
46
|
+
const headers = {
|
|
47
|
+
...this.defaultHeaders,
|
|
48
|
+
Accept: accept,
|
|
49
|
+
"User-Agent": this.userAgent,
|
|
50
|
+
// The MaStR search backend is a Kendo/DataTables endpoint that expects an
|
|
51
|
+
// XHR-style request; send the header a browser would.
|
|
52
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
53
|
+
};
|
|
54
|
+
let attempt = 0;
|
|
55
|
+
for (;;) {
|
|
56
|
+
const response = await this.transport({
|
|
57
|
+
method: "GET",
|
|
58
|
+
url,
|
|
59
|
+
headers,
|
|
60
|
+
timeoutMs: this.timeoutMs,
|
|
61
|
+
...(this.maxResponseBytes > 0 ? { maxResponseBytes: this.maxResponseBytes } : {}),
|
|
62
|
+
});
|
|
63
|
+
const status = response.status;
|
|
64
|
+
const retryable = status === 429 || status === 503;
|
|
65
|
+
if (retryable && attempt < this.maxRetries) {
|
|
66
|
+
attempt += 1;
|
|
67
|
+
await this.sleep(this.retryDelayMs * attempt);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const contentType = String(response.headers["content-type"] ?? "");
|
|
71
|
+
if (status < 200 || status >= 300) {
|
|
72
|
+
throw this.toApiError(url, status, response.body);
|
|
73
|
+
}
|
|
74
|
+
return { data: response.body, contentType, status };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** GET a path with query params and parse the JSON reply into `T`. */
|
|
78
|
+
async getJson(path, query) {
|
|
79
|
+
const res = await this.request(path, query);
|
|
80
|
+
const text = res.data.toString("utf8");
|
|
81
|
+
if (res.status === 204 || text.trim().length === 0) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
return JSON.parse(text);
|
|
86
|
+
}
|
|
87
|
+
catch (cause) {
|
|
88
|
+
throw new MastrParseError(`Failed to parse JSON response from ${path}`, { cause });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
toApiError(url, status, body) {
|
|
92
|
+
const text = body.toString("utf8");
|
|
93
|
+
let detail;
|
|
94
|
+
try {
|
|
95
|
+
const parsed = JSON.parse(text);
|
|
96
|
+
if (typeof parsed?.Errors === "string")
|
|
97
|
+
detail = parsed.Errors;
|
|
98
|
+
else if (typeof parsed?.message === "string")
|
|
99
|
+
detail = parsed.message;
|
|
100
|
+
else if (typeof parsed?.detail === "string")
|
|
101
|
+
detail = parsed.detail;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Not JSON (e.g. an HTML portal error page). Surface a short, whitespace-
|
|
105
|
+
// collapsed snippet of a textual body; skip HTML pages (start with "<").
|
|
106
|
+
const snippet = text.trim().replace(/\s+/g, " ");
|
|
107
|
+
if (snippet.length > 0 && !snippet.startsWith("<")) {
|
|
108
|
+
detail = snippet.length > 200 ? `${snippet.slice(0, 200)}…` : snippet;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return new MastrApiError({ status, url, method: "GET", body: text, detail });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/client/engine.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,oFAAoF;AACpF,oFAAoF;AACpF,yCAAyC;AAEzC,OAAO,EAAE,iBAAiB,EAAkB,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAoB,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,8CAA8C,CAAC;AAC/E,MAAM,kBAAkB,GAAG,6BAA6B,CAAC;AAgCzD,MAAM,0BAA0B,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAErD,MAAM,SAAS,GAAG,CAAC,EAAU,EAAiB,EAAE,CAC9C,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAEpD,MAAM,OAAO,aAAa;IACP,OAAO,CAAS;IAChB,SAAS,CAAY;IACrB,SAAS,CAAS;IAClB,cAAc,CAAyB;IACvC,SAAS,CAAS;IAClB,UAAU,CAAS;IACnB,YAAY,CAAS;IACrB,gBAAgB,CAAS;IACzB,KAAK,CAAgC;IAEtD,YAAY,UAAyB,EAAE;QACrC,IAAI,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAC;QACxD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAC;QACzD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC;QAC7C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,GAAG,CAAC;QAChD,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;QAC/E,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC;IAC1C,CAAC;IAED,6EAA6E;IAC7E,QAAQ,CAAC,IAAY,EAAE,KAAmB;QACxC,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QAChE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,cAAc,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACjE,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,KAAmB,EAAE,MAAM,GAAG,kBAAkB;QAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvC,MAAM,OAAO,GAA2B;YACtC,GAAG,IAAI,CAAC,cAAc;YACtB,MAAM,EAAE,MAAM;YACd,YAAY,EAAE,IAAI,CAAC,SAAS;YAC5B,0EAA0E;YAC1E,sDAAsD;YACtD,kBAAkB,EAAE,gBAAgB;SACrC,CAAC;QAEF,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,SAAS,CAAC;YACR,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC;gBACpC,MAAM,EAAE,KAAK;gBACb,GAAG;gBACH,OAAO;gBACP,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,GAAG,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAClF,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,MAAM,SAAS,GAAG,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,CAAC;YACnD,IAAI,SAAS,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;gBAC3C,OAAO,IAAI,CAAC,CAAC;gBACb,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,CAAC;gBAC9C,SAAS;YACX,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;YACnE,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;gBAClC,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpD,CAAC;YAED,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;QACtD,CAAC;IACH,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,OAAO,CAAI,IAAY,EAAE,KAAmB;QAChD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnD,OAAO,IAAS,CAAC;QACnB,CAAC;QACD,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,eAAe,CAAC,sCAAsC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAEO,UAAU,CAAC,GAAW,EAAE,MAAc,EAAE,IAAY;QAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,MAA0B,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA8D,CAAC;YAC7F,IAAI,OAAO,MAAM,EAAE,MAAM,KAAK,QAAQ;gBAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;iBAC1D,IAAI,OAAO,MAAM,EAAE,OAAO,KAAK,QAAQ;gBAAE,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC;iBACjE,IAAI,OAAO,MAAM,EAAE,MAAM,KAAK,QAAQ;gBAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QACtE,CAAC;QAAC,MAAM,CAAC;YACP,0EAA0E;YAC1E,yEAAyE;YACzE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YACjD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnD,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YACxE,CAAC;QACH,CAAC;QACD,OAAO,IAAI,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/E,CAAC;CACF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Base class for every error originating from this client. */
|
|
2
|
+
export declare class MastrError extends Error {
|
|
3
|
+
constructor(message: string, options?: {
|
|
4
|
+
cause?: unknown;
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The API signalled a failure. MaStR is unusual: it answers HTTP 200 even when a
|
|
9
|
+
* request logically failed, carrying the message in the envelope's `Errors` field
|
|
10
|
+
* (e.g. "Die Anfrage ist Null."). This error models both worlds:
|
|
11
|
+
* - `status` is set for a genuine transport/HTTP failure (non-2xx);
|
|
12
|
+
* - otherwise it is a logical error taken from the response `Errors` string.
|
|
13
|
+
* `detail` holds the human-readable message in either case.
|
|
14
|
+
*/
|
|
15
|
+
export declare class MastrApiError extends MastrError {
|
|
16
|
+
readonly status: number | undefined;
|
|
17
|
+
readonly detail: string | undefined;
|
|
18
|
+
readonly url: string;
|
|
19
|
+
readonly method: string;
|
|
20
|
+
readonly body: string;
|
|
21
|
+
constructor(args: {
|
|
22
|
+
url: string;
|
|
23
|
+
method: string;
|
|
24
|
+
body: string;
|
|
25
|
+
status?: number;
|
|
26
|
+
detail?: string;
|
|
27
|
+
});
|
|
28
|
+
/** True for HTTP statuses the API treats as transient and retry-able. */
|
|
29
|
+
get isRetryable(): boolean;
|
|
30
|
+
/** True for a transport-level HTTP 404. */
|
|
31
|
+
get isNotFound(): boolean;
|
|
32
|
+
}
|
|
33
|
+
/** A transport-level failure (DNS, connection reset, timeout, ...). */
|
|
34
|
+
export declare class MastrNetworkError extends MastrError {
|
|
35
|
+
}
|
|
36
|
+
/** A client-side validation error (e.g. a bad category) — no request made. */
|
|
37
|
+
export declare class MastrValidationError extends MastrError {
|
|
38
|
+
}
|
|
39
|
+
/** The response body could not be parsed as the expected JSON shape. */
|
|
40
|
+
export declare class MastrParseError extends MastrError {
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/client/errors.ts"],"names":[],"mappings":"AAGA,+DAA+D;AAC/D,qBAAa,UAAW,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAED;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,UAAU;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAWD,yEAAyE;IACzE,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,2CAA2C;IAC3C,IAAI,UAAU,IAAI,OAAO,CAExB;CACF;AAED,uEAAuE;AACvE,qBAAa,iBAAkB,SAAQ,UAAU;CAAG;AAEpD,8EAA8E;AAC9E,qBAAa,oBAAqB,SAAQ,UAAU;CAAG;AAEvD,wEAAwE;AACxE,qBAAa,eAAgB,SAAQ,UAAU;CAAG"}
|
|
@@ -0,0 +1,52 @@
|
|
|
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 MastrError extends Error {
|
|
5
|
+
constructor(message, options) {
|
|
6
|
+
super(message, options);
|
|
7
|
+
this.name = new.target.name;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The API signalled a failure. MaStR is unusual: it answers HTTP 200 even when a
|
|
12
|
+
* request logically failed, carrying the message in the envelope's `Errors` field
|
|
13
|
+
* (e.g. "Die Anfrage ist Null."). This error models both worlds:
|
|
14
|
+
* - `status` is set for a genuine transport/HTTP failure (non-2xx);
|
|
15
|
+
* - otherwise it is a logical error taken from the response `Errors` string.
|
|
16
|
+
* `detail` holds the human-readable message in either case.
|
|
17
|
+
*/
|
|
18
|
+
export class MastrApiError extends MastrError {
|
|
19
|
+
status;
|
|
20
|
+
detail;
|
|
21
|
+
url;
|
|
22
|
+
method;
|
|
23
|
+
body;
|
|
24
|
+
constructor(args) {
|
|
25
|
+
const detailPart = args.detail ? `: ${args.detail}` : "";
|
|
26
|
+
const head = args.status !== undefined ? `HTTP ${args.status}` : "MaStR error";
|
|
27
|
+
super(`${head} for ${args.method} ${args.url}${detailPart}`);
|
|
28
|
+
this.status = args.status;
|
|
29
|
+
this.url = args.url;
|
|
30
|
+
this.method = args.method;
|
|
31
|
+
this.body = args.body;
|
|
32
|
+
this.detail = args.detail;
|
|
33
|
+
}
|
|
34
|
+
/** True for HTTP statuses the API treats as transient and retry-able. */
|
|
35
|
+
get isRetryable() {
|
|
36
|
+
return this.status === 429 || this.status === 503;
|
|
37
|
+
}
|
|
38
|
+
/** True for a transport-level HTTP 404. */
|
|
39
|
+
get isNotFound() {
|
|
40
|
+
return this.status === 404;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** A transport-level failure (DNS, connection reset, timeout, ...). */
|
|
44
|
+
export class MastrNetworkError extends MastrError {
|
|
45
|
+
}
|
|
46
|
+
/** A client-side validation error (e.g. a bad category) — no request made. */
|
|
47
|
+
export class MastrValidationError extends MastrError {
|
|
48
|
+
}
|
|
49
|
+
/** The response body could not be parsed as the expected JSON shape. */
|
|
50
|
+
export class MastrParseError extends MastrError {
|
|
51
|
+
}
|
|
52
|
+
//# 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,UAAW,SAAQ,KAAK;IACnC,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;;;;;;;GAOG;AACH,MAAM,OAAO,aAAc,SAAQ,UAAU;IAClC,MAAM,CAAqB;IAC3B,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,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAC/E,KAAK,CAAC,GAAG,IAAI,QAAQ,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,GAAG,UAAU,EAAE,CAAC,CAAC;QAC7D,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,yEAAyE;IACzE,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC;IACpD,CAAC;IAED,2CAA2C;IAC3C,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC;IAC7B,CAAC;CACF;AAED,uEAAuE;AACvE,MAAM,OAAO,iBAAkB,SAAQ,UAAU;CAAG;AAEpD,8EAA8E;AAC9E,MAAM,OAAO,oBAAqB,SAAQ,UAAU;CAAG;AAEvD,wEAAwE;AACxE,MAAM,OAAO,eAAgB,SAAQ,UAAU;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;AAI7B,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,SAwE5B,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
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 { MastrNetworkError } from "./errors.js";
|
|
11
|
+
/**
|
|
12
|
+
* Default transport. Resolves with the raw response (including non-2xx) — status
|
|
13
|
+
* interpretation is the client's job. Rejects only on transport-level failures
|
|
14
|
+
* (connection errors, timeouts, malformed URLs).
|
|
15
|
+
*/
|
|
16
|
+
export const nodeHttpTransport = (request) => new Promise((resolve, reject) => {
|
|
17
|
+
let url;
|
|
18
|
+
try {
|
|
19
|
+
url = new URL(request.url);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
reject(new MastrNetworkError(`Invalid URL: ${request.url}`));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Only http/https are supported. Reject anything else up front with a clear,
|
|
26
|
+
// typed error instead of letting Node throw an opaque ERR_INVALID_PROTOCOL.
|
|
27
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
28
|
+
reject(new MastrNetworkError(`Unsupported protocol "${url.protocol}" in URL: ${request.url}`));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const isHttps = url.protocol === "https:";
|
|
32
|
+
const driver = isHttps ? https : http;
|
|
33
|
+
const maxBytes = request.maxResponseBytes;
|
|
34
|
+
const req = driver.request(url, {
|
|
35
|
+
method: request.method,
|
|
36
|
+
headers: request.headers,
|
|
37
|
+
}, (res) => {
|
|
38
|
+
const chunks = [];
|
|
39
|
+
let received = 0;
|
|
40
|
+
let aborted = false;
|
|
41
|
+
res.on("data", (chunk) => {
|
|
42
|
+
if (aborted)
|
|
43
|
+
return;
|
|
44
|
+
received += chunk.length;
|
|
45
|
+
if (maxBytes !== undefined && received > maxBytes) {
|
|
46
|
+
aborted = true;
|
|
47
|
+
res.destroy();
|
|
48
|
+
reject(new MastrNetworkError(`Response exceeded maxResponseBytes (${maxBytes})`));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
chunks.push(chunk);
|
|
52
|
+
});
|
|
53
|
+
res.on("end", () => {
|
|
54
|
+
if (aborted)
|
|
55
|
+
return;
|
|
56
|
+
resolve({
|
|
57
|
+
status: res.statusCode ?? 0,
|
|
58
|
+
headers: res.headers,
|
|
59
|
+
body: Buffer.concat(chunks),
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
res.on("error", (err) => {
|
|
63
|
+
if (aborted)
|
|
64
|
+
return; // we already rejected with the size-cap error
|
|
65
|
+
reject(new MastrNetworkError(`Response stream error: ${err.message}`, { cause: err }));
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
if (request.timeoutMs && request.timeoutMs > 0) {
|
|
69
|
+
req.setTimeout(request.timeoutMs, () => {
|
|
70
|
+
req.destroy(new MastrNetworkError(`Request timed out after ${request.timeoutMs}ms`));
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
req.on("error", (err) => {
|
|
74
|
+
reject(err instanceof MastrNetworkError ? err : new MastrNetworkError(err.message, { cause: err }));
|
|
75
|
+
});
|
|
76
|
+
if (request.body !== undefined)
|
|
77
|
+
req.write(request.body);
|
|
78
|
+
req.end();
|
|
79
|
+
});
|
|
80
|
+
//# 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 { MastrClient, parseMsDate, isoifyDates } from "./client.js";
|
|
2
|
+
export type { MastrClientOptions } from "./client.js";
|
|
3
|
+
export { RequestEngine, DEFAULT_BASE_URL } from "./engine.js";
|
|
4
|
+
export type { EngineOptions, RawResponse } from "./engine.js";
|
|
5
|
+
export { nodeHttpTransport } from "./http.js";
|
|
6
|
+
export type { Transport, HttpRequest, HttpResponse } from "./http.js";
|
|
7
|
+
export { buildQueryString } from "./query.js";
|
|
8
|
+
export type { QueryParams, QueryValue } from "./query.js";
|
|
9
|
+
export { MastrError, MastrApiError, MastrNetworkError, MastrValidationError, MastrParseError, } from "./errors.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,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,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,EACL,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Public entry point for the API client library.
|
|
2
|
+
export { MastrClient, parseMsDate, isoifyDates } 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 { MastrError, MastrApiError, MastrNetworkError, MastrValidationError, MastrParseError, } from "./errors.js";
|
|
7
|
+
export * from "./types.js";
|
|
8
|
+
//# 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,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEpE,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,EACL,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,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"}
|