@rg-dev/electron-helpers 1.0.3 → 1.0.5

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,3 +1,4 @@
1
+ "use strict";
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -40,7 +40,7 @@ interface TypedIpcMain<IpcEvents extends InputMap, IpcCommands extends InputMap
40
40
 
41
41
 
42
42
 
43
-
43
+ //@ts-ignore
44
44
  interface TypedIpcRenderer<IpcEvents extends InputMap, IpcCommands extends InputMap
45
45
  > extends IpcRenderer {
46
46
  on<K extends keyof IpcEvents>(
@@ -64,6 +64,13 @@ interface TypedIpcRenderer<IpcEvents extends InputMap, IpcCommands extends Input
64
64
  ...args: Parameters<IpcEvents[K]>
65
65
  ) => void
66
66
  ): this;
67
+ off<K extends keyof IpcEvents>(
68
+ channel: K,
69
+ listener: (
70
+ event: IpcRendererEvent,
71
+ ...args: Parameters<IpcEvents[K]>
72
+ ) => void
73
+ ): this;
67
74
  removeAllListeners<K extends keyof IpcEvents>(channel: K): this;
68
75
  off<K extends keyof IpcEvents>(channel: K): this;
69
76
  send<K extends keyof IpcEvents>(
@@ -40,7 +40,7 @@ interface TypedIpcMain<IpcEvents extends InputMap, IpcCommands extends InputMap
40
40
 
41
41
 
42
42
 
43
-
43
+ //@ts-ignore
44
44
  interface TypedIpcRenderer<IpcEvents extends InputMap, IpcCommands extends InputMap
45
45
  > extends IpcRenderer {
46
46
  on<K extends keyof IpcEvents>(
@@ -64,6 +64,13 @@ interface TypedIpcRenderer<IpcEvents extends InputMap, IpcCommands extends Input
64
64
  ...args: Parameters<IpcEvents[K]>
65
65
  ) => void
66
66
  ): this;
67
+ off<K extends keyof IpcEvents>(
68
+ channel: K,
69
+ listener: (
70
+ event: IpcRendererEvent,
71
+ ...args: Parameters<IpcEvents[K]>
72
+ ) => void
73
+ ): this;
67
74
  removeAllListeners<K extends keyof IpcEvents>(channel: K): this;
68
75
  off<K extends keyof IpcEvents>(channel: K): this;
69
76
  send<K extends keyof IpcEvents>(
package/dist/backend.cjs CHANGED
@@ -1,6 +1,9 @@
1
+ "use strict";
2
+ var __create = Object.create;
1
3
  var __defProp = Object.defineProperty;
2
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
4
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
8
  var __export = (target, all) => {
6
9
  for (var name in all)
@@ -14,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
14
17
  }
15
18
  return to;
16
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
17
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
29
 
19
30
  // src/backend.ts
@@ -29,6 +40,10 @@ var import_electron = require("electron");
29
40
  var __electron_helpers = "1";
30
41
 
31
42
  // src/backend.ts
43
+ var import_path = __toESM(require("path"), 1);
44
+ var import_fs = __toESM(require("fs"), 1);
45
+ var import_node_env = require("@rg-dev/stdlib/lib/node-env");
46
+ var import_electron2 = __toESM(require("electron"), 1);
32
47
  var electronHelpers = class {
33
48
  static isRunningInElectron() {
34
49
  return process.versions["electron"] != void 0;
@@ -53,6 +68,48 @@ var electronHelpers = class {
53
68
  throw new Error("no path");
54
69
  }
55
70
  }
71
+ static createTempSession() {
72
+ const sessionName = String(process.pid);
73
+ const session2 = import_electron2.default.session.fromPartition(sessionName);
74
+ return { sessionName, session: session2 };
75
+ }
76
+ //win.loadURL('file://')
77
+ static async intercept(opts) {
78
+ await (0, import_node_env.checkIfDirExistsOrThrow)(opts.filesDir);
79
+ await (0, import_node_env.checkIfFileExistsOrThrow)(import_path.default.join(opts.filesDir, "index.html"));
80
+ const filesDir = import_path.default.resolve(opts.filesDir);
81
+ const indexFile = import_path.default.join(filesDir, "index.html");
82
+ const proto = opts.session ? opts.session.protocol : import_electron.protocol;
83
+ if (proto.isProtocolIntercepted("file")) {
84
+ throw new Error("already intercepted file protocol");
85
+ }
86
+ proto.interceptFileProtocol(
87
+ "file",
88
+ (request, callback) => {
89
+ try {
90
+ const url = new URL(request.url);
91
+ let resource = decodeURIComponent(url.pathname);
92
+ resource = resource.replace(/^\/+/, "");
93
+ const file = import_path.default.resolve(filesDir, resource);
94
+ const relative = import_path.default.relative(filesDir, file);
95
+ if (relative.startsWith(".." + import_path.default.sep) || import_path.default.isAbsolute(relative)) {
96
+ console.warn(`Blocked path traversal: ${request.url}`);
97
+ callback({ path: indexFile });
98
+ return;
99
+ }
100
+ if (import_fs.default.existsSync(file) && import_fs.default.statSync(file).isFile()) {
101
+ callback({ path: file });
102
+ return;
103
+ }
104
+ console.log("intercpet", `file not found ${file}`);
105
+ callback({ path: indexFile });
106
+ } catch (err) {
107
+ console.error("Failed to intercept file:", request.url, err);
108
+ callback({ path: indexFile });
109
+ }
110
+ }
111
+ );
112
+ }
56
113
  static async electronFilePicker() {
57
114
  if (!this.isRunningInElectron()) {
58
115
  throw new Error("only work in electron");
@@ -3,6 +3,14 @@ export { __electron_helpers } from './index.cjs';
3
3
  declare class electronHelpers {
4
4
  static isRunningInElectron(): boolean;
5
5
  static electronSaveFileDialog(type: string): Promise<string>;
6
+ static createTempSession(): {
7
+ sessionName: string;
8
+ session: Electron.Session;
9
+ };
10
+ static intercept(opts: {
11
+ filesDir: string;
12
+ session?: Electron.Session;
13
+ }): Promise<void>;
6
14
  static electronFilePicker(): Promise<string>;
7
15
  }
8
16
 
package/dist/backend.d.ts CHANGED
@@ -3,6 +3,14 @@ export { __electron_helpers } from './index.js';
3
3
  declare class electronHelpers {
4
4
  static isRunningInElectron(): boolean;
5
5
  static electronSaveFileDialog(type: string): Promise<string>;
6
+ static createTempSession(): {
7
+ sessionName: string;
8
+ session: Electron.Session;
9
+ };
10
+ static intercept(opts: {
11
+ filesDir: string;
12
+ session?: Electron.Session;
13
+ }): Promise<void>;
6
14
  static electronFilePicker(): Promise<string>;
7
15
  }
8
16
 
package/dist/backend.js CHANGED
@@ -1,10 +1,14 @@
1
1
  // src/backend.ts
2
- import { dialog } from "electron";
2
+ import { dialog, protocol } from "electron";
3
3
 
4
4
  // src/index.ts
5
5
  var __electron_helpers = "1";
6
6
 
7
7
  // src/backend.ts
8
+ import path from "path";
9
+ import fs from "fs";
10
+ import { checkIfDirExistsOrThrow, checkIfFileExistsOrThrow } from "@rg-dev/stdlib/lib/node-env";
11
+ import electron from "electron";
8
12
  var electronHelpers = class {
9
13
  static isRunningInElectron() {
10
14
  return process.versions["electron"] != void 0;
@@ -29,6 +33,48 @@ var electronHelpers = class {
29
33
  throw new Error("no path");
30
34
  }
31
35
  }
36
+ static createTempSession() {
37
+ const sessionName = String(process.pid);
38
+ const session2 = electron.session.fromPartition(sessionName);
39
+ return { sessionName, session: session2 };
40
+ }
41
+ //win.loadURL('file://')
42
+ static async intercept(opts) {
43
+ await checkIfDirExistsOrThrow(opts.filesDir);
44
+ await checkIfFileExistsOrThrow(path.join(opts.filesDir, "index.html"));
45
+ const filesDir = path.resolve(opts.filesDir);
46
+ const indexFile = path.join(filesDir, "index.html");
47
+ const proto = opts.session ? opts.session.protocol : protocol;
48
+ if (proto.isProtocolIntercepted("file")) {
49
+ throw new Error("already intercepted file protocol");
50
+ }
51
+ proto.interceptFileProtocol(
52
+ "file",
53
+ (request, callback) => {
54
+ try {
55
+ const url = new URL(request.url);
56
+ let resource = decodeURIComponent(url.pathname);
57
+ resource = resource.replace(/^\/+/, "");
58
+ const file = path.resolve(filesDir, resource);
59
+ const relative = path.relative(filesDir, file);
60
+ if (relative.startsWith(".." + path.sep) || path.isAbsolute(relative)) {
61
+ console.warn(`Blocked path traversal: ${request.url}`);
62
+ callback({ path: indexFile });
63
+ return;
64
+ }
65
+ if (fs.existsSync(file) && fs.statSync(file).isFile()) {
66
+ callback({ path: file });
67
+ return;
68
+ }
69
+ console.log("intercpet", `file not found ${file}`);
70
+ callback({ path: indexFile });
71
+ } catch (err) {
72
+ console.error("Failed to intercept file:", request.url, err);
73
+ callback({ path: indexFile });
74
+ }
75
+ }
76
+ );
77
+ }
32
78
  static async electronFilePicker() {
33
79
  if (!this.isRunningInElectron()) {
34
80
  throw new Error("only work in electron");
package/dist/client.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -36,6 +37,9 @@ var IpcClient = class _IpcClient {
36
37
  ipc;
37
38
  static create(electronIpc, _shape) {
38
39
  const client = new _IpcClient();
40
+ if (!electronIpc) {
41
+ console.warn("electron ipc object undefined");
42
+ }
39
43
  client.ipc = electronIpc;
40
44
  return client;
41
45
  }
@@ -43,6 +47,10 @@ var IpcClient = class _IpcClient {
43
47
  return new Promise(
44
48
  async (resolve, reject) => {
45
49
  try {
50
+ if (!this.ipc) {
51
+ resolve(void 0);
52
+ return;
53
+ }
46
54
  const res = await this.ipc.invoke(route, ...args);
47
55
  if (!res) {
48
56
  resolve(void 0);
@@ -61,11 +69,17 @@ var IpcClient = class _IpcClient {
61
69
  );
62
70
  }
63
71
  on(channel, listener) {
72
+ if (!this.ipc) {
73
+ return this;
74
+ }
64
75
  this.ipc.on(channel, (_event, ...args) => listener(...args));
65
76
  return this;
66
77
  }
67
78
  off(channel, listener) {
68
- this.ipc.removeListener(channel, (_event, ...args) => listener(...args));
79
+ if (!this.ipc) {
80
+ return this;
81
+ }
82
+ this.ipc.off(channel, (_event, ...args) => listener(...args));
69
83
  return this;
70
84
  }
71
85
  };
package/dist/client.js CHANGED
@@ -8,6 +8,9 @@ var IpcClient = class _IpcClient {
8
8
  ipc;
9
9
  static create(electronIpc, _shape) {
10
10
  const client = new _IpcClient();
11
+ if (!electronIpc) {
12
+ console.warn("electron ipc object undefined");
13
+ }
11
14
  client.ipc = electronIpc;
12
15
  return client;
13
16
  }
@@ -15,6 +18,10 @@ var IpcClient = class _IpcClient {
15
18
  return new Promise(
16
19
  async (resolve, reject) => {
17
20
  try {
21
+ if (!this.ipc) {
22
+ resolve(void 0);
23
+ return;
24
+ }
18
25
  const res = await this.ipc.invoke(route, ...args);
19
26
  if (!res) {
20
27
  resolve(void 0);
@@ -33,11 +40,17 @@ var IpcClient = class _IpcClient {
33
40
  );
34
41
  }
35
42
  on(channel, listener) {
43
+ if (!this.ipc) {
44
+ return this;
45
+ }
36
46
  this.ipc.on(channel, (_event, ...args) => listener(...args));
37
47
  return this;
38
48
  }
39
49
  off(channel, listener) {
40
- this.ipc.removeListener(channel, (_event, ...args) => listener(...args));
50
+ if (!this.ipc) {
51
+ return this;
52
+ }
53
+ this.ipc.off(channel, (_event, ...args) => listener(...args));
41
54
  return this;
42
55
  }
43
56
  };
package/dist/index.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rg-dev/electron-helpers",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "tsup && node dist/index.cjs",
@@ -12,13 +12,13 @@
12
12
  "files": [
13
13
  "dist"
14
14
  ],
15
- "publishConfig": {
16
- "access": "public"
15
+ "publishConfig": {
16
+ "access": "public"
17
17
  },
18
18
  "module": "./dist/index.js",
19
19
  "types": "./dist/index.d.ts",
20
20
  "type": "module",
21
- "typesVersions": {
21
+ "typesVersions": {
22
22
  "*": {
23
23
  "dist/backend": [
24
24
  "dist/backend.d.ts"
@@ -29,17 +29,17 @@
29
29
  }
30
30
  },
31
31
  "exports": {
32
- ".": {
33
- "import": "./dist/index.js",
34
- "require": "./dist/index.cjs"
32
+ ".": {
33
+ "import": "./dist/index.js",
34
+ "require": "./dist/index.cjs"
35
35
  },
36
- "./dist/client": {
37
- "import": "./dist/client.js",
38
- "require": "./dist/client.cjs"
36
+ "./dist/client": {
37
+ "import": "./dist/client.js",
38
+ "require": "./dist/client.cjs"
39
39
  },
40
- "./dist/backend": {
41
- "import": "./dist/backend.js",
42
- "require": "./dist/backend.cjs"
40
+ "./dist/backend": {
41
+ "import": "./dist/backend.js",
42
+ "require": "./dist/backend.cjs"
43
43
  }
44
44
  },
45
45
  "devDependencies": {
@@ -49,5 +49,8 @@
49
49
  "execa": "^8.0.1",
50
50
  "tsup": "^8.0.2",
51
51
  "typescript": "^5.4.5"
52
+ },
53
+ "dependencies": {
54
+ "@rg-dev/stdlib": "^1.0.80"
52
55
  }
53
56
  }