@ledgerhq/device-mockserver-client 0.0.0-develop-20260825075721 → 0.0.0-develop-20260827155839
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/lib/cjs/package.json +1 -1
- package/lib/cjs/src/DmkNetworkClient.stub.js +1 -1
- package/lib/cjs/src/DmkNetworkClient.stub.js.map +3 -3
- package/lib/cjs/src/MockClient.js +1 -1
- package/lib/cjs/src/MockClient.js.map +3 -3
- package/lib/cjs/src/MockClient.test.js +1 -1
- package/lib/cjs/src/MockClient.test.js.map +3 -3
- package/lib/cjs/src/index.js +1 -1
- package/lib/cjs/src/index.js.map +1 -1
- package/lib/cjs/src/model/Speculos.js +1 -1
- package/lib/cjs/src/model/Speculos.js.map +1 -1
- package/lib/esm/package.json +1 -1
- package/lib/esm/src/DmkNetworkClient.stub.js +1 -1
- package/lib/esm/src/DmkNetworkClient.stub.js.map +3 -3
- package/lib/esm/src/MockClient.js +1 -1
- package/lib/esm/src/MockClient.js.map +3 -3
- package/lib/esm/src/MockClient.test.js +1 -1
- package/lib/esm/src/MockClient.test.js.map +3 -3
- package/lib/esm/src/index.js +1 -1
- package/lib/esm/src/index.js.map +1 -1
- package/lib/esm/src/model/Speculos.js +1 -1
- package/lib/esm/src/model/Speculos.js.map +1 -1
- package/lib/types/src/DmkNetworkClient.stub.d.ts +7 -1
- package/lib/types/src/DmkNetworkClient.stub.d.ts.map +1 -1
- package/lib/types/src/MockClient.d.ts +11 -1
- package/lib/types/src/MockClient.d.ts.map +1 -1
- package/lib/types/src/index.d.ts +1 -1
- package/lib/types/src/index.d.ts.map +1 -1
- package/lib/types/src/model/Speculos.d.ts +7 -0
- package/lib/types/src/model/Speculos.d.ts.map +1 -1
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
- package/package.json +5 -5
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{httpClientStubBuilder as s}from"./DmkNetworkClient.stub";import{MockClient as n}from"./MockClient";const i=(e={})=>({id:"dev-1",name:"Ledger Nano X",device_type:"nanoX",connectivity_type:"USB",...e});describe("MockClient",()=>{describe("authentication",()=>{it("lazily creates a session via /auth when no token is provided",async()=>{const e=s().mockResponse({method:"post",endpoint:"auth",response:{token:"tok-123",expires_at:42}}).mockResponse({method:"get",endpoint:"devices",response:[]}),t=new n("http://localhost:8080",{httpClient:e}),o=await t.listDevices();expect(t.getToken()).toBe("tok-123"),expect(e.calls).toContainEqual({method:"post",endpoint:"auth",body:{}}),expect(o).toEqual([])}),it("does not call /auth when a token is injected",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices",response:[]}),t=new n("http://localhost:8080",{token:"injected",httpClient:e});await t.listDevices(),expect(t.getToken()).toBe("injected"),expect(e.calls.find(o=>o.endpoint==="auth")).toBeUndefined()}),it("returns the token from an explicit authenticate() call",async()=>{const e=s().mockResponse({method:"post",endpoint:"auth",response:{token:"tok-abc",expires_at:99}}),t=new n("http://localhost:8080",{httpClient:e}),o=await t.authenticate();expect(o).toBe("tok-abc"),expect(t.getToken()).toBe("tok-abc")}),it("reuses a single in-flight /auth call for concurrent requests",async()=>{const e=s().mockResponse({method:"post",endpoint:"auth",response:{token:"tok-shared",expires_at:1}}).mockResponse({method:"get",endpoint:"devices",response:[]}),t=new n("http://localhost:8080",{httpClient:e});await Promise.all([t.listDevices(),t.listDevices()]);const o=e.calls.filter(c=>c.endpoint==="auth");expect(o).toHaveLength(1)}),it("returns undefined token before any session is established",()=>{const e=new n("http://localhost:8080",{httpClient:s()});expect(e.getToken()).toBeUndefined()})}),describe("constructor",()=>{it("normalizes a base url without a trailing slash",()=>{const e=new n("http://localhost:8080/"),t=new n("http://localhost:8080");expect(e.getToken()).toBeUndefined(),expect(t.getToken()).toBeUndefined()})}),describe("devices",()=>{it("lists devices",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices",response:[i()]}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).listDevices();expect(o).toEqual([expect.objectContaining({id:"dev-1"})])}),it("adds a device with a default empty config",async()=>{const e=s().mockResponse({method:"post",endpoint:"devices",response:i()}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).addDevice();expect(o.id).toBe("dev-1"),expect(e.calls).toContainEqual({method:"post",endpoint:"devices",body:{}})}),it("gets a single device",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices/dev-1",response:i()}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).getDevice("dev-1");expect(o.id).toBe("dev-1")}),it("edits a device",async()=>{const e=s().mockResponse({method:"patch",endpoint:"devices/dev-1",response:i({name:"Renamed"})}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).editDevice("dev-1",{name:"Renamed"});expect(o.name).toBe("Renamed"),expect(e.calls).toContainEqual({method:"patch",endpoint:"devices/dev-1",body:{name:"Renamed"}})}),it("deletes a device",async()=>{const e=s().mockResponse({method:"delete",endpoint:"devices/dev-1",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.deleteDevice("dev-1")).resolves.toBe(!0),expect(e.calls).toContainEqual({method:"delete",endpoint:"devices/dev-1"})})}),describe("connection state",()=>{it("connects a device",async()=>{const e=s().mockResponse({method:"post",endpoint:"devices/dev-1/connect",response:{device:i(),connected:!0}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).connect("dev-1");expect(o.connected).toBe(!0),expect(o.device.id).toBe("dev-1")}),it("disconnects a device",async()=>{const e=s().mockResponse({method:"post",endpoint:"devices/dev-1/disconnect",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.disconnect("dev-1")).resolves.toBe(!0)}),it("disconnects every connected device",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices",response:[i({id:"dev-1",connected:!0}),i({id:"dev-2",connected:!1}),i({id:"dev-3",connected:!0})]}).mockResponse({method:"post",endpoint:"devices/dev-1/disconnect",response:{}}).mockResponse({method:"post",endpoint:"devices/dev-3/disconnect",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.disconnectAll()).resolves.toBe(!0);const o=e.calls.filter(c=>c.endpoint.endsWith("/disconnect"));expect(o.map(c=>c.endpoint)).toEqual(["devices/dev-1/disconnect","devices/dev-3/disconnect"])})}),describe("mocks",()=>{it("lists device-scoped mocks",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices/dev-1/mocks",response:[{id:"m1",prefix:"e0010000",responses:["9000"]}]}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).listMocks("dev-1");expect(o).toEqual([expect.objectContaining({id:"m1"})])}),it("creates a device-scoped mock",async()=>{const e=s().mockResponse({method:"post",endpoint:"devices/dev-1/mocks",response:{id:"m1",prefix:"e0010000",responses:["9000"]}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).addMock("dev-1",{prefix:"e0010000",response:"9000"});expect(o.id).toBe("m1"),expect(e.calls).toContainEqual({method:"post",endpoint:"devices/dev-1/mocks",body:{prefix:"e0010000",response:"9000"}})}),it("edits a mock",async()=>{const e=s().mockResponse({method:"patch",endpoint:"devices/dev-1/mocks/m1",response:{id:"m1",prefix:"e0010000",responses:["6985"]}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).editMock("dev-1","m1",{prefix:"e0010000",response:"6985"});expect(o.responses).toEqual(["6985"]),expect(e.calls).toContainEqual({method:"patch",endpoint:"devices/dev-1/mocks/m1",body:{prefix:"e0010000",response:"6985"}})}),it("deletes a single mock",async()=>{const e=s().mockResponse({method:"delete",endpoint:"devices/dev-1/mocks/m1",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.deleteMock("dev-1","m1")).resolves.toBe(!0),expect(e.calls).toContainEqual({method:"delete",endpoint:"devices/dev-1/mocks/m1"})}),it("clears all mocks of a device",async()=>{const e=s().mockResponse({method:"delete",endpoint:"devices/dev-1/mocks",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.clearMocks("dev-1")).resolves.toBe(!0),expect(e.calls).toContainEqual({method:"delete",endpoint:"devices/dev-1/mocks"})})}),describe("speculos",()=>{it("resolves the live speculos instance backing a device",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices/dev-1/speculos",response:{run_id:"run-1",speculos_url:"https://speculos:5000",model:"stax"}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).getSpeculos("dev-1");expect(o).toEqual({run_id:"run-1",speculos_url:"https://speculos:5000",model:"stax"})})}),describe("session",()=>{it("fetches the current session",async()=>{const e=s().mockResponse({method:"get",endpoint:"sessions/current",response:{id:"sess-1",created_at:1,expires_at:2,devices:[i()]}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).getSession();expect(o.id).toBe("sess-1"),expect(o.devices).toHaveLength(1)}),it("disposes the session and clears the stored token",async()=>{const e=s().mockResponse({method:"delete",endpoint:"sessions/current",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.disposeSession()).resolves.toBe(!0),expect(t.getToken()).toBeUndefined()})}),describe("response validation",()=>{it("throws a descriptive error when the server response is malformed",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices/dev-1",response:{id:123}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.getDevice("dev-1")).rejects.toThrow(/MockClient: invalid server response/)})}),describe("import/export",()=>{it("exports the session snapshot",async()=>{const e={devices:[{name:"Ledger Stax",device_type:"stax",mocks:[{prefix:"ff",responses:["9000"]}]}]},t=s().mockResponse({method:"get",endpoint:"export",response:e}),c=await new n("http://localhost:8080",{token:"tok",httpClient:t}).exportSession();expect(c).toEqual(e)}),it("posts a snapshot to the import endpoint",async()=>{const e={devices:[{name:"Ledger Flex",device_type:"flex",mocks:[{prefix:"e0010000",responses:["aa9000","5515"]}]}]},t=s().mockResponse({method:"post",endpoint:"import",response:e}),c=await new n("http://localhost:8080",{token:"tok",httpClient:t}).importSession(e);expect(c).toEqual(e),expect(t.calls).toContainEqual({method:"post",endpoint:"import",body:e})})}),describe("apdu",()=>{it("sends a binary APDU as hex to the device apdu endpoint",async()=>{const e=s().mockResponse({method:"post",endpoint:"devices/dev-1/apdu",response:{response:"9000"}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).sendApdu("dev-1",Uint8Array.from([224,1,0,0]));expect(o.response).toBe("9000"),expect(e.calls).toContainEqual({method:"post",endpoint:"devices/dev-1/apdu",body:{apdu:"e0010000"}})})})});
|
|
1
|
+
import{httpClientStubBuilder as s}from"./DmkNetworkClient.stub";import{MockClient as n}from"./MockClient";const i=(e={})=>({id:"dev-1",name:"Ledger Nano X",device_type:"nanoX",connectivity_type:"USB",...e});describe("MockClient",()=>{describe("authentication",()=>{it("lazily creates a session via /auth when no token is provided",async()=>{const e=s().mockResponse({method:"post",endpoint:"auth",response:{token:"tok-123",expires_at:42}}).mockResponse({method:"get",endpoint:"devices",response:[]}),t=new n("http://localhost:8080",{httpClient:e}),o=await t.listDevices();expect(t.getToken()).toBe("tok-123"),expect(e.calls).toContainEqual({method:"post",endpoint:"auth",body:{}}),expect(o).toEqual([])}),it("does not call /auth when a token is injected",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices",response:[]}),t=new n("http://localhost:8080",{token:"injected",httpClient:e});await t.listDevices(),expect(t.getToken()).toBe("injected"),expect(e.calls.find(o=>o.endpoint==="auth")).toBeUndefined()}),it("returns the token from an explicit authenticate() call",async()=>{const e=s().mockResponse({method:"post",endpoint:"auth",response:{token:"tok-abc",expires_at:99}}),t=new n("http://localhost:8080",{httpClient:e}),o=await t.authenticate();expect(o).toBe("tok-abc"),expect(t.getToken()).toBe("tok-abc")}),it("reuses a single in-flight /auth call for concurrent requests",async()=>{const e=s().mockResponse({method:"post",endpoint:"auth",response:{token:"tok-shared",expires_at:1}}).mockResponse({method:"get",endpoint:"devices",response:[]}),t=new n("http://localhost:8080",{httpClient:e});await Promise.all([t.listDevices(),t.listDevices()]);const o=e.calls.filter(c=>c.endpoint==="auth");expect(o).toHaveLength(1)}),it("returns undefined token before any session is established",()=>{const e=new n("http://localhost:8080",{httpClient:s()});expect(e.getToken()).toBeUndefined()})}),describe("constructor",()=>{it("normalizes a base url without a trailing slash",()=>{const e=new n("http://localhost:8080/"),t=new n("http://localhost:8080");expect(e.getToken()).toBeUndefined(),expect(t.getToken()).toBeUndefined()})}),describe("devices",()=>{it("lists devices",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices",response:[i()]}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).listDevices();expect(o).toEqual([expect.objectContaining({id:"dev-1"})])}),it("adds a device with a default empty config",async()=>{const e=s().mockResponse({method:"post",endpoint:"devices",response:i()}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).addDevice();expect(o.id).toBe("dev-1"),expect(e.calls).toContainEqual({method:"post",endpoint:"devices",body:{}})}),it("gets a single device",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices/dev-1",response:i()}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).getDevice("dev-1");expect(o.id).toBe("dev-1")}),it("edits a device",async()=>{const e=s().mockResponse({method:"patch",endpoint:"devices/dev-1",response:i({name:"Renamed"})}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).editDevice("dev-1",{name:"Renamed"});expect(o.name).toBe("Renamed"),expect(e.calls).toContainEqual({method:"patch",endpoint:"devices/dev-1",body:{name:"Renamed"}})}),it("deletes a device",async()=>{const e=s().mockResponse({method:"delete",endpoint:"devices/dev-1",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.deleteDevice("dev-1")).resolves.toBe(!0),expect(e.calls).toContainEqual({method:"delete",endpoint:"devices/dev-1"})})}),describe("connection state",()=>{it("connects a device",async()=>{const e=s().mockResponse({method:"post",endpoint:"devices/dev-1/connect",response:{device:i(),connected:!0}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).connect("dev-1");expect(o.connected).toBe(!0),expect(o.device.id).toBe("dev-1")}),it("disconnects a device",async()=>{const e=s().mockResponse({method:"post",endpoint:"devices/dev-1/disconnect",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.disconnect("dev-1")).resolves.toBe(!0)}),it("disconnects every connected device",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices",response:[i({id:"dev-1",connected:!0}),i({id:"dev-2",connected:!1}),i({id:"dev-3",connected:!0})]}).mockResponse({method:"post",endpoint:"devices/dev-1/disconnect",response:{}}).mockResponse({method:"post",endpoint:"devices/dev-3/disconnect",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.disconnectAll()).resolves.toBe(!0);const o=e.calls.filter(c=>c.endpoint.endsWith("/disconnect"));expect(o.map(c=>c.endpoint)).toEqual(["devices/dev-1/disconnect","devices/dev-3/disconnect"])})}),describe("mocks",()=>{it("lists device-scoped mocks",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices/dev-1/mocks",response:[{id:"m1",prefix:"e0010000",responses:["9000"]}]}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).listMocks("dev-1");expect(o).toEqual([expect.objectContaining({id:"m1"})])}),it("creates a device-scoped mock",async()=>{const e=s().mockResponse({method:"post",endpoint:"devices/dev-1/mocks",response:{id:"m1",prefix:"e0010000",responses:["9000"]}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).addMock("dev-1",{prefix:"e0010000",response:"9000"});expect(o.id).toBe("m1"),expect(e.calls).toContainEqual({method:"post",endpoint:"devices/dev-1/mocks",body:{prefix:"e0010000",response:"9000"}})}),it("edits a mock",async()=>{const e=s().mockResponse({method:"patch",endpoint:"devices/dev-1/mocks/m1",response:{id:"m1",prefix:"e0010000",responses:["6985"]}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).editMock("dev-1","m1",{prefix:"e0010000",response:"6985"});expect(o.responses).toEqual(["6985"]),expect(e.calls).toContainEqual({method:"patch",endpoint:"devices/dev-1/mocks/m1",body:{prefix:"e0010000",response:"6985"}})}),it("deletes a single mock",async()=>{const e=s().mockResponse({method:"delete",endpoint:"devices/dev-1/mocks/m1",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.deleteMock("dev-1","m1")).resolves.toBe(!0),expect(e.calls).toContainEqual({method:"delete",endpoint:"devices/dev-1/mocks/m1"})}),it("clears all mocks of a device",async()=>{const e=s().mockResponse({method:"delete",endpoint:"devices/dev-1/mocks",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.clearMocks("dev-1")).resolves.toBe(!0),expect(e.calls).toContainEqual({method:"delete",endpoint:"devices/dev-1/mocks"})})}),describe("speculos",()=>{it("resolves the live speculos instance backing a device",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices/dev-1/speculos",response:{run_id:"run-1",speculos_url:"https://speculos:5000",model:"stax"}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).getSpeculos("dev-1");expect(o).toEqual({run_id:"run-1",speculos_url:"https://speculos:5000",model:"stax"})}),it("requests the screenshot as a blob",async()=>{const e=new Blob([new Uint8Array([137,80])],{type:"image/png"}),t=s().mockResponse({method:"get",endpoint:"devices/dev-1/speculos/screenshot",response:e}),c=await new n("http://localhost:8080",{token:"tok",httpClient:t}).getScreenshot("dev-1");expect(c).toBe(e);const p=t.configs.find(({endpoint:d})=>d==="devices/dev-1/speculos/screenshot");expect(p?.config?.responseType).toBe("blob")}),it("presses a button",async()=>{const e=s();await new n("http://localhost:8080",{token:"tok",httpClient:e}).pressButton("dev-1","both"),expect(e.calls).toContainEqual({method:"post",endpoint:"devices/dev-1/speculos/button/both",body:{action:"press-and-release"}})}),it("forwards an explicit button action",async()=>{const e=s();await new n("http://localhost:8080",{token:"tok",httpClient:e}).pressButton("dev-1","left","press"),expect(e.calls).toContainEqual({method:"post",endpoint:"devices/dev-1/speculos/button/left",body:{action:"press"}})}),it("taps the screen at device coordinates",async()=>{const e=s();await new n("http://localhost:8080",{token:"tok",httpClient:e}).touchScreen("dev-1",200,537),expect(e.calls).toContainEqual({method:"post",endpoint:"devices/dev-1/speculos/finger",body:{action:"press-and-release",x:200,y:537}})})}),describe("session",()=>{it("fetches the current session",async()=>{const e=s().mockResponse({method:"get",endpoint:"sessions/current",response:{id:"sess-1",created_at:1,expires_at:2,devices:[i()]}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).getSession();expect(o.id).toBe("sess-1"),expect(o.devices).toHaveLength(1)}),it("disposes the session and clears the stored token",async()=>{const e=s().mockResponse({method:"delete",endpoint:"sessions/current",response:{}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.disposeSession()).resolves.toBe(!0),expect(t.getToken()).toBeUndefined()})}),describe("response validation",()=>{it("throws a descriptive error when the server response is malformed",async()=>{const e=s().mockResponse({method:"get",endpoint:"devices/dev-1",response:{id:123}}),t=new n("http://localhost:8080",{token:"tok",httpClient:e});await expect(t.getDevice("dev-1")).rejects.toThrow(/MockClient: invalid server response/)})}),describe("import/export",()=>{it("exports the session snapshot",async()=>{const e={devices:[{name:"Ledger Stax",device_type:"stax",mocks:[{prefix:"ff",responses:["9000"]}]}]},t=s().mockResponse({method:"get",endpoint:"export",response:e}),c=await new n("http://localhost:8080",{token:"tok",httpClient:t}).exportSession();expect(c).toEqual(e)}),it("posts a snapshot to the import endpoint",async()=>{const e={devices:[{name:"Ledger Flex",device_type:"flex",mocks:[{prefix:"e0010000",responses:["aa9000","5515"]}]}]},t=s().mockResponse({method:"post",endpoint:"import",response:e}),c=await new n("http://localhost:8080",{token:"tok",httpClient:t}).importSession(e);expect(c).toEqual(e),expect(t.calls).toContainEqual({method:"post",endpoint:"import",body:e})})}),describe("apdu",()=>{it("sends a binary APDU as hex to the device apdu endpoint",async()=>{const e=s().mockResponse({method:"post",endpoint:"devices/dev-1/apdu",response:{response:"9000"}}),o=await new n("http://localhost:8080",{token:"tok",httpClient:e}).sendApdu("dev-1",Uint8Array.from([224,1,0,0]));expect(o.response).toBe("9000"),expect(e.calls).toContainEqual({method:"post",endpoint:"devices/dev-1/apdu",body:{apdu:"e0010000"}})})})});
|
|
2
2
|
//# sourceMappingURL=MockClient.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/MockClient.test.ts"],
|
|
4
|
-
"sourcesContent": ["import { httpClientStubBuilder } from \"./DmkNetworkClient.stub\";\nimport { MockClient } from \"./MockClient\";\n\nconst aDevice = (overrides: Record<string, unknown> = {}) => ({\n id: \"dev-1\",\n name: \"Ledger Nano X\",\n device_type: \"nanoX\",\n connectivity_type: \"USB\",\n ...overrides,\n});\n\ndescribe(\"MockClient\", () => {\n describe(\"authentication\", () => {\n it(\"lazily creates a session via /auth when no token is provided\", async () => {\n const http = httpClientStubBuilder()\n .mockResponse({\n method: \"post\",\n endpoint: \"auth\",\n response: { token: \"tok-123\", expires_at: 42 },\n })\n .mockResponse({\n method: \"get\",\n endpoint: \"devices\",\n response: [],\n });\n const client = new MockClient(\"http://localhost:8080\", {\n httpClient: http,\n });\n\n const devices = await client.listDevices();\n\n expect(client.getToken()).toBe(\"tok-123\");\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"auth\",\n body: {},\n });\n expect(devices).toEqual([]);\n });\n\n it(\"does not call /auth when a token is injected\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices\",\n response: [],\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"injected\",\n httpClient: http,\n });\n\n await client.listDevices();\n\n expect(client.getToken()).toBe(\"injected\");\n expect(\n http.calls.find((call) => call.endpoint === \"auth\"),\n ).toBeUndefined();\n });\n\n it(\"returns the token from an explicit authenticate() call\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"auth\",\n response: { token: \"tok-abc\", expires_at: 99 },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n httpClient: http,\n });\n\n const token = await client.authenticate();\n\n expect(token).toBe(\"tok-abc\");\n expect(client.getToken()).toBe(\"tok-abc\");\n });\n\n it(\"reuses a single in-flight /auth call for concurrent requests\", async () => {\n const http = httpClientStubBuilder()\n .mockResponse({\n method: \"post\",\n endpoint: \"auth\",\n response: { token: \"tok-shared\", expires_at: 1 },\n })\n .mockResponse({ method: \"get\", endpoint: \"devices\", response: [] });\n const client = new MockClient(\"http://localhost:8080\", {\n httpClient: http,\n });\n\n await Promise.all([client.listDevices(), client.listDevices()]);\n\n const authCalls = http.calls.filter((call) => call.endpoint === \"auth\");\n expect(authCalls).toHaveLength(1);\n });\n\n it(\"returns undefined token before any session is established\", () => {\n const client = new MockClient(\"http://localhost:8080\", {\n httpClient: httpClientStubBuilder(),\n });\n\n expect(client.getToken()).toBeUndefined();\n });\n });\n\n describe(\"constructor\", () => {\n it(\"normalizes a base url without a trailing slash\", () => {\n const withSlash = new MockClient(\"http://localhost:8080/\");\n const withoutSlash = new MockClient(\"http://localhost:8080\");\n\n expect(withSlash.getToken()).toBeUndefined();\n expect(withoutSlash.getToken()).toBeUndefined();\n });\n });\n\n describe(\"devices\", () => {\n it(\"lists devices\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices\",\n response: [aDevice()],\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const devices = await client.listDevices();\n\n expect(devices).toEqual([expect.objectContaining({ id: \"dev-1\" })]);\n });\n\n it(\"adds a device with a default empty config\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"devices\",\n response: aDevice(),\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const device = await client.addDevice();\n\n expect(device.id).toBe(\"dev-1\");\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"devices\",\n body: {},\n });\n });\n\n it(\"gets a single device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices/dev-1\",\n response: aDevice(),\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const device = await client.getDevice(\"dev-1\");\n\n expect(device.id).toBe(\"dev-1\");\n });\n\n it(\"edits a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"patch\",\n endpoint: \"devices/dev-1\",\n response: aDevice({ name: \"Renamed\" }),\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const device = await client.editDevice(\"dev-1\", { name: \"Renamed\" });\n\n expect(device.name).toBe(\"Renamed\");\n expect(http.calls).toContainEqual({\n method: \"patch\",\n endpoint: \"devices/dev-1\",\n body: { name: \"Renamed\" },\n });\n });\n\n it(\"deletes a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"delete\",\n endpoint: \"devices/dev-1\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.deleteDevice(\"dev-1\")).resolves.toBe(true);\n expect(http.calls).toContainEqual({\n method: \"delete\",\n endpoint: \"devices/dev-1\",\n });\n });\n });\n\n describe(\"connection state\", () => {\n it(\"connects a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-1/connect\",\n response: { device: aDevice(), connected: true },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const state = await client.connect(\"dev-1\");\n\n expect(state.connected).toBe(true);\n expect(state.device.id).toBe(\"dev-1\");\n });\n\n it(\"disconnects a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-1/disconnect\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.disconnect(\"dev-1\")).resolves.toBe(true);\n });\n\n it(\"disconnects every connected device\", async () => {\n const http = httpClientStubBuilder()\n .mockResponse({\n method: \"get\",\n endpoint: \"devices\",\n response: [\n aDevice({ id: \"dev-1\", connected: true }),\n aDevice({ id: \"dev-2\", connected: false }),\n aDevice({ id: \"dev-3\", connected: true }),\n ],\n })\n .mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-1/disconnect\",\n response: {},\n })\n .mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-3/disconnect\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.disconnectAll()).resolves.toBe(true);\n\n const disconnectCalls = http.calls.filter((call) =>\n call.endpoint.endsWith(\"/disconnect\"),\n );\n expect(disconnectCalls.map((call) => call.endpoint)).toEqual([\n \"devices/dev-1/disconnect\",\n \"devices/dev-3/disconnect\",\n ]);\n });\n });\n\n describe(\"mocks\", () => {\n it(\"lists device-scoped mocks\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices/dev-1/mocks\",\n response: [{ id: \"m1\", prefix: \"e0010000\", responses: [\"9000\"] }],\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const mocks = await client.listMocks(\"dev-1\");\n\n expect(mocks).toEqual([expect.objectContaining({ id: \"m1\" })]);\n });\n\n it(\"creates a device-scoped mock\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-1/mocks\",\n response: { id: \"m1\", prefix: \"e0010000\", responses: [\"9000\"] },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const mock = await client.addMock(\"dev-1\", {\n prefix: \"e0010000\",\n response: \"9000\",\n });\n\n expect(mock.id).toBe(\"m1\");\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"devices/dev-1/mocks\",\n body: { prefix: \"e0010000\", response: \"9000\" },\n });\n });\n\n it(\"edits a mock\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"patch\",\n endpoint: \"devices/dev-1/mocks/m1\",\n response: { id: \"m1\", prefix: \"e0010000\", responses: [\"6985\"] },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const mock = await client.editMock(\"dev-1\", \"m1\", {\n prefix: \"e0010000\",\n response: \"6985\",\n });\n\n expect(mock.responses).toEqual([\"6985\"]);\n expect(http.calls).toContainEqual({\n method: \"patch\",\n endpoint: \"devices/dev-1/mocks/m1\",\n body: { prefix: \"e0010000\", response: \"6985\" },\n });\n });\n\n it(\"deletes a single mock\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"delete\",\n endpoint: \"devices/dev-1/mocks/m1\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.deleteMock(\"dev-1\", \"m1\")).resolves.toBe(true);\n expect(http.calls).toContainEqual({\n method: \"delete\",\n endpoint: \"devices/dev-1/mocks/m1\",\n });\n });\n\n it(\"clears all mocks of a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"delete\",\n endpoint: \"devices/dev-1/mocks\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.clearMocks(\"dev-1\")).resolves.toBe(true);\n expect(http.calls).toContainEqual({\n method: \"delete\",\n endpoint: \"devices/dev-1/mocks\",\n });\n });\n });\n\n describe(\"speculos\", () => {\n it(\"resolves the live speculos instance backing a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices/dev-1/speculos\",\n response: {\n run_id: \"run-1\",\n speculos_url: \"https://speculos:5000\",\n model: \"stax\",\n },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const instance = await client.getSpeculos(\"dev-1\");\n\n expect(instance).toEqual({\n run_id: \"run-1\",\n speculos_url: \"https://speculos:5000\",\n model: \"stax\",\n });\n });\n });\n\n describe(\"session\", () => {\n it(\"fetches the current session\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"sessions/current\",\n response: {\n id: \"sess-1\",\n created_at: 1,\n expires_at: 2,\n devices: [aDevice()],\n },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const session = await client.getSession();\n\n expect(session.id).toBe(\"sess-1\");\n expect(session.devices).toHaveLength(1);\n });\n\n it(\"disposes the session and clears the stored token\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"delete\",\n endpoint: \"sessions/current\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.disposeSession()).resolves.toBe(true);\n expect(client.getToken()).toBeUndefined();\n });\n });\n\n describe(\"response validation\", () => {\n it(\"throws a descriptive error when the server response is malformed\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices/dev-1\",\n response: { id: 123 } as unknown as object,\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.getDevice(\"dev-1\")).rejects.toThrow(\n /MockClient: invalid server response/,\n );\n });\n });\n\n describe(\"import/export\", () => {\n it(\"exports the session snapshot\", async () => {\n const snapshot = {\n devices: [\n {\n name: \"Ledger Stax\",\n device_type: \"stax\",\n mocks: [{ prefix: \"ff\", responses: [\"9000\"] }],\n },\n ],\n };\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"export\",\n response: snapshot,\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const result = await client.exportSession();\n\n expect(result).toEqual(snapshot);\n });\n\n it(\"posts a snapshot to the import endpoint\", async () => {\n const snapshot = {\n devices: [\n {\n name: \"Ledger Flex\",\n device_type: \"flex\",\n mocks: [{ prefix: \"e0010000\", responses: [\"aa9000\", \"5515\"] }],\n },\n ],\n };\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"import\",\n response: snapshot,\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const result = await client.importSession(snapshot);\n\n expect(result).toEqual(snapshot);\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"import\",\n body: snapshot,\n });\n });\n });\n\n describe(\"apdu\", () => {\n it(\"sends a binary APDU as hex to the device apdu endpoint\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-1/apdu\",\n response: { response: \"9000\" },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const result = await client.sendApdu(\n \"dev-1\",\n Uint8Array.from([0xe0, 0x01, 0x00, 0x00]),\n );\n\n expect(result.response).toBe(\"9000\");\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"devices/dev-1/apdu\",\n body: { apdu: \"e0010000\" },\n });\n });\n });\n});\n"],
|
|
5
|
-
"mappings": "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
|
|
6
|
-
"names": ["httpClientStubBuilder", "MockClient", "aDevice", "overrides", "http", "client", "devices", "call", "token", "authCalls", "withSlash", "withoutSlash", "device", "state", "disconnectCalls", "mocks", "mock", "instance", "session", "snapshot", "result"]
|
|
4
|
+
"sourcesContent": ["import { httpClientStubBuilder } from \"./DmkNetworkClient.stub\";\nimport { MockClient } from \"./MockClient\";\n\nconst aDevice = (overrides: Record<string, unknown> = {}) => ({\n id: \"dev-1\",\n name: \"Ledger Nano X\",\n device_type: \"nanoX\",\n connectivity_type: \"USB\",\n ...overrides,\n});\n\ndescribe(\"MockClient\", () => {\n describe(\"authentication\", () => {\n it(\"lazily creates a session via /auth when no token is provided\", async () => {\n const http = httpClientStubBuilder()\n .mockResponse({\n method: \"post\",\n endpoint: \"auth\",\n response: { token: \"tok-123\", expires_at: 42 },\n })\n .mockResponse({\n method: \"get\",\n endpoint: \"devices\",\n response: [],\n });\n const client = new MockClient(\"http://localhost:8080\", {\n httpClient: http,\n });\n\n const devices = await client.listDevices();\n\n expect(client.getToken()).toBe(\"tok-123\");\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"auth\",\n body: {},\n });\n expect(devices).toEqual([]);\n });\n\n it(\"does not call /auth when a token is injected\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices\",\n response: [],\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"injected\",\n httpClient: http,\n });\n\n await client.listDevices();\n\n expect(client.getToken()).toBe(\"injected\");\n expect(\n http.calls.find((call) => call.endpoint === \"auth\"),\n ).toBeUndefined();\n });\n\n it(\"returns the token from an explicit authenticate() call\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"auth\",\n response: { token: \"tok-abc\", expires_at: 99 },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n httpClient: http,\n });\n\n const token = await client.authenticate();\n\n expect(token).toBe(\"tok-abc\");\n expect(client.getToken()).toBe(\"tok-abc\");\n });\n\n it(\"reuses a single in-flight /auth call for concurrent requests\", async () => {\n const http = httpClientStubBuilder()\n .mockResponse({\n method: \"post\",\n endpoint: \"auth\",\n response: { token: \"tok-shared\", expires_at: 1 },\n })\n .mockResponse({ method: \"get\", endpoint: \"devices\", response: [] });\n const client = new MockClient(\"http://localhost:8080\", {\n httpClient: http,\n });\n\n await Promise.all([client.listDevices(), client.listDevices()]);\n\n const authCalls = http.calls.filter((call) => call.endpoint === \"auth\");\n expect(authCalls).toHaveLength(1);\n });\n\n it(\"returns undefined token before any session is established\", () => {\n const client = new MockClient(\"http://localhost:8080\", {\n httpClient: httpClientStubBuilder(),\n });\n\n expect(client.getToken()).toBeUndefined();\n });\n });\n\n describe(\"constructor\", () => {\n it(\"normalizes a base url without a trailing slash\", () => {\n const withSlash = new MockClient(\"http://localhost:8080/\");\n const withoutSlash = new MockClient(\"http://localhost:8080\");\n\n expect(withSlash.getToken()).toBeUndefined();\n expect(withoutSlash.getToken()).toBeUndefined();\n });\n });\n\n describe(\"devices\", () => {\n it(\"lists devices\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices\",\n response: [aDevice()],\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const devices = await client.listDevices();\n\n expect(devices).toEqual([expect.objectContaining({ id: \"dev-1\" })]);\n });\n\n it(\"adds a device with a default empty config\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"devices\",\n response: aDevice(),\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const device = await client.addDevice();\n\n expect(device.id).toBe(\"dev-1\");\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"devices\",\n body: {},\n });\n });\n\n it(\"gets a single device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices/dev-1\",\n response: aDevice(),\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const device = await client.getDevice(\"dev-1\");\n\n expect(device.id).toBe(\"dev-1\");\n });\n\n it(\"edits a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"patch\",\n endpoint: \"devices/dev-1\",\n response: aDevice({ name: \"Renamed\" }),\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const device = await client.editDevice(\"dev-1\", { name: \"Renamed\" });\n\n expect(device.name).toBe(\"Renamed\");\n expect(http.calls).toContainEqual({\n method: \"patch\",\n endpoint: \"devices/dev-1\",\n body: { name: \"Renamed\" },\n });\n });\n\n it(\"deletes a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"delete\",\n endpoint: \"devices/dev-1\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.deleteDevice(\"dev-1\")).resolves.toBe(true);\n expect(http.calls).toContainEqual({\n method: \"delete\",\n endpoint: \"devices/dev-1\",\n });\n });\n });\n\n describe(\"connection state\", () => {\n it(\"connects a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-1/connect\",\n response: { device: aDevice(), connected: true },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const state = await client.connect(\"dev-1\");\n\n expect(state.connected).toBe(true);\n expect(state.device.id).toBe(\"dev-1\");\n });\n\n it(\"disconnects a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-1/disconnect\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.disconnect(\"dev-1\")).resolves.toBe(true);\n });\n\n it(\"disconnects every connected device\", async () => {\n const http = httpClientStubBuilder()\n .mockResponse({\n method: \"get\",\n endpoint: \"devices\",\n response: [\n aDevice({ id: \"dev-1\", connected: true }),\n aDevice({ id: \"dev-2\", connected: false }),\n aDevice({ id: \"dev-3\", connected: true }),\n ],\n })\n .mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-1/disconnect\",\n response: {},\n })\n .mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-3/disconnect\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.disconnectAll()).resolves.toBe(true);\n\n const disconnectCalls = http.calls.filter((call) =>\n call.endpoint.endsWith(\"/disconnect\"),\n );\n expect(disconnectCalls.map((call) => call.endpoint)).toEqual([\n \"devices/dev-1/disconnect\",\n \"devices/dev-3/disconnect\",\n ]);\n });\n });\n\n describe(\"mocks\", () => {\n it(\"lists device-scoped mocks\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices/dev-1/mocks\",\n response: [{ id: \"m1\", prefix: \"e0010000\", responses: [\"9000\"] }],\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const mocks = await client.listMocks(\"dev-1\");\n\n expect(mocks).toEqual([expect.objectContaining({ id: \"m1\" })]);\n });\n\n it(\"creates a device-scoped mock\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-1/mocks\",\n response: { id: \"m1\", prefix: \"e0010000\", responses: [\"9000\"] },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const mock = await client.addMock(\"dev-1\", {\n prefix: \"e0010000\",\n response: \"9000\",\n });\n\n expect(mock.id).toBe(\"m1\");\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"devices/dev-1/mocks\",\n body: { prefix: \"e0010000\", response: \"9000\" },\n });\n });\n\n it(\"edits a mock\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"patch\",\n endpoint: \"devices/dev-1/mocks/m1\",\n response: { id: \"m1\", prefix: \"e0010000\", responses: [\"6985\"] },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const mock = await client.editMock(\"dev-1\", \"m1\", {\n prefix: \"e0010000\",\n response: \"6985\",\n });\n\n expect(mock.responses).toEqual([\"6985\"]);\n expect(http.calls).toContainEqual({\n method: \"patch\",\n endpoint: \"devices/dev-1/mocks/m1\",\n body: { prefix: \"e0010000\", response: \"6985\" },\n });\n });\n\n it(\"deletes a single mock\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"delete\",\n endpoint: \"devices/dev-1/mocks/m1\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.deleteMock(\"dev-1\", \"m1\")).resolves.toBe(true);\n expect(http.calls).toContainEqual({\n method: \"delete\",\n endpoint: \"devices/dev-1/mocks/m1\",\n });\n });\n\n it(\"clears all mocks of a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"delete\",\n endpoint: \"devices/dev-1/mocks\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.clearMocks(\"dev-1\")).resolves.toBe(true);\n expect(http.calls).toContainEqual({\n method: \"delete\",\n endpoint: \"devices/dev-1/mocks\",\n });\n });\n });\n\n describe(\"speculos\", () => {\n it(\"resolves the live speculos instance backing a device\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices/dev-1/speculos\",\n response: {\n run_id: \"run-1\",\n speculos_url: \"https://speculos:5000\",\n model: \"stax\",\n },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const instance = await client.getSpeculos(\"dev-1\");\n\n expect(instance).toEqual({\n run_id: \"run-1\",\n speculos_url: \"https://speculos:5000\",\n model: \"stax\",\n });\n });\n\n it(\"requests the screenshot as a blob\", async () => {\n const png = new Blob([new Uint8Array([0x89, 0x50])], {\n type: \"image/png\",\n });\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices/dev-1/speculos/screenshot\",\n response: png,\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const screenshot = await client.getScreenshot(\"dev-1\");\n\n expect(screenshot).toBe(png);\n // Anything but \"blob\" would decode the PNG as text and corrupt it.\n const request = http.configs.find(\n ({ endpoint }) => endpoint === \"devices/dev-1/speculos/screenshot\",\n );\n expect(request?.config?.responseType).toBe(\"blob\");\n });\n\n it(\"presses a button\", async () => {\n const http = httpClientStubBuilder();\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await client.pressButton(\"dev-1\", \"both\");\n\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"devices/dev-1/speculos/button/both\",\n body: { action: \"press-and-release\" },\n });\n });\n\n it(\"forwards an explicit button action\", async () => {\n const http = httpClientStubBuilder();\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await client.pressButton(\"dev-1\", \"left\", \"press\");\n\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"devices/dev-1/speculos/button/left\",\n body: { action: \"press\" },\n });\n });\n\n it(\"taps the screen at device coordinates\", async () => {\n const http = httpClientStubBuilder();\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await client.touchScreen(\"dev-1\", 200, 537);\n\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"devices/dev-1/speculos/finger\",\n body: { action: \"press-and-release\", x: 200, y: 537 },\n });\n });\n });\n\n describe(\"session\", () => {\n it(\"fetches the current session\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"sessions/current\",\n response: {\n id: \"sess-1\",\n created_at: 1,\n expires_at: 2,\n devices: [aDevice()],\n },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const session = await client.getSession();\n\n expect(session.id).toBe(\"sess-1\");\n expect(session.devices).toHaveLength(1);\n });\n\n it(\"disposes the session and clears the stored token\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"delete\",\n endpoint: \"sessions/current\",\n response: {},\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.disposeSession()).resolves.toBe(true);\n expect(client.getToken()).toBeUndefined();\n });\n });\n\n describe(\"response validation\", () => {\n it(\"throws a descriptive error when the server response is malformed\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"devices/dev-1\",\n response: { id: 123 } as unknown as object,\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n await expect(client.getDevice(\"dev-1\")).rejects.toThrow(\n /MockClient: invalid server response/,\n );\n });\n });\n\n describe(\"import/export\", () => {\n it(\"exports the session snapshot\", async () => {\n const snapshot = {\n devices: [\n {\n name: \"Ledger Stax\",\n device_type: \"stax\",\n mocks: [{ prefix: \"ff\", responses: [\"9000\"] }],\n },\n ],\n };\n const http = httpClientStubBuilder().mockResponse({\n method: \"get\",\n endpoint: \"export\",\n response: snapshot,\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const result = await client.exportSession();\n\n expect(result).toEqual(snapshot);\n });\n\n it(\"posts a snapshot to the import endpoint\", async () => {\n const snapshot = {\n devices: [\n {\n name: \"Ledger Flex\",\n device_type: \"flex\",\n mocks: [{ prefix: \"e0010000\", responses: [\"aa9000\", \"5515\"] }],\n },\n ],\n };\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"import\",\n response: snapshot,\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const result = await client.importSession(snapshot);\n\n expect(result).toEqual(snapshot);\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"import\",\n body: snapshot,\n });\n });\n });\n\n describe(\"apdu\", () => {\n it(\"sends a binary APDU as hex to the device apdu endpoint\", async () => {\n const http = httpClientStubBuilder().mockResponse({\n method: \"post\",\n endpoint: \"devices/dev-1/apdu\",\n response: { response: \"9000\" },\n });\n const client = new MockClient(\"http://localhost:8080\", {\n token: \"tok\",\n httpClient: http,\n });\n\n const result = await client.sendApdu(\n \"dev-1\",\n Uint8Array.from([0xe0, 0x01, 0x00, 0x00]),\n );\n\n expect(result.response).toBe(\"9000\");\n expect(http.calls).toContainEqual({\n method: \"post\",\n endpoint: \"devices/dev-1/apdu\",\n body: { apdu: \"e0010000\" },\n });\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["httpClientStubBuilder", "MockClient", "aDevice", "overrides", "http", "client", "devices", "call", "token", "authCalls", "withSlash", "withoutSlash", "device", "state", "disconnectCalls", "mocks", "mock", "instance", "png", "screenshot", "request", "endpoint", "session", "snapshot", "result"]
|
|
7
7
|
}
|
package/lib/esm/src/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{MockClient as t}from"./MockClient";import{catalogAppCodec as n,deviceConfigCodec as c}from"./model/Device";import{mockConfigCodec as
|
|
1
|
+
import{MockClient as t}from"./MockClient";import{catalogAppCodec as n,deviceConfigCodec as c}from"./model/Device";import{mockConfigCodec as s}from"./model/Mock";import{sessionExportCodec as m}from"./model/SessionExport";export{t as MockClient,n as catalogAppCodec,c as deviceConfigCodec,s as mockConfigCodec,m as sessionExportCodec};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/lib/esm/src/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["export type { MockClientOptions } from \"./MockClient\";\nexport { MockClient } from \"./MockClient\";\nexport type { AuthResponse, ConnectionState } from \"./model/Auth\";\nexport type { CommandResponse } from \"./model/CommandResponse\";\nexport {\n type CatalogApp,\n catalogAppCodec,\n type Device,\n type DeviceApp,\n type DeviceConfig,\n deviceConfigCodec,\n type DeviceConnectivityType,\n} from \"./model/Device\";\nexport { type Mock, type MockConfig, mockConfigCodec } from \"./model/Mock\";\nexport type { Session } from \"./model/Session\";\nexport { type SessionExport, sessionExportCodec } from \"./model/SessionExport\";\nexport type {
|
|
4
|
+
"sourcesContent": ["export type { MockClientOptions } from \"./MockClient\";\nexport { MockClient } from \"./MockClient\";\nexport type { AuthResponse, ConnectionState } from \"./model/Auth\";\nexport type { CommandResponse } from \"./model/CommandResponse\";\nexport {\n type CatalogApp,\n catalogAppCodec,\n type Device,\n type DeviceApp,\n type DeviceConfig,\n deviceConfigCodec,\n type DeviceConnectivityType,\n} from \"./model/Device\";\nexport { type Mock, type MockConfig, mockConfigCodec } from \"./model/Mock\";\nexport type { Session } from \"./model/Session\";\nexport { type SessionExport, sessionExportCodec } from \"./model/SessionExport\";\nexport type {\n SpeculosAction,\n SpeculosButton,\n SpeculosInstance,\n} from \"./model/Speculos\";\n"],
|
|
5
5
|
"mappings": "AACA,OAAS,cAAAA,MAAkB,eAG3B,OAEE,mBAAAC,EAIA,qBAAAC,MAEK,iBACP,OAAqC,mBAAAC,MAAuB,eAE5D,OAA6B,sBAAAC,MAA0B",
|
|
6
6
|
"names": ["MockClient", "catalogAppCodec", "deviceConfigCodec", "mockConfigCodec", "sessionExportCodec"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Codec as r,string as e}from"purify-ts";const
|
|
1
|
+
import{Codec as r,string as e}from"purify-ts";const s=r.interface({run_id:e,speculos_url:e,model:e});export{s as speculosInstanceCodec};
|
|
2
2
|
//# sourceMappingURL=Speculos.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/model/Speculos.ts"],
|
|
4
|
-
"sourcesContent": ["import { Codec, string } from \"purify-ts\";\n\n/**\n * The live Speculos emulator instance backing a device, returned by\n * `GET /devices/:id/speculos`. Control calls are proxied through\n * `/devices/:id/speculos/*`.\n */\nexport interface SpeculosInstance {\n /** Speculinho run id owning the emulator pod. */\n readonly run_id: string;\n /** Per-pod emulator URL (reachable from the mock server). */\n readonly speculos_url: string;\n /** Device model (e.g. \"nanoX\", \"stax\", \"flex\"). */\n readonly model: string;\n}\n\nexport const speculosInstanceCodec = Codec.interface({\n run_id: string,\n speculos_url: string,\n model: string,\n});\n"],
|
|
4
|
+
"sourcesContent": ["import { Codec, string } from \"purify-ts\";\n\n/**\n * The live Speculos emulator instance backing a device, returned by\n * `GET /devices/:id/speculos`. Control calls are proxied through\n * `/devices/:id/speculos/*`.\n */\nexport interface SpeculosInstance {\n /** Speculinho run id owning the emulator pod. */\n readonly run_id: string;\n /** Per-pod emulator URL (reachable from the mock server). */\n readonly speculos_url: string;\n /** Device model (e.g. \"nanoX\", \"stax\", \"flex\"). */\n readonly model: string;\n}\n\nexport const speculosInstanceCodec = Codec.interface({\n run_id: string,\n speculos_url: string,\n model: string,\n});\n\n/** A physical button on a button-driven device. */\nexport type SpeculosButton = \"left\" | \"right\" | \"both\";\n\n/**\n * How an input is delivered. `press-and-release` covers a normal click or tap;\n * the split variants exist for flows that require a held input.\n */\nexport type SpeculosAction = \"press\" | \"release\" | \"press-and-release\";\n"],
|
|
5
5
|
"mappings": "AAAA,OAAS,SAAAA,EAAO,UAAAC,MAAc,YAgBvB,MAAMC,EAAwBF,EAAM,UAAU,CACnD,OAAQC,EACR,aAAcA,EACd,MAAOA,CACT,CAAC",
|
|
6
6
|
"names": ["Codec", "string", "speculosInstanceCodec"]
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DmkNetworkClient } from "@ledgerhq/device-management-kit";
|
|
1
|
+
import { type DmkNetworkClient, type DmkRequestConfig } from "@ledgerhq/device-management-kit";
|
|
2
2
|
type Method = "get" | "post" | "patch" | "delete";
|
|
3
3
|
export type DmkNetworkClientStub = DmkNetworkClient & {
|
|
4
4
|
responses: Record<Method, Record<string, unknown>>;
|
|
@@ -7,6 +7,12 @@ export type DmkNetworkClientStub = DmkNetworkClient & {
|
|
|
7
7
|
endpoint: string;
|
|
8
8
|
body?: object;
|
|
9
9
|
}[];
|
|
10
|
+
/** Per-call request config, kept aside so `calls` stays easy to match on. */
|
|
11
|
+
configs: {
|
|
12
|
+
method: Method;
|
|
13
|
+
endpoint: string;
|
|
14
|
+
config?: DmkRequestConfig;
|
|
15
|
+
}[];
|
|
10
16
|
mockResponse(args: {
|
|
11
17
|
method: Method;
|
|
12
18
|
endpoint: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DmkNetworkClient.stub.d.ts","sourceRoot":"","sources":["../../../src/DmkNetworkClient.stub.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"DmkNetworkClient.stub.d.ts","sourceRoot":"","sources":["../../../src/DmkNetworkClient.stub.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,iCAAiC,CAAC;AAEzC,KAAK,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAElD,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IACpD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7D,6EAA6E;IAC7E,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,gBAAgB,CAAA;KAAE,EAAE,CAAC;IAC3E,YAAY,CAAC,IAAI,EAAE;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,oBAAoB,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,qBAAqB,QAAO,oBAiExC,CAAC"}
|
|
@@ -5,7 +5,7 @@ import { type Device, type DeviceConfig } from "./model/Device";
|
|
|
5
5
|
import { type Mock, type MockConfig } from "./model/Mock";
|
|
6
6
|
import { type Session } from "./model/Session";
|
|
7
7
|
import { type SessionExport } from "./model/SessionExport";
|
|
8
|
-
import { type SpeculosInstance } from "./model/Speculos";
|
|
8
|
+
import { type SpeculosAction, type SpeculosButton, type SpeculosInstance } from "./model/Speculos";
|
|
9
9
|
export interface MockClientOptions {
|
|
10
10
|
/**
|
|
11
11
|
* An existing mock server session token. When provided the client operates
|
|
@@ -53,6 +53,16 @@ export declare class MockClient {
|
|
|
53
53
|
* proxying its APDUs). Throws if the device has no active instance.
|
|
54
54
|
*/
|
|
55
55
|
getSpeculos(deviceId: string): Promise<SpeculosInstance>;
|
|
56
|
+
/**
|
|
57
|
+
* Capture the device's current screen as a PNG. Throws with status 409 when
|
|
58
|
+
* the device has no active instance, which is the case whenever no app is
|
|
59
|
+
* running.
|
|
60
|
+
*/
|
|
61
|
+
getScreenshot(deviceId: string): Promise<Blob>;
|
|
62
|
+
/** Actuate a physical button on a button-driven device. */
|
|
63
|
+
pressButton(deviceId: string, button: SpeculosButton, action?: SpeculosAction): Promise<void>;
|
|
64
|
+
/** Tap a touchscreen device, in device screen pixels. */
|
|
65
|
+
touchScreen(deviceId: string, x: number, y: number, action?: SpeculosAction): Promise<void>;
|
|
56
66
|
getSession(): Promise<Session>;
|
|
57
67
|
disposeSession(): Promise<boolean>;
|
|
58
68
|
/** Export the session's devices and mocks as a portable snapshot. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MockClient.d.ts","sourceRoot":"","sources":["../../../src/MockClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,gBAAgB,EACjB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,MAAM,EAAe,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,KAAK,IAAI,EAAa,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,KAAK,OAAO,EAAgB,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,KAAK,aAAa,EAAsB,MAAM,uBAAuB,CAAC;AAC/E,OAAO,
|
|
1
|
+
{"version":3,"file":"MockClient.d.ts","sourceRoot":"","sources":["../../../src/MockClient.ts"],"names":[],"mappings":"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"}
|
package/lib/types/src/index.d.ts
CHANGED
|
@@ -6,5 +6,5 @@ export { type CatalogApp, catalogAppCodec, type Device, type DeviceApp, type Dev
|
|
|
6
6
|
export { type Mock, type MockConfig, mockConfigCodec } from "./model/Mock";
|
|
7
7
|
export type { Session } from "./model/Session";
|
|
8
8
|
export { type SessionExport, sessionExportCodec } from "./model/SessionExport";
|
|
9
|
-
export type { SpeculosInstance } from "./model/Speculos";
|
|
9
|
+
export type { SpeculosAction, SpeculosButton, SpeculosInstance, } from "./model/Speculos";
|
|
10
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAClE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EACL,KAAK,UAAU,EACf,eAAe,EACf,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,iBAAiB,EACjB,KAAK,sBAAsB,GAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC3E,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,KAAK,aAAa,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAClE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EACL,KAAK,UAAU,EACf,eAAe,EACf,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,iBAAiB,EACjB,KAAK,sBAAsB,GAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC3E,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,KAAK,aAAa,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,YAAY,EACV,cAAc,EACd,cAAc,EACd,gBAAgB,GACjB,MAAM,kBAAkB,CAAC"}
|
|
@@ -17,4 +17,11 @@ export declare const speculosInstanceCodec: Codec<{
|
|
|
17
17
|
speculos_url: string;
|
|
18
18
|
model: string;
|
|
19
19
|
}>;
|
|
20
|
+
/** A physical button on a button-driven device. */
|
|
21
|
+
export type SpeculosButton = "left" | "right" | "both";
|
|
22
|
+
/**
|
|
23
|
+
* How an input is delivered. `press-and-release` covers a normal click or tap;
|
|
24
|
+
* the split variants exist for flows that require a held input.
|
|
25
|
+
*/
|
|
26
|
+
export type SpeculosAction = "press" | "release" | "press-and-release";
|
|
20
27
|
//# sourceMappingURL=Speculos.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Speculos.d.ts","sourceRoot":"","sources":["../../../../src/model/Speculos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAU,MAAM,WAAW,CAAC;AAE1C;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,qBAAqB;;;;EAIhC,CAAC"}
|
|
1
|
+
{"version":3,"file":"Speculos.d.ts","sourceRoot":"","sources":["../../../../src/model/Speculos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAU,MAAM,WAAW,CAAC;AAE1C;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,qBAAqB;;;;EAIhC,CAAC;AAEH,mDAAmD;AACnD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEvD;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,mBAAmB,CAAC"}
|