@crosscopy/clipboard 0.1.0-beta-1 → 0.1.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 CHANGED
@@ -93,4 +93,17 @@ The process here is from nodejs.
93
93
 
94
94
  Supported platforms can be found in `go-clipboard-monitor`.
95
95
 
96
- If your nodejs gives different platform or arch, it may not work.
96
+ If your nodejs gives different platform or arch, it may not work.
97
+
98
+ ## Release
99
+
100
+ Cross Compile doesn't work due to some CGO problem. Have to build on different platforms manually.
101
+
102
+ ```bash
103
+ go build -o binaries/go-clipboard-darwin-arm64
104
+ go build -o binaries/go-clipboard-darwin-x64
105
+ go build -o binaries/go-clipboard-win32-x64.exe
106
+ go build -o binaries/go-clipboard-linux-x64
107
+ go build -o binaries/go-clipboard-linux-arm
108
+ go build -o binaries/go-clipboard-linux-arm64
109
+ ```
package/dist/demo.js CHANGED
@@ -3,12 +3,16 @@
3
3
  var fs = require('fs');
4
4
  var path = require('path');
5
5
  var events = require('events');
6
+ var net = require('net');
6
7
  var child_process = require('child_process');
8
+ var util = require('util');
7
9
 
8
10
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
11
 
10
12
  var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
11
13
  var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
14
+ var net__default = /*#__PURE__*/_interopDefaultLegacy(net);
15
+ var util__default = /*#__PURE__*/_interopDefaultLegacy(util);
12
16
 
13
17
  var __getOwnPropNames = Object.getOwnPropertyNames;
14
18
  var __esm = (fn, res) => function __init() {
@@ -17,75 +21,201 @@ var __esm = (fn, res) => function __init() {
17
21
  var __commonJS = (cb, mod) => function __require() {
18
22
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
19
23
  };
20
- var ClipboardEventListener, clipboard_default;
24
+
25
+ // src/util.ts
26
+ var base64StringToUTF8, base64BufToUTF8;
27
+ var init_util = __esm({
28
+ "src/util.ts"() {
29
+ base64StringToUTF8 = (base64Str) => {
30
+ const base64buf = Buffer.from(base64Str, "base64");
31
+ const text = base64buf.toString("utf8");
32
+ return text;
33
+ };
34
+ base64BufToUTF8 = (buf) => {
35
+ const base64Text = buf.toString();
36
+ return base64StringToUTF8(base64Text);
37
+ };
38
+ }
39
+ });
40
+
41
+ // src/constants.ts
42
+ var init_constants = __esm({
43
+ "src/constants.ts"() {
44
+ }
45
+ });
46
+ var execFileAsync, Clipboard, clipboard_default;
21
47
  var init_clipboard = __esm({
22
48
  "index.ts"() {
23
- ClipboardEventListener = class extends events.EventEmitter {
49
+ init_util();
50
+ init_constants();
51
+ execFileAsync = util__default["default"].promisify(child_process.execFile);
52
+ Clipboard = class {
24
53
  constructor() {
25
- super();
26
54
  this.child = void 0;
55
+ this.emitter = new events.EventEmitter();
27
56
  }
28
- startListening() {
29
- var _a, _b;
57
+ get exeFilename() {
30
58
  const { platform, arch } = process;
31
- const pathArr = [__dirname];
32
- if (path__default["default"].basename(__dirname) === "dist") {
33
- pathArr.push("..");
34
- }
35
59
  let exeFilename = `go-clipboard-${platform}-${arch}`;
36
60
  if (platform === "win32") {
37
61
  exeFilename += ".exe";
38
62
  }
39
- pathArr.push(...["go-clipboard", "binaries", exeFilename]);
63
+ return exeFilename;
64
+ }
65
+ get goClipboardPath() {
66
+ const pathArr = [__dirname];
67
+ if (path__default["default"].basename(__dirname) === "dist") {
68
+ pathArr.push("..");
69
+ }
70
+ pathArr.push(...["go-clipboard", "binaries", this.exeFilename]);
40
71
  const exePath = path__default["default"].join(...pathArr);
41
- console.log(exePath);
42
- if (!fs__default["default"].existsSync(exePath)) {
43
- throw new Error(
44
- `Executable (${exeFilename}) not found, your platform is ${platform} ${arch} and may not be supported.`
45
- );
72
+ return exePath;
73
+ }
74
+ readText() {
75
+ return execFileAsync(this.goClipboardPath, [
76
+ "READ_TEXT" /* READ_TEXT */
77
+ ]).then((result) => {
78
+ return base64StringToUTF8(result.stdout);
79
+ });
80
+ }
81
+ readTextSync() {
82
+ const buf = child_process.execFileSync(this.goClipboardPath, [
83
+ "READ_TEXT" /* READ_TEXT */
84
+ ]);
85
+ return base64BufToUTF8(buf);
86
+ }
87
+ writeText(content) {
88
+ return Promise.resolve(this.writeTextSync(content));
89
+ }
90
+ writeTextSync(content) {
91
+ var _a, _b;
92
+ const writeTextProcess = child_process.execFile(this.goClipboardPath, [
93
+ "WRITE_TEXT" /* WRITE_TEXT */
94
+ ]);
95
+ (_a = writeTextProcess.stdin) == null ? void 0 : _a.write(content);
96
+ (_b = writeTextProcess.stdin) == null ? void 0 : _b.end();
97
+ }
98
+ writeImageSync(data) {
99
+ var _a, _b;
100
+ if (data instanceof String || typeof data === "string") {
101
+ const writeImageProcess = child_process.execFile(this.goClipboardPath, [
102
+ "WRITE_IMAGE" /* WRITE_IMAGE */
103
+ ]);
104
+ (_a = writeImageProcess.stdin) == null ? void 0 : _a.write(data);
105
+ (_b = writeImageProcess.stdin) == null ? void 0 : _b.end();
106
+ } else if (data instanceof Buffer) {
107
+ this.writeImageSync(data.toString("base64"));
108
+ } else {
109
+ throw new Error("Invalid Data Type. Has to be string or Buffer");
110
+ }
111
+ }
112
+ writeImage(data) {
113
+ if (data instanceof String || typeof data === "string") {
114
+ return Promise.resolve(this.writeImageSync(data));
115
+ } else if (data instanceof Buffer) {
116
+ return Promise.resolve(this.writeImageSync(data));
117
+ } else {
118
+ throw new Error("Invalid Data Type. Has to be string or Buffer");
46
119
  }
47
- this.child = child_process.execFile(exePath);
48
- (_a = this.child.stdout) == null ? void 0 : _a.on("data", (data) => {
49
- const dataStr = data.toString();
50
- if (dataStr.trim() === "TEXT_CHANGED") {
51
- this.emit("text");
52
- }
53
- if (dataStr.trim() === "IMAGE_CHANGED") {
54
- this.emit("image");
55
- }
120
+ }
121
+ readImage() {
122
+ return Promise.resolve(this.readImageSync());
123
+ }
124
+ readImageBase64() {
125
+ return Promise.resolve(this.readImageBase64Sync());
126
+ }
127
+ readImageSync() {
128
+ const buf = child_process.execFileSync(this.goClipboardPath, [
129
+ "READ_IMAGE" /* READ_IMAGE */
130
+ ]);
131
+ const stdoutStr = buf.toString();
132
+ const imgBuf = Buffer.from(stdoutStr, "base64");
133
+ fs__default["default"].writeFileSync("test.png", imgBuf);
134
+ return imgBuf;
135
+ }
136
+ readImageBase64Sync() {
137
+ return this.readImageSync().toString("base64");
138
+ }
139
+ listen() {
140
+ this.server = net__default["default"].createServer((con) => {
141
+ let data = "";
142
+ con.on("data", (packet) => {
143
+ data += packet.toString();
144
+ });
145
+ con.on("close", () => {
146
+ const strData = data.toString();
147
+ const subStr = strData.substring(0, 14);
148
+ if (subStr.includes(`${"TEXT_CHANGED" /* TEXT_CHANGED */}:`)) {
149
+ const text = Buffer.from(strData.substring(13), "base64").toString();
150
+ this.emitter.emit("text", text);
151
+ } else if (subStr.includes(`${"IMAGE_CHANGED" /* IMAGE_CHANGED */}:`)) {
152
+ const data2 = strData.substring(14);
153
+ this.emitter.emit("image", Buffer.from(data2, "base64"));
154
+ }
155
+ });
56
156
  });
57
- (_b = this.child.stderr) == null ? void 0 : _b.on("data", (data) => {
58
- this.emit("open", data.toString());
157
+ this.server.listen(8090, () => {
158
+ var _a;
159
+ const addr = (_a = this.server) == null ? void 0 : _a.address();
160
+ if (!addr)
161
+ throw new Error("Unexpected Error: TCP Socket Server not Started");
162
+ const port = addr.port;
163
+ this.child = child_process.execFile(this.goClipboardPath, [port.toString()]);
59
164
  });
60
165
  }
61
- stopListening() {
62
- var _a;
63
- this.emit("close");
64
- const res = (_a = this.child) == null ? void 0 : _a.kill();
166
+ close() {
167
+ var _a, _b;
168
+ this.emitter.emit("close");
169
+ this.emitter.removeAllListeners();
170
+ (_a = this.server) == null ? void 0 : _a.close();
171
+ const res = (_b = this.child) == null ? void 0 : _b.kill();
65
172
  return res;
66
173
  }
174
+ on(event, cb) {
175
+ this.emitter.on(event, cb);
176
+ }
67
177
  };
68
- clipboard_default = new ClipboardEventListener();
178
+ clipboard_default = new Clipboard();
69
179
  }
70
180
  });
71
181
 
72
- // demo.ts
182
+ // __tests__/data.ts
183
+ var base64img;
184
+ var init_data = __esm({
185
+ "__tests__/data.ts"() {
186
+ base64img = "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAgACADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDumIVSx6AZrD0LxPba9d3sFujD7K+xie5rVvpPJsJ5P7qE/pXn3woXdY6rfdWluWNcEYpxbOlvVI9JormvDPioa/eahbGHy3tJNh966WpaadmUnfYy/ESzP4fvVgUtK0TBQOpOK8s8Kaj4q8P6MbC38PPJlifMbjOa9npMD0FXGdlaxLjd3ueFeDr/AMTReJtRjsrSPzpJd1yr/wAHPavc4S5hQyDD4G761mWXh6xsNWudSgQrPcffPY1rUVJqT0CEWkf/2Q==";
187
+ }
188
+ });
73
189
  var require_demo = __commonJS({
74
190
  "demo.ts"() {
75
191
  init_clipboard();
76
- clipboard_default.on("text", () => {
77
- console.log("Clipboard Text Updated");
78
- });
79
- clipboard_default.on("image", () => {
80
- console.log("Clipboard Image Updated");
81
- });
82
- clipboard_default.on("open", (data) => {
83
- console.log(data);
84
- });
85
- clipboard_default.startListening();
86
- setTimeout(() => {
87
- clipboard_default.stopListening();
88
- }, 1e4);
192
+ init_data();
193
+ (async function() {
194
+ console.log(clipboard_default.readTextSync());
195
+ console.log(await clipboard_default.readText());
196
+ clipboard_default.readImageSync();
197
+ clipboard_default.writeImageSync(base64img);
198
+ console.log("");
199
+ console.assert(clipboard_default.readImageBase64Sync() === base64img);
200
+ clipboard_default.writeImageSync(base64img);
201
+ console.log();
202
+ console.assert(
203
+ (await clipboard_default.readImage()).toString("base64") === base64img
204
+ );
205
+ await clipboard_default.writeImage(base64img);
206
+ console.log();
207
+ console.assert(await clipboard_default.readImageBase64() === base64img);
208
+ clipboard_default.on("text", (text) => {
209
+ console.log(text);
210
+ });
211
+ clipboard_default.on("image", (data) => {
212
+ fs__default["default"].writeFileSync("test.png", data);
213
+ });
214
+ clipboard_default.listen();
215
+ setTimeout(() => {
216
+ clipboard_default.close();
217
+ }, 1e4);
218
+ })();
89
219
  }
90
220
  });
91
221
  var demo = require_demo();
package/dist/demo.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts","../demo.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,oBAAoB;AAC7B,SAAgB,gBAA8D;AAH9E,IAKM,wBAkDC;AAvDP;AAAA;AAAA;AAKA,IAAM,yBAAN,cAAqC,aAAa;AAAA,MAEhD,cAAc;AACZ,cAAM;AACN,aAAK,QAAQ;AAAA,MACf;AAAA,MAEA,iBAAiB;AAZnB;AAaI,cAAM,EAAE,UAAU,KAAK,IAAI;AAC3B,cAAM,UAAU,CAAC,SAAS;AAE1B,YAAI,KAAK,SAAS,SAAS,MAAM,QAAQ;AACvC,kBAAQ,KAAK,IAAI;AAAA,QACnB;AACA,YAAI,cAAc,gBAAgB,YAAY;AAC9C,YAAI,aAAa,SAAS;AACxB,yBAAe;AAAA,QACjB;AACA,gBAAQ,KAAK,GAAG,CAAC,gBAAgB,YAAY,WAAW,CAAC;AACzD,cAAM,UAAU,KAAK,KAAK,GAAG,OAAO;AACpC,gBAAQ,IAAI,OAAO;AAEnB,YAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,gBAAM,IAAI;AAAA,YACR,eAAe,4CAA4C,YAAY;AAAA,UACzE;AAAA,QACF;AACA,aAAK,QAAQ,SAAS,OAAO;AAC7B,mBAAK,MAAM,WAAX,mBAAmB,GAAG,QAAQ,CAAC,SAAiB;AAC9C,gBAAM,UAAU,KAAK,SAAS;AAC9B,cAAI,QAAQ,KAAK,MAAM,gBAAgB;AACrC,iBAAK,KAAK,MAAM;AAAA,UAClB;AACA,cAAI,QAAQ,KAAK,MAAM,iBAAiB;AACtC,iBAAK,KAAK,OAAO;AAAA,UACnB;AAAA,QACF;AAEA,mBAAK,MAAM,WAAX,mBAAmB,GAAG,QAAQ,CAAC,SAAiB;AAC9C,eAAK,KAAK,QAAQ,KAAK,SAAS,CAAC;AAAA,QACnC;AAAA,MACF;AAAA,MAEA,gBAAgB;AAhDlB;AAiDI,aAAK,KAAK,OAAO;AACjB,cAAM,OAAM,UAAK,UAAL,mBAAY;AACxB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,IAAO,oBAAQ,IAAI,uBAAuB;AAAA;AAAA;;;ACvD1C;AAAA;AAAA;AAEA,sBAAuB,GAAG,QAAQ,MAAM;AACtC,cAAQ,IAAI,wBAAwB;AAAA,IACtC,CAAC;AAED,sBAAuB,GAAG,SAAS,MAAM;AACvC,cAAQ,IAAI,yBAAyB;AAAA,IACvC,CAAC;AAED,sBAAuB,GAAG,QAAQ,CAAC,SAAS;AAC1C,cAAQ,IAAI,IAAI;AAAA,IAClB,CAAC;AAED,sBAAuB,eAAe;AAEtC,eAAW,MAAM;AACf,wBAAuB,cAAc;AAAA,IACvC,GAAG,GAAK;AAAA;AAAA","sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { EventEmitter } from 'events';\nimport { spawn, execFile, ChildProcessWithoutNullStreams, ChildProcess } from 'node:child_process';\n\nclass ClipboardEventListener extends EventEmitter {\n child: ChildProcess | undefined;\n constructor() {\n super();\n this.child = undefined;\n }\n\n startListening() {\n const { platform, arch } = process;\n const pathArr = [__dirname];\n\n if (path.basename(__dirname) === 'dist') {\n pathArr.push('..');\n }\n let exeFilename = `go-clipboard-${platform}-${arch}`;\n if (platform === 'win32') {\n exeFilename += '.exe';\n }\n pathArr.push(...['go-clipboard', 'binaries', exeFilename]);\n const exePath = path.join(...pathArr);\n console.log(exePath);\n \n if (!fs.existsSync(exePath)) {\n throw new Error(\n `Executable (${exeFilename}) not found, your platform is ${platform} ${arch} and may not be supported.`\n );\n }\n this.child = execFile(exePath);\n this.child.stdout?.on('data', (data: Buffer) => {\n const dataStr = data.toString();\n if (dataStr.trim() === 'TEXT_CHANGED') {\n this.emit('text');\n }\n if (dataStr.trim() === 'IMAGE_CHANGED') {\n this.emit('image');\n }\n });\n\n this.child.stderr?.on('data', (data: Buffer) => {\n this.emit('open', data.toString());\n });\n }\n\n stopListening() {\n this.emit('close');\n const res = this.child?.kill();\n return res;\n }\n}\n\nexport default new ClipboardEventListener();\n","import clipboardEventListener from \"./index\";\n\nclipboardEventListener.on(\"text\", () => {\n console.log(\"Clipboard Text Updated\");\n});\n\nclipboardEventListener.on(\"image\", () => {\n console.log(\"Clipboard Image Updated\");\n});\n\nclipboardEventListener.on(\"open\", (data) => {\n console.log(data);\n});\n\nclipboardEventListener.startListening();\n\nsetTimeout(() => {\n clipboardEventListener.stopListening();\n}, 10000);\n"]}
1
+ {"version":3,"sources":["../src/util.ts","../src/constants.ts","../index.ts","../__tests__/data.ts","../demo.ts"],"names":["data","fs"],"mappings":"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","sourcesContent":["export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport const base64StringToUTF8 = (base64Str: string) => {\n const base64buf = Buffer.from(base64Str, \"base64\"); // parse base64 string to buffer\n const text = base64buf.toString(\"utf8\"); // base64 buffer to utf-8 string\n return text;\n};\n\nexport const base64BufToUTF8 = (buf: Buffer): string => {\n const base64Text = buf.toString();\n return base64StringToUTF8(base64Text);\n};","export enum ClipboardOperation {\n READ_TEXT = \"READ_TEXT\",\n WRITE_TEXT = \"WRITE_TEXT\",\n READ_IMAGE = \"READ_IMAGE\",\n WRITE_IMAGE = \"WRITE_IMAGE\",\n}\n\nexport enum WatchEvent {\n TEXT_CHANGED = \"TEXT_CHANGED\",\n IMAGE_CHANGED = \"IMAGE_CHANGED\",\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { EventEmitter } from \"node:events\";\nimport net from \"net\";\nimport { execFile, ChildProcess, execFileSync } from \"node:child_process\";\nimport util from \"util\";\nimport { base64BufToUTF8, base64StringToUTF8 } from \"./src/util\";\nimport { ClipboardOperation, WatchEvent } from \"./src/constants\";\n\nconst execFileAsync = util.promisify(execFile);\n\nexport class Clipboard {\n child: ChildProcess | undefined;\n server: net.Server | undefined;\n emitter: EventEmitter;\n\n constructor() {\n this.child = undefined;\n this.emitter = new EventEmitter();\n }\n\n get exeFilename(): string {\n const { platform, arch } = process;\n let exeFilename = `go-clipboard-${platform}-${arch}`;\n if (platform === \"win32\") {\n exeFilename += \".exe\";\n }\n return exeFilename;\n }\n\n get goClipboardPath(): string {\n const pathArr = [__dirname];\n\n if (path.basename(__dirname) === \"dist\") {\n pathArr.push(\"..\");\n }\n\n pathArr.push(...[\"go-clipboard\", \"binaries\", this.exeFilename]);\n const exePath = path.join(...pathArr);\n return exePath;\n }\n\n readText(): Promise<string> {\n return execFileAsync(this.goClipboardPath, [\n ClipboardOperation.READ_TEXT,\n ]).then((result) => {\n return base64StringToUTF8(result.stdout);\n });\n }\n\n readTextSync(): string {\n const buf = execFileSync(this.goClipboardPath, [\n ClipboardOperation.READ_TEXT,\n ]);\n return base64BufToUTF8(buf);\n }\n\n writeText(content: string): Promise<void> {\n return Promise.resolve(this.writeTextSync(content));\n }\n\n writeTextSync(content: string): void {\n const writeTextProcess = execFile(this.goClipboardPath, [\n ClipboardOperation.WRITE_TEXT,\n ]);\n writeTextProcess.stdin?.write(content);\n writeTextProcess.stdin?.end();\n }\n\n writeImageSync(base64ImgStr: string): void;\n writeImageSync(imgBuf: Buffer): void;\n writeImageSync(data: string | Buffer): void {\n if (data instanceof String || typeof data === \"string\") {\n const writeImageProcess = execFile(this.goClipboardPath, [\n ClipboardOperation.WRITE_IMAGE,\n ]);\n writeImageProcess.stdin?.write(data);\n writeImageProcess.stdin?.end();\n } else if (data instanceof Buffer) {\n this.writeImageSync(data.toString(\"base64\"));\n } else {\n throw new Error(\"Invalid Data Type. Has to be string or Buffer\");\n }\n }\n writeImage(data: string): Promise<void>;\n writeImage(data: Buffer): Promise<void>;\n writeImage(data: string | Buffer): Promise<void> {\n if (data instanceof String || typeof data === \"string\") {\n return Promise.resolve(this.writeImageSync(data as string));\n } else if (data instanceof Buffer) {\n return Promise.resolve(this.writeImageSync(data as Buffer));\n } else {\n throw new Error(\"Invalid Data Type. Has to be string or Buffer\");\n }\n }\n\n readImage(): Promise<Buffer> {\n return Promise.resolve(this.readImageSync());\n }\n\n readImageBase64(): Promise<string> {\n return Promise.resolve(this.readImageBase64Sync());\n }\n\n readImageSync(): Buffer {\n const buf = execFileSync(this.goClipboardPath, [\n ClipboardOperation.READ_IMAGE,\n ]);\n const stdoutStr = buf.toString();\n const imgBuf = Buffer.from(stdoutStr, \"base64\");\n fs.writeFileSync(\"test.png\", imgBuf);\n return imgBuf;\n }\n\n readImageBase64Sync(): string {\n return this.readImageSync().toString(\"base64\");\n }\n\n listen() {\n this.server = net.createServer((con) => {\n // client connected\n let data = \"\";\n\n // * demo of sending message to client,\n // con.write(\"close\");\n\n /**\n * Accumulate data by concatenating chunks of received data\n */\n con.on(\"data\", (packet) => {\n data += packet.toString();\n });\n\n /**\n * When socket connection closes, wrap up received data\n */\n con.on(\"close\", () => {\n const strData = data.toString();\n const subStr = strData.substring(0, 14);\n if (subStr.includes(`${WatchEvent.TEXT_CHANGED}:`)) {\n const text = Buffer.from(strData.substring(13), \"base64\").toString();\n this.emitter.emit(\"text\", text);\n } else if (subStr.includes(`${WatchEvent.IMAGE_CHANGED}:`)) {\n const data = strData.substring(14) as string;\n this.emitter.emit(\"image\", Buffer.from(data, \"base64\"));\n // const imageBase64 = data.toString(\"base64\");\n // console.log(`Image Changed`);\n // fs.writeFileSync(\"test.png\", Buffer.from(data, \"base64\"));\n }\n });\n });\n\n this.server.listen(8090, () => {\n const addr = this.server?.address();\n if (!addr)\n throw new Error(\"Unexpected Error: TCP Socket Server not Started\");\n const port = (addr as net.AddressInfo).port;\n this.child = execFile(this.goClipboardPath, [port.toString()]);\n // this.child.stdout?.on(\"data\", (data) => {\n // console.log(\"Received data from client socket stdout:\\n\" + data);\n // });\n });\n }\n\n close() {\n this.emitter.emit(\"close\");\n this.emitter.removeAllListeners();\n this.server?.close();\n const res = this.child?.kill();\n return res;\n }\n\n on(event: \"text\", cb: (text: string) => void): void;\n on(event: \"image\", cb: (text: string) => void): void;\n on(event: \"close\", cb: (text: string) => void): void;\n on(event: \"text\" | \"image\" | \"close\", cb: (text: string) => void): void {\n this.emitter.on(event, cb);\n }\n}\n\nexport default new Clipboard();\n","export const base64img =\n \"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAgACADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDumIVSx6AZrD0LxPba9d3sFujD7K+xie5rVvpPJsJ5P7qE/pXn3woXdY6rfdWluWNcEYpxbOlvVI9JormvDPioa/eahbGHy3tJNh966WpaadmUnfYy/ESzP4fvVgUtK0TBQOpOK8s8Kaj4q8P6MbC38PPJlifMbjOa9npMD0FXGdlaxLjd3ueFeDr/AMTReJtRjsrSPzpJd1yr/wAHPavc4S5hQyDD4G761mWXh6xsNWudSgQrPcffPY1rUVJqT0CEWkf/2Q==\";","import clipboard from \"./index\";\nimport fs from \"node:fs\";\nimport { base64img } from \"./__tests__/data\";\n\n(async function () {\n console.log(clipboard.readTextSync());\n console.log(await clipboard.readText());\n const imgBuf = clipboard.readImageSync();\n // console.log(imgBuf.toString(\"base64\"));\n // console.log(clipboard.readImageBase64Sync());\n // await clipboard.writeImage(base64img); // add fake image to clipboard\n clipboard.writeImageSync(base64img); // add fake image to clipboard\n console.log(\"\"); // give some time\n console.assert(clipboard.readImageBase64Sync() === base64img);\n\n // * test readimage\n clipboard.writeImageSync(base64img);\n console.log();\n console.assert(\n (await clipboard.readImage()).toString(\"base64\") === base64img\n );\n\n await clipboard.writeImage(base64img);\n console.log();\n console.assert((await clipboard.readImageBase64()) === base64img);\n clipboard.on(\"text\", (text) => {\n console.log(text);\n });\n clipboard.on(\"image\", (data) => {\n fs.writeFileSync(\"test.png\", data);\n });\n clipboard.listen();\n setTimeout(() => {\n clipboard.close();\n }, 10000);\n})();\n"]}
package/dist/demo.mjs CHANGED
@@ -1,7 +1,9 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { EventEmitter } from 'events';
4
- import { execFile } from 'child_process';
4
+ import net from 'net';
5
+ import { execFile, execFileSync } from 'child_process';
6
+ import util from 'util';
5
7
 
6
8
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
9
  var __esm = (fn, res) => function __init() {
@@ -10,75 +12,201 @@ var __esm = (fn, res) => function __init() {
10
12
  var __commonJS = (cb, mod) => function __require() {
11
13
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
12
14
  };
13
- var ClipboardEventListener, clipboard_default;
15
+
16
+ // src/util.ts
17
+ var base64StringToUTF8, base64BufToUTF8;
18
+ var init_util = __esm({
19
+ "src/util.ts"() {
20
+ base64StringToUTF8 = (base64Str) => {
21
+ const base64buf = Buffer.from(base64Str, "base64");
22
+ const text = base64buf.toString("utf8");
23
+ return text;
24
+ };
25
+ base64BufToUTF8 = (buf) => {
26
+ const base64Text = buf.toString();
27
+ return base64StringToUTF8(base64Text);
28
+ };
29
+ }
30
+ });
31
+
32
+ // src/constants.ts
33
+ var init_constants = __esm({
34
+ "src/constants.ts"() {
35
+ }
36
+ });
37
+ var execFileAsync, Clipboard, clipboard_default;
14
38
  var init_clipboard = __esm({
15
39
  "index.ts"() {
16
- ClipboardEventListener = class extends EventEmitter {
40
+ init_util();
41
+ init_constants();
42
+ execFileAsync = util.promisify(execFile);
43
+ Clipboard = class {
17
44
  constructor() {
18
- super();
19
45
  this.child = void 0;
46
+ this.emitter = new EventEmitter();
20
47
  }
21
- startListening() {
22
- var _a, _b;
48
+ get exeFilename() {
23
49
  const { platform, arch } = process;
24
- const pathArr = [__dirname];
25
- if (path.basename(__dirname) === "dist") {
26
- pathArr.push("..");
27
- }
28
50
  let exeFilename = `go-clipboard-${platform}-${arch}`;
29
51
  if (platform === "win32") {
30
52
  exeFilename += ".exe";
31
53
  }
32
- pathArr.push(...["go-clipboard", "binaries", exeFilename]);
54
+ return exeFilename;
55
+ }
56
+ get goClipboardPath() {
57
+ const pathArr = [__dirname];
58
+ if (path.basename(__dirname) === "dist") {
59
+ pathArr.push("..");
60
+ }
61
+ pathArr.push(...["go-clipboard", "binaries", this.exeFilename]);
33
62
  const exePath = path.join(...pathArr);
34
- console.log(exePath);
35
- if (!fs.existsSync(exePath)) {
36
- throw new Error(
37
- `Executable (${exeFilename}) not found, your platform is ${platform} ${arch} and may not be supported.`
38
- );
63
+ return exePath;
64
+ }
65
+ readText() {
66
+ return execFileAsync(this.goClipboardPath, [
67
+ "READ_TEXT" /* READ_TEXT */
68
+ ]).then((result) => {
69
+ return base64StringToUTF8(result.stdout);
70
+ });
71
+ }
72
+ readTextSync() {
73
+ const buf = execFileSync(this.goClipboardPath, [
74
+ "READ_TEXT" /* READ_TEXT */
75
+ ]);
76
+ return base64BufToUTF8(buf);
77
+ }
78
+ writeText(content) {
79
+ return Promise.resolve(this.writeTextSync(content));
80
+ }
81
+ writeTextSync(content) {
82
+ var _a, _b;
83
+ const writeTextProcess = execFile(this.goClipboardPath, [
84
+ "WRITE_TEXT" /* WRITE_TEXT */
85
+ ]);
86
+ (_a = writeTextProcess.stdin) == null ? void 0 : _a.write(content);
87
+ (_b = writeTextProcess.stdin) == null ? void 0 : _b.end();
88
+ }
89
+ writeImageSync(data) {
90
+ var _a, _b;
91
+ if (data instanceof String || typeof data === "string") {
92
+ const writeImageProcess = execFile(this.goClipboardPath, [
93
+ "WRITE_IMAGE" /* WRITE_IMAGE */
94
+ ]);
95
+ (_a = writeImageProcess.stdin) == null ? void 0 : _a.write(data);
96
+ (_b = writeImageProcess.stdin) == null ? void 0 : _b.end();
97
+ } else if (data instanceof Buffer) {
98
+ this.writeImageSync(data.toString("base64"));
99
+ } else {
100
+ throw new Error("Invalid Data Type. Has to be string or Buffer");
101
+ }
102
+ }
103
+ writeImage(data) {
104
+ if (data instanceof String || typeof data === "string") {
105
+ return Promise.resolve(this.writeImageSync(data));
106
+ } else if (data instanceof Buffer) {
107
+ return Promise.resolve(this.writeImageSync(data));
108
+ } else {
109
+ throw new Error("Invalid Data Type. Has to be string or Buffer");
39
110
  }
40
- this.child = execFile(exePath);
41
- (_a = this.child.stdout) == null ? void 0 : _a.on("data", (data) => {
42
- const dataStr = data.toString();
43
- if (dataStr.trim() === "TEXT_CHANGED") {
44
- this.emit("text");
45
- }
46
- if (dataStr.trim() === "IMAGE_CHANGED") {
47
- this.emit("image");
48
- }
111
+ }
112
+ readImage() {
113
+ return Promise.resolve(this.readImageSync());
114
+ }
115
+ readImageBase64() {
116
+ return Promise.resolve(this.readImageBase64Sync());
117
+ }
118
+ readImageSync() {
119
+ const buf = execFileSync(this.goClipboardPath, [
120
+ "READ_IMAGE" /* READ_IMAGE */
121
+ ]);
122
+ const stdoutStr = buf.toString();
123
+ const imgBuf = Buffer.from(stdoutStr, "base64");
124
+ fs.writeFileSync("test.png", imgBuf);
125
+ return imgBuf;
126
+ }
127
+ readImageBase64Sync() {
128
+ return this.readImageSync().toString("base64");
129
+ }
130
+ listen() {
131
+ this.server = net.createServer((con) => {
132
+ let data = "";
133
+ con.on("data", (packet) => {
134
+ data += packet.toString();
135
+ });
136
+ con.on("close", () => {
137
+ const strData = data.toString();
138
+ const subStr = strData.substring(0, 14);
139
+ if (subStr.includes(`${"TEXT_CHANGED" /* TEXT_CHANGED */}:`)) {
140
+ const text = Buffer.from(strData.substring(13), "base64").toString();
141
+ this.emitter.emit("text", text);
142
+ } else if (subStr.includes(`${"IMAGE_CHANGED" /* IMAGE_CHANGED */}:`)) {
143
+ const data2 = strData.substring(14);
144
+ this.emitter.emit("image", Buffer.from(data2, "base64"));
145
+ }
146
+ });
49
147
  });
50
- (_b = this.child.stderr) == null ? void 0 : _b.on("data", (data) => {
51
- this.emit("open", data.toString());
148
+ this.server.listen(8090, () => {
149
+ var _a;
150
+ const addr = (_a = this.server) == null ? void 0 : _a.address();
151
+ if (!addr)
152
+ throw new Error("Unexpected Error: TCP Socket Server not Started");
153
+ const port = addr.port;
154
+ this.child = execFile(this.goClipboardPath, [port.toString()]);
52
155
  });
53
156
  }
54
- stopListening() {
55
- var _a;
56
- this.emit("close");
57
- const res = (_a = this.child) == null ? void 0 : _a.kill();
157
+ close() {
158
+ var _a, _b;
159
+ this.emitter.emit("close");
160
+ this.emitter.removeAllListeners();
161
+ (_a = this.server) == null ? void 0 : _a.close();
162
+ const res = (_b = this.child) == null ? void 0 : _b.kill();
58
163
  return res;
59
164
  }
165
+ on(event, cb) {
166
+ this.emitter.on(event, cb);
167
+ }
60
168
  };
61
- clipboard_default = new ClipboardEventListener();
169
+ clipboard_default = new Clipboard();
62
170
  }
63
171
  });
64
172
 
65
- // demo.ts
173
+ // __tests__/data.ts
174
+ var base64img;
175
+ var init_data = __esm({
176
+ "__tests__/data.ts"() {
177
+ base64img = "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAgACADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDumIVSx6AZrD0LxPba9d3sFujD7K+xie5rVvpPJsJ5P7qE/pXn3woXdY6rfdWluWNcEYpxbOlvVI9JormvDPioa/eahbGHy3tJNh966WpaadmUnfYy/ESzP4fvVgUtK0TBQOpOK8s8Kaj4q8P6MbC38PPJlifMbjOa9npMD0FXGdlaxLjd3ueFeDr/AMTReJtRjsrSPzpJd1yr/wAHPavc4S5hQyDD4G761mWXh6xsNWudSgQrPcffPY1rUVJqT0CEWkf/2Q==";
178
+ }
179
+ });
66
180
  var require_demo = __commonJS({
67
181
  "demo.ts"() {
68
182
  init_clipboard();
69
- clipboard_default.on("text", () => {
70
- console.log("Clipboard Text Updated");
71
- });
72
- clipboard_default.on("image", () => {
73
- console.log("Clipboard Image Updated");
74
- });
75
- clipboard_default.on("open", (data) => {
76
- console.log(data);
77
- });
78
- clipboard_default.startListening();
79
- setTimeout(() => {
80
- clipboard_default.stopListening();
81
- }, 1e4);
183
+ init_data();
184
+ (async function() {
185
+ console.log(clipboard_default.readTextSync());
186
+ console.log(await clipboard_default.readText());
187
+ clipboard_default.readImageSync();
188
+ clipboard_default.writeImageSync(base64img);
189
+ console.log("");
190
+ console.assert(clipboard_default.readImageBase64Sync() === base64img);
191
+ clipboard_default.writeImageSync(base64img);
192
+ console.log();
193
+ console.assert(
194
+ (await clipboard_default.readImage()).toString("base64") === base64img
195
+ );
196
+ await clipboard_default.writeImage(base64img);
197
+ console.log();
198
+ console.assert(await clipboard_default.readImageBase64() === base64img);
199
+ clipboard_default.on("text", (text) => {
200
+ console.log(text);
201
+ });
202
+ clipboard_default.on("image", (data) => {
203
+ fs.writeFileSync("test.png", data);
204
+ });
205
+ clipboard_default.listen();
206
+ setTimeout(() => {
207
+ clipboard_default.close();
208
+ }, 1e4);
209
+ })();
82
210
  }
83
211
  });
84
212
  var demo = require_demo();
package/dist/demo.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts","../demo.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,oBAAoB;AAC7B,SAAgB,gBAA8D;AAH9E,IAKM,wBAkDC;AAvDP;AAAA;AAAA;AAKA,IAAM,yBAAN,cAAqC,aAAa;AAAA,MAEhD,cAAc;AACZ,cAAM;AACN,aAAK,QAAQ;AAAA,MACf;AAAA,MAEA,iBAAiB;AAZnB;AAaI,cAAM,EAAE,UAAU,KAAK,IAAI;AAC3B,cAAM,UAAU,CAAC,SAAS;AAE1B,YAAI,KAAK,SAAS,SAAS,MAAM,QAAQ;AACvC,kBAAQ,KAAK,IAAI;AAAA,QACnB;AACA,YAAI,cAAc,gBAAgB,YAAY;AAC9C,YAAI,aAAa,SAAS;AACxB,yBAAe;AAAA,QACjB;AACA,gBAAQ,KAAK,GAAG,CAAC,gBAAgB,YAAY,WAAW,CAAC;AACzD,cAAM,UAAU,KAAK,KAAK,GAAG,OAAO;AACpC,gBAAQ,IAAI,OAAO;AAEnB,YAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,gBAAM,IAAI;AAAA,YACR,eAAe,4CAA4C,YAAY;AAAA,UACzE;AAAA,QACF;AACA,aAAK,QAAQ,SAAS,OAAO;AAC7B,mBAAK,MAAM,WAAX,mBAAmB,GAAG,QAAQ,CAAC,SAAiB;AAC9C,gBAAM,UAAU,KAAK,SAAS;AAC9B,cAAI,QAAQ,KAAK,MAAM,gBAAgB;AACrC,iBAAK,KAAK,MAAM;AAAA,UAClB;AACA,cAAI,QAAQ,KAAK,MAAM,iBAAiB;AACtC,iBAAK,KAAK,OAAO;AAAA,UACnB;AAAA,QACF;AAEA,mBAAK,MAAM,WAAX,mBAAmB,GAAG,QAAQ,CAAC,SAAiB;AAC9C,eAAK,KAAK,QAAQ,KAAK,SAAS,CAAC;AAAA,QACnC;AAAA,MACF;AAAA,MAEA,gBAAgB;AAhDlB;AAiDI,aAAK,KAAK,OAAO;AACjB,cAAM,OAAM,UAAK,UAAL,mBAAY;AACxB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,IAAO,oBAAQ,IAAI,uBAAuB;AAAA;AAAA;;;ACvD1C;AAAA;AAAA;AAEA,sBAAuB,GAAG,QAAQ,MAAM;AACtC,cAAQ,IAAI,wBAAwB;AAAA,IACtC,CAAC;AAED,sBAAuB,GAAG,SAAS,MAAM;AACvC,cAAQ,IAAI,yBAAyB;AAAA,IACvC,CAAC;AAED,sBAAuB,GAAG,QAAQ,CAAC,SAAS;AAC1C,cAAQ,IAAI,IAAI;AAAA,IAClB,CAAC;AAED,sBAAuB,eAAe;AAEtC,eAAW,MAAM;AACf,wBAAuB,cAAc;AAAA,IACvC,GAAG,GAAK;AAAA;AAAA","sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { EventEmitter } from 'events';\nimport { spawn, execFile, ChildProcessWithoutNullStreams, ChildProcess } from 'node:child_process';\n\nclass ClipboardEventListener extends EventEmitter {\n child: ChildProcess | undefined;\n constructor() {\n super();\n this.child = undefined;\n }\n\n startListening() {\n const { platform, arch } = process;\n const pathArr = [__dirname];\n\n if (path.basename(__dirname) === 'dist') {\n pathArr.push('..');\n }\n let exeFilename = `go-clipboard-${platform}-${arch}`;\n if (platform === 'win32') {\n exeFilename += '.exe';\n }\n pathArr.push(...['go-clipboard', 'binaries', exeFilename]);\n const exePath = path.join(...pathArr);\n console.log(exePath);\n \n if (!fs.existsSync(exePath)) {\n throw new Error(\n `Executable (${exeFilename}) not found, your platform is ${platform} ${arch} and may not be supported.`\n );\n }\n this.child = execFile(exePath);\n this.child.stdout?.on('data', (data: Buffer) => {\n const dataStr = data.toString();\n if (dataStr.trim() === 'TEXT_CHANGED') {\n this.emit('text');\n }\n if (dataStr.trim() === 'IMAGE_CHANGED') {\n this.emit('image');\n }\n });\n\n this.child.stderr?.on('data', (data: Buffer) => {\n this.emit('open', data.toString());\n });\n }\n\n stopListening() {\n this.emit('close');\n const res = this.child?.kill();\n return res;\n }\n}\n\nexport default new ClipboardEventListener();\n","import clipboardEventListener from \"./index\";\n\nclipboardEventListener.on(\"text\", () => {\n console.log(\"Clipboard Text Updated\");\n});\n\nclipboardEventListener.on(\"image\", () => {\n console.log(\"Clipboard Image Updated\");\n});\n\nclipboardEventListener.on(\"open\", (data) => {\n console.log(data);\n});\n\nclipboardEventListener.startListening();\n\nsetTimeout(() => {\n clipboardEventListener.stopListening();\n}, 10000);\n"]}
1
+ {"version":3,"sources":["../src/util.ts","../src/constants.ts","../index.ts","../__tests__/data.ts","../demo.ts"],"names":["data","fs"],"mappings":"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","sourcesContent":["export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport const base64StringToUTF8 = (base64Str: string) => {\n const base64buf = Buffer.from(base64Str, \"base64\"); // parse base64 string to buffer\n const text = base64buf.toString(\"utf8\"); // base64 buffer to utf-8 string\n return text;\n};\n\nexport const base64BufToUTF8 = (buf: Buffer): string => {\n const base64Text = buf.toString();\n return base64StringToUTF8(base64Text);\n};","export enum ClipboardOperation {\n READ_TEXT = \"READ_TEXT\",\n WRITE_TEXT = \"WRITE_TEXT\",\n READ_IMAGE = \"READ_IMAGE\",\n WRITE_IMAGE = \"WRITE_IMAGE\",\n}\n\nexport enum WatchEvent {\n TEXT_CHANGED = \"TEXT_CHANGED\",\n IMAGE_CHANGED = \"IMAGE_CHANGED\",\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { EventEmitter } from \"node:events\";\nimport net from \"net\";\nimport { execFile, ChildProcess, execFileSync } from \"node:child_process\";\nimport util from \"util\";\nimport { base64BufToUTF8, base64StringToUTF8 } from \"./src/util\";\nimport { ClipboardOperation, WatchEvent } from \"./src/constants\";\n\nconst execFileAsync = util.promisify(execFile);\n\nexport class Clipboard {\n child: ChildProcess | undefined;\n server: net.Server | undefined;\n emitter: EventEmitter;\n\n constructor() {\n this.child = undefined;\n this.emitter = new EventEmitter();\n }\n\n get exeFilename(): string {\n const { platform, arch } = process;\n let exeFilename = `go-clipboard-${platform}-${arch}`;\n if (platform === \"win32\") {\n exeFilename += \".exe\";\n }\n return exeFilename;\n }\n\n get goClipboardPath(): string {\n const pathArr = [__dirname];\n\n if (path.basename(__dirname) === \"dist\") {\n pathArr.push(\"..\");\n }\n\n pathArr.push(...[\"go-clipboard\", \"binaries\", this.exeFilename]);\n const exePath = path.join(...pathArr);\n return exePath;\n }\n\n readText(): Promise<string> {\n return execFileAsync(this.goClipboardPath, [\n ClipboardOperation.READ_TEXT,\n ]).then((result) => {\n return base64StringToUTF8(result.stdout);\n });\n }\n\n readTextSync(): string {\n const buf = execFileSync(this.goClipboardPath, [\n ClipboardOperation.READ_TEXT,\n ]);\n return base64BufToUTF8(buf);\n }\n\n writeText(content: string): Promise<void> {\n return Promise.resolve(this.writeTextSync(content));\n }\n\n writeTextSync(content: string): void {\n const writeTextProcess = execFile(this.goClipboardPath, [\n ClipboardOperation.WRITE_TEXT,\n ]);\n writeTextProcess.stdin?.write(content);\n writeTextProcess.stdin?.end();\n }\n\n writeImageSync(base64ImgStr: string): void;\n writeImageSync(imgBuf: Buffer): void;\n writeImageSync(data: string | Buffer): void {\n if (data instanceof String || typeof data === \"string\") {\n const writeImageProcess = execFile(this.goClipboardPath, [\n ClipboardOperation.WRITE_IMAGE,\n ]);\n writeImageProcess.stdin?.write(data);\n writeImageProcess.stdin?.end();\n } else if (data instanceof Buffer) {\n this.writeImageSync(data.toString(\"base64\"));\n } else {\n throw new Error(\"Invalid Data Type. Has to be string or Buffer\");\n }\n }\n writeImage(data: string): Promise<void>;\n writeImage(data: Buffer): Promise<void>;\n writeImage(data: string | Buffer): Promise<void> {\n if (data instanceof String || typeof data === \"string\") {\n return Promise.resolve(this.writeImageSync(data as string));\n } else if (data instanceof Buffer) {\n return Promise.resolve(this.writeImageSync(data as Buffer));\n } else {\n throw new Error(\"Invalid Data Type. Has to be string or Buffer\");\n }\n }\n\n readImage(): Promise<Buffer> {\n return Promise.resolve(this.readImageSync());\n }\n\n readImageBase64(): Promise<string> {\n return Promise.resolve(this.readImageBase64Sync());\n }\n\n readImageSync(): Buffer {\n const buf = execFileSync(this.goClipboardPath, [\n ClipboardOperation.READ_IMAGE,\n ]);\n const stdoutStr = buf.toString();\n const imgBuf = Buffer.from(stdoutStr, \"base64\");\n fs.writeFileSync(\"test.png\", imgBuf);\n return imgBuf;\n }\n\n readImageBase64Sync(): string {\n return this.readImageSync().toString(\"base64\");\n }\n\n listen() {\n this.server = net.createServer((con) => {\n // client connected\n let data = \"\";\n\n // * demo of sending message to client,\n // con.write(\"close\");\n\n /**\n * Accumulate data by concatenating chunks of received data\n */\n con.on(\"data\", (packet) => {\n data += packet.toString();\n });\n\n /**\n * When socket connection closes, wrap up received data\n */\n con.on(\"close\", () => {\n const strData = data.toString();\n const subStr = strData.substring(0, 14);\n if (subStr.includes(`${WatchEvent.TEXT_CHANGED}:`)) {\n const text = Buffer.from(strData.substring(13), \"base64\").toString();\n this.emitter.emit(\"text\", text);\n } else if (subStr.includes(`${WatchEvent.IMAGE_CHANGED}:`)) {\n const data = strData.substring(14) as string;\n this.emitter.emit(\"image\", Buffer.from(data, \"base64\"));\n // const imageBase64 = data.toString(\"base64\");\n // console.log(`Image Changed`);\n // fs.writeFileSync(\"test.png\", Buffer.from(data, \"base64\"));\n }\n });\n });\n\n this.server.listen(8090, () => {\n const addr = this.server?.address();\n if (!addr)\n throw new Error(\"Unexpected Error: TCP Socket Server not Started\");\n const port = (addr as net.AddressInfo).port;\n this.child = execFile(this.goClipboardPath, [port.toString()]);\n // this.child.stdout?.on(\"data\", (data) => {\n // console.log(\"Received data from client socket stdout:\\n\" + data);\n // });\n });\n }\n\n close() {\n this.emitter.emit(\"close\");\n this.emitter.removeAllListeners();\n this.server?.close();\n const res = this.child?.kill();\n return res;\n }\n\n on(event: \"text\", cb: (text: string) => void): void;\n on(event: \"image\", cb: (text: string) => void): void;\n on(event: \"close\", cb: (text: string) => void): void;\n on(event: \"text\" | \"image\" | \"close\", cb: (text: string) => void): void {\n this.emitter.on(event, cb);\n }\n}\n\nexport default new Clipboard();\n","export const base64img =\n \"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAgACADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDumIVSx6AZrD0LxPba9d3sFujD7K+xie5rVvpPJsJ5P7qE/pXn3woXdY6rfdWluWNcEYpxbOlvVI9JormvDPioa/eahbGHy3tJNh966WpaadmUnfYy/ESzP4fvVgUtK0TBQOpOK8s8Kaj4q8P6MbC38PPJlifMbjOa9npMD0FXGdlaxLjd3ueFeDr/AMTReJtRjsrSPzpJd1yr/wAHPavc4S5hQyDD4G761mWXh6xsNWudSgQrPcffPY1rUVJqT0CEWkf/2Q==\";","import clipboard from \"./index\";\nimport fs from \"node:fs\";\nimport { base64img } from \"./__tests__/data\";\n\n(async function () {\n console.log(clipboard.readTextSync());\n console.log(await clipboard.readText());\n const imgBuf = clipboard.readImageSync();\n // console.log(imgBuf.toString(\"base64\"));\n // console.log(clipboard.readImageBase64Sync());\n // await clipboard.writeImage(base64img); // add fake image to clipboard\n clipboard.writeImageSync(base64img); // add fake image to clipboard\n console.log(\"\"); // give some time\n console.assert(clipboard.readImageBase64Sync() === base64img);\n\n // * test readimage\n clipboard.writeImageSync(base64img);\n console.log();\n console.assert(\n (await clipboard.readImage()).toString(\"base64\") === base64img\n );\n\n await clipboard.writeImage(base64img);\n console.log();\n console.assert((await clipboard.readImageBase64()) === base64img);\n clipboard.on(\"text\", (text) => {\n console.log(text);\n });\n clipboard.on(\"image\", (data) => {\n fs.writeFileSync(\"test.png\", data);\n });\n clipboard.listen();\n setTimeout(() => {\n clipboard.close();\n }, 10000);\n})();\n"]}
package/dist/index.d.ts CHANGED
@@ -1,12 +1,32 @@
1
- import { EventEmitter } from 'events';
1
+ import { EventEmitter } from 'node:events';
2
+ import net from 'net';
2
3
  import { ChildProcess } from 'node:child_process';
3
4
 
4
- declare class ClipboardEventListener extends EventEmitter {
5
+ declare class Clipboard {
5
6
  child: ChildProcess | undefined;
7
+ server: net.Server | undefined;
8
+ emitter: EventEmitter;
6
9
  constructor();
7
- startListening(): void;
8
- stopListening(): boolean | undefined;
10
+ get exeFilename(): string;
11
+ get goClipboardPath(): string;
12
+ readText(): Promise<string>;
13
+ readTextSync(): string;
14
+ writeText(content: string): Promise<void>;
15
+ writeTextSync(content: string): void;
16
+ writeImageSync(base64ImgStr: string): void;
17
+ writeImageSync(imgBuf: Buffer): void;
18
+ writeImage(data: string): Promise<void>;
19
+ writeImage(data: Buffer): Promise<void>;
20
+ readImage(): Promise<Buffer>;
21
+ readImageBase64(): Promise<string>;
22
+ readImageSync(): Buffer;
23
+ readImageBase64Sync(): string;
24
+ listen(): void;
25
+ close(): boolean | undefined;
26
+ on(event: "text", cb: (text: string) => void): void;
27
+ on(event: "image", cb: (text: string) => void): void;
28
+ on(event: "close", cb: (text: string) => void): void;
9
29
  }
10
- declare const _default: ClipboardEventListener;
30
+ declare const _default: Clipboard;
11
31
 
12
- export { _default as default };
32
+ export { Clipboard, _default as default };
package/dist/index.js CHANGED
@@ -1,62 +1,164 @@
1
1
  'use strict';
2
2
 
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
3
5
  var fs = require('fs');
4
6
  var path = require('path');
5
7
  var events = require('events');
8
+ var net = require('net');
6
9
  var child_process = require('child_process');
10
+ var util = require('util');
7
11
 
8
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
13
 
10
14
  var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
11
15
  var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
16
+ var net__default = /*#__PURE__*/_interopDefaultLegacy(net);
17
+ var util__default = /*#__PURE__*/_interopDefaultLegacy(util);
12
18
 
13
19
  // index.ts
14
- var ClipboardEventListener = class extends events.EventEmitter {
20
+
21
+ // src/util.ts
22
+ var base64StringToUTF8 = (base64Str) => {
23
+ const base64buf = Buffer.from(base64Str, "base64");
24
+ const text = base64buf.toString("utf8");
25
+ return text;
26
+ };
27
+ var base64BufToUTF8 = (buf) => {
28
+ const base64Text = buf.toString();
29
+ return base64StringToUTF8(base64Text);
30
+ };
31
+
32
+ // index.ts
33
+ var execFileAsync = util__default["default"].promisify(child_process.execFile);
34
+ var Clipboard = class {
15
35
  constructor() {
16
- super();
17
36
  this.child = void 0;
37
+ this.emitter = new events.EventEmitter();
18
38
  }
19
- startListening() {
20
- var _a, _b;
39
+ get exeFilename() {
21
40
  const { platform, arch } = process;
22
- const pathArr = [__dirname];
23
- if (path__default["default"].basename(__dirname) === "dist") {
24
- pathArr.push("..");
25
- }
26
41
  let exeFilename = `go-clipboard-${platform}-${arch}`;
27
42
  if (platform === "win32") {
28
43
  exeFilename += ".exe";
29
44
  }
30
- pathArr.push(...["go-clipboard", "binaries", exeFilename]);
45
+ return exeFilename;
46
+ }
47
+ get goClipboardPath() {
48
+ const pathArr = [__dirname];
49
+ if (path__default["default"].basename(__dirname) === "dist") {
50
+ pathArr.push("..");
51
+ }
52
+ pathArr.push(...["go-clipboard", "binaries", this.exeFilename]);
31
53
  const exePath = path__default["default"].join(...pathArr);
32
- console.log(exePath);
33
- if (!fs__default["default"].existsSync(exePath)) {
34
- throw new Error(
35
- `Executable (${exeFilename}) not found, your platform is ${platform} ${arch} and may not be supported.`
36
- );
54
+ return exePath;
55
+ }
56
+ readText() {
57
+ return execFileAsync(this.goClipboardPath, [
58
+ "READ_TEXT" /* READ_TEXT */
59
+ ]).then((result) => {
60
+ return base64StringToUTF8(result.stdout);
61
+ });
62
+ }
63
+ readTextSync() {
64
+ const buf = child_process.execFileSync(this.goClipboardPath, [
65
+ "READ_TEXT" /* READ_TEXT */
66
+ ]);
67
+ return base64BufToUTF8(buf);
68
+ }
69
+ writeText(content) {
70
+ return Promise.resolve(this.writeTextSync(content));
71
+ }
72
+ writeTextSync(content) {
73
+ var _a, _b;
74
+ const writeTextProcess = child_process.execFile(this.goClipboardPath, [
75
+ "WRITE_TEXT" /* WRITE_TEXT */
76
+ ]);
77
+ (_a = writeTextProcess.stdin) == null ? void 0 : _a.write(content);
78
+ (_b = writeTextProcess.stdin) == null ? void 0 : _b.end();
79
+ }
80
+ writeImageSync(data) {
81
+ var _a, _b;
82
+ if (data instanceof String || typeof data === "string") {
83
+ const writeImageProcess = child_process.execFile(this.goClipboardPath, [
84
+ "WRITE_IMAGE" /* WRITE_IMAGE */
85
+ ]);
86
+ (_a = writeImageProcess.stdin) == null ? void 0 : _a.write(data);
87
+ (_b = writeImageProcess.stdin) == null ? void 0 : _b.end();
88
+ } else if (data instanceof Buffer) {
89
+ this.writeImageSync(data.toString("base64"));
90
+ } else {
91
+ throw new Error("Invalid Data Type. Has to be string or Buffer");
92
+ }
93
+ }
94
+ writeImage(data) {
95
+ if (data instanceof String || typeof data === "string") {
96
+ return Promise.resolve(this.writeImageSync(data));
97
+ } else if (data instanceof Buffer) {
98
+ return Promise.resolve(this.writeImageSync(data));
99
+ } else {
100
+ throw new Error("Invalid Data Type. Has to be string or Buffer");
37
101
  }
38
- this.child = child_process.execFile(exePath);
39
- (_a = this.child.stdout) == null ? void 0 : _a.on("data", (data) => {
40
- const dataStr = data.toString();
41
- if (dataStr.trim() === "TEXT_CHANGED") {
42
- this.emit("text");
43
- }
44
- if (dataStr.trim() === "IMAGE_CHANGED") {
45
- this.emit("image");
46
- }
102
+ }
103
+ readImage() {
104
+ return Promise.resolve(this.readImageSync());
105
+ }
106
+ readImageBase64() {
107
+ return Promise.resolve(this.readImageBase64Sync());
108
+ }
109
+ readImageSync() {
110
+ const buf = child_process.execFileSync(this.goClipboardPath, [
111
+ "READ_IMAGE" /* READ_IMAGE */
112
+ ]);
113
+ const stdoutStr = buf.toString();
114
+ const imgBuf = Buffer.from(stdoutStr, "base64");
115
+ fs__default["default"].writeFileSync("test.png", imgBuf);
116
+ return imgBuf;
117
+ }
118
+ readImageBase64Sync() {
119
+ return this.readImageSync().toString("base64");
120
+ }
121
+ listen() {
122
+ this.server = net__default["default"].createServer((con) => {
123
+ let data = "";
124
+ con.on("data", (packet) => {
125
+ data += packet.toString();
126
+ });
127
+ con.on("close", () => {
128
+ const strData = data.toString();
129
+ const subStr = strData.substring(0, 14);
130
+ if (subStr.includes(`${"TEXT_CHANGED" /* TEXT_CHANGED */}:`)) {
131
+ const text = Buffer.from(strData.substring(13), "base64").toString();
132
+ this.emitter.emit("text", text);
133
+ } else if (subStr.includes(`${"IMAGE_CHANGED" /* IMAGE_CHANGED */}:`)) {
134
+ const data2 = strData.substring(14);
135
+ this.emitter.emit("image", Buffer.from(data2, "base64"));
136
+ }
137
+ });
47
138
  });
48
- (_b = this.child.stderr) == null ? void 0 : _b.on("data", (data) => {
49
- this.emit("open", data.toString());
139
+ this.server.listen(8090, () => {
140
+ var _a;
141
+ const addr = (_a = this.server) == null ? void 0 : _a.address();
142
+ if (!addr)
143
+ throw new Error("Unexpected Error: TCP Socket Server not Started");
144
+ const port = addr.port;
145
+ this.child = child_process.execFile(this.goClipboardPath, [port.toString()]);
50
146
  });
51
147
  }
52
- stopListening() {
53
- var _a;
54
- this.emit("close");
55
- const res = (_a = this.child) == null ? void 0 : _a.kill();
148
+ close() {
149
+ var _a, _b;
150
+ this.emitter.emit("close");
151
+ this.emitter.removeAllListeners();
152
+ (_a = this.server) == null ? void 0 : _a.close();
153
+ const res = (_b = this.child) == null ? void 0 : _b.kill();
56
154
  return res;
57
155
  }
156
+ on(event, cb) {
157
+ this.emitter.on(event, cb);
158
+ }
58
159
  };
59
- var clipboard_default = new ClipboardEventListener();
160
+ var clipboard_default = new Clipboard();
60
161
 
61
- module.exports = clipboard_default;
162
+ exports.Clipboard = Clipboard;
163
+ exports["default"] = clipboard_default;
62
164
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"names":[],"mappings":";AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,oBAAoB;AAC7B,SAAgB,gBAA8D;AAE9E,IAAM,yBAAN,cAAqC,aAAa;AAAA,EAEhD,cAAc;AACZ,UAAM;AACN,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,iBAAiB;AAZnB;AAaI,UAAM,EAAE,UAAU,KAAK,IAAI;AAC3B,UAAM,UAAU,CAAC,SAAS;AAE1B,QAAI,KAAK,SAAS,SAAS,MAAM,QAAQ;AACvC,cAAQ,KAAK,IAAI;AAAA,IACnB;AACA,QAAI,cAAc,gBAAgB,YAAY;AAC9C,QAAI,aAAa,SAAS;AACxB,qBAAe;AAAA,IACjB;AACA,YAAQ,KAAK,GAAG,CAAC,gBAAgB,YAAY,WAAW,CAAC;AACzD,UAAM,UAAU,KAAK,KAAK,GAAG,OAAO;AACpC,YAAQ,IAAI,OAAO;AAEnB,QAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,YAAM,IAAI;AAAA,QACR,eAAe,4CAA4C,YAAY;AAAA,MACzE;AAAA,IACF;AACA,SAAK,QAAQ,SAAS,OAAO;AAC7B,eAAK,MAAM,WAAX,mBAAmB,GAAG,QAAQ,CAAC,SAAiB;AAC9C,YAAM,UAAU,KAAK,SAAS;AAC9B,UAAI,QAAQ,KAAK,MAAM,gBAAgB;AACrC,aAAK,KAAK,MAAM;AAAA,MAClB;AACA,UAAI,QAAQ,KAAK,MAAM,iBAAiB;AACtC,aAAK,KAAK,OAAO;AAAA,MACnB;AAAA,IACF;AAEA,eAAK,MAAM,WAAX,mBAAmB,GAAG,QAAQ,CAAC,SAAiB;AAC9C,WAAK,KAAK,QAAQ,KAAK,SAAS,CAAC;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,gBAAgB;AAhDlB;AAiDI,SAAK,KAAK,OAAO;AACjB,UAAM,OAAM,UAAK,UAAL,mBAAY;AACxB,WAAO;AAAA,EACT;AACF;AAEA,IAAO,oBAAQ,IAAI,uBAAuB","sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { EventEmitter } from 'events';\nimport { spawn, execFile, ChildProcessWithoutNullStreams, ChildProcess } from 'node:child_process';\n\nclass ClipboardEventListener extends EventEmitter {\n child: ChildProcess | undefined;\n constructor() {\n super();\n this.child = undefined;\n }\n\n startListening() {\n const { platform, arch } = process;\n const pathArr = [__dirname];\n\n if (path.basename(__dirname) === 'dist') {\n pathArr.push('..');\n }\n let exeFilename = `go-clipboard-${platform}-${arch}`;\n if (platform === 'win32') {\n exeFilename += '.exe';\n }\n pathArr.push(...['go-clipboard', 'binaries', exeFilename]);\n const exePath = path.join(...pathArr);\n console.log(exePath);\n \n if (!fs.existsSync(exePath)) {\n throw new Error(\n `Executable (${exeFilename}) not found, your platform is ${platform} ${arch} and may not be supported.`\n );\n }\n this.child = execFile(exePath);\n this.child.stdout?.on('data', (data: Buffer) => {\n const dataStr = data.toString();\n if (dataStr.trim() === 'TEXT_CHANGED') {\n this.emit('text');\n }\n if (dataStr.trim() === 'IMAGE_CHANGED') {\n this.emit('image');\n }\n });\n\n this.child.stderr?.on('data', (data: Buffer) => {\n this.emit('open', data.toString());\n });\n }\n\n stopListening() {\n this.emit('close');\n const res = this.child?.kill();\n return res;\n }\n}\n\nexport default new ClipboardEventListener();\n"]}
1
+ {"version":3,"sources":["../index.ts","../src/util.ts"],"names":["data"],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { EventEmitter } from \"node:events\";\nimport net from \"net\";\nimport { execFile, ChildProcess, execFileSync } from \"node:child_process\";\nimport util from \"util\";\nimport { base64BufToUTF8, base64StringToUTF8 } from \"./src/util\";\nimport { ClipboardOperation, WatchEvent } from \"./src/constants\";\n\nconst execFileAsync = util.promisify(execFile);\n\nexport class Clipboard {\n child: ChildProcess | undefined;\n server: net.Server | undefined;\n emitter: EventEmitter;\n\n constructor() {\n this.child = undefined;\n this.emitter = new EventEmitter();\n }\n\n get exeFilename(): string {\n const { platform, arch } = process;\n let exeFilename = `go-clipboard-${platform}-${arch}`;\n if (platform === \"win32\") {\n exeFilename += \".exe\";\n }\n return exeFilename;\n }\n\n get goClipboardPath(): string {\n const pathArr = [__dirname];\n\n if (path.basename(__dirname) === \"dist\") {\n pathArr.push(\"..\");\n }\n\n pathArr.push(...[\"go-clipboard\", \"binaries\", this.exeFilename]);\n const exePath = path.join(...pathArr);\n return exePath;\n }\n\n readText(): Promise<string> {\n return execFileAsync(this.goClipboardPath, [\n ClipboardOperation.READ_TEXT,\n ]).then((result) => {\n return base64StringToUTF8(result.stdout);\n });\n }\n\n readTextSync(): string {\n const buf = execFileSync(this.goClipboardPath, [\n ClipboardOperation.READ_TEXT,\n ]);\n return base64BufToUTF8(buf);\n }\n\n writeText(content: string): Promise<void> {\n return Promise.resolve(this.writeTextSync(content));\n }\n\n writeTextSync(content: string): void {\n const writeTextProcess = execFile(this.goClipboardPath, [\n ClipboardOperation.WRITE_TEXT,\n ]);\n writeTextProcess.stdin?.write(content);\n writeTextProcess.stdin?.end();\n }\n\n writeImageSync(base64ImgStr: string): void;\n writeImageSync(imgBuf: Buffer): void;\n writeImageSync(data: string | Buffer): void {\n if (data instanceof String || typeof data === \"string\") {\n const writeImageProcess = execFile(this.goClipboardPath, [\n ClipboardOperation.WRITE_IMAGE,\n ]);\n writeImageProcess.stdin?.write(data);\n writeImageProcess.stdin?.end();\n } else if (data instanceof Buffer) {\n this.writeImageSync(data.toString(\"base64\"));\n } else {\n throw new Error(\"Invalid Data Type. Has to be string or Buffer\");\n }\n }\n writeImage(data: string): Promise<void>;\n writeImage(data: Buffer): Promise<void>;\n writeImage(data: string | Buffer): Promise<void> {\n if (data instanceof String || typeof data === \"string\") {\n return Promise.resolve(this.writeImageSync(data as string));\n } else if (data instanceof Buffer) {\n return Promise.resolve(this.writeImageSync(data as Buffer));\n } else {\n throw new Error(\"Invalid Data Type. Has to be string or Buffer\");\n }\n }\n\n readImage(): Promise<Buffer> {\n return Promise.resolve(this.readImageSync());\n }\n\n readImageBase64(): Promise<string> {\n return Promise.resolve(this.readImageBase64Sync());\n }\n\n readImageSync(): Buffer {\n const buf = execFileSync(this.goClipboardPath, [\n ClipboardOperation.READ_IMAGE,\n ]);\n const stdoutStr = buf.toString();\n const imgBuf = Buffer.from(stdoutStr, \"base64\");\n fs.writeFileSync(\"test.png\", imgBuf);\n return imgBuf;\n }\n\n readImageBase64Sync(): string {\n return this.readImageSync().toString(\"base64\");\n }\n\n listen() {\n this.server = net.createServer((con) => {\n // client connected\n let data = \"\";\n\n // * demo of sending message to client,\n // con.write(\"close\");\n\n /**\n * Accumulate data by concatenating chunks of received data\n */\n con.on(\"data\", (packet) => {\n data += packet.toString();\n });\n\n /**\n * When socket connection closes, wrap up received data\n */\n con.on(\"close\", () => {\n const strData = data.toString();\n const subStr = strData.substring(0, 14);\n if (subStr.includes(`${WatchEvent.TEXT_CHANGED}:`)) {\n const text = Buffer.from(strData.substring(13), \"base64\").toString();\n this.emitter.emit(\"text\", text);\n } else if (subStr.includes(`${WatchEvent.IMAGE_CHANGED}:`)) {\n const data = strData.substring(14) as string;\n this.emitter.emit(\"image\", Buffer.from(data, \"base64\"));\n // const imageBase64 = data.toString(\"base64\");\n // console.log(`Image Changed`);\n // fs.writeFileSync(\"test.png\", Buffer.from(data, \"base64\"));\n }\n });\n });\n\n this.server.listen(8090, () => {\n const addr = this.server?.address();\n if (!addr)\n throw new Error(\"Unexpected Error: TCP Socket Server not Started\");\n const port = (addr as net.AddressInfo).port;\n this.child = execFile(this.goClipboardPath, [port.toString()]);\n // this.child.stdout?.on(\"data\", (data) => {\n // console.log(\"Received data from client socket stdout:\\n\" + data);\n // });\n });\n }\n\n close() {\n this.emitter.emit(\"close\");\n this.emitter.removeAllListeners();\n this.server?.close();\n const res = this.child?.kill();\n return res;\n }\n\n on(event: \"text\", cb: (text: string) => void): void;\n on(event: \"image\", cb: (text: string) => void): void;\n on(event: \"close\", cb: (text: string) => void): void;\n on(event: \"text\" | \"image\" | \"close\", cb: (text: string) => void): void {\n this.emitter.on(event, cb);\n }\n}\n\nexport default new Clipboard();\n","export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport const base64StringToUTF8 = (base64Str: string) => {\n const base64buf = Buffer.from(base64Str, \"base64\"); // parse base64 string to buffer\n const text = base64buf.toString(\"utf8\"); // base64 buffer to utf-8 string\n return text;\n};\n\nexport const base64BufToUTF8 = (buf: Buffer): string => {\n const base64Text = buf.toString();\n return base64StringToUTF8(base64Text);\n};"]}
package/dist/index.mjs CHANGED
@@ -1,55 +1,152 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { EventEmitter } from 'events';
4
- import { execFile } from 'child_process';
4
+ import net from 'net';
5
+ import { execFile, execFileSync } from 'child_process';
6
+ import util from 'util';
5
7
 
6
8
  // index.ts
7
- var ClipboardEventListener = class extends EventEmitter {
9
+
10
+ // src/util.ts
11
+ var base64StringToUTF8 = (base64Str) => {
12
+ const base64buf = Buffer.from(base64Str, "base64");
13
+ const text = base64buf.toString("utf8");
14
+ return text;
15
+ };
16
+ var base64BufToUTF8 = (buf) => {
17
+ const base64Text = buf.toString();
18
+ return base64StringToUTF8(base64Text);
19
+ };
20
+
21
+ // index.ts
22
+ var execFileAsync = util.promisify(execFile);
23
+ var Clipboard = class {
8
24
  constructor() {
9
- super();
10
25
  this.child = void 0;
26
+ this.emitter = new EventEmitter();
11
27
  }
12
- startListening() {
13
- var _a, _b;
28
+ get exeFilename() {
14
29
  const { platform, arch } = process;
15
- const pathArr = [__dirname];
16
- if (path.basename(__dirname) === "dist") {
17
- pathArr.push("..");
18
- }
19
30
  let exeFilename = `go-clipboard-${platform}-${arch}`;
20
31
  if (platform === "win32") {
21
32
  exeFilename += ".exe";
22
33
  }
23
- pathArr.push(...["go-clipboard", "binaries", exeFilename]);
34
+ return exeFilename;
35
+ }
36
+ get goClipboardPath() {
37
+ const pathArr = [__dirname];
38
+ if (path.basename(__dirname) === "dist") {
39
+ pathArr.push("..");
40
+ }
41
+ pathArr.push(...["go-clipboard", "binaries", this.exeFilename]);
24
42
  const exePath = path.join(...pathArr);
25
- console.log(exePath);
26
- if (!fs.existsSync(exePath)) {
27
- throw new Error(
28
- `Executable (${exeFilename}) not found, your platform is ${platform} ${arch} and may not be supported.`
29
- );
43
+ return exePath;
44
+ }
45
+ readText() {
46
+ return execFileAsync(this.goClipboardPath, [
47
+ "READ_TEXT" /* READ_TEXT */
48
+ ]).then((result) => {
49
+ return base64StringToUTF8(result.stdout);
50
+ });
51
+ }
52
+ readTextSync() {
53
+ const buf = execFileSync(this.goClipboardPath, [
54
+ "READ_TEXT" /* READ_TEXT */
55
+ ]);
56
+ return base64BufToUTF8(buf);
57
+ }
58
+ writeText(content) {
59
+ return Promise.resolve(this.writeTextSync(content));
60
+ }
61
+ writeTextSync(content) {
62
+ var _a, _b;
63
+ const writeTextProcess = execFile(this.goClipboardPath, [
64
+ "WRITE_TEXT" /* WRITE_TEXT */
65
+ ]);
66
+ (_a = writeTextProcess.stdin) == null ? void 0 : _a.write(content);
67
+ (_b = writeTextProcess.stdin) == null ? void 0 : _b.end();
68
+ }
69
+ writeImageSync(data) {
70
+ var _a, _b;
71
+ if (data instanceof String || typeof data === "string") {
72
+ const writeImageProcess = execFile(this.goClipboardPath, [
73
+ "WRITE_IMAGE" /* WRITE_IMAGE */
74
+ ]);
75
+ (_a = writeImageProcess.stdin) == null ? void 0 : _a.write(data);
76
+ (_b = writeImageProcess.stdin) == null ? void 0 : _b.end();
77
+ } else if (data instanceof Buffer) {
78
+ this.writeImageSync(data.toString("base64"));
79
+ } else {
80
+ throw new Error("Invalid Data Type. Has to be string or Buffer");
81
+ }
82
+ }
83
+ writeImage(data) {
84
+ if (data instanceof String || typeof data === "string") {
85
+ return Promise.resolve(this.writeImageSync(data));
86
+ } else if (data instanceof Buffer) {
87
+ return Promise.resolve(this.writeImageSync(data));
88
+ } else {
89
+ throw new Error("Invalid Data Type. Has to be string or Buffer");
30
90
  }
31
- this.child = execFile(exePath);
32
- (_a = this.child.stdout) == null ? void 0 : _a.on("data", (data) => {
33
- const dataStr = data.toString();
34
- if (dataStr.trim() === "TEXT_CHANGED") {
35
- this.emit("text");
36
- }
37
- if (dataStr.trim() === "IMAGE_CHANGED") {
38
- this.emit("image");
39
- }
91
+ }
92
+ readImage() {
93
+ return Promise.resolve(this.readImageSync());
94
+ }
95
+ readImageBase64() {
96
+ return Promise.resolve(this.readImageBase64Sync());
97
+ }
98
+ readImageSync() {
99
+ const buf = execFileSync(this.goClipboardPath, [
100
+ "READ_IMAGE" /* READ_IMAGE */
101
+ ]);
102
+ const stdoutStr = buf.toString();
103
+ const imgBuf = Buffer.from(stdoutStr, "base64");
104
+ fs.writeFileSync("test.png", imgBuf);
105
+ return imgBuf;
106
+ }
107
+ readImageBase64Sync() {
108
+ return this.readImageSync().toString("base64");
109
+ }
110
+ listen() {
111
+ this.server = net.createServer((con) => {
112
+ let data = "";
113
+ con.on("data", (packet) => {
114
+ data += packet.toString();
115
+ });
116
+ con.on("close", () => {
117
+ const strData = data.toString();
118
+ const subStr = strData.substring(0, 14);
119
+ if (subStr.includes(`${"TEXT_CHANGED" /* TEXT_CHANGED */}:`)) {
120
+ const text = Buffer.from(strData.substring(13), "base64").toString();
121
+ this.emitter.emit("text", text);
122
+ } else if (subStr.includes(`${"IMAGE_CHANGED" /* IMAGE_CHANGED */}:`)) {
123
+ const data2 = strData.substring(14);
124
+ this.emitter.emit("image", Buffer.from(data2, "base64"));
125
+ }
126
+ });
40
127
  });
41
- (_b = this.child.stderr) == null ? void 0 : _b.on("data", (data) => {
42
- this.emit("open", data.toString());
128
+ this.server.listen(8090, () => {
129
+ var _a;
130
+ const addr = (_a = this.server) == null ? void 0 : _a.address();
131
+ if (!addr)
132
+ throw new Error("Unexpected Error: TCP Socket Server not Started");
133
+ const port = addr.port;
134
+ this.child = execFile(this.goClipboardPath, [port.toString()]);
43
135
  });
44
136
  }
45
- stopListening() {
46
- var _a;
47
- this.emit("close");
48
- const res = (_a = this.child) == null ? void 0 : _a.kill();
137
+ close() {
138
+ var _a, _b;
139
+ this.emitter.emit("close");
140
+ this.emitter.removeAllListeners();
141
+ (_a = this.server) == null ? void 0 : _a.close();
142
+ const res = (_b = this.child) == null ? void 0 : _b.kill();
49
143
  return res;
50
144
  }
145
+ on(event, cb) {
146
+ this.emitter.on(event, cb);
147
+ }
51
148
  };
52
- var clipboard_default = new ClipboardEventListener();
149
+ var clipboard_default = new Clipboard();
53
150
 
54
- export { clipboard_default as default };
151
+ export { Clipboard, clipboard_default as default };
55
152
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"names":[],"mappings":";AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,oBAAoB;AAC7B,SAAgB,gBAA8D;AAE9E,IAAM,yBAAN,cAAqC,aAAa;AAAA,EAEhD,cAAc;AACZ,UAAM;AACN,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,iBAAiB;AAZnB;AAaI,UAAM,EAAE,UAAU,KAAK,IAAI;AAC3B,UAAM,UAAU,CAAC,SAAS;AAE1B,QAAI,KAAK,SAAS,SAAS,MAAM,QAAQ;AACvC,cAAQ,KAAK,IAAI;AAAA,IACnB;AACA,QAAI,cAAc,gBAAgB,YAAY;AAC9C,QAAI,aAAa,SAAS;AACxB,qBAAe;AAAA,IACjB;AACA,YAAQ,KAAK,GAAG,CAAC,gBAAgB,YAAY,WAAW,CAAC;AACzD,UAAM,UAAU,KAAK,KAAK,GAAG,OAAO;AACpC,YAAQ,IAAI,OAAO;AAEnB,QAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,YAAM,IAAI;AAAA,QACR,eAAe,4CAA4C,YAAY;AAAA,MACzE;AAAA,IACF;AACA,SAAK,QAAQ,SAAS,OAAO;AAC7B,eAAK,MAAM,WAAX,mBAAmB,GAAG,QAAQ,CAAC,SAAiB;AAC9C,YAAM,UAAU,KAAK,SAAS;AAC9B,UAAI,QAAQ,KAAK,MAAM,gBAAgB;AACrC,aAAK,KAAK,MAAM;AAAA,MAClB;AACA,UAAI,QAAQ,KAAK,MAAM,iBAAiB;AACtC,aAAK,KAAK,OAAO;AAAA,MACnB;AAAA,IACF;AAEA,eAAK,MAAM,WAAX,mBAAmB,GAAG,QAAQ,CAAC,SAAiB;AAC9C,WAAK,KAAK,QAAQ,KAAK,SAAS,CAAC;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,gBAAgB;AAhDlB;AAiDI,SAAK,KAAK,OAAO;AACjB,UAAM,OAAM,UAAK,UAAL,mBAAY;AACxB,WAAO;AAAA,EACT;AACF;AAEA,IAAO,oBAAQ,IAAI,uBAAuB","sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { EventEmitter } from 'events';\nimport { spawn, execFile, ChildProcessWithoutNullStreams, ChildProcess } from 'node:child_process';\n\nclass ClipboardEventListener extends EventEmitter {\n child: ChildProcess | undefined;\n constructor() {\n super();\n this.child = undefined;\n }\n\n startListening() {\n const { platform, arch } = process;\n const pathArr = [__dirname];\n\n if (path.basename(__dirname) === 'dist') {\n pathArr.push('..');\n }\n let exeFilename = `go-clipboard-${platform}-${arch}`;\n if (platform === 'win32') {\n exeFilename += '.exe';\n }\n pathArr.push(...['go-clipboard', 'binaries', exeFilename]);\n const exePath = path.join(...pathArr);\n console.log(exePath);\n \n if (!fs.existsSync(exePath)) {\n throw new Error(\n `Executable (${exeFilename}) not found, your platform is ${platform} ${arch} and may not be supported.`\n );\n }\n this.child = execFile(exePath);\n this.child.stdout?.on('data', (data: Buffer) => {\n const dataStr = data.toString();\n if (dataStr.trim() === 'TEXT_CHANGED') {\n this.emit('text');\n }\n if (dataStr.trim() === 'IMAGE_CHANGED') {\n this.emit('image');\n }\n });\n\n this.child.stderr?.on('data', (data: Buffer) => {\n this.emit('open', data.toString());\n });\n }\n\n stopListening() {\n this.emit('close');\n const res = this.child?.kill();\n return res;\n }\n}\n\nexport default new ClipboardEventListener();\n"]}
1
+ {"version":3,"sources":["../index.ts","../src/util.ts"],"names":["data"],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { EventEmitter } from \"node:events\";\nimport net from \"net\";\nimport { execFile, ChildProcess, execFileSync } from \"node:child_process\";\nimport util from \"util\";\nimport { base64BufToUTF8, base64StringToUTF8 } from \"./src/util\";\nimport { ClipboardOperation, WatchEvent } from \"./src/constants\";\n\nconst execFileAsync = util.promisify(execFile);\n\nexport class Clipboard {\n child: ChildProcess | undefined;\n server: net.Server | undefined;\n emitter: EventEmitter;\n\n constructor() {\n this.child = undefined;\n this.emitter = new EventEmitter();\n }\n\n get exeFilename(): string {\n const { platform, arch } = process;\n let exeFilename = `go-clipboard-${platform}-${arch}`;\n if (platform === \"win32\") {\n exeFilename += \".exe\";\n }\n return exeFilename;\n }\n\n get goClipboardPath(): string {\n const pathArr = [__dirname];\n\n if (path.basename(__dirname) === \"dist\") {\n pathArr.push(\"..\");\n }\n\n pathArr.push(...[\"go-clipboard\", \"binaries\", this.exeFilename]);\n const exePath = path.join(...pathArr);\n return exePath;\n }\n\n readText(): Promise<string> {\n return execFileAsync(this.goClipboardPath, [\n ClipboardOperation.READ_TEXT,\n ]).then((result) => {\n return base64StringToUTF8(result.stdout);\n });\n }\n\n readTextSync(): string {\n const buf = execFileSync(this.goClipboardPath, [\n ClipboardOperation.READ_TEXT,\n ]);\n return base64BufToUTF8(buf);\n }\n\n writeText(content: string): Promise<void> {\n return Promise.resolve(this.writeTextSync(content));\n }\n\n writeTextSync(content: string): void {\n const writeTextProcess = execFile(this.goClipboardPath, [\n ClipboardOperation.WRITE_TEXT,\n ]);\n writeTextProcess.stdin?.write(content);\n writeTextProcess.stdin?.end();\n }\n\n writeImageSync(base64ImgStr: string): void;\n writeImageSync(imgBuf: Buffer): void;\n writeImageSync(data: string | Buffer): void {\n if (data instanceof String || typeof data === \"string\") {\n const writeImageProcess = execFile(this.goClipboardPath, [\n ClipboardOperation.WRITE_IMAGE,\n ]);\n writeImageProcess.stdin?.write(data);\n writeImageProcess.stdin?.end();\n } else if (data instanceof Buffer) {\n this.writeImageSync(data.toString(\"base64\"));\n } else {\n throw new Error(\"Invalid Data Type. Has to be string or Buffer\");\n }\n }\n writeImage(data: string): Promise<void>;\n writeImage(data: Buffer): Promise<void>;\n writeImage(data: string | Buffer): Promise<void> {\n if (data instanceof String || typeof data === \"string\") {\n return Promise.resolve(this.writeImageSync(data as string));\n } else if (data instanceof Buffer) {\n return Promise.resolve(this.writeImageSync(data as Buffer));\n } else {\n throw new Error(\"Invalid Data Type. Has to be string or Buffer\");\n }\n }\n\n readImage(): Promise<Buffer> {\n return Promise.resolve(this.readImageSync());\n }\n\n readImageBase64(): Promise<string> {\n return Promise.resolve(this.readImageBase64Sync());\n }\n\n readImageSync(): Buffer {\n const buf = execFileSync(this.goClipboardPath, [\n ClipboardOperation.READ_IMAGE,\n ]);\n const stdoutStr = buf.toString();\n const imgBuf = Buffer.from(stdoutStr, \"base64\");\n fs.writeFileSync(\"test.png\", imgBuf);\n return imgBuf;\n }\n\n readImageBase64Sync(): string {\n return this.readImageSync().toString(\"base64\");\n }\n\n listen() {\n this.server = net.createServer((con) => {\n // client connected\n let data = \"\";\n\n // * demo of sending message to client,\n // con.write(\"close\");\n\n /**\n * Accumulate data by concatenating chunks of received data\n */\n con.on(\"data\", (packet) => {\n data += packet.toString();\n });\n\n /**\n * When socket connection closes, wrap up received data\n */\n con.on(\"close\", () => {\n const strData = data.toString();\n const subStr = strData.substring(0, 14);\n if (subStr.includes(`${WatchEvent.TEXT_CHANGED}:`)) {\n const text = Buffer.from(strData.substring(13), \"base64\").toString();\n this.emitter.emit(\"text\", text);\n } else if (subStr.includes(`${WatchEvent.IMAGE_CHANGED}:`)) {\n const data = strData.substring(14) as string;\n this.emitter.emit(\"image\", Buffer.from(data, \"base64\"));\n // const imageBase64 = data.toString(\"base64\");\n // console.log(`Image Changed`);\n // fs.writeFileSync(\"test.png\", Buffer.from(data, \"base64\"));\n }\n });\n });\n\n this.server.listen(8090, () => {\n const addr = this.server?.address();\n if (!addr)\n throw new Error(\"Unexpected Error: TCP Socket Server not Started\");\n const port = (addr as net.AddressInfo).port;\n this.child = execFile(this.goClipboardPath, [port.toString()]);\n // this.child.stdout?.on(\"data\", (data) => {\n // console.log(\"Received data from client socket stdout:\\n\" + data);\n // });\n });\n }\n\n close() {\n this.emitter.emit(\"close\");\n this.emitter.removeAllListeners();\n this.server?.close();\n const res = this.child?.kill();\n return res;\n }\n\n on(event: \"text\", cb: (text: string) => void): void;\n on(event: \"image\", cb: (text: string) => void): void;\n on(event: \"close\", cb: (text: string) => void): void;\n on(event: \"text\" | \"image\" | \"close\", cb: (text: string) => void): void {\n this.emitter.on(event, cb);\n }\n}\n\nexport default new Clipboard();\n","export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport const base64StringToUTF8 = (base64Str: string) => {\n const base64buf = Buffer.from(base64Str, \"base64\"); // parse base64 string to buffer\n const text = base64buf.toString(\"utf8\"); // base64 buffer to utf-8 string\n return text;\n};\n\nexport const base64BufToUTF8 = (buf: Buffer): string => {\n const base64Text = buf.toString();\n return base64StringToUTF8(base64Text);\n};"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crosscopy/clipboard",
3
- "version": "0.1.0-beta-1",
3
+ "version": "0.1.1",
4
4
  "description": "Cross Platform Clipboard listener that detects both text and image update in clipboard",
5
5
  "source": "index.ts",
6
6
  "types": "./dist/index.d.ts",
@@ -25,10 +25,7 @@
25
25
  "url": "https://github.com/HuakunShen/general-clipboard-listener/issues"
26
26
  },
27
27
  "homepage": "https://github.com/HuakunShen/general-clipboard-listener#readme",
28
- "dependencies": {
29
- "events": "^3.3.0",
30
- "execa": "^6.1.0"
31
- },
28
+ "dependencies": {},
32
29
  "devDependencies": {
33
30
  "@jest/globals": "^29.3.1",
34
31
  "@types/jest": "^29.2.4",