@miragon/pulse-engine-client 0.0.0-stage → 0.25.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.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -2
  3. package/dist/client.d.ts +65 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +144 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/engine-contract/batches.d.ts +41 -0
  8. package/dist/engine-contract/batches.d.ts.map +1 -0
  9. package/dist/engine-contract/batches.js +39 -0
  10. package/dist/engine-contract/batches.js.map +1 -0
  11. package/dist/engine-contract/index.d.ts +11 -0
  12. package/dist/engine-contract/index.d.ts.map +1 -0
  13. package/dist/engine-contract/index.js +11 -0
  14. package/dist/engine-contract/index.js.map +1 -0
  15. package/dist/engine-contract/reads.d.ts +43 -0
  16. package/dist/engine-contract/reads.d.ts.map +1 -0
  17. package/dist/engine-contract/reads.js +86 -0
  18. package/dist/engine-contract/reads.js.map +1 -0
  19. package/dist/engine-error.d.ts +73 -0
  20. package/dist/engine-error.d.ts.map +1 -0
  21. package/dist/engine-error.js +231 -0
  22. package/dist/engine-error.js.map +1 -0
  23. package/dist/generated/client/client.gen.d.ts +3 -0
  24. package/dist/generated/client/client.gen.d.ts.map +1 -0
  25. package/dist/generated/client/client.gen.js +217 -0
  26. package/dist/generated/client/client.gen.js.map +1 -0
  27. package/dist/generated/client/index.d.ts +11 -0
  28. package/dist/generated/client/index.d.ts.map +1 -0
  29. package/dist/generated/client/index.js +7 -0
  30. package/dist/generated/client/index.js.map +1 -0
  31. package/dist/generated/client/types.gen.d.ts +121 -0
  32. package/dist/generated/client/types.gen.d.ts.map +1 -0
  33. package/dist/generated/client/types.gen.js +3 -0
  34. package/dist/generated/client/types.gen.js.map +1 -0
  35. package/dist/generated/client/utils.gen.d.ts +38 -0
  36. package/dist/generated/client/utils.gen.d.ts.map +1 -0
  37. package/dist/generated/client/utils.gen.js +229 -0
  38. package/dist/generated/client/utils.gen.js.map +1 -0
  39. package/dist/generated/client.gen.d.ts +13 -0
  40. package/dist/generated/client.gen.d.ts.map +1 -0
  41. package/dist/generated/client.gen.js +5 -0
  42. package/dist/generated/client.gen.js.map +1 -0
  43. package/dist/generated/core/auth.gen.d.ts +26 -0
  44. package/dist/generated/core/auth.gen.d.ts.map +1 -0
  45. package/dist/generated/core/auth.gen.js +15 -0
  46. package/dist/generated/core/auth.gen.js.map +1 -0
  47. package/dist/generated/core/bodySerializer.gen.d.ts +26 -0
  48. package/dist/generated/core/bodySerializer.gen.d.ts.map +1 -0
  49. package/dist/generated/core/bodySerializer.gen.js +58 -0
  50. package/dist/generated/core/bodySerializer.gen.js.map +1 -0
  51. package/dist/generated/core/params.gen.d.ts +44 -0
  52. package/dist/generated/core/params.gen.d.ts.map +1 -0
  53. package/dist/generated/core/params.gen.js +110 -0
  54. package/dist/generated/core/params.gen.js.map +1 -0
  55. package/dist/generated/core/pathSerializer.gen.d.ts +34 -0
  56. package/dist/generated/core/pathSerializer.gen.d.ts.map +1 -0
  57. package/dist/generated/core/pathSerializer.gen.js +107 -0
  58. package/dist/generated/core/pathSerializer.gen.js.map +1 -0
  59. package/dist/generated/core/queryKeySerializer.gen.d.ts +19 -0
  60. package/dist/generated/core/queryKeySerializer.gen.d.ts.map +1 -0
  61. package/dist/generated/core/queryKeySerializer.gen.js +93 -0
  62. package/dist/generated/core/queryKeySerializer.gen.js.map +1 -0
  63. package/dist/generated/core/serverSentEvents.gen.d.ts +72 -0
  64. package/dist/generated/core/serverSentEvents.gen.d.ts.map +1 -0
  65. package/dist/generated/core/serverSentEvents.gen.js +133 -0
  66. package/dist/generated/core/serverSentEvents.gen.js.map +1 -0
  67. package/dist/generated/core/types.gen.d.ts +84 -0
  68. package/dist/generated/core/types.gen.d.ts.map +1 -0
  69. package/dist/generated/core/types.gen.js +3 -0
  70. package/dist/generated/core/types.gen.js.map +1 -0
  71. package/dist/generated/core/utils.gen.d.ts +20 -0
  72. package/dist/generated/core/utils.gen.d.ts.map +1 -0
  73. package/dist/generated/core/utils.gen.js +88 -0
  74. package/dist/generated/core/utils.gen.js.map +1 -0
  75. package/dist/generated/index.d.ts +3 -0
  76. package/dist/generated/index.d.ts.map +1 -0
  77. package/dist/generated/index.js +3 -0
  78. package/dist/generated/index.js.map +1 -0
  79. package/dist/generated/sdk.gen.d.ts +3207 -0
  80. package/dist/generated/sdk.gen.d.ts.map +1 -0
  81. package/dist/generated/sdk.gen.js +5794 -0
  82. package/dist/generated/sdk.gen.js.map +1 -0
  83. package/dist/generated/types.gen.d.ts +27591 -0
  84. package/dist/generated/types.gen.d.ts.map +1 -0
  85. package/dist/generated/types.gen.js +3 -0
  86. package/dist/generated/types.gen.js.map +1 -0
  87. package/dist/hey-api.d.ts +10 -0
  88. package/dist/hey-api.d.ts.map +1 -0
  89. package/dist/hey-api.js +27 -0
  90. package/dist/hey-api.js.map +1 -0
  91. package/dist/index.d.ts +5 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +4 -0
  94. package/dist/index.js.map +1 -0
  95. package/package.json +63 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Miragon GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,110 @@
1
- # Temporary Holding Version
1
+ # @miragon/pulse-engine-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
+ [![npm](https://img.shields.io/npm/v/@miragon/pulse-engine-client?style=flat-square)](https://www.npmjs.com/package/@miragon/pulse-engine-client)
4
+ [![CI](https://img.shields.io/github/actions/workflow/status/Miragon/pulse/ci.yml?style=flat-square&label=ci)](https://github.com/Miragon/pulse/actions/workflows/ci.yml)
5
+ [![Docs](https://img.shields.io/badge/docs-miragon.github.io%2Fpulse-335DE5?style=flat-square)](https://miragon.github.io/pulse/)
6
+
7
+ A typed TypeScript client for the REST API of Camunda 7, CIB seven and Operaton.
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ npm install @miragon/pulse-engine-client
13
+ ```
14
+
15
+ ## Overview
16
+
17
+ TypeScript client for the [CIB seven](https://cibseven.org/) REST API: an SDK
18
+ generated with [`@hey-api/openapi-ts`](https://heyapi.dev/), a client factory
19
+ with deadlines and engine errors, and the reads whose REST contract the SDK
20
+ defaults miss. There is no official TypeScript client for CIB seven; this
21
+ package fills that gap for Pulse and is usable by any CIB seven / Camunda 7
22
+ project. It has no runtime dependency. The pure engine REST rules (dates,
23
+ filters, sorting, variable writes, incident recovery) live in
24
+ [`@miragon/pulse-engine-core`](../engine-core/README.md), which this package
25
+ does not import.
26
+
27
+ ## Exports
28
+
29
+ | Subpath | Contents |
30
+ | --------- | ----------------------------------------------------------------------------------------- |
31
+ | `.` | `createEngineClient` factory, `EngineRequestError`, the SDK-bound reads and batch reports |
32
+ | `./sdk` | Generated SDK, one typed function per REST operation |
33
+ | `./types` | Generated request/response types |
34
+
35
+ These three subpaths are the public API. The internal layout of the generated
36
+ output (`dist/generated/**`) is not: it may change with any `@hey-api/openapi-ts`
37
+ upgrade, so deep imports are deliberately not exported.
38
+
39
+ ## Client behavior
40
+
41
+ SDK functions return the response payload directly (`responseStyle: "data"`)
42
+ and reject on HTTP error responses (`throwOnError: true`). Both options are
43
+ declared once in the generator config (`openapi-ts.config.ts`) and applied at
44
+ runtime through `createClientConfig` (`src/hey-api.ts`), which the generated
45
+ default client and `createEngineClient` share, so generated types and runtime
46
+ behavior always agree.
47
+
48
+ ```ts
49
+ import { createEngineClient } from "@miragon/pulse-engine-client"
50
+ import { getProcessDefinitions } from "@miragon/pulse-engine-client/sdk"
51
+
52
+ const client = createEngineClient({
53
+ baseUrl: "http://localhost:8410/engine-rest",
54
+ authType: "basic",
55
+ username: "demo",
56
+ password: "demo",
57
+ })
58
+ const definitions = await getProcessDefinitions({ client, query: { latestVersion: true } })
59
+ ```
60
+
61
+ Every `createEngineClient` client, whatever its auth type, rejects with an
62
+ `EngineRequestError` (an `Error` with `kind`, `httpStatus`, `type`,
63
+ `engineMessage`, `engineCode`, `engineId`) instead of the raw error body, with
64
+ a message that is safe and useful to show a model (engine text truncated, the
65
+ request's credentials masked):
66
+ `[404 InvalidRequestException] Process instance with id x does not exist (engine prod-a)`,
67
+ `engine prod-a unreachable (ECONNREFUSED)` (no connection: the engine never
68
+ saw the request), `connection to engine prod-a failed (ECONNRESET)` (dropped
69
+ mid-request; a write adds that it may still have been applied), or
70
+ `engine prod-a did not respond within 30000 ms (timeout)`. Pass `engineId` to
71
+ name the engine in those messages and `timeoutMs` to change the per-request
72
+ deadline (default 30 000 ms). `withCallerSignal(client, signal)` returns a view
73
+ whose reads (`GET`/`HEAD`/`OPTIONS`) also abort with the caller's signal;
74
+ writes never do, since aborting a started write cannot undo it.
75
+
76
+ The deadline lives in the client's `fetch`, so it binds each request after
77
+ every request interceptor. A custom `fetch` (per call or via `setConfig`)
78
+ replaces it, so wrap `client.getConfig().fetch` instead. Request interceptors
79
+ should mutate the request (`request.headers.set(…)`): one that returns a new
80
+ `Request` keeps the deadline, but can detach the caller's signal.
81
+
82
+ ## OpenAPI spec: origin & refresh
83
+
84
+ The spec is checked in as `cibseven-open-api-doc.json` (currently reporting
85
+ `info.version` **2.1.2**). It originates from the engine's published OpenAPI
86
+ artifact `org.cibseven.bpm:cibseven-engine-rest-openapi` (a jar containing
87
+ `openapi.json`); Maven Central publishes the minor releases (2.1.0, 2.2.0, …).
88
+ The running engine does not serve its spec over HTTP, so the artifact is the
89
+ canonical source.
90
+
91
+ To refresh:
92
+
93
+ ```bash
94
+ pnpm spec:refresh <version> # downloads + extracts the spec, e.g. pnpm spec:refresh 2.2.0
95
+ pnpm generate # regenerate src/generated from the new spec
96
+ git diff # review spec + SDK changes, run the repo verification suite
97
+ ```
98
+
99
+ Commit the spec and the regenerated output together: `src/generated/` is
100
+ checked in and CI assumes it matches the spec.
101
+
102
+ ## The SDK-bound reads
103
+
104
+ `src/engine-contract/` holds the reads whose REST contract differs from the SDK
105
+ defaults: the `text/plain`-only stacktrace and error-details endpoints
106
+ (`fetchJobStacktrace`, `fetchExternalTaskErrorDetails`, `null` on a 404),
107
+ variable reads with `deserializeValues=false` (`readProcessInstanceVariables`,
108
+ `readTaskVariables`) and `readBatch`, which falls back from the runtime
109
+ statistics to the history record. The MCP tools' input schemas live in
110
+ `@miragon/pulse-engine-connector` next to its tools.
@@ -0,0 +1,65 @@
1
+ import type { Client } from "./generated/client/types.gen.js";
2
+ export type { Client };
3
+ export type EngineAuthType = "basic" | "bearer" | "passthrough" | "none";
4
+ /** Default per-request deadline for engine calls (`timeoutMs`). */
5
+ export declare const DEFAULT_ENGINE_TIMEOUT_MS = 30000;
6
+ export interface EngineClientOptions {
7
+ baseUrl: string;
8
+ /**
9
+ * Id of the configured engine this client talks to. Carried into every
10
+ * error message (`… (engine prod-a)`) so the model can tell WHICH engine
11
+ * failed in a multi-engine fleet; left out of the message when unset.
12
+ */
13
+ engineId?: string;
14
+ /**
15
+ * Per-request deadline in ms (default {@link DEFAULT_ENGINE_TIMEOUT_MS}),
16
+ * covering connect, headers and body. A hung engine then fails the call
17
+ * with a timeout error instead of holding it for undici's minutes-long
18
+ * defaults.
19
+ */
20
+ timeoutMs?: number;
21
+ authType?: EngineAuthType;
22
+ username?: string;
23
+ password?: string;
24
+ token?: string;
25
+ /**
26
+ * Token source for `authType: "passthrough"`, called on every request; the
27
+ * returned bearer token (without the `Bearer ` scheme prefix) is sent as
28
+ * the `Authorization` header. When it returns `undefined` (or no provider
29
+ * is given), the request is sent without auth, like `authType: "none"`;
30
+ * an engine with REST auth enabled then answers 401.
31
+ */
32
+ tokenProvider?: () => string | undefined;
33
+ }
34
+ /**
35
+ * Per-engine client factory. All defaults (JSON content negotiation headers,
36
+ * `throwOnError`, `responseStyle`) come from `createClientConfig` in
37
+ * src/hey-api.ts (the same function the generated default client uses), so
38
+ * runtime behavior and the generated SDK types stay in sync.
39
+ *
40
+ * Every client, whatever its auth type, carries a per-request deadline in its
41
+ * `fetch` (combined with a caller `signal`, see {@link withCallerSignal}) and
42
+ * an error interceptor that maps every failure to an `EngineRequestError`
43
+ * (status, exception type, engine message, engine id; credentials masked).
44
+ *
45
+ * The deadline binds the request as it LEAVES (after every request
46
+ * interceptor), so an interceptor that returns a new `Request` can neither
47
+ * detach it nor disguise it as a cancellation. A custom `fetch` (per call or
48
+ * via `setConfig`) replaces the deadline with it: wrap
49
+ * `client.getConfig().fetch` instead. Request interceptors should mutate the
50
+ * request (`request.headers.set(…)`); one that returns a new `Request` keeps
51
+ * the deadline, but the caller's signal reaches the new request only through
52
+ * the dropped one (undici follows signals via a `WeakRef`), so after a
53
+ * garbage collection a cancelled call runs on until the deadline.
54
+ */
55
+ export declare function createEngineClient(options: EngineClientOptions): Client;
56
+ /**
57
+ * A view of `client` whose READS honor the caller's `signal` (an MCP
58
+ * request's `ctx.signal`, aborted when the MCP client cancels or
59
+ * disconnects), on top of the client's own deadline. Writes never see it:
60
+ * aborting a started write cannot roll it back on the engine, it only turns
61
+ * a known outcome into an unknown one. An explicit per-call `signal` wins.
62
+ * Without a signal the client itself is returned.
63
+ */
64
+ export declare function withCallerSignal(client: Client, signal: AbortSignal | undefined): Client;
65
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAA;AAI7D,YAAY,EAAE,MAAM,EAAE,CAAA;AAEtB,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,aAAa,GAAG,MAAM,CAAA;AAExE,mEAAmE;AACnE,eAAO,MAAM,yBAAyB,QAAS,CAAA;AAK/C,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;CACzC;AAsDD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAsDvE;AAKD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CASxF"}
package/dist/client.js ADDED
@@ -0,0 +1,144 @@
1
+ import { createClient } from "./generated/client/client.gen.js";
2
+ import { createClientConfig } from "./hey-api.js";
3
+ import { toEngineRequestError } from "./engine-error.js";
4
+ /** Default per-request deadline for engine calls (`timeoutMs`). */
5
+ export const DEFAULT_ENGINE_TIMEOUT_MS = 30_000;
6
+ /** The largest delay a Node timer holds; a longer one would fire immediately. */
7
+ const MAX_TIMEOUT_MS = 2_147_483_647;
8
+ function buildAuthHeader(options) {
9
+ const { authType = "none", username, password, token } = options;
10
+ if (authType === "basic" && username && password) {
11
+ const encoded = typeof btoa === "function"
12
+ ? btoa(`${username}:${password}`)
13
+ : Buffer.from(`${username}:${password}`).toString("base64");
14
+ return { Authorization: `Basic ${encoded}` };
15
+ }
16
+ if (authType === "bearer" && token) {
17
+ return { Authorization: `Bearer ${token}` };
18
+ }
19
+ // "passthrough" deliberately sets no static header: the per-request
20
+ // interceptor below owns the Authorization header instead.
21
+ return {};
22
+ }
23
+ /** The remedy a 401 message names: it depends on where the credential came from. */
24
+ function unauthorizedHint(options) {
25
+ switch (options.authType ?? "none") {
26
+ case "passthrough":
27
+ return options.tokenProvider?.()
28
+ ? "The engine rejected the forwarded bearer token."
29
+ : "The MCP request carried no bearer token to pass through.";
30
+ case "none":
31
+ return "The engine requires authentication, but none is configured.";
32
+ default:
33
+ return "The engine rejected the configured credentials.";
34
+ }
35
+ }
36
+ function resolveTimeout(timeoutMs) {
37
+ if (timeoutMs === undefined)
38
+ return DEFAULT_ENGINE_TIMEOUT_MS;
39
+ if (!Number.isInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > MAX_TIMEOUT_MS) {
40
+ throw new RangeError(`Engine request timeout must be a positive integer of at most ${MAX_TIMEOUT_MS} ms, got ${timeoutMs}`);
41
+ }
42
+ return timeoutMs;
43
+ }
44
+ /**
45
+ * The credentials a request carried, for masking in error text (an engine or
46
+ * proxy may quote them back): the configured password/token and whatever the
47
+ * request's own `Authorization` header holds (the Basic value, a static or a
48
+ * passed-through bearer token).
49
+ */
50
+ function credentialsOf(options, request) {
51
+ const authorization = request?.headers.get("Authorization") ?? undefined;
52
+ return [options.password, options.token, authorization?.replace(/^\S+\s+/, "")];
53
+ }
54
+ /**
55
+ * Per-engine client factory. All defaults (JSON content negotiation headers,
56
+ * `throwOnError`, `responseStyle`) come from `createClientConfig` in
57
+ * src/hey-api.ts (the same function the generated default client uses), so
58
+ * runtime behavior and the generated SDK types stay in sync.
59
+ *
60
+ * Every client, whatever its auth type, carries a per-request deadline in its
61
+ * `fetch` (combined with a caller `signal`, see {@link withCallerSignal}) and
62
+ * an error interceptor that maps every failure to an `EngineRequestError`
63
+ * (status, exception type, engine message, engine id; credentials masked).
64
+ *
65
+ * The deadline binds the request as it LEAVES (after every request
66
+ * interceptor), so an interceptor that returns a new `Request` can neither
67
+ * detach it nor disguise it as a cancellation. A custom `fetch` (per call or
68
+ * via `setConfig`) replaces the deadline with it: wrap
69
+ * `client.getConfig().fetch` instead. Request interceptors should mutate the
70
+ * request (`request.headers.set(…)`); one that returns a new `Request` keeps
71
+ * the deadline, but the caller's signal reaches the new request only through
72
+ * the dropped one (undici follows signals via a `WeakRef`), so after a
73
+ * garbage collection a cancelled call runs on until the deadline.
74
+ */
75
+ export function createEngineClient(options) {
76
+ const timeoutMs = resolveTimeout(options.timeoutMs);
77
+ // Keyed by the request hey-api sends, i.e. the one its error interceptors
78
+ // receive: tells OUR deadline from a caller's cancellation, and keeps the
79
+ // timer alive exactly as long as hey-api holds that request (body read
80
+ // included).
81
+ const deadlines = new WeakMap();
82
+ const fetchWithDeadline = (request) => {
83
+ const deadline = AbortSignal.timeout(timeoutMs);
84
+ deadlines.set(request, deadline);
85
+ return fetch(request, { signal: AbortSignal.any([request.signal, deadline]) });
86
+ };
87
+ const client = createClient(createClientConfig({
88
+ baseUrl: options.baseUrl,
89
+ headers: buildAuthHeader(options),
90
+ // hey-api calls its `fetch` with the finished Request only.
91
+ fetch: fetchWithDeadline,
92
+ // Redirects are FOLLOWED, hey-api's own default, stated so the difference shows: the CLI
93
+ // and the VS Code extension send `redirect: "manual"` (a followed 302/303 turns a write
94
+ // into a GET). One policy for all three is a behaviour change of its own.
95
+ redirect: "follow",
96
+ }));
97
+ if (options.authType === "passthrough" && options.tokenProvider) {
98
+ const { tokenProvider } = options;
99
+ // Not the hey-api `auth` option: the generated operations all declare the
100
+ // `basic` security scheme, so `auth` would base64-mangle a bearer token.
101
+ // The interceptor must only ever touch Authorization: the multipart
102
+ // operations rely on an absent Content-Type for the boundary parameter.
103
+ client.interceptors.request.use((request) => {
104
+ const token = tokenProvider();
105
+ if (token) {
106
+ request.headers.set("Authorization", `Bearer ${token}`);
107
+ }
108
+ return request;
109
+ });
110
+ }
111
+ // Always on: hey-api throws the parsed error BODY (an ExceptionDto object,
112
+ // the text, or `{}`), which the model would read as "[object Object]".
113
+ client.interceptors.error.use((error, response, request) => toEngineRequestError(error, {
114
+ response,
115
+ request,
116
+ engineId: options.engineId,
117
+ timeoutMs,
118
+ timedOut: request ? deadlines.get(request)?.aborted === true : false,
119
+ unauthorizedHint: response?.status === 401 ? unauthorizedHint(options) : undefined,
120
+ secrets: credentialsOf(options, request),
121
+ }));
122
+ return client;
123
+ }
124
+ /** The methods a caller's cancellation may abort: reads, never writes. */
125
+ const CANCELLABLE_METHODS = ["get", "head", "options"];
126
+ /**
127
+ * A view of `client` whose READS honor the caller's `signal` (an MCP
128
+ * request's `ctx.signal`, aborted when the MCP client cancels or
129
+ * disconnects), on top of the client's own deadline. Writes never see it:
130
+ * aborting a started write cannot roll it back on the engine, it only turns
131
+ * a known outcome into an unknown one. An explicit per-call `signal` wins.
132
+ * Without a signal the client itself is returned.
133
+ */
134
+ export function withCallerSignal(client, signal) {
135
+ if (!signal)
136
+ return client;
137
+ const bound = { ...client };
138
+ for (const method of CANCELLABLE_METHODS) {
139
+ const call = client[method];
140
+ bound[method] = ((callOptions) => call({ ...callOptions, signal: callOptions.signal ?? signal }));
141
+ }
142
+ return bound;
143
+ }
144
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Batches. A batch write (`POST /job/retries`, `POST /migration/executeAsync`)
3
+ * returns as soon as the engine has QUEUED the batch: the work and its
4
+ * failures happen later, in batch jobs. A tool must therefore never report
5
+ * the queued batch as done: it hands back the batch id with status `queued`,
6
+ * and `engine_get_batch` reports what became of it.
7
+ */
8
+ import type { BatchDto, BatchStatisticsDto, HistoricBatchDto } from "../generated/types.gen.js";
9
+ /** What a batch write returns: the id to follow up on, never a success flag. */
10
+ export interface QueuedBatch {
11
+ batchId: string;
12
+ status: "queued";
13
+ /** Engine batch type, e.g. `set-job-retries`, `instance-migration`. */
14
+ type: string | null;
15
+ totalJobs: number | null;
16
+ }
17
+ export declare function queuedBatch(batch: BatchDto): QueuedBatch;
18
+ /**
19
+ * - `running`: batch jobs are still being created or executed;
20
+ * - `failing`: some batch jobs ran out of retries, so the batch cannot finish
21
+ * until they are retried or the batch is deleted;
22
+ * - `suspended`: suspended, nothing executes;
23
+ * - `completed`: the batch ended (all jobs done, or it was deleted).
24
+ */
25
+ export type BatchStatus = "running" | "failing" | "suspended" | "completed";
26
+ export interface BatchReport {
27
+ batchId: string;
28
+ type: string | null;
29
+ status: BatchStatus;
30
+ totalJobs: number | null;
31
+ /** Runtime counts, null once the batch has ended. */
32
+ remainingJobs: number | null;
33
+ completedJobs: number | null;
34
+ failedJobs: number | null;
35
+ startTime: string | null;
36
+ endTime: string | null;
37
+ }
38
+ export declare function runningBatchReport(stats: BatchStatisticsDto): BatchReport;
39
+ /** A batch the runtime no longer holds, from its history record. */
40
+ export declare function endedBatchReport(batch: HistoricBatchDto): BatchReport;
41
+ //# sourceMappingURL=batches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batches.d.ts","sourceRoot":"","sources":["../../src/engine-contract/batches.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAE/F,gFAAgF;AAChF,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,QAAQ,CAAA;IAChB,uEAAuE;IACvE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,WAAW,CAOxD;AAED;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,CAAA;AAE3E,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,MAAM,EAAE,WAAW,CAAA;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,qDAAqD;IACrD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,WAAW,CAczE;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAarE"}
@@ -0,0 +1,39 @@
1
+ export function queuedBatch(batch) {
2
+ return {
3
+ batchId: batch.id ?? "",
4
+ status: "queued",
5
+ type: batch.type ?? null,
6
+ totalJobs: batch.totalJobs ?? null,
7
+ };
8
+ }
9
+ export function runningBatchReport(stats) {
10
+ const failedJobs = stats.failedJobs ?? 0;
11
+ const status = stats.suspended ? "suspended" : failedJobs > 0 ? "failing" : "running";
12
+ return {
13
+ batchId: stats.id ?? "",
14
+ type: stats.type ?? null,
15
+ status,
16
+ totalJobs: stats.totalJobs ?? null,
17
+ remainingJobs: stats.remainingJobs ?? null,
18
+ completedJobs: stats.completedJobs ?? null,
19
+ failedJobs,
20
+ startTime: stats.startTime ?? null,
21
+ endTime: null,
22
+ };
23
+ }
24
+ /** A batch the runtime no longer holds, from its history record. */
25
+ export function endedBatchReport(batch) {
26
+ return {
27
+ batchId: batch.id ?? "",
28
+ type: batch.type ?? null,
29
+ // A historic batch without endTime is one the runtime query just missed.
30
+ status: batch.endTime ? "completed" : "running",
31
+ totalJobs: batch.totalJobs ?? null,
32
+ remainingJobs: null,
33
+ completedJobs: null,
34
+ failedJobs: null,
35
+ startTime: batch.startTime ?? null,
36
+ endTime: batch.endTime ?? null,
37
+ };
38
+ }
39
+ //# sourceMappingURL=batches.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batches.js","sourceRoot":"","sources":["../../src/engine-contract/batches.ts"],"names":[],"mappings":"AAkBA,MAAM,UAAU,WAAW,CAAC,KAAe;IACzC,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE;QACvB,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;QACxB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;KACnC,CAAA;AACH,CAAC;AAwBD,MAAM,UAAU,kBAAkB,CAAC,KAAyB;IAC1D,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,CAAC,CAAA;IACxC,MAAM,MAAM,GAAgB,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IAClG,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE;QACvB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;QACxB,MAAM;QACN,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;QAClC,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,IAAI;QAC1C,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,IAAI;QAC1C,UAAU;QACV,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;QAClC,OAAO,EAAE,IAAI;KACd,CAAA;AACH,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,gBAAgB,CAAC,KAAuB;IACtD,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE;QACvB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;QACxB,yEAAyE;QACzE,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;QAC/C,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;QAClC,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;QAClC,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;KAC/B,CAAA;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The engine contract's SDK-bound half: the reads whose REST contract differs from the client
3
+ * defaults (text-only endpoints, raw variable reads, the batch fallback) and the batch status.
4
+ * The pure rules (dates, filters, sorting, variable writes, incident recovery) live in
5
+ * `@miragon/pulse-engine-core`; this package stays a leaf and does not import it. The engine
6
+ * module's tools (`tools/`) and widget feeds (`data/`) take both from there (CLAUDE.md
7
+ * invariant 7).
8
+ */
9
+ export { endedBatchReport, queuedBatch, runningBatchReport, type BatchReport, type BatchStatus, type QueuedBatch, } from "./batches.js";
10
+ export { fetchExternalTaskErrorDetails, fetchJobStacktrace, readBatch, readProcessInstanceVariables, readTaskVariables, type VariableMap, } from "./reads.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine-contract/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,6BAA6B,EAC7B,kBAAkB,EAClB,SAAS,EACT,4BAA4B,EAC5B,iBAAiB,EACjB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The engine contract's SDK-bound half: the reads whose REST contract differs from the client
3
+ * defaults (text-only endpoints, raw variable reads, the batch fallback) and the batch status.
4
+ * The pure rules (dates, filters, sorting, variable writes, incident recovery) live in
5
+ * `@miragon/pulse-engine-core`; this package stays a leaf and does not import it. The engine
6
+ * module's tools (`tools/`) and widget feeds (`data/`) take both from there (CLAUDE.md
7
+ * invariant 7).
8
+ */
9
+ export { endedBatchReport, queuedBatch, runningBatchReport, } from "./batches.js";
10
+ export { fetchExternalTaskErrorDetails, fetchJobStacktrace, readBatch, readProcessInstanceVariables, readTaskVariables, } from "./reads.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engine-contract/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,kBAAkB,GAInB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,6BAA6B,EAC7B,kBAAkB,EAClB,SAAS,EACT,4BAA4B,EAC5B,iBAAiB,GAElB,MAAM,YAAY,CAAA"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Engine reads whose REST contract differs from the client defaults, the
3
+ * ONE place `tools/` and `data/` take them from, so no call site can forget
4
+ * the override:
5
+ *
6
+ * - Text endpoints (`/job/{id}/stacktrace`, `/external-task/{id}/errorDetails`)
7
+ * produce ONLY `text/plain` and answer the client's default
8
+ * `Accept: application/json` with a 406 before the resource runs.
9
+ * - Runtime variable reads default to `deserializeValues=true`: the engine
10
+ * then deserializes every Object variable eagerly (one class missing on its
11
+ * classpath fails the WHOLE read with a 500) and renders Json variables as
12
+ * Jackson's view of the Spin node instead of their JSON. With `false`,
13
+ * Object/Json/Xml values come back as their serialized string + `valueInfo`,
14
+ * exactly the shape a variable write takes back.
15
+ */
16
+ import type { Client } from "../generated/client/types.gen.js";
17
+ import type { VariableValueDto } from "../generated/types.gen.js";
18
+ import { type BatchReport } from "./batches.js";
19
+ export type VariableMap = Record<string, VariableValueDto>;
20
+ /**
21
+ * The exception stacktrace of a job; `null` when the job has none or no
22
+ * longer exists (404). Every other failure throws: the caller decides
23
+ * whether a missing stacktrace may degrade.
24
+ */
25
+ export declare function fetchJobStacktrace(client: Client, jobId: string): Promise<string | null>;
26
+ /**
27
+ * The error details a worker reported for an external task (its
28
+ * `failedExternalTask` stacktrace); `null` when there are none or the task no
29
+ * longer exists (404). Every other failure throws.
30
+ */
31
+ export declare function fetchExternalTaskErrorDetails(client: Client, externalTaskId: string): Promise<string | null>;
32
+ /** All variables of a process instance, serialized (see the module doc). */
33
+ export declare function readProcessInstanceVariables(client: Client, processInstanceId: string): Promise<VariableMap>;
34
+ /** All variables visible from a task, serialized (see the module doc). */
35
+ export declare function readTaskVariables(client: Client, taskId: string): Promise<VariableMap>;
36
+ /**
37
+ * Where a batch stands: the runtime statistics while it exists (counts incl.
38
+ * failed batch jobs), its history record once it ended. A batch neither
39
+ * holds is reported as an error: it never existed, or ended on an engine
40
+ * without batch history.
41
+ */
42
+ export declare function readBatch(client: Client, batchId: string): Promise<BatchReport>;
43
+ //# sourceMappingURL=reads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reads.d.ts","sourceRoot":"","sources":["../../src/engine-contract/reads.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAA;AAS9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAEjE,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAYrF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;AAiB1D;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO9F;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxB;AAED,4EAA4E;AAC5E,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,WAAW,CAAC,CAMtB;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAEtF;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAYrF"}
@@ -0,0 +1,86 @@
1
+ import { getBatchStatistics, getExternalTaskErrorDetails, getHistoricBatch, getProcessInstanceVariables, getStacktrace, getTaskVariables, } from "../generated/sdk.gen.js";
2
+ import { EngineRequestError } from "../engine-error.js";
3
+ import { endedBatchReport, runningBatchReport } from "./batches.js";
4
+ /** Request options for a `text/plain`-only endpoint. */
5
+ const TEXT_PLAIN = { parseAs: "text", headers: { Accept: "text/plain" } };
6
+ /**
7
+ * The query the variable reads send. The rule's home is engine-core's `RAW_VARIABLES`; this leaf
8
+ * does not import engine-core, so its SDK reads restate the flag (the engine connector's wire
9
+ * tests hold every variable read to `deserializeValues=false`).
10
+ */
11
+ const RAW_VARIABLES = { deserializeValues: false };
12
+ /**
13
+ * The client's "missing" rule: EVERY 404. Broader than engine-core's `isMissing`, which leaves
14
+ * out a 404 of the JAX-RS `NotFoundException` (no such endpoint: a wrong REST root) and of
15
+ * `QueryParamException`; so here a wrong REST root reads as "none". Kept as it is in a refactor:
16
+ * one rule for both is a behaviour change of its own.
17
+ */
18
+ function isAnyNotFound(error) {
19
+ return error instanceof EngineRequestError && error.httpStatus === 404;
20
+ }
21
+ /** Engine text, `null` for an empty body (204, or a resource without one). */
22
+ function textOrNull(text) {
23
+ return typeof text === "string" && text.length > 0 ? text : null;
24
+ }
25
+ /**
26
+ * The exception stacktrace of a job; `null` when the job has none or no
27
+ * longer exists (404). Every other failure throws: the caller decides
28
+ * whether a missing stacktrace may degrade.
29
+ */
30
+ export async function fetchJobStacktrace(client, jobId) {
31
+ try {
32
+ return textOrNull(await getStacktrace({ client, path: { id: jobId }, ...TEXT_PLAIN }));
33
+ }
34
+ catch (error) {
35
+ if (isAnyNotFound(error))
36
+ return null;
37
+ throw error;
38
+ }
39
+ }
40
+ /**
41
+ * The error details a worker reported for an external task (its
42
+ * `failedExternalTask` stacktrace); `null` when there are none or the task no
43
+ * longer exists (404). Every other failure throws.
44
+ */
45
+ export async function fetchExternalTaskErrorDetails(client, externalTaskId) {
46
+ try {
47
+ return textOrNull(await getExternalTaskErrorDetails({ client, path: { id: externalTaskId }, ...TEXT_PLAIN }));
48
+ }
49
+ catch (error) {
50
+ if (isAnyNotFound(error))
51
+ return null;
52
+ throw error;
53
+ }
54
+ }
55
+ /** All variables of a process instance, serialized (see the module doc). */
56
+ export function readProcessInstanceVariables(client, processInstanceId) {
57
+ return getProcessInstanceVariables({
58
+ client,
59
+ path: { id: processInstanceId },
60
+ query: RAW_VARIABLES,
61
+ });
62
+ }
63
+ /** All variables visible from a task, serialized (see the module doc). */
64
+ export function readTaskVariables(client, taskId) {
65
+ return getTaskVariables({ client, path: { id: taskId }, query: RAW_VARIABLES });
66
+ }
67
+ /**
68
+ * Where a batch stands: the runtime statistics while it exists (counts incl.
69
+ * failed batch jobs), its history record once it ended. A batch neither
70
+ * holds is reported as an error: it never existed, or ended on an engine
71
+ * without batch history.
72
+ */
73
+ export async function readBatch(client, batchId) {
74
+ const running = await getBatchStatistics({ client, query: { batchId } });
75
+ if (Array.isArray(running) && running[0])
76
+ return runningBatchReport(running[0]);
77
+ try {
78
+ return endedBatchReport(await getHistoricBatch({ client, path: { id: batchId } }));
79
+ }
80
+ catch (error) {
81
+ if (!isAnyNotFound(error))
82
+ throw error;
83
+ throw new Error(`Batch ${batchId} not found: no running batch has this id and the engine history holds no record of it`, { cause: error });
84
+ }
85
+ }
86
+ //# sourceMappingURL=reads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reads.js","sourceRoot":"","sources":["../../src/engine-contract/reads.ts"],"names":[],"mappings":"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"}