@mac-bug-screenshot/native-host 1.0.1
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 +20 -0
- package/bin/install.js +44 -0
- package/host.js +97 -0
- package/manifest.template.json +7 -0
- package/package.json +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# mac-bug-screenshot native host (npm)
|
|
2
|
+
|
|
3
|
+
크롬 확장 프로그램이 macOS `screencapture`를 호출할 수 있도록 네이티브 메시징 호스트를 설치합니다.
|
|
4
|
+
|
|
5
|
+
## 설치
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @mac-bug-screenshot/native-host
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 등록
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
mac-bug-screenshot-install <확장_프로그램_ID>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 동작
|
|
18
|
+
|
|
19
|
+
- 전체 화면 캡처 후 Preview를 자동으로 엽니다.
|
|
20
|
+
- 저장 경로는 확장 프로그램에서 전달받습니다.
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const os = require("os");
|
|
5
|
+
|
|
6
|
+
const HOST_NAME = "com.sobbangcompany.mac_bug_screenshot";
|
|
7
|
+
const ROOT_DIR = path.resolve(__dirname, "..");
|
|
8
|
+
const TEMPLATE_PATH = path.join(ROOT_DIR, "manifest.template.json");
|
|
9
|
+
const HOST_PATH = path.join(ROOT_DIR, "host.js");
|
|
10
|
+
const TARGET_DIR = path.join(
|
|
11
|
+
os.homedir(),
|
|
12
|
+
"Library",
|
|
13
|
+
"Application Support",
|
|
14
|
+
"Google",
|
|
15
|
+
"Chrome",
|
|
16
|
+
"NativeMessagingHosts"
|
|
17
|
+
);
|
|
18
|
+
const TARGET_PATH = path.join(TARGET_DIR, `${HOST_NAME}.json`);
|
|
19
|
+
|
|
20
|
+
function printUsage() {
|
|
21
|
+
console.log("사용법: mac-bug-screenshot-install <확장_프로그램_ID>");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function main() {
|
|
25
|
+
const extensionId = process.argv[2];
|
|
26
|
+
if (!extensionId) {
|
|
27
|
+
printUsage();
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const template = fs.readFileSync(TEMPLATE_PATH, "utf8");
|
|
32
|
+
const manifest = template
|
|
33
|
+
.replace(/__HOST_PATH__/g, HOST_PATH)
|
|
34
|
+
.replace(/__EXTENSION_ID__/g, extensionId);
|
|
35
|
+
|
|
36
|
+
fs.mkdirSync(TARGET_DIR, { recursive: true });
|
|
37
|
+
fs.writeFileSync(TARGET_PATH, manifest);
|
|
38
|
+
fs.chmodSync(HOST_PATH, 0o755);
|
|
39
|
+
|
|
40
|
+
console.log("Native host 등록 완료:");
|
|
41
|
+
console.log(TARGET_PATH);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
main();
|
package/host.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const os = require("os");
|
|
4
|
+
const { execFile } = require("child_process");
|
|
5
|
+
|
|
6
|
+
const DEFAULT_OUTPUT_DIR = path.join(os.homedir(), "Desktop", "mac-bug-screenshot");
|
|
7
|
+
|
|
8
|
+
function expandHome(input) {
|
|
9
|
+
if (!input) {
|
|
10
|
+
return input;
|
|
11
|
+
}
|
|
12
|
+
const home = os.homedir();
|
|
13
|
+
return input
|
|
14
|
+
.replace(/^~(?=\/|$)/, home)
|
|
15
|
+
.replace(/\$HOME/g, home);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function runCommand(command, args) {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
execFile(command, args, (error) => {
|
|
21
|
+
if (error) {
|
|
22
|
+
reject(error);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
resolve();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function capture(outputDir) {
|
|
31
|
+
const resolvedDir = expandHome(outputDir || DEFAULT_OUTPUT_DIR);
|
|
32
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
33
|
+
const outputPath = path.join(resolvedDir, `screenshot-${timestamp}.png`);
|
|
34
|
+
|
|
35
|
+
await fs.promises.mkdir(resolvedDir, { recursive: true });
|
|
36
|
+
await runCommand("screencapture", ["-x", "-t", "png", outputPath]);
|
|
37
|
+
await runCommand("open", ["-a", "Preview", outputPath]);
|
|
38
|
+
|
|
39
|
+
return outputPath;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function writeMessage(message) {
|
|
43
|
+
const json = JSON.stringify(message);
|
|
44
|
+
const buffer = Buffer.from(json, "utf8");
|
|
45
|
+
const length = Buffer.alloc(4);
|
|
46
|
+
length.writeUInt32LE(buffer.length, 0);
|
|
47
|
+
process.stdout.write(Buffer.concat([length, buffer]));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function readMessage() {
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
const lengthBuffer = Buffer.alloc(4);
|
|
53
|
+
let lengthOffset = 0;
|
|
54
|
+
|
|
55
|
+
function readLength(chunk) {
|
|
56
|
+
chunk.copy(lengthBuffer, lengthOffset);
|
|
57
|
+
lengthOffset += chunk.length;
|
|
58
|
+
if (lengthOffset >= 4) {
|
|
59
|
+
const length = lengthBuffer.readUInt32LE(0);
|
|
60
|
+
const messageBuffer = Buffer.alloc(length);
|
|
61
|
+
let messageOffset = 0;
|
|
62
|
+
|
|
63
|
+
function readMessageBody(bodyChunk) {
|
|
64
|
+
bodyChunk.copy(messageBuffer, messageOffset);
|
|
65
|
+
messageOffset += bodyChunk.length;
|
|
66
|
+
if (messageOffset >= length) {
|
|
67
|
+
process.stdin.removeListener("data", readMessageBody);
|
|
68
|
+
resolve(JSON.parse(messageBuffer.toString("utf8")));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
process.stdin.removeListener("data", readLength);
|
|
73
|
+
process.stdin.on("data", readMessageBody);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
process.stdin.on("data", readLength);
|
|
78
|
+
process.stdin.on("error", reject);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function main() {
|
|
83
|
+
try {
|
|
84
|
+
const message = await readMessage();
|
|
85
|
+
if (!message || message.action !== "capture") {
|
|
86
|
+
writeMessage({ ok: false, error: "지원하지 않는 요청입니다." });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const outputPath = await capture(message.outputDir);
|
|
91
|
+
writeMessage({ ok: true, outputPath });
|
|
92
|
+
} catch (error) {
|
|
93
|
+
writeMessage({ ok: false, error: error.message });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mac-bug-screenshot/native-host",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Native messaging host for Mac Bug Screenshot.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"mac-bug-screenshot-install": "bin/install.js"
|
|
7
|
+
},
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"main": "host.js",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"mac",
|
|
15
|
+
"screenshot",
|
|
16
|
+
"bug"
|
|
17
|
+
],
|
|
18
|
+
"author": "sobbang"
|
|
19
|
+
}
|