mac-helper 0.5.0 → 0.7.0

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/chrome.d.ts CHANGED
@@ -2,7 +2,19 @@ export type ActiveTab = {
2
2
  url: string;
3
3
  title: string;
4
4
  };
5
- export declare const Chrome: {
6
- getActiveTab(): Promise<ActiveTab>;
7
- };
8
- export declare function getChromeActiveTab(): Promise<ActiveTab>;
5
+ export declare enum BrowserAppName {
6
+ Chrome = "Google Chrome",
7
+ Brave = "Brave Browser"
8
+ }
9
+ export declare class ChromiumBrowserHelper {
10
+ appName: string;
11
+ constructor(appName: string);
12
+ isRunning: () => Promise<boolean>;
13
+ isFrontmost: () => Promise<boolean>;
14
+ getActiveTab: () => Promise<ActiveTab | undefined>;
15
+ }
16
+ export declare const Chrome: ChromiumBrowserHelper;
17
+ export declare const Brave: ChromiumBrowserHelper;
18
+ export declare function isChromiumAppRunning(appName?: string): Promise<boolean>;
19
+ export declare function getChromiumActiveTab(appName?: string): Promise<ActiveTab | undefined>;
20
+ export declare function getChromiumIsFrontmost(appName?: string): Promise<boolean>;
package/lib/chrome.js CHANGED
@@ -1,16 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Chrome = void 0;
4
- exports.getChromeActiveTab = getChromeActiveTab;
3
+ exports.Brave = exports.Chrome = exports.ChromiumBrowserHelper = exports.BrowserAppName = void 0;
4
+ exports.isChromiumAppRunning = isChromiumAppRunning;
5
+ exports.getChromiumActiveTab = getChromiumActiveTab;
6
+ exports.getChromiumIsFrontmost = getChromiumIsFrontmost;
5
7
  const run_1 = require("@jxa/run");
6
- exports.Chrome = {
7
- async getActiveTab() {
8
- return await getChromeActiveTab();
9
- },
10
- };
11
- async function getChromeActiveTab() {
12
- return await (0, run_1.run)(() => {
13
- const app = Application('Google Chrome');
8
+ const app_1 = require("./app");
9
+ var BrowserAppName;
10
+ (function (BrowserAppName) {
11
+ BrowserAppName["Chrome"] = "Google Chrome";
12
+ BrowserAppName["Brave"] = "Brave Browser";
13
+ })(BrowserAppName || (exports.BrowserAppName = BrowserAppName = {}));
14
+ class ChromiumBrowserHelper {
15
+ appName;
16
+ constructor(appName) {
17
+ this.appName = appName;
18
+ }
19
+ isRunning = () => isChromiumAppRunning(this.appName);
20
+ isFrontmost = () => getChromiumIsFrontmost(this.appName);
21
+ getActiveTab = () => getChromiumActiveTab(this.appName);
22
+ }
23
+ exports.ChromiumBrowserHelper = ChromiumBrowserHelper;
24
+ exports.Chrome = new ChromiumBrowserHelper(BrowserAppName.Chrome);
25
+ exports.Brave = new ChromiumBrowserHelper(BrowserAppName.Brave);
26
+ /* #region implements */
27
+ function isChromiumAppRunning(appName = BrowserAppName.Chrome) {
28
+ return (0, app_1.isAppRunning)(appName);
29
+ }
30
+ async function getChromiumActiveTab(appName = BrowserAppName.Chrome) {
31
+ if (!(await isChromiumAppRunning(appName)))
32
+ return;
33
+ return await (0, run_1.run)((appName) => {
34
+ const app = Application(appName);
14
35
  app.includeStandardAdditions = true;
15
36
  const win = (app.windows() || []).find((w) => !w.minimized());
16
37
  const tab = win?.activeTab();
@@ -18,6 +39,15 @@ async function getChromeActiveTab() {
18
39
  url: tab?.url(),
19
40
  title: tab?.title(),
20
41
  };
21
- });
42
+ }, appName);
43
+ }
44
+ async function getChromiumIsFrontmost(appName = BrowserAppName.Chrome) {
45
+ if (!isChromiumAppRunning(appName))
46
+ return false;
47
+ return await (0, run_1.run)((appName) => {
48
+ const app = Application(appName);
49
+ app.includeStandardAdditions = true;
50
+ return app.frontmost();
51
+ }, appName);
22
52
  }
23
- // getChromeActiveTab().then(console.log)
53
+ /* #endregion */
package/lib/finder.d.ts CHANGED
@@ -23,6 +23,6 @@ export type QSpaceFileItem = {
23
23
  export declare function isRepresentPF(file: string): boolean;
24
24
  export declare function isRepresentQS(file: string): boolean;
25
25
  /**
26
- * 处理 $PF $QS, ignore case
26
+ * 处理 `@pf` `@qs`, ignore case
27
27
  */
28
28
  export declare function normalizeInputFileList(fileList: string[]): Promise<string[]>;
package/lib/finder.js CHANGED
@@ -7,11 +7,11 @@ exports.QSpace = exports.Finder = exports.PathFinder = void 0;
7
7
  exports.isRepresentPF = isRepresentPF;
8
8
  exports.isRepresentQS = isRepresentQS;
9
9
  exports.normalizeInputFileList = normalizeInputFileList;
10
+ const run_1 = require("@jxa/run");
11
+ const es_toolkit_1 = require("es-toolkit");
10
12
  const node_os_1 = require("node:os");
11
13
  const node_path_1 = __importDefault(require("node:path"));
12
14
  const node_url_1 = require("node:url");
13
- const run_1 = require("@jxa/run");
14
- const es_toolkit_1 = require("es-toolkit");
15
15
  const promise_map_1 = __importDefault(require("promise.map"));
16
16
  const app_1 = require("./app");
17
17
  /**
@@ -109,24 +109,26 @@ async function QSpace_allSelected() {
109
109
  /* #endregion */
110
110
  /* #region Top Level Helper */
111
111
  function isRepresentPF(file) {
112
- return /^\$?pf$/i.test(file);
112
+ return /^[@$]?pf$/i.test(file);
113
113
  }
114
114
  function isRepresentQS(file) {
115
- return /^\$?qs$/i.test(file);
115
+ return /^[@$]?qs$/i.test(file);
116
116
  }
117
117
  /**
118
- * 处理 $PF $QS, ignore case
118
+ * 处理 `@pf` `@qs`, ignore case
119
119
  */
120
120
  async function normalizeInputFileList(fileList) {
121
121
  return (0, es_toolkit_1.uniq)((await (0, promise_map_1.default)(fileList, async (f) => {
122
- if (isRepresentPF(f))
123
- return await exports.PathFinder.allSelected();
124
- if (isRepresentQS(f))
125
- return await exports.QSpace.allSelected();
122
+ if (process.platform === 'darwin') {
123
+ if (isRepresentPF(f))
124
+ return await exports.PathFinder.allSelected();
125
+ if (isRepresentQS(f))
126
+ return await exports.QSpace.allSelected();
127
+ }
126
128
  return node_path_1.default.resolve(f);
127
129
  }, (0, node_os_1.availableParallelism)())).flat());
128
130
  }
129
131
  /* #endregion */
130
132
  // ;(async () => {
131
- // console.log(await getQSpaceSelected())
133
+ // console.log(await normalizeInputFileList(['@pf']))
132
134
  // })()
package/lib/iterm.js CHANGED
@@ -4,14 +4,14 @@ exports.iTerm = void 0;
4
4
  exports.runInIterm = runInIterm;
5
5
  const run_1 = require("@jxa/run");
6
6
  async function runInIterm(command, reuse = true) {
7
- await (0, run_1.run)((command, reuse) => {
7
+ const result = await (0, run_1.run)((command, reuse) => {
8
8
  const app = Application('iTerm');
9
9
  app.includeStandardAdditions = true;
10
10
  app.activate();
11
11
  let usingSession;
12
12
  // reuse when possible
13
13
  if (reuse) {
14
- const session = app.currentWindow().currentSession();
14
+ const session = app.currentWindow()?.currentSession();
15
15
  const isIdle = session?.isAtShellPrompt();
16
16
  if (isIdle) {
17
17
  usingSession = session;
@@ -20,13 +20,15 @@ async function runInIterm(command, reuse = true) {
20
20
  // create new tab when necessary
21
21
  if (!usingSession) {
22
22
  const tab = app.createTabWithDefaultProfile(app.currentWindow);
23
- usingSession = tab.currentSession();
24
- }
25
- if (!usingSession) {
26
- return;
23
+ usingSession = tab?.currentSession(); // TODO: iterm2 updated, this code no longer works
27
24
  }
25
+ if (!usingSession)
26
+ return 'no-session';
28
27
  app.write(usingSession, { text: command });
29
28
  }, command, reuse);
29
+ if (result === 'no-session') {
30
+ console.error('No iTerm session found');
31
+ }
30
32
  }
31
33
  exports.iTerm = {
32
34
  run: runInIterm,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mac-helper",
3
- "version": "0.5.0",
4
- "packageManager": "pnpm@10.25.0+sha512.5e82639027af37cf832061bcc6d639c219634488e0f2baebe785028a793de7b525ffcd3f7ff574f5e9860654e098fe852ba8ac5dd5cefe1767d23a020a92f501",
3
+ "version": "0.7.0",
4
+ "packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be",
5
5
  "description": "useful helper for macOS",
6
6
  "keywords": [
7
7
  "mac",
@@ -39,29 +39,29 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@jxa/run": "^1.4.0",
42
- "es-toolkit": "^1.43.0",
42
+ "es-toolkit": "^1.45.1",
43
43
  "promise.map": "^1.1.3"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@jxa/global-type": "^1.4.0",
47
47
  "@jxa/sdef-to-dts": "^1.4.0",
48
48
  "@jxa/types": "^1.4.0",
49
- "@magicdawn/eslint-config": "^1.5.14",
49
+ "@magicdawn/eslint-config": "^1.6.2",
50
50
  "@magicdawn/prettier-config": "^0.1.0",
51
51
  "@types/fs-extra": "^11.0.4",
52
- "@types/node": "^25.0.2",
53
- "@vitest/coverage-v8": "^4.0.15",
52
+ "@types/node": "^25.5.0",
53
+ "@vitest/coverage-v8": "^4.1.0",
54
54
  "delay": "^7.0.0",
55
- "eslint": "^9.39.2",
55
+ "eslint": "^9.39.4",
56
56
  "eslint-config-prettier": "^10.1.8",
57
- "fs-extra": "^11.3.2",
57
+ "fs-extra": "^11.3.4",
58
58
  "husky": "^9.1.7",
59
59
  "jxa-common-used": "^0.0.3",
60
- "lint-staged": "^16.2.7",
61
- "prettier": "^3.7.4",
60
+ "lint-staged": "^16.4.0",
61
+ "prettier": "^3.8.1",
62
62
  "should": "^13.2.3",
63
63
  "typescript": "^5.9.3",
64
- "vitest": "^4.0.15"
64
+ "vitest": "^4.1.0"
65
65
  },
66
66
  "pnpm": {
67
67
  "onlyBuiltDependencies": [
package/src/chrome.ts CHANGED
@@ -1,26 +1,47 @@
1
1
  import { run } from '@jxa/run'
2
2
  import type { GoogleChrome } from 'jxa-common-used'
3
+ import { isAppRunning } from './app'
3
4
 
4
5
  export type ActiveTab = { url: string; title: string }
5
6
 
6
- export const Chrome = {
7
- async getActiveTab(): Promise<ActiveTab> {
8
- return await getChromeActiveTab()
9
- },
7
+ export enum BrowserAppName {
8
+ Chrome = 'Google Chrome',
9
+ Brave = 'Brave Browser',
10
10
  }
11
11
 
12
- export async function getChromeActiveTab(): Promise<ActiveTab> {
13
- return await run(() => {
14
- const app = Application<GoogleChrome>('Google Chrome')
15
- app.includeStandardAdditions = true
12
+ export class ChromiumBrowserHelper {
13
+ constructor(public appName: string) {}
14
+ isRunning = (): Promise<boolean> => isChromiumAppRunning(this.appName)
15
+ isFrontmost = (): Promise<boolean> => getChromiumIsFrontmost(this.appName)
16
+ getActiveTab = (): Promise<ActiveTab | undefined> => getChromiumActiveTab(this.appName)
17
+ }
16
18
 
19
+ export const Chrome = new ChromiumBrowserHelper(BrowserAppName.Chrome)
20
+ export const Brave = new ChromiumBrowserHelper(BrowserAppName.Brave)
21
+
22
+ /* #region implements */
23
+ export function isChromiumAppRunning(appName: string = BrowserAppName.Chrome): Promise<boolean> {
24
+ return isAppRunning(appName)
25
+ }
26
+ export async function getChromiumActiveTab(appName: string = BrowserAppName.Chrome): Promise<ActiveTab | undefined> {
27
+ if (!(await isChromiumAppRunning(appName))) return
28
+ return await run((appName: string) => {
29
+ const app = Application<GoogleChrome>(appName)
30
+ app.includeStandardAdditions = true
17
31
  const win = (app.windows() || []).find((w) => !w.minimized())
18
32
  const tab = win?.activeTab()
19
33
  return {
20
34
  url: tab?.url(),
21
35
  title: tab?.title(),
22
36
  }
23
- })
37
+ }, appName)
24
38
  }
25
-
26
- // getChromeActiveTab().then(console.log)
39
+ export async function getChromiumIsFrontmost(appName: string = BrowserAppName.Chrome): Promise<boolean> {
40
+ if (!isChromiumAppRunning(appName)) return false
41
+ return await run((appName: string) => {
42
+ const app = Application<GoogleChrome>(appName)
43
+ app.includeStandardAdditions = true
44
+ return app.frontmost()
45
+ }, appName)
46
+ }
47
+ /* #endregion */
package/src/finder.ts CHANGED
@@ -1,11 +1,11 @@
1
+ import { run as jxaRun } from '@jxa/run'
2
+ import { uniq } from 'es-toolkit'
3
+ import type { PathFinder as PathFinderType } from 'jxa-common-used'
1
4
  import { availableParallelism } from 'node:os'
2
5
  import path from 'node:path'
3
6
  import { fileURLToPath } from 'node:url'
4
- import { run as jxaRun } from '@jxa/run'
5
- import { uniq } from 'es-toolkit'
6
7
  import pmap from 'promise.map'
7
8
  import { isAppRunning } from './app'
8
- import type { PathFinder as PathFinderType } from 'jxa-common-used'
9
9
 
10
10
  /**
11
11
  * `App` named epxorts
@@ -124,15 +124,15 @@ async function QSpace_allSelected() {
124
124
 
125
125
  /* #region Top Level Helper */
126
126
  export function isRepresentPF(file: string) {
127
- return /^\$?pf$/i.test(file)
127
+ return /^[@$]?pf$/i.test(file)
128
128
  }
129
129
 
130
130
  export function isRepresentQS(file: string) {
131
- return /^\$?qs$/i.test(file)
131
+ return /^[@$]?qs$/i.test(file)
132
132
  }
133
133
 
134
134
  /**
135
- * 处理 $PF $QS, ignore case
135
+ * 处理 `@pf` `@qs`, ignore case
136
136
  */
137
137
  export async function normalizeInputFileList(fileList: string[]) {
138
138
  return uniq(
@@ -140,8 +140,10 @@ export async function normalizeInputFileList(fileList: string[]) {
140
140
  await pmap(
141
141
  fileList,
142
142
  async (f) => {
143
- if (isRepresentPF(f)) return await PathFinder.allSelected()
144
- if (isRepresentQS(f)) return await QSpace.allSelected()
143
+ if (process.platform === 'darwin') {
144
+ if (isRepresentPF(f)) return await PathFinder.allSelected()
145
+ if (isRepresentQS(f)) return await QSpace.allSelected()
146
+ }
145
147
  return path.resolve(f)
146
148
  },
147
149
  availableParallelism(),
@@ -152,5 +154,5 @@ export async function normalizeInputFileList(fileList: string[]) {
152
154
  /* #endregion */
153
155
 
154
156
  // ;(async () => {
155
- // console.log(await getQSpaceSelected())
157
+ // console.log(await normalizeInputFileList(['@pf']))
156
158
  // })()
package/src/iterm.ts CHANGED
@@ -2,8 +2,9 @@ import { run } from '@jxa/run'
2
2
  import type { iTerm2 } from 'jxa-common-used'
3
3
 
4
4
  export async function runInIterm(command: string, reuse = true) {
5
- await run(
6
- (command, reuse) => {
5
+ type RunResult = 'no-session' | undefined
6
+ const result: RunResult = await run(
7
+ (command, reuse): RunResult => {
7
8
  const app = Application<iTerm2>('iTerm')
8
9
  app.includeStandardAdditions = true
9
10
  app.activate()
@@ -12,7 +13,7 @@ export async function runInIterm(command: string, reuse = true) {
12
13
 
13
14
  // reuse when possible
14
15
  if (reuse) {
15
- const session: iTerm2.Session = app.currentWindow().currentSession()
16
+ const session: iTerm2.Session | undefined = app.currentWindow()?.currentSession()
16
17
  const isIdle = session?.isAtShellPrompt()
17
18
  if (isIdle) {
18
19
  usingSession = session
@@ -22,18 +23,19 @@ export async function runInIterm(command: string, reuse = true) {
22
23
  // create new tab when necessary
23
24
  if (!usingSession) {
24
25
  const tab = app.createTabWithDefaultProfile(app.currentWindow)
25
- usingSession = tab.currentSession()
26
- }
27
-
28
- if (!usingSession) {
29
- return
26
+ usingSession = tab?.currentSession() // TODO: iterm2 updated, this code no longer works
30
27
  }
31
28
 
29
+ if (!usingSession) return 'no-session'
32
30
  app.write(usingSession, { text: command })
33
31
  },
34
32
  command,
35
33
  reuse,
36
34
  )
35
+
36
+ if (result === 'no-session') {
37
+ console.error('No iTerm session found')
38
+ }
37
39
  }
38
40
 
39
41
  export const iTerm = {