@mcpmesh/sdk 1.3.4 → 2.0.0-beta.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/dist/__tests__/a2a/a2a-bearer.spec.d.ts +2 -0
- package/dist/__tests__/a2a/a2a-bearer.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/a2a-bearer.spec.js +58 -0
- package/dist/__tests__/a2a/a2a-bearer.spec.js.map +1 -0
- package/dist/__tests__/a2a/a2a-client.spec.d.ts +2 -0
- package/dist/__tests__/a2a/a2a-client.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/a2a-client.spec.js +334 -0
- package/dist/__tests__/a2a/a2a-client.spec.js.map +1 -0
- package/dist/__tests__/a2a/a2a-job.spec.d.ts +2 -0
- package/dist/__tests__/a2a/a2a-job.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/a2a-job.spec.js +255 -0
- package/dist/__tests__/a2a/a2a-job.spec.js.map +1 -0
- package/dist/__tests__/a2a/a2a-stream.spec.d.ts +2 -0
- package/dist/__tests__/a2a/a2a-stream.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/a2a-stream.spec.js +278 -0
- package/dist/__tests__/a2a/a2a-stream.spec.js.map +1 -0
- package/dist/__tests__/a2a/agent-a2a-config.spec.d.ts +2 -0
- package/dist/__tests__/a2a/agent-a2a-config.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/agent-a2a-config.spec.js +262 -0
- package/dist/__tests__/a2a/agent-a2a-config.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/auth-filter.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/auth-filter.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/auth-filter.spec.js +127 -0
- package/dist/__tests__/a2a/producer/auth-filter.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/card-builder.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/card-builder.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/card-builder.spec.js +113 -0
- package/dist/__tests__/a2a/producer/card-builder.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/dispatcher.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/dispatcher.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/dispatcher.spec.js +850 -0
- package/dist/__tests__/a2a/producer/dispatcher.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/mount-surface-push.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/mount-surface-push.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/mount-surface-push.spec.js +164 -0
- package/dist/__tests__/a2a/producer/mount-surface-push.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/mount.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/mount.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/mount.spec.js +433 -0
- package/dist/__tests__/a2a/producer/mount.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/public-url-cache.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/public-url-cache.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/public-url-cache.spec.js +116 -0
- package/dist/__tests__/a2a/producer/public-url-cache.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/sse-emitter.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/sse-emitter.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/sse-emitter.spec.js +754 -0
- package/dist/__tests__/a2a/producer/sse-emitter.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/state-translator.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/state-translator.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/state-translator.spec.js +124 -0
- package/dist/__tests__/a2a/producer/state-translator.spec.js.map +1 -0
- package/dist/__tests__/a2a/producer/task-store.spec.d.ts +2 -0
- package/dist/__tests__/a2a/producer/task-store.spec.d.ts.map +1 -0
- package/dist/__tests__/a2a/producer/task-store.spec.js +180 -0
- package/dist/__tests__/a2a/producer/task-store.spec.js.map +1 -0
- package/dist/__tests__/agent-add-tool.spec.d.ts +2 -0
- package/dist/__tests__/agent-add-tool.spec.d.ts.map +1 -0
- package/dist/__tests__/agent-add-tool.spec.js +483 -0
- package/dist/__tests__/agent-add-tool.spec.js.map +1 -0
- package/dist/__tests__/api-runtime-race.spec.d.ts +2 -0
- package/dist/__tests__/api-runtime-race.spec.d.ts.map +1 -0
- package/dist/__tests__/api-runtime-race.spec.js +193 -0
- package/dist/__tests__/api-runtime-race.spec.js.map +1 -0
- package/dist/__tests__/claim-dispatcher.spec.d.ts +2 -0
- package/dist/__tests__/claim-dispatcher.spec.d.ts.map +1 -0
- package/dist/__tests__/claim-dispatcher.spec.js +408 -0
- package/dist/__tests__/claim-dispatcher.spec.js.map +1 -0
- package/dist/__tests__/inbound-job-dispatch.spec.d.ts +2 -0
- package/dist/__tests__/inbound-job-dispatch.spec.d.ts.map +1 -0
- package/dist/__tests__/inbound-job-dispatch.spec.js +185 -0
- package/dist/__tests__/inbound-job-dispatch.spec.js.map +1 -0
- package/dist/__tests__/job-controller-progress.spec.d.ts +2 -0
- package/dist/__tests__/job-controller-progress.spec.d.ts.map +1 -0
- package/dist/__tests__/job-controller-progress.spec.js +85 -0
- package/dist/__tests__/job-controller-progress.spec.js.map +1 -0
- package/dist/__tests__/jobs-cancel-route.spec.d.ts +2 -0
- package/dist/__tests__/jobs-cancel-route.spec.d.ts.map +1 -0
- package/dist/__tests__/jobs-cancel-route.spec.js +88 -0
- package/dist/__tests__/jobs-cancel-route.spec.js.map +1 -0
- package/dist/__tests__/llm-agent-stream.test.d.ts +14 -0
- package/dist/__tests__/llm-agent-stream.test.d.ts.map +1 -0
- package/dist/__tests__/llm-agent-stream.test.js +341 -0
- package/dist/__tests__/llm-agent-stream.test.js.map +1 -0
- package/dist/__tests__/llm-provider.test.js +22 -1
- package/dist/__tests__/llm-provider.test.js.map +1 -1
- package/dist/__tests__/media-resolver.test.js +40 -0
- package/dist/__tests__/media-resolver.test.js.map +1 -1
- package/dist/__tests__/mesh-job-submitter.spec.d.ts +2 -0
- package/dist/__tests__/mesh-job-submitter.spec.d.ts.map +1 -0
- package/dist/__tests__/mesh-job-submitter.spec.js +110 -0
- package/dist/__tests__/mesh-job-submitter.spec.js.map +1 -0
- package/dist/__tests__/proxy-stream.test.d.ts +9 -0
- package/dist/__tests__/proxy-stream.test.d.ts.map +1 -0
- package/dist/__tests__/proxy-stream.test.js +347 -0
- package/dist/__tests__/proxy-stream.test.js.map +1 -0
- package/dist/__tests__/resolver-meshjob.spec.d.ts +26 -0
- package/dist/__tests__/resolver-meshjob.spec.d.ts.map +1 -0
- package/dist/__tests__/resolver-meshjob.spec.js +201 -0
- package/dist/__tests__/resolver-meshjob.spec.js.map +1 -0
- package/dist/__tests__/schema-verdict-policy.test.d.ts +6 -0
- package/dist/__tests__/schema-verdict-policy.test.d.ts.map +1 -0
- package/dist/__tests__/schema-verdict-policy.test.js +126 -0
- package/dist/__tests__/schema-verdict-policy.test.js.map +1 -0
- package/dist/__tests__/sse-stream.test.d.ts +12 -0
- package/dist/__tests__/sse-stream.test.d.ts.map +1 -0
- package/dist/__tests__/sse-stream.test.js +170 -0
- package/dist/__tests__/sse-stream.test.js.map +1 -0
- package/dist/a2a/a2a-bearer.d.ts +27 -0
- package/dist/a2a/a2a-bearer.d.ts.map +1 -0
- package/dist/a2a/a2a-bearer.js +63 -0
- package/dist/a2a/a2a-bearer.js.map +1 -0
- package/dist/a2a/a2a-client.d.ts +114 -0
- package/dist/a2a/a2a-client.d.ts.map +1 -0
- package/dist/a2a/a2a-client.js +405 -0
- package/dist/a2a/a2a-client.js.map +1 -0
- package/dist/a2a/a2a-event.d.ts +25 -0
- package/dist/a2a/a2a-event.d.ts.map +1 -0
- package/dist/a2a/a2a-event.js +9 -0
- package/dist/a2a/a2a-event.js.map +1 -0
- package/dist/a2a/a2a-job.d.ts +58 -0
- package/dist/a2a/a2a-job.d.ts.map +1 -0
- package/dist/a2a/a2a-job.js +264 -0
- package/dist/a2a/a2a-job.js.map +1 -0
- package/dist/a2a/a2a-stream.d.ts +39 -0
- package/dist/a2a/a2a-stream.d.ts.map +1 -0
- package/dist/a2a/a2a-stream.js +290 -0
- package/dist/a2a/a2a-stream.js.map +1 -0
- package/dist/a2a/errors.d.ts +29 -0
- package/dist/a2a/errors.d.ts.map +1 -0
- package/dist/a2a/errors.js +48 -0
- package/dist/a2a/errors.js.map +1 -0
- package/dist/a2a/index.d.ts +12 -0
- package/dist/a2a/index.d.ts.map +1 -0
- package/dist/a2a/index.js +11 -0
- package/dist/a2a/index.js.map +1 -0
- package/dist/a2a/producer/auth-filter.d.ts +34 -0
- package/dist/a2a/producer/auth-filter.d.ts.map +1 -0
- package/dist/a2a/producer/auth-filter.js +39 -0
- package/dist/a2a/producer/auth-filter.js.map +1 -0
- package/dist/a2a/producer/card-builder.d.ts +59 -0
- package/dist/a2a/producer/card-builder.d.ts.map +1 -0
- package/dist/a2a/producer/card-builder.js +59 -0
- package/dist/a2a/producer/card-builder.js.map +1 -0
- package/dist/a2a/producer/dispatcher.d.ts +276 -0
- package/dist/a2a/producer/dispatcher.d.ts.map +1 -0
- package/dist/a2a/producer/dispatcher.js +896 -0
- package/dist/a2a/producer/dispatcher.js.map +1 -0
- package/dist/a2a/producer/index.d.ts +26 -0
- package/dist/a2a/producer/index.d.ts.map +1 -0
- package/dist/a2a/producer/index.js +23 -0
- package/dist/a2a/producer/index.js.map +1 -0
- package/dist/a2a/producer/mount.d.ts +75 -0
- package/dist/a2a/producer/mount.d.ts.map +1 -0
- package/dist/a2a/producer/mount.js +422 -0
- package/dist/a2a/producer/mount.js.map +1 -0
- package/dist/a2a/producer/public-url-cache.d.ts +73 -0
- package/dist/a2a/producer/public-url-cache.d.ts.map +1 -0
- package/dist/a2a/producer/public-url-cache.js +0 -0
- package/dist/a2a/producer/public-url-cache.js.map +1 -0
- package/dist/a2a/producer/registry.d.ts +138 -0
- package/dist/a2a/producer/registry.d.ts.map +1 -0
- package/dist/a2a/producer/registry.js +117 -0
- package/dist/a2a/producer/registry.js.map +1 -0
- package/dist/a2a/producer/sse-emitter.d.ts +85 -0
- package/dist/a2a/producer/sse-emitter.d.ts.map +1 -0
- package/dist/a2a/producer/sse-emitter.js +405 -0
- package/dist/a2a/producer/sse-emitter.js.map +1 -0
- package/dist/a2a/producer/state-translator.d.ts +63 -0
- package/dist/a2a/producer/state-translator.d.ts.map +1 -0
- package/dist/a2a/producer/state-translator.js +108 -0
- package/dist/a2a/producer/state-translator.js.map +1 -0
- package/dist/a2a/producer/task-store.d.ts +128 -0
- package/dist/a2a/producer/task-store.d.ts.map +1 -0
- package/dist/a2a/producer/task-store.js +128 -0
- package/dist/a2a/producer/task-store.js.map +1 -0
- package/dist/agent.d.ts +99 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +754 -19
- package/dist/agent.js.map +1 -1
- package/dist/api-runtime.d.ts +25 -0
- package/dist/api-runtime.d.ts.map +1 -1
- package/dist/api-runtime.js +75 -2
- package/dist/api-runtime.js.map +1 -1
- package/dist/claim-dispatcher.d.ts +126 -0
- package/dist/claim-dispatcher.d.ts.map +1 -0
- package/dist/claim-dispatcher.js +478 -0
- package/dist/claim-dispatcher.js.map +1 -0
- package/dist/express.d.ts.map +1 -1
- package/dist/express.js +33 -6
- package/dist/express.js.map +1 -1
- package/dist/inbound-job-dispatch.d.ts +105 -0
- package/dist/inbound-job-dispatch.d.ts.map +1 -0
- package/dist/inbound-job-dispatch.js +335 -0
- package/dist/inbound-job-dispatch.js.map +1 -0
- package/dist/index.d.ts +40 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -3
- package/dist/index.js.map +1 -1
- package/dist/job-context.d.ts +107 -0
- package/dist/job-context.d.ts.map +1 -0
- package/dist/job-context.js +95 -0
- package/dist/job-context.js.map +1 -0
- package/dist/jobs-cancel-route.d.ts +36 -0
- package/dist/jobs-cancel-route.d.ts.map +1 -0
- package/dist/jobs-cancel-route.js +60 -0
- package/dist/jobs-cancel-route.js.map +1 -0
- package/dist/jobs-helper-tools.d.ts +48 -0
- package/dist/jobs-helper-tools.d.ts.map +1 -0
- package/dist/jobs-helper-tools.js +133 -0
- package/dist/jobs-helper-tools.js.map +1 -0
- package/dist/llm-agent.d.ts +62 -53
- package/dist/llm-agent.d.ts.map +1 -1
- package/dist/llm-agent.js +211 -292
- package/dist/llm-agent.js.map +1 -1
- package/dist/llm-provider.d.ts +11 -4
- package/dist/llm-provider.d.ts.map +1 -1
- package/dist/llm-provider.js +57 -4
- package/dist/llm-provider.js.map +1 -1
- package/dist/llm.d.ts +4 -1
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +7 -17
- package/dist/llm.js.map +1 -1
- package/dist/media/resolver.d.ts.map +1 -1
- package/dist/media/resolver.js +3 -2
- package/dist/media/resolver.js.map +1 -1
- package/dist/mesh-job-submitter.d.ts +83 -0
- package/dist/mesh-job-submitter.d.ts.map +1 -0
- package/dist/mesh-job-submitter.js +143 -0
- package/dist/mesh-job-submitter.js.map +1 -0
- package/dist/provider-handlers/gemini-handler.js +5 -0
- package/dist/provider-handlers/gemini-handler.js.map +1 -1
- package/dist/proxy.d.ts +40 -0
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +375 -2
- package/dist/proxy.js.map +1 -1
- package/dist/resolver-meshjob.d.ts +170 -0
- package/dist/resolver-meshjob.d.ts.map +1 -0
- package/dist/resolver-meshjob.js +159 -0
- package/dist/resolver-meshjob.js.map +1 -0
- package/dist/route.d.ts +4 -0
- package/dist/route.d.ts.map +1 -1
- package/dist/route.js.map +1 -1
- package/dist/schema-normalize.d.ts +62 -0
- package/dist/schema-normalize.d.ts.map +1 -0
- package/dist/schema-normalize.js +128 -0
- package/dist/schema-normalize.js.map +1 -0
- package/dist/sse-stream.d.ts +44 -0
- package/dist/sse-stream.d.ts.map +1 -0
- package/dist/sse-stream.js +173 -0
- package/dist/sse-stream.js.map +1 -0
- package/dist/tool-worker-entry.d.ts +21 -0
- package/dist/tool-worker-entry.d.ts.map +1 -0
- package/dist/tool-worker-entry.js +162 -0
- package/dist/tool-worker-entry.js.map +1 -0
- package/dist/tool-worker-pool.d.ts +49 -0
- package/dist/tool-worker-pool.d.ts.map +1 -0
- package/dist/tool-worker-pool.js +272 -0
- package/dist/tool-worker-pool.js.map +1 -0
- package/dist/types.d.ts +351 -9
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for MeshJobSubmitter (Phase 1 — MeshJob substrate).
|
|
3
|
+
*
|
|
4
|
+
* We don't bind to a real registry here — the napi `submitJob` is
|
|
5
|
+
* mocked via vitest. The tests exercise:
|
|
6
|
+
*
|
|
7
|
+
* - The retry policy (3 attempts on transient errors with 200ms then
|
|
8
|
+
* 1s of backoff between attempts — 2 gaps for 3 attempts).
|
|
9
|
+
* - Fail-fast on non-transient errors (404 / 4xx / serialization).
|
|
10
|
+
* - Date → unix-epoch-seconds conversion for `totalDeadline`.
|
|
11
|
+
* - Number → unix-epoch-seconds normalisation (heuristic for
|
|
12
|
+
* callers that pass milliseconds).
|
|
13
|
+
*/
|
|
14
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
15
|
+
import { MeshJobSubmitter } from "../mesh-job-submitter.js";
|
|
16
|
+
// Mock napi-rs core's submit_job. Vitest hoists the factory above
|
|
17
|
+
// imports so the SDK reads the mock regardless of import order.
|
|
18
|
+
vi.mock("@mcpmesh/core", async () => {
|
|
19
|
+
const actual = await vi.importActual("@mcpmesh/core");
|
|
20
|
+
return {
|
|
21
|
+
...actual,
|
|
22
|
+
submitJob: vi.fn(),
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
import { submitJob } from "@mcpmesh/core";
|
|
26
|
+
const submitJobMock = submitJob;
|
|
27
|
+
describe("MeshJobSubmitter", () => {
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
submitJobMock.mockReset();
|
|
30
|
+
});
|
|
31
|
+
it("calls napi submitJob with the bound capability + payload", async () => {
|
|
32
|
+
submitJobMock.mockResolvedValueOnce({ jobId: "job-123" });
|
|
33
|
+
const sub = new MeshJobSubmitter("generate_report", "consumer-abc", "http://localhost:8000");
|
|
34
|
+
const proxy = await sub.submit({ user_id: "u1", sections: ["a"] });
|
|
35
|
+
expect(proxy).toEqual({ jobId: "job-123" });
|
|
36
|
+
expect(submitJobMock).toHaveBeenCalledOnce();
|
|
37
|
+
expect(submitJobMock).toHaveBeenCalledWith({
|
|
38
|
+
registryUrl: "http://localhost:8000",
|
|
39
|
+
capability: "generate_report",
|
|
40
|
+
payload: { user_id: "u1", sections: ["a"] },
|
|
41
|
+
submittedBy: "consumer-abc",
|
|
42
|
+
ownerInstanceId: undefined,
|
|
43
|
+
maxDuration: undefined,
|
|
44
|
+
maxRetries: undefined,
|
|
45
|
+
totalDeadline: undefined,
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
it("forwards optional knobs to napi submit", async () => {
|
|
49
|
+
submitJobMock.mockResolvedValueOnce({ jobId: "j" });
|
|
50
|
+
const sub = new MeshJobSubmitter("c", "by", "http://r");
|
|
51
|
+
const deadlineMs = 1735689600 * 1000; // 2025-01-01T00:00:00Z
|
|
52
|
+
await sub.submit({ foo: 1 }, {
|
|
53
|
+
maxDuration: 60,
|
|
54
|
+
maxRetries: 3,
|
|
55
|
+
totalDeadline: new Date(deadlineMs),
|
|
56
|
+
});
|
|
57
|
+
const call = submitJobMock.mock.calls[0][0];
|
|
58
|
+
expect(call.maxDuration).toBe(60);
|
|
59
|
+
expect(call.maxRetries).toBe(3);
|
|
60
|
+
expect(call.totalDeadline).toBe(1735689600);
|
|
61
|
+
});
|
|
62
|
+
it("normalises a millisecond-shaped number to seconds for totalDeadline", async () => {
|
|
63
|
+
submitJobMock.mockResolvedValueOnce({});
|
|
64
|
+
const sub = new MeshJobSubmitter("c", "by", "http://r");
|
|
65
|
+
await sub.submit({}, { totalDeadline: 1735689600_000 });
|
|
66
|
+
expect(submitJobMock.mock.calls[0][0].totalDeadline).toBe(1735689600);
|
|
67
|
+
});
|
|
68
|
+
it("passes seconds-shaped number through unchanged", async () => {
|
|
69
|
+
submitJobMock.mockResolvedValueOnce({});
|
|
70
|
+
const sub = new MeshJobSubmitter("c", "by", "http://r");
|
|
71
|
+
await sub.submit({}, { totalDeadline: 1735689600 });
|
|
72
|
+
expect(submitJobMock.mock.calls[0][0].totalDeadline).toBe(1735689600);
|
|
73
|
+
});
|
|
74
|
+
it("retries up to 3 times on a network error then succeeds", async () => {
|
|
75
|
+
submitJobMock
|
|
76
|
+
.mockRejectedValueOnce(new Error("backend error: network error: ECONNREFUSED"))
|
|
77
|
+
.mockRejectedValueOnce(new Error("backend error: network error: ECONNREFUSED"))
|
|
78
|
+
.mockResolvedValueOnce({ jobId: "ok" });
|
|
79
|
+
const sub = new MeshJobSubmitter("c", "by", "http://r");
|
|
80
|
+
const proxy = await sub.submit({});
|
|
81
|
+
expect(proxy).toEqual({ jobId: "ok" });
|
|
82
|
+
expect(submitJobMock).toHaveBeenCalledTimes(3);
|
|
83
|
+
});
|
|
84
|
+
it("fails-fast on a 4xx error (not transient)", async () => {
|
|
85
|
+
submitJobMock.mockRejectedValueOnce(new Error("backend error: backend error: HTTP 400: bad payload"));
|
|
86
|
+
const sub = new MeshJobSubmitter("c", "by", "http://r");
|
|
87
|
+
await expect(sub.submit({})).rejects.toThrow(/HTTP 400/);
|
|
88
|
+
expect(submitJobMock).toHaveBeenCalledOnce();
|
|
89
|
+
});
|
|
90
|
+
it("fails-fast on job-not-found (404)", async () => {
|
|
91
|
+
submitJobMock.mockRejectedValueOnce(new Error("backend error: job not found: abc"));
|
|
92
|
+
const sub = new MeshJobSubmitter("c", "by", "http://r");
|
|
93
|
+
await expect(sub.submit({})).rejects.toThrow(/not found/);
|
|
94
|
+
expect(submitJobMock).toHaveBeenCalledOnce();
|
|
95
|
+
});
|
|
96
|
+
it("propagates the last transient error after exhausting retries", async () => {
|
|
97
|
+
submitJobMock.mockRejectedValue(new Error("backend error: backend unavailable: 503"));
|
|
98
|
+
const sub = new MeshJobSubmitter("c", "by", "http://r");
|
|
99
|
+
await expect(sub.submit({})).rejects.toThrow(/backend unavailable/);
|
|
100
|
+
// 3 attempts total per the policy.
|
|
101
|
+
expect(submitJobMock).toHaveBeenCalledTimes(3);
|
|
102
|
+
}, 10_000);
|
|
103
|
+
it("rejects an invalid totalDeadline shape with a TypeError", async () => {
|
|
104
|
+
const sub = new MeshJobSubmitter("c", "by", "http://r");
|
|
105
|
+
await expect(
|
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
107
|
+
sub.submit({}, { totalDeadline: "not-a-date" })).rejects.toThrow(TypeError);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=mesh-job-submitter.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mesh-job-submitter.spec.js","sourceRoot":"","sources":["../../src/__tests__/mesh-job-submitter.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for streamMcpTool / proxy.stream() in proxy.ts
|
|
3
|
+
*
|
|
4
|
+
* Mocks ``fetch`` to return a Response whose body is a ReadableStream emitting
|
|
5
|
+
* hand-crafted SSE events (``notifications/progress`` followed by a final
|
|
6
|
+
* ``result``). Verifies the wire-protocol contract documented in #854.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=proxy-stream.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-stream.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/proxy-stream.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for streamMcpTool / proxy.stream() in proxy.ts
|
|
3
|
+
*
|
|
4
|
+
* Mocks ``fetch`` to return a Response whose body is a ReadableStream emitting
|
|
5
|
+
* hand-crafted SSE events (``notifications/progress`` followed by a final
|
|
6
|
+
* ``result``). Verifies the wire-protocol contract documented in #854.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
9
|
+
import { createProxy, streamMcpTool, DEFAULT_CALL_OPTIONS } from "../proxy.js";
|
|
10
|
+
// Mock @mcpmesh/core so trace injection / dispatcher pieces don't need a Rust build
|
|
11
|
+
vi.mock("@mcpmesh/core", () => ({
|
|
12
|
+
generateTraceId: () => "trace-mock",
|
|
13
|
+
generateSpanId: () => "span-mock",
|
|
14
|
+
injectTraceContext: (argsJson) => argsJson,
|
|
15
|
+
publishSpan: vi.fn(async () => false),
|
|
16
|
+
parseSseResponse: (s) => s,
|
|
17
|
+
parseSseResponseToObject: (s) => JSON.parse(s),
|
|
18
|
+
}));
|
|
19
|
+
vi.mock("../http-pool.js", () => ({
|
|
20
|
+
getDispatcher: () => undefined,
|
|
21
|
+
}));
|
|
22
|
+
/**
|
|
23
|
+
* Build a ReadableStream<Uint8Array> that emits the given SSE event blocks
|
|
24
|
+
* one chunk at a time. Each block should already include the trailing blank
|
|
25
|
+
* line per SSE spec.
|
|
26
|
+
*/
|
|
27
|
+
function makeSseStream(blocks) {
|
|
28
|
+
const encoder = new TextEncoder();
|
|
29
|
+
let i = 0;
|
|
30
|
+
return new ReadableStream({
|
|
31
|
+
pull(controller) {
|
|
32
|
+
if (i < blocks.length) {
|
|
33
|
+
controller.enqueue(encoder.encode(blocks[i]));
|
|
34
|
+
i += 1;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
controller.close();
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function sseEvent(payload) {
|
|
43
|
+
return `event: message\ndata: ${JSON.stringify(payload)}\n\n`;
|
|
44
|
+
}
|
|
45
|
+
function makeMockResponse(blocks, opts = {}) {
|
|
46
|
+
return {
|
|
47
|
+
ok: opts.ok ?? true,
|
|
48
|
+
status: opts.status ?? 200,
|
|
49
|
+
statusText: "OK",
|
|
50
|
+
body: makeSseStream(blocks),
|
|
51
|
+
headers: {
|
|
52
|
+
get: (name) => (name.toLowerCase() === "content-type" ? "text/event-stream" : null),
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const ENDPOINT = "http://producer.local:9000";
|
|
57
|
+
const TOOL = "stream_chunks";
|
|
58
|
+
const CAPABILITY = "streamer";
|
|
59
|
+
describe("streamMcpTool", () => {
|
|
60
|
+
let originalFetch;
|
|
61
|
+
beforeEach(() => {
|
|
62
|
+
originalFetch = globalThis.fetch;
|
|
63
|
+
});
|
|
64
|
+
afterEach(() => {
|
|
65
|
+
globalThis.fetch = originalFetch;
|
|
66
|
+
vi.restoreAllMocks();
|
|
67
|
+
});
|
|
68
|
+
it("yields each progress chunk in order", async () => {
|
|
69
|
+
let capturedBody;
|
|
70
|
+
const fetchMock = vi.fn(async (_url, init) => {
|
|
71
|
+
capturedBody = init.body;
|
|
72
|
+
const reqId = JSON.parse(capturedBody).id;
|
|
73
|
+
const token = JSON.parse(capturedBody).params._meta.progressToken;
|
|
74
|
+
return makeMockResponse([
|
|
75
|
+
sseEvent({
|
|
76
|
+
jsonrpc: "2.0",
|
|
77
|
+
method: "notifications/progress",
|
|
78
|
+
params: { progressToken: token, progress: 1, message: "alpha" },
|
|
79
|
+
}),
|
|
80
|
+
sseEvent({
|
|
81
|
+
jsonrpc: "2.0",
|
|
82
|
+
method: "notifications/progress",
|
|
83
|
+
params: { progressToken: token, progress: 2, message: "beta" },
|
|
84
|
+
}),
|
|
85
|
+
sseEvent({
|
|
86
|
+
jsonrpc: "2.0",
|
|
87
|
+
method: "notifications/progress",
|
|
88
|
+
params: { progressToken: token, progress: 3, message: "gamma" },
|
|
89
|
+
}),
|
|
90
|
+
sseEvent({ jsonrpc: "2.0", id: reqId, result: { content: [{ type: "text", text: "alphabetagamma" }] } }),
|
|
91
|
+
]);
|
|
92
|
+
});
|
|
93
|
+
globalThis.fetch = fetchMock;
|
|
94
|
+
const chunks = [];
|
|
95
|
+
for await (const chunk of streamMcpTool(ENDPOINT, TOOL, { foo: 1 }, DEFAULT_CALL_OPTIONS, CAPABILITY)) {
|
|
96
|
+
chunks.push(chunk);
|
|
97
|
+
}
|
|
98
|
+
expect(chunks).toEqual(["alpha", "beta", "gamma"]);
|
|
99
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
100
|
+
// Verify the request body has _meta.progressToken
|
|
101
|
+
const body = JSON.parse(capturedBody);
|
|
102
|
+
expect(body.method).toBe("tools/call");
|
|
103
|
+
expect(body.params.name).toBe(TOOL);
|
|
104
|
+
expect(typeof body.params._meta.progressToken).toBe("string");
|
|
105
|
+
expect(body.params._meta.progressToken.length).toBeGreaterThan(0);
|
|
106
|
+
// Verify Accept header
|
|
107
|
+
const headers = fetchMock.mock.calls[0][1].headers;
|
|
108
|
+
// FastMCP requires both content types in Accept (or it returns 406)
|
|
109
|
+
expect(headers["Accept"]).toBe("application/json, text/event-stream");
|
|
110
|
+
});
|
|
111
|
+
it("does not yield the final result message content", async () => {
|
|
112
|
+
const fetchMock = vi.fn(async (_url, init) => {
|
|
113
|
+
const body = JSON.parse(init.body);
|
|
114
|
+
return makeMockResponse([
|
|
115
|
+
sseEvent({
|
|
116
|
+
jsonrpc: "2.0",
|
|
117
|
+
method: "notifications/progress",
|
|
118
|
+
params: { progressToken: body.params._meta.progressToken, progress: 1, message: "only-chunk" },
|
|
119
|
+
}),
|
|
120
|
+
// Final result with content that must NOT be yielded
|
|
121
|
+
sseEvent({
|
|
122
|
+
jsonrpc: "2.0",
|
|
123
|
+
id: body.id,
|
|
124
|
+
result: { content: [{ type: "text", text: "FINAL-RESULT-DO-NOT-YIELD" }] },
|
|
125
|
+
}),
|
|
126
|
+
]);
|
|
127
|
+
});
|
|
128
|
+
globalThis.fetch = fetchMock;
|
|
129
|
+
const chunks = [];
|
|
130
|
+
for await (const chunk of streamMcpTool(ENDPOINT, TOOL, undefined, DEFAULT_CALL_OPTIONS, CAPABILITY)) {
|
|
131
|
+
chunks.push(chunk);
|
|
132
|
+
}
|
|
133
|
+
expect(chunks).toEqual(["only-chunk"]);
|
|
134
|
+
expect(chunks).not.toContain("FINAL-RESULT-DO-NOT-YIELD");
|
|
135
|
+
});
|
|
136
|
+
it("ignores progress notifications with a mismatched progressToken", async () => {
|
|
137
|
+
const fetchMock = vi.fn(async (_url, init) => {
|
|
138
|
+
const body = JSON.parse(init.body);
|
|
139
|
+
return makeMockResponse([
|
|
140
|
+
// Notification from a DIFFERENT in-flight call (unlikely but defensive)
|
|
141
|
+
sseEvent({
|
|
142
|
+
jsonrpc: "2.0",
|
|
143
|
+
method: "notifications/progress",
|
|
144
|
+
params: { progressToken: "some-other-token", progress: 1, message: "ignored" },
|
|
145
|
+
}),
|
|
146
|
+
sseEvent({
|
|
147
|
+
jsonrpc: "2.0",
|
|
148
|
+
method: "notifications/progress",
|
|
149
|
+
params: { progressToken: body.params._meta.progressToken, progress: 1, message: "kept" },
|
|
150
|
+
}),
|
|
151
|
+
sseEvent({ jsonrpc: "2.0", id: body.id, result: {} }),
|
|
152
|
+
]);
|
|
153
|
+
});
|
|
154
|
+
globalThis.fetch = fetchMock;
|
|
155
|
+
const chunks = [];
|
|
156
|
+
for await (const chunk of streamMcpTool(ENDPOINT, TOOL, undefined, DEFAULT_CALL_OPTIONS, CAPABILITY)) {
|
|
157
|
+
chunks.push(chunk);
|
|
158
|
+
}
|
|
159
|
+
expect(chunks).toEqual(["kept"]);
|
|
160
|
+
});
|
|
161
|
+
it("throws when the JSON-RPC final message contains an error", async () => {
|
|
162
|
+
const fetchMock = vi.fn(async (_url, init) => {
|
|
163
|
+
const body = JSON.parse(init.body);
|
|
164
|
+
return makeMockResponse([
|
|
165
|
+
sseEvent({
|
|
166
|
+
jsonrpc: "2.0",
|
|
167
|
+
method: "notifications/progress",
|
|
168
|
+
params: { progressToken: body.params._meta.progressToken, progress: 1, message: "partial" },
|
|
169
|
+
}),
|
|
170
|
+
sseEvent({
|
|
171
|
+
jsonrpc: "2.0",
|
|
172
|
+
id: body.id,
|
|
173
|
+
error: { code: -32000, message: "tool blew up" },
|
|
174
|
+
}),
|
|
175
|
+
]);
|
|
176
|
+
});
|
|
177
|
+
globalThis.fetch = fetchMock;
|
|
178
|
+
const collect = async () => {
|
|
179
|
+
const out = [];
|
|
180
|
+
for await (const chunk of streamMcpTool(ENDPOINT, TOOL, undefined, DEFAULT_CALL_OPTIONS, CAPABILITY)) {
|
|
181
|
+
out.push(chunk);
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
};
|
|
185
|
+
await expect(collect()).rejects.toThrow(/tool blew up/);
|
|
186
|
+
});
|
|
187
|
+
it("throws on non-2xx HTTP response", async () => {
|
|
188
|
+
const fetchMock = vi.fn(async () => {
|
|
189
|
+
return {
|
|
190
|
+
ok: false,
|
|
191
|
+
status: 503,
|
|
192
|
+
statusText: "Service Unavailable",
|
|
193
|
+
body: makeSseStream([]),
|
|
194
|
+
headers: { get: () => null },
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
globalThis.fetch = fetchMock;
|
|
198
|
+
const collect = async () => {
|
|
199
|
+
for await (const _ of streamMcpTool(ENDPOINT, TOOL, undefined, DEFAULT_CALL_OPTIONS, CAPABILITY)) {
|
|
200
|
+
// no-op
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
await expect(collect()).rejects.toThrow(/503 Service Unavailable/);
|
|
204
|
+
});
|
|
205
|
+
it("releases the underlying reader when the consumer breaks early", async () => {
|
|
206
|
+
let reader;
|
|
207
|
+
const fetchMock = vi.fn(async (_url, init) => {
|
|
208
|
+
const body = JSON.parse(init.body);
|
|
209
|
+
const stream = makeSseStream([
|
|
210
|
+
sseEvent({
|
|
211
|
+
jsonrpc: "2.0",
|
|
212
|
+
method: "notifications/progress",
|
|
213
|
+
params: { progressToken: body.params._meta.progressToken, progress: 1, message: "first" },
|
|
214
|
+
}),
|
|
215
|
+
sseEvent({
|
|
216
|
+
jsonrpc: "2.0",
|
|
217
|
+
method: "notifications/progress",
|
|
218
|
+
params: { progressToken: body.params._meta.progressToken, progress: 2, message: "second" },
|
|
219
|
+
}),
|
|
220
|
+
sseEvent({ jsonrpc: "2.0", id: body.id, result: {} }),
|
|
221
|
+
]);
|
|
222
|
+
// Wrap stream so we can spy on the reader after getReader is called
|
|
223
|
+
const origGetReader = stream.getReader.bind(stream);
|
|
224
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
225
|
+
stream.getReader = function (...rargs) {
|
|
226
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
227
|
+
reader = origGetReader(...rargs);
|
|
228
|
+
return reader;
|
|
229
|
+
};
|
|
230
|
+
return {
|
|
231
|
+
ok: true,
|
|
232
|
+
status: 200,
|
|
233
|
+
statusText: "OK",
|
|
234
|
+
body: stream,
|
|
235
|
+
headers: { get: () => "text/event-stream" },
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
globalThis.fetch = fetchMock;
|
|
239
|
+
const iter = streamMcpTool(ENDPOINT, TOOL, undefined, DEFAULT_CALL_OPTIONS, CAPABILITY);
|
|
240
|
+
const out = [];
|
|
241
|
+
for await (const chunk of iter) {
|
|
242
|
+
out.push(chunk);
|
|
243
|
+
// Break on first chunk
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
expect(out).toEqual(["first"]);
|
|
247
|
+
// Wait a tick so finally{} can run
|
|
248
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
249
|
+
expect(reader).toBeDefined();
|
|
250
|
+
// After cancel(), reads should resolve with done:true
|
|
251
|
+
const post = await reader.read();
|
|
252
|
+
expect(post.done).toBe(true);
|
|
253
|
+
});
|
|
254
|
+
it("yields nothing when the producer emits no progress notifications (TS soft-fallback skipped)", async () => {
|
|
255
|
+
// Per #854: TS Stage 1 does NOT implement Python's soft-fallback. If the
|
|
256
|
+
// producer didn't emit progress, the iterable yields nothing.
|
|
257
|
+
const fetchMock = vi.fn(async (_url, init) => {
|
|
258
|
+
const body = JSON.parse(init.body);
|
|
259
|
+
return makeMockResponse([
|
|
260
|
+
sseEvent({
|
|
261
|
+
jsonrpc: "2.0",
|
|
262
|
+
id: body.id,
|
|
263
|
+
result: { content: [{ type: "text", text: "buffered final" }] },
|
|
264
|
+
}),
|
|
265
|
+
]);
|
|
266
|
+
});
|
|
267
|
+
globalThis.fetch = fetchMock;
|
|
268
|
+
const out = [];
|
|
269
|
+
for await (const chunk of streamMcpTool(ENDPOINT, TOOL, undefined, DEFAULT_CALL_OPTIONS, CAPABILITY)) {
|
|
270
|
+
out.push(chunk);
|
|
271
|
+
}
|
|
272
|
+
expect(out).toEqual([]);
|
|
273
|
+
});
|
|
274
|
+
it("handles SSE events split across multiple network chunks", async () => {
|
|
275
|
+
// Split a single SSE event in the middle of its payload to verify the
|
|
276
|
+
// \n\n boundary parser correctly buffers partial reads.
|
|
277
|
+
const fetchMock = vi.fn(async (_url, init) => {
|
|
278
|
+
const body = JSON.parse(init.body);
|
|
279
|
+
const ev1 = sseEvent({
|
|
280
|
+
jsonrpc: "2.0",
|
|
281
|
+
method: "notifications/progress",
|
|
282
|
+
params: { progressToken: body.params._meta.progressToken, progress: 1, message: "one" },
|
|
283
|
+
});
|
|
284
|
+
const ev2 = sseEvent({
|
|
285
|
+
jsonrpc: "2.0",
|
|
286
|
+
method: "notifications/progress",
|
|
287
|
+
params: { progressToken: body.params._meta.progressToken, progress: 2, message: "two" },
|
|
288
|
+
});
|
|
289
|
+
const final = sseEvent({ jsonrpc: "2.0", id: body.id, result: {} });
|
|
290
|
+
const all = ev1 + ev2 + final;
|
|
291
|
+
const mid = Math.floor(all.length / 2);
|
|
292
|
+
return makeMockResponse([all.slice(0, mid), all.slice(mid)]);
|
|
293
|
+
});
|
|
294
|
+
globalThis.fetch = fetchMock;
|
|
295
|
+
const out = [];
|
|
296
|
+
for await (const chunk of streamMcpTool(ENDPOINT, TOOL, undefined, DEFAULT_CALL_OPTIONS, CAPABILITY)) {
|
|
297
|
+
out.push(chunk);
|
|
298
|
+
}
|
|
299
|
+
expect(out).toEqual(["one", "two"]);
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
describe("createProxy.stream() integration", () => {
|
|
303
|
+
let originalFetch;
|
|
304
|
+
beforeEach(() => {
|
|
305
|
+
originalFetch = globalThis.fetch;
|
|
306
|
+
});
|
|
307
|
+
afterEach(() => {
|
|
308
|
+
globalThis.fetch = originalFetch;
|
|
309
|
+
vi.restoreAllMocks();
|
|
310
|
+
});
|
|
311
|
+
it("attaches a non-enumerable stream method that yields progress chunks", async () => {
|
|
312
|
+
const fetchMock = vi.fn(async (_url, init) => {
|
|
313
|
+
const body = JSON.parse(init.body);
|
|
314
|
+
const token = body.params._meta.progressToken;
|
|
315
|
+
return makeMockResponse([
|
|
316
|
+
sseEvent({
|
|
317
|
+
jsonrpc: "2.0",
|
|
318
|
+
method: "notifications/progress",
|
|
319
|
+
params: { progressToken: token, progress: 1, message: "x" },
|
|
320
|
+
}),
|
|
321
|
+
sseEvent({
|
|
322
|
+
jsonrpc: "2.0",
|
|
323
|
+
method: "notifications/progress",
|
|
324
|
+
params: { progressToken: token, progress: 2, message: "y" },
|
|
325
|
+
}),
|
|
326
|
+
sseEvent({ jsonrpc: "2.0", id: body.id, result: {} }),
|
|
327
|
+
]);
|
|
328
|
+
});
|
|
329
|
+
globalThis.fetch = fetchMock;
|
|
330
|
+
const proxy = createProxy(ENDPOINT, CAPABILITY, TOOL);
|
|
331
|
+
expect(typeof proxy.stream).toBe("function");
|
|
332
|
+
// Non-enumerable: JSON.stringify on a function returns undefined entirely,
|
|
333
|
+
// which is the strongest possible guarantee that no internal field leaks.
|
|
334
|
+
// Also verify the property descriptor is non-enumerable explicitly.
|
|
335
|
+
const json = JSON.stringify(proxy);
|
|
336
|
+
expect(json).toBeUndefined();
|
|
337
|
+
const desc = Object.getOwnPropertyDescriptor(proxy, "stream");
|
|
338
|
+
expect(desc).toBeDefined();
|
|
339
|
+
expect(desc?.enumerable).toBe(false);
|
|
340
|
+
const chunks = [];
|
|
341
|
+
for await (const chunk of proxy.stream({ foo: "bar" })) {
|
|
342
|
+
chunks.push(chunk);
|
|
343
|
+
}
|
|
344
|
+
expect(chunks).toEqual(["x", "y"]);
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
//# sourceMappingURL=proxy-stream.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-stream.test.js","sourceRoot":"","sources":["../../src/__tests__/proxy-stream.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DDDI resolver tests for the `MeshJob` injectable (Phase 1).
|
|
3
|
+
*
|
|
4
|
+
* These tests are the TypeScript instance of the cross-runtime test
|
|
5
|
+
* seam specified in `MESHJOB_DDDI_CONTRACT.md` → "Equivalence across
|
|
6
|
+
* SDKs". The same scenarios MUST be covered by the Python and Java
|
|
7
|
+
* SDKs in their corresponding files
|
|
8
|
+
* (`tests/test_resolver_meshjob.py` and `MeshJobResolverTest.java`).
|
|
9
|
+
*
|
|
10
|
+
* If any behaviour here changes, update the contract first, then
|
|
11
|
+
* mirror across both other SDK test files. Each numbered scenario maps
|
|
12
|
+
* to the checklist in the contract document.
|
|
13
|
+
*
|
|
14
|
+
* # TS-shape note
|
|
15
|
+
*
|
|
16
|
+
* Python's resolver classifies parameters by reflection on
|
|
17
|
+
* `inspect.signature` + `typing.get_type_hints`. TypeScript erases
|
|
18
|
+
* types at runtime, so the TS resolver's input is the explicit
|
|
19
|
+
* `addTool({ dependencies, meshJobParamIndex })` declaration. The
|
|
20
|
+
* scenarios below translate the contract's signature-shape examples
|
|
21
|
+
* into the equivalent declarative form, then assert the same
|
|
22
|
+
* `meshToolDeps[*].signaturePosition` and `meshJobParamIndex` outputs
|
|
23
|
+
* the contract requires.
|
|
24
|
+
*/
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=resolver-meshjob.spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver-meshjob.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/resolver-meshjob.spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG"}
|