• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

electron / fiddle / 8bc99060-84d3-480c-a35f-0c4c5335e308

31 Aug 2023 06:45PM UTC coverage: 88.082% (-0.2%) from 88.325%
8bc99060-84d3-480c-a35f-0c4c5335e308

push

circleci

web-flow
refactor: move remaining file-manager file access to main process (#1451)

* refactor: move remaining file-manager file access to main process

* test: use BrowserWindowMock

* refactor: keep track of window being saved

965 of 1187 branches covered (0.0%)

Branch coverage included in aggregate %.

68 of 68 new or added lines in 5 files covered. (100.0%)

3654 of 4057 relevant lines covered (90.07%)

31.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

10.29
/src/preload/preload.ts
1
// Remember to update ambient.d.ts for extending window object
2
import { IpcRendererEvent, ipcRenderer } from 'electron';
1✔
3

4
import {
5
  FiddleEvent,
6
  FileTransformOperation,
7
  Files,
8
  PackageJsonOptions,
9
} from '../interfaces';
10
import { IpcEvents, WEBCONTENTS_READY_FOR_IPC_SIGNAL } from '../ipc-events';
1✔
11
import { FiddleTheme } from '../themes-defaults';
12

13
const channelMapping: Record<FiddleEvent, IpcEvents> = {
1✔
14
  'before-quit': IpcEvents.BEFORE_QUIT,
15
  'bisect-task': IpcEvents.TASK_BISECT,
16
  'clear-console': IpcEvents.CLEAR_CONSOLE,
17
  'electron-types-changed': IpcEvents.ELECTRON_TYPES_CHANGED,
18
  'execute-monaco-command': IpcEvents.MONACO_EXECUTE_COMMAND,
19
  'load-example': IpcEvents.LOAD_ELECTRON_EXAMPLE_REQUEST,
20
  'load-gist': IpcEvents.LOAD_GIST_REQUEST,
21
  'make-fiddle': IpcEvents.FIDDLE_MAKE,
22
  'new-fiddle': IpcEvents.FS_NEW_FIDDLE,
23
  'new-test': IpcEvents.FS_NEW_TEST,
24
  'open-fiddle': IpcEvents.FS_OPEN_FIDDLE,
25
  'open-settings': IpcEvents.OPEN_SETTINGS,
26
  'open-template': IpcEvents.FS_OPEN_TEMPLATE,
27
  'package-fiddle': IpcEvents.FIDDLE_PACKAGE,
28
  'redo-in-editor': IpcEvents.REDO_IN_EDITOR,
29
  'run-fiddle': IpcEvents.FIDDLE_RUN,
30
  'saved-local-fiddle': IpcEvents.SAVED_LOCAL_FIDDLE,
31
  'save-fiddle-gist': IpcEvents.FS_SAVE_FIDDLE_GIST,
32
  'select-all-in-editor': IpcEvents.SELECT_ALL_IN_EDITOR,
33
  'set-show-me-template': IpcEvents.SET_SHOW_ME_TEMPLATE,
34
  'show-welcome-tour': IpcEvents.SHOW_WELCOME_TOUR,
35
  'test-task': IpcEvents.TASK_TEST,
36
  'toggle-bisect': IpcEvents.BISECT_COMMANDS_TOGGLE,
37
  'toggle-monaco-option': IpcEvents.MONACO_TOGGLE_OPTION,
38
  'undo-in-editor': IpcEvents.UNDO_IN_EDITOR,
39
} as const;
40

41
async function preload() {
42
  await setupFiddleGlobal();
1✔
43
}
44

45
export async function setupFiddleGlobal() {
1✔
46
  window.ElectronFiddle = {
3✔
47
    addEventListener(
48
      type: FiddleEvent,
49
      listener: (...args: any[]) => void,
50
      options?: { signal: AbortSignal },
51
    ) {
52
      const channel = channelMapping[type];
×
53
      if (channel) {
×
54
        const ipcListener = (_event: IpcRendererEvent, ...args: any[]) => {
×
55
          listener(...args);
×
56
        };
57
        ipcRenderer.on(channel, ipcListener);
×
58
        if (options?.signal) {
×
59
          options.signal.addEventListener('abort', () => {
×
60
            ipcRenderer.off(channel, ipcListener);
×
61
          });
62
        }
63
      }
64
    },
65
    addModules({ dir, packageManager }, ...names) {
66
      return ipcRenderer.invoke(
×
67
        IpcEvents.NPM_ADD_MODULES,
68
        { dir, packageManager },
69
        ...names,
70
      );
71
    },
72
    app: null as any, // will be set in main.tsx
73
    appPaths: await ipcRenderer.invoke(IpcEvents.GET_APP_PATHS),
74
    arch: process.arch,
75
    blockAccelerators(acceleratorsToBlock) {
76
      ipcRenderer.send(IpcEvents.BLOCK_ACCELERATORS, acceleratorsToBlock);
×
77
    },
78
    cleanupDirectory(dir: string) {
79
      return ipcRenderer.invoke(IpcEvents.CLEANUP_DIRECTORY, dir);
×
80
    },
81
    confirmQuit() {
82
      ipcRenderer.send(IpcEvents.CONFIRM_QUIT);
×
83
    },
84
    createThemeFile(newTheme: FiddleTheme, name?: string) {
85
      return ipcRenderer.invoke(IpcEvents.CREATE_THEME_FILE, newTheme, name);
×
86
    },
87
    async deleteUserData(name: string) {
88
      await ipcRenderer.invoke(IpcEvents.DELETE_USER_DATA, name);
×
89
    },
90
    fetchVersions() {
91
      return ipcRenderer.invoke(IpcEvents.FETCH_VERSIONS);
×
92
    },
93
    getElectronTypes(ver) {
94
      // Destructure ver into a copy, as the object sometimes can't be cloned
95
      return ipcRenderer.invoke(IpcEvents.GET_ELECTRON_TYPES, { ...ver });
×
96
    },
97
    getLatestStable() {
98
      return ipcRenderer.sendSync(IpcEvents.GET_LATEST_STABLE);
×
99
    },
100
    getLocalVersionState(ver) {
101
      // Destructure ver into a copy, as the object sometimes can't be cloned
102
      return ipcRenderer.sendSync(IpcEvents.GET_LOCAL_VERSION_STATE, {
×
103
        ...ver,
104
      });
105
    },
106
    getOldestSupportedMajor() {
107
      return ipcRenderer.sendSync(IpcEvents.GET_OLDEST_SUPPORTED_MAJOR);
×
108
    },
109
    getReleasedVersions() {
110
      return ipcRenderer.sendSync(IpcEvents.GET_RELEASED_VERSIONS);
×
111
    },
112
    getReleaseInfo(version: string) {
113
      return ipcRenderer.invoke(IpcEvents.GET_RELEASE_INFO, version);
×
114
    },
115
    getAvailableThemes() {
116
      return ipcRenderer.invoke(IpcEvents.GET_AVAILABLE_THEMES);
×
117
    },
118
    getIsPackageManagerInstalled(packageManager, ignoreCache) {
119
      return ipcRenderer.invoke(
×
120
        IpcEvents.NPM_IS_PM_INSTALLED,
121
        packageManager,
122
        ignoreCache,
123
      );
124
    },
125
    getNodeTypes(version) {
126
      return ipcRenderer.invoke(IpcEvents.GET_NODE_TYPES, version);
×
127
    },
128
    getProjectName(localPath?: string) {
129
      return ipcRenderer.invoke(IpcEvents.GET_PROJECT_NAME, localPath);
×
130
    },
131
    getTemplate: (version: string) =>
132
      ipcRenderer.invoke(IpcEvents.GET_TEMPLATE, version),
×
133
    getTemplateValues: (name: string) => {
134
      return ipcRenderer.invoke(IpcEvents.GET_TEMPLATE_VALUES, name);
×
135
    },
136
    isReleasedMajor(major: number) {
137
      return ipcRenderer.invoke(IpcEvents.IS_RELEASED_MAJOR, major);
×
138
    },
139
    getTestTemplate: () => ipcRenderer.invoke(IpcEvents.GET_TEST_TEMPLATE),
×
140
    getUsername: () => ipcRenderer.sendSync(IpcEvents.GET_USERNAME),
×
141
    isDevMode: ipcRenderer.sendSync(IpcEvents.IS_DEV_MODE),
142
    macTitlebarClicked() {
143
      ipcRenderer.send(IpcEvents.CLICK_TITLEBAR_MAC);
×
144
    },
145
    monaco: null as any, // will be set in main.tsx
146
    onGetFiles(
147
      callback: (
148
        options: PackageJsonOptions | undefined,
149
        transforms: Array<FileTransformOperation>,
150
      ) => Promise<{ localPath?: string; files: Files }>,
151
    ) {
152
      ipcRenderer.removeAllListeners(IpcEvents.GET_FILES);
×
153
      ipcRenderer.on(
×
154
        IpcEvents.GET_FILES,
155
        async (e, { options, transforms }) => {
156
          const { localPath, files } = await callback(options, transforms);
×
157
          e.ports[0].postMessage({ localPath, files: [...files.entries()] });
×
158
        },
159
      );
160
    },
161
    async openThemeFolder() {
162
      await ipcRenderer.invoke(IpcEvents.OPEN_THEME_FOLDER);
×
163
    },
164
    packageRun({ dir, packageManager }, command) {
165
      return ipcRenderer.invoke(
×
166
        IpcEvents.NPM_PACKAGE_RUN,
167
        { dir, packageManager },
168
        command,
169
      );
170
    },
171
    pathExists: (path: string) =>
172
      ipcRenderer.sendSync(IpcEvents.PATH_EXISTS, path),
×
173
    platform: process.platform,
174
    pushOutputEntry(entry) {
175
      ipcRenderer.send(IpcEvents.OUTPUT_ENTRY, entry);
×
176
    },
177
    reloadWindows() {
178
      ipcRenderer.send(IpcEvents.RELOAD_WINDOW);
×
179
    },
180
    readThemeFile(name?: string) {
181
      return ipcRenderer.invoke(IpcEvents.READ_THEME_FILE, name);
×
182
    },
183
    removeAllListeners(type: FiddleEvent) {
184
      const channel = channelMapping[type];
×
185
      if (channel) {
×
186
        ipcRenderer.removeAllListeners(channel);
×
187
      }
188
    },
189
    saveFilesToTemp(files: Files) {
190
      return ipcRenderer.invoke(IpcEvents.SAVE_FILES_TO_TEMP, [
×
191
        ...files.entries(),
192
      ]);
193
    },
194
    selectLocalVersion: () => {
195
      return ipcRenderer.invoke(IpcEvents.LOAD_LOCAL_VERSION_FOLDER);
×
196
    },
197
    sendReady() {
198
      ipcRenderer.send(WEBCONTENTS_READY_FOR_IPC_SIGNAL);
×
199
    },
200
    setNativeTheme(theme) {
201
      ipcRenderer.send(IpcEvents.SET_NATIVE_THEME, theme);
×
202
    },
203
    setShowMeTemplate(template?: string) {
204
      ipcRenderer.send(IpcEvents.SET_SHOW_ME_TEMPLATE, template);
×
205
    },
206
    showWarningDialog(messageOptions) {
207
      ipcRenderer.send(IpcEvents.SHOW_WARNING_DIALOG, messageOptions);
×
208
    },
209
    showWindow() {
210
      ipcRenderer.send(IpcEvents.SHOW_WINDOW);
×
211
    },
212
    taskDone(result) {
213
      ipcRenderer.send(IpcEvents.TASK_DONE, result);
×
214
    },
215
    themePath: await ipcRenderer.sendSync(IpcEvents.GET_THEME_PATH),
216
    async uncacheTypes(ver) {
217
      // Destructure ver into a copy, as the object sometimes can't be cloned
218
      await ipcRenderer.invoke(IpcEvents.UNCACHE_TYPES, { ...ver });
×
219
    },
220
    async unwatchElectronTypes() {
221
      await ipcRenderer.invoke(IpcEvents.UNWATCH_ELECTRON_TYPES);
×
222
    },
223
  };
224
}
225

226
preload();
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc