mac-helper 0.1.2 → 0.1.4

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/README.md CHANGED
@@ -2,8 +2,9 @@
2
2
 
3
3
  > useful helper for macOS
4
4
 
5
- [![Build Status](https://img.shields.io/github/actions/workflow/status/magicdawn/mac-helper/ci.yml?style=flat-square&branch=main)](https://github.com/magicdawn/mac-helper/actions/workflows/ci.yml)
6
- [![Coverage Status](https://img.shields.io/codecov/c/github/magicdawn/mac-helper.svg?style=flat-square)](https://codecov.io/gh/magicdawn/mac-helper)
5
+ <!-- [![Build Status](https://img.shields.io/github/actions/workflow/status/magicdawn/mac-helper/ci.yml?style=flat-square&branch=main)](https://github.com/magicdawn/mac-helper/actions/workflows/ci.yml)
6
+ [![Coverage Status](https://img.shields.io/codecov/c/github/magicdawn/mac-helper.svg?style=flat-square)](https://codecov.io/gh/magicdawn/mac-helper) -->
7
+
7
8
  [![npm version](https://img.shields.io/npm/v/mac-helper.svg?style=flat-square)](https://www.npmjs.com/package/mac-helper)
8
9
  [![npm downloads](https://img.shields.io/npm/dm/mac-helper.svg?style=flat-square)](https://www.npmjs.com/package/mac-helper)
9
10
  [![npm license](https://img.shields.io/npm/l/mac-helper.svg?style=flat-square)](http://magicdawn.mit-license.org)
@@ -16,8 +17,8 @@ $ pnpm add mac-helper
16
17
 
17
18
  ## API
18
19
 
19
- ```js
20
- const MacHelper = require('mac-helper')
20
+ ```ts
21
+ import * as MacHelper from 'mac-helper'
21
22
  ```
22
23
 
23
24
  ## Changelog
package/lib/app.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * file path based process running detect.
3
+ * for vscode, process name = `Code`, file is `Visual Studio Code.app`, the `Visual Studio Code` should be passed
4
+ */
5
+ export declare function isAppRunning(appName: string): Promise<boolean>;
package/lib/app.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isAppRunning = void 0;
4
+ const child_process_1 = require("child_process");
5
+ /**
6
+ * file path based process running detect.
7
+ * for vscode, process name = `Code`, file is `Visual Studio Code.app`, the `Visual Studio Code` should be passed
8
+ */
9
+ async function isAppRunning(appName) {
10
+ return new Promise((resolve, reject) => {
11
+ (0, child_process_1.exec)(`ps -ax -o command`, (err, stdout, stderr) => {
12
+ if (err)
13
+ return reject(err);
14
+ const lines = stdout
15
+ .trim()
16
+ .split('\n')
17
+ .map((x) => x.trim())
18
+ .filter(Boolean);
19
+ const searchText = `${appName}.app/Contents/MacOS/`;
20
+ const running = !!lines.find((line) => line.includes(searchText));
21
+ resolve(running);
22
+ });
23
+ });
24
+ }
25
+ exports.isAppRunning = isAppRunning;
26
+ // isAppRunning('Visual Studio Code').then(console.log)
package/lib/finder.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export declare function getPathFinderSelected(): Promise<string[]>;
2
- export declare function getFinderSelected(): Promise<string[]>;
1
+ /**
2
+ * `App` named epxorts
3
+ */
3
4
  export declare const PathFinder: {
4
5
  allSelected(): Promise<string[]>;
5
6
  singleSelected(): Promise<string | undefined>;
@@ -8,3 +9,18 @@ export declare const Finder: {
8
9
  allSelected(): Promise<string[]>;
9
10
  singleSelected(): Promise<string | undefined>;
10
11
  };
12
+ export declare const QSpace: {
13
+ allSelected(): Promise<string[]>;
14
+ singleSelected(): Promise<string | undefined>;
15
+ };
16
+ /**
17
+ * impls
18
+ */
19
+ export declare function getPathFinderSelected(): Promise<string[]>;
20
+ export declare function getFinderSelected(): Promise<string[]>;
21
+ export type QSpaceFileItem = {
22
+ id: () => string;
23
+ name: () => string;
24
+ urlstr: () => string;
25
+ };
26
+ export declare function getQSpaceSelected(): Promise<string[]>;
package/lib/finder.js CHANGED
@@ -1,8 +1,38 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Finder = exports.PathFinder = exports.getFinderSelected = exports.getPathFinderSelected = void 0;
3
+ exports.getQSpaceSelected = exports.getFinderSelected = exports.getPathFinderSelected = exports.QSpace = exports.Finder = exports.PathFinder = void 0;
4
4
  const run_1 = require("@jxa/run");
5
5
  const url_1 = require("url");
6
+ /**
7
+ * `App` named epxorts
8
+ */
9
+ exports.PathFinder = {
10
+ async allSelected() {
11
+ return getPathFinderSelected();
12
+ },
13
+ async singleSelected() {
14
+ return (await getPathFinderSelected())[0];
15
+ },
16
+ };
17
+ exports.Finder = {
18
+ async allSelected() {
19
+ return getFinderSelected();
20
+ },
21
+ async singleSelected() {
22
+ return (await getFinderSelected())[0];
23
+ },
24
+ };
25
+ exports.QSpace = {
26
+ async allSelected() {
27
+ return getQSpaceSelected();
28
+ },
29
+ async singleSelected() {
30
+ return (await getQSpaceSelected())[0];
31
+ },
32
+ };
33
+ /**
34
+ * impls
35
+ */
6
36
  async function getPathFinderSelected() {
7
37
  const filePaths = await (0, run_1.run)(() => {
8
38
  const app = Application('Path Finder');
@@ -20,22 +50,15 @@ async function getFinderSelected() {
20
50
  return urls.map((u) => (0, url_1.fileURLToPath)(u));
21
51
  }
22
52
  exports.getFinderSelected = getFinderSelected;
23
- exports.PathFinder = {
24
- async allSelected() {
25
- return getPathFinderSelected();
26
- },
27
- async singleSelected() {
28
- return (await getPathFinderSelected())[0];
29
- },
30
- };
31
- exports.Finder = {
32
- async allSelected() {
33
- return getFinderSelected();
34
- },
35
- async singleSelected() {
36
- return (await getFinderSelected())[0];
37
- },
38
- };
53
+ async function getQSpaceSelected() {
54
+ const urls = await (0, run_1.run)(() => {
55
+ const app = Application('QSpace Pro');
56
+ const selection = (app.selectedItems() || []).map((x) => x.urlstr());
57
+ return selection;
58
+ });
59
+ return urls.map((u) => (0, url_1.fileURLToPath)(u));
60
+ }
61
+ exports.getQSpaceSelected = getQSpaceSelected;
39
62
  // ;(async () => {
40
- // console.log(await PathFinder.allSelected())
63
+ // console.log(await getQSpaceSelected())
41
64
  // })()
package/lib/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './app';
1
2
  export * from './chrome';
2
3
  export * from './dialog';
3
4
  export * from './finder';
package/lib/index.js CHANGED
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
17
17
  };
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
+ __exportStar(require("./app"), exports);
19
20
  __exportStar(require("./chrome"), exports);
20
21
  __exportStar(require("./dialog"), exports);
21
22
  __exportStar(require("./finder"), exports);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const run_1 = require("@jxa/run");
4
+ /**
5
+ * 不太准确, 比如 vscode 进程 `Code` 在运行, 检测不到
6
+ */
7
+ async function isAppRunning(appName) {
8
+ return await (0, run_1.run)((appName) => {
9
+ const app = Application('System Events');
10
+ app.includeStandardAdditions = true;
11
+ const runningAppNames = app
12
+ .processes()
13
+ .map((p) => p.name());
14
+ return runningAppNames.includes(appName);
15
+ }, appName);
16
+ }
17
+ async function getRunningAppNames() {
18
+ return await (0, run_1.run)(() => {
19
+ const app = Application('System Events');
20
+ app.includeStandardAdditions = true;
21
+ const runningAppNames = app
22
+ .processes()
23
+ .map((p) => p.name());
24
+ return runningAppNames;
25
+ });
26
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mac-helper",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "useful helper for macOS",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -39,27 +39,26 @@
39
39
  "@jxa/global-type": "^1.3.6",
40
40
  "@jxa/sdef-to-dts": "^1.3.6",
41
41
  "@jxa/types": "^1.3.6",
42
- "@magicdawn/prettier-config": "^0.0.2",
43
- "@swc/core": "1.3.78",
44
- "@types/fs-extra": "^11.0.2",
45
- "@types/mocha": "^10.0.1",
46
- "@types/node": "^20.6.2",
47
- "@typescript-eslint/eslint-plugin": "^6.7.0",
48
- "@typescript-eslint/parser": "^6.7.0",
49
- "@vitest/coverage-v8": "^0.34.4",
50
- "delay": "^5.0.0",
51
- "eslint": "^8.49.0",
52
- "eslint-config-prettier": "^9.0.0",
53
- "fs-extra": "^11.1.1",
54
- "husky": "^8.0.3",
42
+ "@magicdawn/prettier-config": "^0.0.3",
43
+ "@swc/core": "1.5.7",
44
+ "@types/fs-extra": "^11.0.4",
45
+ "@types/mocha": "^10.0.6",
46
+ "@types/node": "^20.12.12",
47
+ "@typescript-eslint/eslint-plugin": "^7.10.0",
48
+ "@typescript-eslint/parser": "^7.10.0",
49
+ "@vitest/coverage-v8": "^1.6.0",
50
+ "delay": "^6.0.0",
51
+ "eslint": "^9.3.0",
52
+ "eslint-config-prettier": "^9.1.0",
53
+ "fs-extra": "^11.2.0",
54
+ "husky": "^9.0.11",
55
55
  "jxa-common-used": "^0.0.3",
56
- "lint-staged": "^14.0.1",
57
- "prettier": "^3.0.3",
56
+ "lint-staged": "^15.2.4",
57
+ "prettier": "^3.2.5",
58
58
  "should": "^13.2.3",
59
- "typescript": "^5.2.2",
60
- "vitest": "^0.34.4"
59
+ "typescript": "^5.4.5",
60
+ "vitest": "^1.6.0"
61
61
  },
62
- "packageManager": "pnpm@8.7.5",
63
62
  "publishConfig": {
64
63
  "registry": "https://registry.npmjs.org"
65
64
  },
@@ -67,5 +66,6 @@
67
66
  "*.{js,jsx,ts,tsx,less,md}": [
68
67
  "prettier --write"
69
68
  ]
70
- }
69
+ },
70
+ "packageManager": "pnpm@9.1.2+sha512.127dc83b9ea10c32be65d22a8efb4a65fb952e8fefbdfded39bdc3c97efc32d31b48b00420df2c1187ace28c921c902f0cb5a134a4d032b8b5295cbfa2c681e2"
71
71
  }
package/src/app.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { exec } from 'child_process'
2
+
3
+ /**
4
+ * file path based process running detect.
5
+ * for vscode, process name = `Code`, file is `Visual Studio Code.app`, the `Visual Studio Code` should be passed
6
+ */
7
+
8
+ export async function isAppRunning(appName: string): Promise<boolean> {
9
+ return new Promise((resolve, reject) => {
10
+ exec(`ps -ax -o command`, (err, stdout, stderr) => {
11
+ if (err) return reject(err)
12
+
13
+ const lines = stdout
14
+ .trim()
15
+ .split('\n')
16
+ .map((x) => x.trim())
17
+ .filter(Boolean)
18
+ const searchText = `${appName}.app/Contents/MacOS/`
19
+
20
+ const running = !!lines.find((line) => line.includes(searchText))
21
+ resolve(running)
22
+ })
23
+ })
24
+ }
25
+
26
+ // isAppRunning('Visual Studio Code').then(console.log)
package/src/finder.ts CHANGED
@@ -2,6 +2,38 @@ import { run as jxaRun } from '@jxa/run'
2
2
  import { type PathFinder as PathFinderType } from 'jxa-common-used'
3
3
  import { fileURLToPath } from 'url'
4
4
 
5
+ /**
6
+ * `App` named epxorts
7
+ */
8
+ export const PathFinder = {
9
+ async allSelected() {
10
+ return getPathFinderSelected()
11
+ },
12
+ async singleSelected(): Promise<string | undefined> {
13
+ return (await getPathFinderSelected())[0]
14
+ },
15
+ }
16
+ export const Finder = {
17
+ async allSelected() {
18
+ return getFinderSelected()
19
+ },
20
+ async singleSelected(): Promise<string | undefined> {
21
+ return (await getFinderSelected())[0]
22
+ },
23
+ }
24
+ export const QSpace = {
25
+ async allSelected() {
26
+ return getQSpaceSelected()
27
+ },
28
+ async singleSelected(): Promise<string | undefined> {
29
+ return (await getQSpaceSelected())[0]
30
+ },
31
+ }
32
+
33
+ /**
34
+ * impls
35
+ */
36
+
5
37
  export async function getPathFinderSelected() {
6
38
  const filePaths: string[] = await jxaRun(() => {
7
39
  const app = Application<PathFinderType>('Path Finder')
@@ -19,24 +51,29 @@ export async function getFinderSelected() {
19
51
  return urls.map((u) => fileURLToPath(u))
20
52
  }
21
53
 
22
- export const PathFinder = {
23
- async allSelected() {
24
- return getPathFinderSelected()
25
- },
26
- async singleSelected(): Promise<string | undefined> {
27
- return (await getPathFinderSelected())[0]
28
- },
54
+ // file item n [inh. item] : A file item.
55
+ // properties
56
+ // - id (text, r/o) : The unique identifier of the item.
57
+ // - name (text, r/o) : The name of the file.
58
+ // - urlstr (text, r/o) : The absolute string of URL of the file.
59
+ export type QSpaceFileItem = {
60
+ // the unique identifier of the item
61
+ id: () => string
62
+ // the name of the file
63
+ name: () => string
64
+ // the absolute string of URL of the file
65
+ urlstr: () => string
29
66
  }
30
67
 
31
- export const Finder = {
32
- async allSelected() {
33
- return getFinderSelected()
34
- },
35
- async singleSelected(): Promise<string | undefined> {
36
- return (await getFinderSelected())[0]
37
- },
68
+ export async function getQSpaceSelected() {
69
+ const urls: string[] = await jxaRun(() => {
70
+ const app = Application('QSpace Pro')
71
+ const selection = (app.selectedItems() || []).map((x: QSpaceFileItem) => x.urlstr())
72
+ return selection
73
+ })
74
+ return urls.map((u) => fileURLToPath(u))
38
75
  }
39
76
 
40
77
  // ;(async () => {
41
- // console.log(await PathFinder.allSelected())
78
+ // console.log(await getQSpaceSelected())
42
79
  // })()
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  /// <reference types='@jxa/global-type' />
2
2
  /// <reference types='@jxa/types' />
3
3
 
4
+ export * from './app'
4
5
  export * from './chrome'
5
6
  export * from './dialog'
6
7
  export * from './finder'
@@ -0,0 +1,28 @@
1
+ import { run } from '@jxa/run'
2
+ import type { SystemEvents } from '@jxa/types'
3
+
4
+ /**
5
+ * 不太准确, 比如 vscode 进程 `Code` 在运行, 检测不到
6
+ */
7
+
8
+ async function isAppRunning(appName: string): Promise<boolean> {
9
+ return await run((appName) => {
10
+ const app = Application<SystemEvents.SystemEvents.Application>('System Events')
11
+ app.includeStandardAdditions = true
12
+ const runningAppNames: string[] = app
13
+ .processes()
14
+ .map((p: SystemEvents.SystemEvents.Process) => p.name())
15
+ return runningAppNames.includes(appName)
16
+ }, appName)
17
+ }
18
+
19
+ async function getRunningAppNames(): Promise<string[]> {
20
+ return await run(() => {
21
+ const app = Application<SystemEvents.SystemEvents.Application>('System Events')
22
+ app.includeStandardAdditions = true
23
+ const runningAppNames: string[] = app
24
+ .processes()
25
+ .map((p: SystemEvents.SystemEvents.Process) => p.name())
26
+ return runningAppNames
27
+ })
28
+ }