@deployagram/logger-client 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,14 @@
1
+ DEPLOYAGRAM PROPRIETARY LICENSE
2
+
3
+ Copyright (c) 2025 Deployagram, Cookiebit and Andy Muir.
4
+
5
+ Permission is hereby granted to use this software solely for its intended purpose.
6
+
7
+ RESTRICTIONS:
8
+ - No modification of the software is permitted
9
+ - No reverse engineering, decompilation, or disassembly
10
+ - No redistribution without explicit written permission
11
+ - Source code remains proprietary and confidential
12
+ - Usage is limited to the compiled npm package (the distributed tarball) artifact only
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
package/README.md CHANGED
@@ -1,3 +1,55 @@
1
- # Temporary Holding Version
1
+ # @deployagram/logger-client
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A client for the Deployagram Collector (`living-http-logger`), built on Node's `fetch`. It is the
4
+ Node.js equivalent of the Java `DiagramLoggerClient`.
5
+
6
+ ```bash
7
+ npm install @deployagram/logger-client
8
+ ```
9
+
10
+ ```ts
11
+ import { DiagramLoggerClient } from '@deployagram/logger-client';
12
+
13
+ const logger = new DiagramLoggerClient({ baseUrl: 'http://localhost:1152' });
14
+
15
+ await logger.log({
16
+ timestamp: new Date().toISOString(),
17
+ protocol: 'HTTP',
18
+ source: 'EmailClient',
19
+ target: 'Emailer',
20
+ message: 'POST /Emailer/email',
21
+ body: '{"email":"eddie@eddie.com"}',
22
+ });
23
+
24
+ const all = await logger.read(); // GET /log/read
25
+ const marked = await logger.read('marker'); // GET /log/read/{id}
26
+ await logger.markEnd('marker'); // POST /log/markEnd/{id}
27
+ await logger.flushToCloud('Emailer', 'run-1'); // POST /run/markTestRunEnd/{container}/{run}
28
+ ```
29
+
30
+ | Method | Collector endpoint |
31
+ |---|---|
32
+ | `log(log)` | `POST /log` |
33
+ | `read()` | `GET /log/read` |
34
+ | `read(id)` | `GET /log/read/{id}` |
35
+ | `markEnd(id)` | `POST /log/markEnd/{id}` |
36
+ | `flushToCloud(container, run)` | `POST /run/markTestRunEnd/{container}/{run}` |
37
+
38
+ Differences from the Java client:
39
+
40
+ * A non-2xx response throws `CollectorError`, which has `status` and `responseBody`. The Java
41
+ client ignores the status.
42
+ * Every method returns a Promise.
43
+ * `flushToCloud` calls `markTestRunEnd`, as the Java client does. On a Collector with a Central
44
+ Logger configured, that also sends the run to the cloud.
45
+
46
+ ## Testing
47
+
48
+ ```bash
49
+ npm test
50
+ ```
51
+
52
+ The tests need no Collector. They stub the Collector's endpoints with
53
+ [MSW (Mock Service Worker)](https://mswjs.io), declaring each route the way a WireMock stub is
54
+ declared, then check the method, path, body and error handling. Any request without a matching
55
+ stub fails the test. `flushToCloud` is not tested.
@@ -0,0 +1,30 @@
1
+ import type { DiagramLogger, Log, Logs } from '@deployagram/api';
2
+ export interface DiagramLoggerClientOptions {
3
+ /** Base URL of the Collector, for example "http://localhost:1152". */
4
+ baseUrl: string;
5
+ /** Replaces the global fetch. Mainly for tests. */
6
+ fetch?: typeof fetch;
7
+ }
8
+ /**
9
+ * Client for the Deployagram Collector. Mirrors the Java DiagramLoggerClient, with two changes:
10
+ * HTTP errors are thrown (the Java client ignores them), and calls return Promises.
11
+ */
12
+ export declare class DiagramLoggerClient implements DiagramLogger {
13
+ private readonly baseUrl;
14
+ private readonly fetchImpl;
15
+ constructor(options: DiagramLoggerClientOptions);
16
+ /** POST /log: store one interaction. */
17
+ log(log: Log): Promise<void>;
18
+ /** GET /log/read: all logs held by the Collector. */
19
+ read(): Promise<Logs>;
20
+ /** GET /log/read/{logId}: the logs recorded under one marker. */
21
+ read(logId: string): Promise<Logs>;
22
+ /** POST /log/markEnd/{sequenceDiagramId}: close the current sequence diagram. */
23
+ markEnd(sequenceDiagramId: string): Promise<void>;
24
+ /**
25
+ * POST /run/markTestRunEnd/{containerId}/{testRunId}. As in the Java client, this is the call
26
+ * that ends a test run and, when a Central Logger is configured on the Collector, flushes it.
27
+ */
28
+ flushToCloud(containerId: string, testRunId: string): Promise<void>;
29
+ private request;
30
+ }
@@ -0,0 +1,46 @@
1
+ import { CollectorError } from './errors.js';
2
+ /**
3
+ * Client for the Deployagram Collector. Mirrors the Java DiagramLoggerClient, with two changes:
4
+ * HTTP errors are thrown (the Java client ignores them), and calls return Promises.
5
+ */
6
+ export class DiagramLoggerClient {
7
+ baseUrl;
8
+ fetchImpl;
9
+ constructor(options) {
10
+ this.baseUrl = options.baseUrl.replace(/\/+$/, '');
11
+ this.fetchImpl = options.fetch ?? fetch;
12
+ }
13
+ /** POST /log: store one interaction. */
14
+ async log(log) {
15
+ await this.request('POST', '/log', log);
16
+ }
17
+ async read(logId) {
18
+ const path = logId === undefined ? '/log/read' : `/log/read/${encodeURIComponent(logId)}`;
19
+ return (await this.request('GET', path));
20
+ }
21
+ /** POST /log/markEnd/{sequenceDiagramId}: close the current sequence diagram. */
22
+ async markEnd(sequenceDiagramId) {
23
+ await this.request('POST', `/log/markEnd/${encodeURIComponent(sequenceDiagramId)}`);
24
+ }
25
+ /**
26
+ * POST /run/markTestRunEnd/{containerId}/{testRunId}. As in the Java client, this is the call
27
+ * that ends a test run and, when a Central Logger is configured on the Collector, flushes it.
28
+ */
29
+ async flushToCloud(containerId, testRunId) {
30
+ await this.request('POST', `/run/markTestRunEnd/${encodeURIComponent(containerId)}/${encodeURIComponent(testRunId)}`);
31
+ }
32
+ async request(method, path, body) {
33
+ const init = { method, headers: { Accept: 'application/json' } };
34
+ if (body !== undefined) {
35
+ init.headers = { ...init.headers, 'Content-Type': 'application/json' };
36
+ init.body = JSON.stringify(body);
37
+ }
38
+ const response = await this.fetchImpl(this.baseUrl + path, init);
39
+ const text = await response.text();
40
+ if (!response.ok) {
41
+ throw new CollectorError(method, path, response.status, text);
42
+ }
43
+ return text ? JSON.parse(text) : undefined;
44
+ }
45
+ }
46
+ //# sourceMappingURL=diagram-logger-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagram-logger-client.js","sourceRoot":"","sources":["../src/diagram-logger-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAS7C;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IACb,OAAO,CAAS;IAChB,SAAS,CAAe;IAEzC,YAAY,OAAmC;QAC7C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;IAC1C,CAAC;IAED,wCAAwC;IACxC,KAAK,CAAC,GAAG,CAAC,GAAQ;QAChB,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IAMD,KAAK,CAAC,IAAI,CAAC,KAAc;QACvB,MAAM,IAAI,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1F,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAS,CAAC;IACnD,CAAC;IAED,iFAAiF;IACjF,KAAK,CAAC,OAAO,CAAC,iBAAyB;QACrC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,gBAAgB,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY,CAAC,WAAmB,EAAE,SAAiB;QACvD,MAAM,IAAI,CAAC,OAAO,CAChB,MAAM,EACN,uBAAuB,kBAAkB,CAAC,WAAW,CAAC,IAAI,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAC1F,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,MAAsB,EAAE,IAAY,EAAE,IAAc;QACxE,MAAM,IAAI,GAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,CAAC;QAC9E,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;YACvE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;QACjE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7C,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ /** Thrown when the Collector answers with a non-2xx status. */
2
+ export declare class CollectorError extends Error {
3
+ readonly status: number;
4
+ readonly responseBody: string;
5
+ constructor(method: string, path: string, status: number, responseBody: string);
6
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,12 @@
1
+ /** Thrown when the Collector answers with a non-2xx status. */
2
+ export class CollectorError extends Error {
3
+ status;
4
+ responseBody;
5
+ constructor(method, path, status, responseBody) {
6
+ super(`Collector ${method} ${path} failed with HTTP ${status}${responseBody ? `: ${responseBody}` : ''}`);
7
+ this.name = 'CollectorError';
8
+ this.status = status;
9
+ this.responseBody = responseBody;
10
+ }
11
+ }
12
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,MAAM,CAAS;IACf,YAAY,CAAS;IAE9B,YAAY,MAAc,EAAE,IAAY,EAAE,MAAc,EAAE,YAAoB;QAC5E,KAAK,CAAC,aAAa,MAAM,IAAI,IAAI,qBAAqB,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,KAAK,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1G,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export { DiagramLoggerClient } from './diagram-logger-client.js';
2
+ export type { DiagramLoggerClientOptions } from './diagram-logger-client.js';
3
+ export { CollectorError } from './errors.js';
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { DiagramLoggerClient } from './diagram-logger-client.js';
2
+ export { CollectorError } from './errors.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,40 @@
1
1
  {
2
2
  "name": "@deployagram/logger-client",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "HTTP client for the Deployagram Collector (living-http-logger), built on fetch. Node.js 22+.",
5
+ "type": "module",
6
+ "license": "SEE LICENSE IN LICENSE",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "engines": {
24
+ "node": ">=22"
25
+ },
26
+ "scripts": {
27
+ "build": "tsc -p tsconfig.json",
28
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
29
+ "test": "vitest run"
30
+ },
31
+ "dependencies": {
32
+ "@deployagram/api": "^0.1.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^22.20.5",
36
+ "msw": "^3.0.4",
37
+ "typescript": "^7.0.2",
38
+ "vitest": "^5.1.0"
39
+ }
40
+ }