@testsmith/api-spector 0.3.1 → 0.3.2

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.
@@ -1,139 +1,292 @@
1
1
  "use strict";
2
2
  const electron = require("electron");
3
+ const IPC = {
4
+ // ─── Workspace / File ──────────────────────────────────────────────────────
5
+ file: {
6
+ openWorkspace: "file:openWorkspace",
7
+ getLastWorkspace: "file:getLastWorkspace",
8
+ saveWorkspace: "file:saveWorkspace",
9
+ newWorkspace: "file:newWorkspace",
10
+ closeWorkspace: "file:closeWorkspace",
11
+ loadCollection: "file:loadCollection",
12
+ saveCollection: "file:saveCollection",
13
+ loadEnvironment: "file:loadEnvironment",
14
+ saveEnvironment: "file:saveEnvironment",
15
+ deleteWorkspaceFile: "file:deleteWorkspaceFile",
16
+ saveMock: "file:saveMock",
17
+ loadMock: "file:loadMock"
18
+ },
19
+ // ─── Native dialogs ────────────────────────────────────────────────────────
20
+ dialog: {
21
+ pickDir: "dialog:pickDir"
22
+ },
23
+ // ─── HTTP execution ────────────────────────────────────────────────────────
24
+ request: {
25
+ send: "request:send"
26
+ },
27
+ // ─── Secrets ───────────────────────────────────────────────────────────────
28
+ secret: {
29
+ checkMasterKey: "secret:checkMasterKey",
30
+ setMasterKey: "secret:setMasterKey",
31
+ set: "secret:set"
32
+ },
33
+ // ─── Global variables ──────────────────────────────────────────────────────
34
+ globals: {
35
+ get: "globals:get",
36
+ set: "globals:set"
37
+ },
38
+ // ─── Collection runner ─────────────────────────────────────────────────────
39
+ runner: {
40
+ start: "runner:start",
41
+ /** Event: per-request progress pushed from main during a run. */
42
+ progress: "runner:progress"
43
+ },
44
+ // ─── Run results export ────────────────────────────────────────────────────
45
+ results: {
46
+ save: "results:save"
47
+ },
48
+ // ─── Import ────────────────────────────────────────────────────────────────
49
+ import: {
50
+ postman: "import:postman",
51
+ openapi: "import:openapi",
52
+ openapiUrl: "import:openapi-url",
53
+ insomnia: "import:insomnia",
54
+ bruno: "import:bruno",
55
+ http: "import:http",
56
+ openapiSchemas: "import:openapi-schemas",
57
+ openapiSchemasUrl: "import:openapi-schemas-url"
58
+ },
59
+ // ─── Code generation ───────────────────────────────────────────────────────
60
+ generate: {
61
+ code: "generate:code",
62
+ save: "generate:save",
63
+ saveZip: "generate:saveZip"
64
+ },
65
+ // ─── OAuth 2.0 ─────────────────────────────────────────────────────────────
66
+ oauth2: {
67
+ startFlow: "oauth2:startFlow",
68
+ refreshToken: "oauth2:refreshToken"
69
+ },
70
+ // ─── Mock servers ──────────────────────────────────────────────────────────
71
+ mock: {
72
+ start: "mock:start",
73
+ stop: "mock:stop",
74
+ isRunning: "mock:isRunning",
75
+ runningIds: "mock:runningIds",
76
+ updateRoutes: "mock:updateRoutes",
77
+ /** Event: a mock server route was hit. */
78
+ hit: "mock:hit"
79
+ },
80
+ // ─── WebSocket ─────────────────────────────────────────────────────────────
81
+ ws: {
82
+ connect: "ws:connect",
83
+ send: "ws:send",
84
+ disconnect: "ws:disconnect",
85
+ /** Event: inbound/outbound WS message. */
86
+ message: "ws:message",
87
+ /** Event: connection status change. */
88
+ status: "ws:status"
89
+ },
90
+ // ─── SOAP / WSDL ───────────────────────────────────────────────────────────
91
+ wsdl: {
92
+ fetch: "wsdl:fetch",
93
+ import: "wsdl:import"
94
+ },
95
+ // ─── Docs generation ───────────────────────────────────────────────────────
96
+ docs: {
97
+ generate: "docs:generate"
98
+ },
99
+ // ─── Contract testing ──────────────────────────────────────────────────────
100
+ contract: {
101
+ run: "contract:run",
102
+ inferSchema: "contract:inferSchema",
103
+ exportReportHtml: "contract:exportReportHtml",
104
+ captureSnapshot: "contract:captureSnapshot",
105
+ listSnapshots: "contract:listSnapshots",
106
+ loadSnapshot: "contract:loadSnapshot",
107
+ deleteSnapshot: "contract:deleteSnapshot"
108
+ },
109
+ // ─── Script hooks ──────────────────────────────────────────────────────────
110
+ script: {
111
+ runHook: "script:run-hook"
112
+ },
113
+ // ─── Git ───────────────────────────────────────────────────────────────────
114
+ git: {
115
+ isRepo: "git:isRepo",
116
+ init: "git:init",
117
+ status: "git:status",
118
+ diff: "git:diff",
119
+ diffStaged: "git:diffStaged",
120
+ stage: "git:stage",
121
+ unstage: "git:unstage",
122
+ stageAll: "git:stageAll",
123
+ commit: "git:commit",
124
+ log: "git:log",
125
+ branches: "git:branches",
126
+ checkout: "git:checkout",
127
+ deleteBranch: "git:deleteBranch",
128
+ pull: "git:pull",
129
+ push: "git:push",
130
+ remotes: "git:remotes",
131
+ addRemote: "git:addRemote",
132
+ setRemoteUrl: "git:setRemoteUrl",
133
+ removeRemote: "git:removeRemote",
134
+ writeCiFile: "git:writeCiFile",
135
+ resolveOurs: "git:resolveOurs",
136
+ resolveTheirs: "git:resolveTheirs",
137
+ markResolved: "git:markResolved"
138
+ },
139
+ // ─── Recorder ──────────────────────────────────────────────────────────────
140
+ record: {
141
+ start: "record:start",
142
+ stop: "record:stop",
143
+ isRunning: "record:isRunning",
144
+ entries: "record:entries",
145
+ toMock: "record:toMock",
146
+ /** Event: a recorded proxy entry was captured. */
147
+ hit: "record:hit"
148
+ },
149
+ // ─── Shell ─────────────────────────────────────────────────────────────────
150
+ shell: {
151
+ openExternal: "shell:openExternal"
152
+ }
153
+ };
3
154
  const api = {
4
155
  // ─── Workspace / File ──────────────────────────────────────────────────────
5
- openWorkspace: () => electron.ipcRenderer.invoke("file:openWorkspace"),
6
- getLastWorkspace: () => electron.ipcRenderer.invoke("file:getLastWorkspace"),
7
- saveWorkspace: (ws) => electron.ipcRenderer.invoke("file:saveWorkspace", ws),
8
- newWorkspace: () => electron.ipcRenderer.invoke("file:newWorkspace"),
9
- closeWorkspace: () => electron.ipcRenderer.invoke("file:closeWorkspace"),
10
- loadCollection: (relPath) => electron.ipcRenderer.invoke("file:loadCollection", relPath),
11
- saveCollection: (relPath, col) => electron.ipcRenderer.invoke("file:saveCollection", relPath, col),
12
- loadEnvironment: (relPath) => electron.ipcRenderer.invoke("file:loadEnvironment", relPath),
13
- saveEnvironment: (relPath, env) => electron.ipcRenderer.invoke("file:saveEnvironment", relPath, env),
156
+ openWorkspace: () => electron.ipcRenderer.invoke(IPC.file.openWorkspace),
157
+ getLastWorkspace: () => electron.ipcRenderer.invoke(IPC.file.getLastWorkspace),
158
+ saveWorkspace: (ws) => electron.ipcRenderer.invoke(IPC.file.saveWorkspace, ws),
159
+ newWorkspace: () => electron.ipcRenderer.invoke(IPC.file.newWorkspace),
160
+ closeWorkspace: () => electron.ipcRenderer.invoke(IPC.file.closeWorkspace),
161
+ loadCollection: (relPath) => electron.ipcRenderer.invoke(IPC.file.loadCollection, relPath),
162
+ saveCollection: (relPath, col) => electron.ipcRenderer.invoke(IPC.file.saveCollection, relPath, col),
163
+ loadEnvironment: (relPath) => electron.ipcRenderer.invoke(IPC.file.loadEnvironment, relPath),
164
+ saveEnvironment: (relPath, env) => electron.ipcRenderer.invoke(IPC.file.saveEnvironment, relPath, env),
14
165
  /** Idempotent unlink of a workspace-relative file. Used by collection /
15
166
  * environment / mock delete flows so the file is removed from disk, not
16
167
  * just from the workspace manifest. */
17
- deleteWorkspaceFile: (relPath) => electron.ipcRenderer.invoke("file:deleteWorkspaceFile", relPath),
168
+ deleteWorkspaceFile: (relPath) => electron.ipcRenderer.invoke(IPC.file.deleteWorkspaceFile, relPath),
18
169
  // ─── HTTP execution ────────────────────────────────────────────────────────
19
- sendRequest: (payload) => electron.ipcRenderer.invoke("request:send", payload),
170
+ sendRequest: (payload) => electron.ipcRenderer.invoke(IPC.request.send, payload),
20
171
  // ─── Secrets (encrypted, master-key-based) ───────────────────────────────
21
- checkMasterKey: () => electron.ipcRenderer.invoke("secret:checkMasterKey"),
22
- setMasterKey: (value) => electron.ipcRenderer.invoke("secret:setMasterKey", value),
172
+ checkMasterKey: () => electron.ipcRenderer.invoke(IPC.secret.checkMasterKey),
173
+ setMasterKey: (value) => electron.ipcRenderer.invoke(IPC.secret.setMasterKey, value),
23
174
  /** Save a named secret to the OS keychain (safeStorage). */
24
- setSecret: (ref, value) => electron.ipcRenderer.invoke("secret:set", ref, value),
175
+ setSecret: (ref, value) => electron.ipcRenderer.invoke(IPC.secret.set, ref, value),
25
176
  // ─── Globals ──────────────────────────────────────────────────────────────
26
- getGlobals: () => electron.ipcRenderer.invoke("globals:get"),
27
- setGlobals: (globals) => electron.ipcRenderer.invoke("globals:set", globals),
177
+ getGlobals: () => electron.ipcRenderer.invoke(IPC.globals.get),
178
+ setGlobals: (globals) => electron.ipcRenderer.invoke(IPC.globals.set, globals),
28
179
  // ─── Runner ───────────────────────────────────────────────────────────────
29
- runCollection: (payload) => electron.ipcRenderer.invoke("runner:start", payload),
180
+ runCollection: (payload) => electron.ipcRenderer.invoke(IPC.runner.start, payload),
30
181
  onRunProgress: (cb) => {
31
- electron.ipcRenderer.on("runner:progress", (_e, result) => cb(result));
182
+ electron.ipcRenderer.on(IPC.runner.progress, (_e, result) => cb(result));
32
183
  },
33
184
  offRunProgress: () => {
34
- electron.ipcRenderer.removeAllListeners("runner:progress");
185
+ electron.ipcRenderer.removeAllListeners(IPC.runner.progress);
35
186
  },
36
- saveResults: (content, defaultName) => electron.ipcRenderer.invoke("results:save", content, defaultName),
187
+ saveResults: (content, defaultName) => electron.ipcRenderer.invoke(IPC.results.save, content, defaultName),
37
188
  // ─── Import ────────────────────────────────────────────────────────────────
38
- importPostman: () => electron.ipcRenderer.invoke("import:postman"),
39
- importOpenApi: () => electron.ipcRenderer.invoke("import:openapi"),
40
- importOpenApiFromUrl: (url) => electron.ipcRenderer.invoke("import:openapi-url", url),
41
- importInsomnia: () => electron.ipcRenderer.invoke("import:insomnia"),
42
- importBruno: () => electron.ipcRenderer.invoke("import:bruno"),
189
+ importPostman: () => electron.ipcRenderer.invoke(IPC.import.postman),
190
+ importOpenApi: () => electron.ipcRenderer.invoke(IPC.import.openapi),
191
+ importOpenApiFromUrl: (url) => electron.ipcRenderer.invoke(IPC.import.openapiUrl, url),
192
+ importInsomnia: () => electron.ipcRenderer.invoke(IPC.import.insomnia),
193
+ importBruno: () => electron.ipcRenderer.invoke(IPC.import.bruno),
194
+ importHttpFile: () => electron.ipcRenderer.invoke(IPC.import.http),
43
195
  /** Extract response-body schemas from an OpenAPI spec file (no full import). */
44
- extractOpenApiSchemas: () => electron.ipcRenderer.invoke("import:openapi-schemas"),
196
+ extractOpenApiSchemas: () => electron.ipcRenderer.invoke(IPC.import.openapiSchemas),
45
197
  /** Extract response-body schemas from an OpenAPI spec URL (no full import). */
46
- extractOpenApiSchemasFromUrl: (url) => electron.ipcRenderer.invoke("import:openapi-schemas-url", url),
198
+ extractOpenApiSchemasFromUrl: (url) => electron.ipcRenderer.invoke(IPC.import.openapiSchemasUrl, url),
47
199
  // ─── Code generation ──────────────────────────────────────────────────────
48
- generateCode: (opts) => electron.ipcRenderer.invoke("generate:code", opts),
49
- pickOutputDir: () => electron.ipcRenderer.invoke("dialog:pickDir"),
50
- saveGeneratedFiles: (files, outputDir) => electron.ipcRenderer.invoke("generate:save", files, outputDir),
51
- saveGeneratedFilesAsZip: (files, collectionName, target) => electron.ipcRenderer.invoke("generate:saveZip", files, collectionName, target),
200
+ generateCode: (opts) => electron.ipcRenderer.invoke(IPC.generate.code, opts),
201
+ pickOutputDir: () => electron.ipcRenderer.invoke(IPC.dialog.pickDir),
202
+ saveGeneratedFiles: (files, outputDir) => electron.ipcRenderer.invoke(IPC.generate.save, files, outputDir),
203
+ saveGeneratedFilesAsZip: (files, collectionName, target) => electron.ipcRenderer.invoke(IPC.generate.saveZip, files, collectionName, target),
52
204
  // ─── OAuth 2.0 ────────────────────────────────────────────────────────────
53
- oauth2StartFlow: (auth, vars) => electron.ipcRenderer.invoke("oauth2:startFlow", auth, vars),
54
- oauth2RefreshToken: (auth, vars, refreshToken) => electron.ipcRenderer.invoke("oauth2:refreshToken", auth, vars, refreshToken),
205
+ oauth2StartFlow: (auth, vars) => electron.ipcRenderer.invoke(IPC.oauth2.startFlow, auth, vars),
206
+ oauth2RefreshToken: (auth, vars, refreshToken) => electron.ipcRenderer.invoke(IPC.oauth2.refreshToken, auth, vars, refreshToken),
55
207
  // ─── Mock servers ─────────────────────────────────────────────────────────────
56
- mockStart: (server) => electron.ipcRenderer.invoke("mock:start", server),
57
- mockStop: (id) => electron.ipcRenderer.invoke("mock:stop", id),
58
- mockIsRunning: (id) => electron.ipcRenderer.invoke("mock:isRunning", id),
59
- mockRunningIds: () => electron.ipcRenderer.invoke("mock:runningIds"),
60
- saveMock: (relPath, server) => electron.ipcRenderer.invoke("file:saveMock", relPath, server),
61
- loadMock: (relPath) => electron.ipcRenderer.invoke("file:loadMock", relPath),
62
- mockUpdateRoutes: (id, routes) => electron.ipcRenderer.invoke("mock:updateRoutes", id, routes),
208
+ mockStart: (server) => electron.ipcRenderer.invoke(IPC.mock.start, server),
209
+ mockStop: (id) => electron.ipcRenderer.invoke(IPC.mock.stop, id),
210
+ mockIsRunning: (id) => electron.ipcRenderer.invoke(IPC.mock.isRunning, id),
211
+ mockRunningIds: () => electron.ipcRenderer.invoke(IPC.mock.runningIds),
212
+ saveMock: (relPath, server) => electron.ipcRenderer.invoke(IPC.file.saveMock, relPath, server),
213
+ loadMock: (relPath) => electron.ipcRenderer.invoke(IPC.file.loadMock, relPath),
214
+ mockUpdateRoutes: (id, routes) => electron.ipcRenderer.invoke(IPC.mock.updateRoutes, id, routes),
63
215
  onMockHit: (cb) => {
64
- electron.ipcRenderer.on("mock:hit", (_e, hit) => cb(hit));
216
+ electron.ipcRenderer.on(IPC.mock.hit, (_e, hit) => cb(hit));
65
217
  },
66
218
  offMockHit: () => {
67
- electron.ipcRenderer.removeAllListeners("mock:hit");
219
+ electron.ipcRenderer.removeAllListeners(IPC.mock.hit);
68
220
  },
69
221
  // ─── WebSocket ────────────────────────────────────────────────────────────
70
- wsConnect: (requestId, url, headers) => electron.ipcRenderer.invoke("ws:connect", requestId, url, headers),
71
- wsSend: (requestId, data) => electron.ipcRenderer.invoke("ws:send", requestId, data),
72
- wsDisconnect: (requestId) => electron.ipcRenderer.invoke("ws:disconnect", requestId),
222
+ wsConnect: (requestId, url, headers) => electron.ipcRenderer.invoke(IPC.ws.connect, requestId, url, headers),
223
+ wsSend: (requestId, data) => electron.ipcRenderer.invoke(IPC.ws.send, requestId, data),
224
+ wsDisconnect: (requestId) => electron.ipcRenderer.invoke(IPC.ws.disconnect, requestId),
73
225
  onWsMessage: (cb) => {
74
- electron.ipcRenderer.on("ws:message", (_e, payload) => cb(payload));
226
+ electron.ipcRenderer.on(IPC.ws.message, (_e, payload) => cb(payload));
75
227
  },
76
228
  onWsStatus: (cb) => {
77
- electron.ipcRenderer.on("ws:status", (_e, payload) => cb(payload));
229
+ electron.ipcRenderer.on(IPC.ws.status, (_e, payload) => cb(payload));
78
230
  },
79
231
  offWsEvents: () => {
80
- electron.ipcRenderer.removeAllListeners("ws:message");
81
- electron.ipcRenderer.removeAllListeners("ws:status");
232
+ electron.ipcRenderer.removeAllListeners(IPC.ws.message);
233
+ electron.ipcRenderer.removeAllListeners(IPC.ws.status);
82
234
  },
83
235
  // ─── SOAP / WSDL ──────────────────────────────────────────────────────────
84
- wsdlFetch: (url, extraHeaders) => electron.ipcRenderer.invoke("wsdl:fetch", url, extraHeaders ?? {}),
236
+ wsdlFetch: (url, extraHeaders) => electron.ipcRenderer.invoke(IPC.wsdl.fetch, url, extraHeaders ?? {}),
85
237
  /** Build a Collection + MockServer from a WSDL. Renderer registers the
86
238
  * returned objects via the usual loadCollection/loadMock + save flows. */
87
- wsdlImport: (opts) => electron.ipcRenderer.invoke("wsdl:import", opts),
239
+ wsdlImport: (opts) => electron.ipcRenderer.invoke(IPC.wsdl.import, opts),
88
240
  // ─── Docs generation ──────────────────────────────────────────────────────
89
- generateDocs: (payload) => electron.ipcRenderer.invoke("docs:generate", payload),
241
+ generateDocs: (payload) => electron.ipcRenderer.invoke(IPC.docs.generate, payload),
90
242
  // ─── Contract testing ─────────────────────────────────────────────────────
91
- runContracts: (payload) => electron.ipcRenderer.invoke("contract:run", payload),
92
- inferContractSchema: (jsonBody) => electron.ipcRenderer.invoke("contract:inferSchema", jsonBody),
93
- captureContractSnapshot: (opts) => electron.ipcRenderer.invoke("contract:captureSnapshot", opts),
94
- listContractSnapshots: (registered = []) => electron.ipcRenderer.invoke("contract:listSnapshots", registered),
95
- loadContractSnapshot: (relPath) => electron.ipcRenderer.invoke("contract:loadSnapshot", relPath),
96
- deleteContractSnapshot: (relPath) => electron.ipcRenderer.invoke("contract:deleteSnapshot", relPath),
243
+ runContracts: (payload) => electron.ipcRenderer.invoke(IPC.contract.run, payload),
244
+ inferContractSchema: (jsonBody) => electron.ipcRenderer.invoke(IPC.contract.inferSchema, jsonBody),
245
+ exportContractReportHtml: (report, meta) => electron.ipcRenderer.invoke(IPC.contract.exportReportHtml, report, meta),
246
+ captureContractSnapshot: (opts) => electron.ipcRenderer.invoke(IPC.contract.captureSnapshot, opts),
247
+ listContractSnapshots: (registered = []) => electron.ipcRenderer.invoke(IPC.contract.listSnapshots, registered),
248
+ loadContractSnapshot: (relPath) => electron.ipcRenderer.invoke(IPC.contract.loadSnapshot, relPath),
249
+ deleteContractSnapshot: (relPath) => electron.ipcRenderer.invoke(IPC.contract.deleteSnapshot, relPath),
97
250
  // ─── Script hooks ─────────────────────────────────────────────────────────
98
- runScriptHook: (payload) => electron.ipcRenderer.invoke("script:run-hook", payload),
251
+ runScriptHook: (payload) => electron.ipcRenderer.invoke(IPC.script.runHook, payload),
99
252
  // ─── Git ──────────────────────────────────────────────────────────────────
100
- gitIsRepo: () => electron.ipcRenderer.invoke("git:isRepo"),
101
- gitInit: () => electron.ipcRenderer.invoke("git:init"),
102
- gitStatus: () => electron.ipcRenderer.invoke("git:status"),
103
- gitDiff: (filePath) => electron.ipcRenderer.invoke("git:diff", filePath),
104
- gitDiffStaged: (filePath) => electron.ipcRenderer.invoke("git:diffStaged", filePath),
105
- gitStage: (paths) => electron.ipcRenderer.invoke("git:stage", paths),
106
- gitUnstage: (paths) => electron.ipcRenderer.invoke("git:unstage", paths),
107
- gitStageAll: () => electron.ipcRenderer.invoke("git:stageAll"),
108
- gitCommit: (message) => electron.ipcRenderer.invoke("git:commit", message),
109
- gitLog: (limit) => electron.ipcRenderer.invoke("git:log", limit),
110
- gitBranches: () => electron.ipcRenderer.invoke("git:branches"),
111
- gitCheckout: (branch, create) => electron.ipcRenderer.invoke("git:checkout", branch, create),
112
- gitDeleteBranch: (name, force = false) => electron.ipcRenderer.invoke("git:deleteBranch", name, force),
113
- gitPull: () => electron.ipcRenderer.invoke("git:pull"),
114
- gitPush: (setUpstream) => electron.ipcRenderer.invoke("git:push", setUpstream),
115
- gitRemotes: () => electron.ipcRenderer.invoke("git:remotes"),
116
- gitAddRemote: (name, url) => electron.ipcRenderer.invoke("git:addRemote", name, url),
117
- gitSetRemoteUrl: (name, url) => electron.ipcRenderer.invoke("git:setRemoteUrl", name, url),
118
- gitRemoveRemote: (name) => electron.ipcRenderer.invoke("git:removeRemote", name),
119
- gitWriteCiFile: (relPath, content) => electron.ipcRenderer.invoke("git:writeCiFile", relPath, content),
120
- gitResolveOurs: (filePath) => electron.ipcRenderer.invoke("git:resolveOurs", filePath),
121
- gitResolveTheirs: (filePath) => electron.ipcRenderer.invoke("git:resolveTheirs", filePath),
122
- gitMarkResolved: (filePath) => electron.ipcRenderer.invoke("git:markResolved", filePath),
253
+ gitIsRepo: () => electron.ipcRenderer.invoke(IPC.git.isRepo),
254
+ gitInit: () => electron.ipcRenderer.invoke(IPC.git.init),
255
+ gitStatus: () => electron.ipcRenderer.invoke(IPC.git.status),
256
+ gitDiff: (filePath) => electron.ipcRenderer.invoke(IPC.git.diff, filePath),
257
+ gitDiffStaged: (filePath) => electron.ipcRenderer.invoke(IPC.git.diffStaged, filePath),
258
+ gitStage: (paths) => electron.ipcRenderer.invoke(IPC.git.stage, paths),
259
+ gitUnstage: (paths) => electron.ipcRenderer.invoke(IPC.git.unstage, paths),
260
+ gitStageAll: () => electron.ipcRenderer.invoke(IPC.git.stageAll),
261
+ gitCommit: (message) => electron.ipcRenderer.invoke(IPC.git.commit, message),
262
+ gitLog: (limit) => electron.ipcRenderer.invoke(IPC.git.log, limit),
263
+ gitBranches: () => electron.ipcRenderer.invoke(IPC.git.branches),
264
+ gitCheckout: (branch, create) => electron.ipcRenderer.invoke(IPC.git.checkout, branch, create),
265
+ gitDeleteBranch: (name, force = false) => electron.ipcRenderer.invoke(IPC.git.deleteBranch, name, force),
266
+ gitPull: () => electron.ipcRenderer.invoke(IPC.git.pull),
267
+ gitPush: (setUpstream) => electron.ipcRenderer.invoke(IPC.git.push, setUpstream),
268
+ gitRemotes: () => electron.ipcRenderer.invoke(IPC.git.remotes),
269
+ gitAddRemote: (name, url) => electron.ipcRenderer.invoke(IPC.git.addRemote, name, url),
270
+ gitSetRemoteUrl: (name, url) => electron.ipcRenderer.invoke(IPC.git.setRemoteUrl, name, url),
271
+ gitRemoveRemote: (name) => electron.ipcRenderer.invoke(IPC.git.removeRemote, name),
272
+ gitWriteCiFile: (relPath, content) => electron.ipcRenderer.invoke(IPC.git.writeCiFile, relPath, content),
273
+ gitResolveOurs: (filePath) => electron.ipcRenderer.invoke(IPC.git.resolveOurs, filePath),
274
+ gitResolveTheirs: (filePath) => electron.ipcRenderer.invoke(IPC.git.resolveTheirs, filePath),
275
+ gitMarkResolved: (filePath) => electron.ipcRenderer.invoke(IPC.git.markResolved, filePath),
123
276
  // ─── Recorder ─────────────────────────────────────────────────────────────
124
- recordStart: (config) => electron.ipcRenderer.invoke("record:start", config),
125
- recordStop: () => electron.ipcRenderer.invoke("record:stop"),
126
- recordIsRunning: () => electron.ipcRenderer.invoke("record:isRunning"),
127
- recordEntries: () => electron.ipcRenderer.invoke("record:entries"),
128
- recordToMock: (entries, upstream, name, port) => electron.ipcRenderer.invoke("record:toMock", entries, upstream, name, port),
277
+ recordStart: (config) => electron.ipcRenderer.invoke(IPC.record.start, config),
278
+ recordStop: () => electron.ipcRenderer.invoke(IPC.record.stop),
279
+ recordIsRunning: () => electron.ipcRenderer.invoke(IPC.record.isRunning),
280
+ recordEntries: () => electron.ipcRenderer.invoke(IPC.record.entries),
281
+ recordToMock: (entries, upstream, name, port) => electron.ipcRenderer.invoke(IPC.record.toMock, entries, upstream, name, port),
129
282
  onRecordHit: (cb) => {
130
- electron.ipcRenderer.on("record:hit", (_e, entry) => cb(entry));
283
+ electron.ipcRenderer.on(IPC.record.hit, (_e, entry) => cb(entry));
131
284
  },
132
285
  offRecordHit: () => {
133
- electron.ipcRenderer.removeAllListeners("record:hit");
286
+ electron.ipcRenderer.removeAllListeners(IPC.record.hit);
134
287
  },
135
288
  // ─── Shell ────────────────────────────────────────────────────────────────
136
- openExternal: (url) => electron.ipcRenderer.invoke("shell:openExternal", url),
289
+ openExternal: (url) => electron.ipcRenderer.invoke(IPC.shell.openExternal, url),
137
290
  // ─── Zoom ─────────────────────────────────────────────────────────────────
138
291
  setZoomFactor: (factor) => electron.webFrame.setZoomFactor(factor),
139
292
  // ─── Platform ─────────────────────────────────────────────────────────────