keyspy 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +287 -0
- package/build/index.d.ts +53 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +149 -0
- package/build/ts/MacKeyServer.d.ts +45 -0
- package/build/ts/MacKeyServer.d.ts.map +1 -0
- package/build/ts/MacKeyServer.js +159 -0
- package/build/ts/WinKeyServer.d.ts +30 -0
- package/build/ts/WinKeyServer.d.ts.map +1 -0
- package/build/ts/WinKeyServer.js +88 -0
- package/build/ts/X11KeyServer.d.ts +45 -0
- package/build/ts/X11KeyServer.d.ts.map +1 -0
- package/build/ts/X11KeyServer.js +159 -0
- package/build/ts/_data/MacGlobalKeyLookup.d.ts +3 -0
- package/build/ts/_data/MacGlobalKeyLookup.d.ts.map +1 -0
- package/build/ts/_data/MacGlobalKeyLookup.js +155 -0
- package/build/ts/_data/WinGlobalKeyLookup.d.ts +6 -0
- package/build/ts/_data/WinGlobalKeyLookup.d.ts.map +1 -0
- package/build/ts/_data/WinGlobalKeyLookup.js +181 -0
- package/build/ts/_data/X11GlobalKeyLookup.d.ts +3 -0
- package/build/ts/_data/X11GlobalKeyLookup.d.ts.map +1 -0
- package/build/ts/_data/X11GlobalKeyLookup.js +144 -0
- package/build/ts/_types/IConfig.d.ts +15 -0
- package/build/ts/_types/IConfig.d.ts.map +1 -0
- package/build/ts/_types/IConfig.js +3 -0
- package/build/ts/_types/IGlobalKey.d.ts +19 -0
- package/build/ts/_types/IGlobalKey.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKey.js +3 -0
- package/build/ts/_types/IGlobalKeyDownMap.d.ts +5 -0
- package/build/ts/_types/IGlobalKeyDownMap.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyDownMap.js +3 -0
- package/build/ts/_types/IGlobalKeyEvent.d.ts +17 -0
- package/build/ts/_types/IGlobalKeyEvent.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyEvent.js +3 -0
- package/build/ts/_types/IGlobalKeyListener.d.ts +14 -0
- package/build/ts/_types/IGlobalKeyListener.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyListener.js +3 -0
- package/build/ts/_types/IGlobalKeyListenerRaw.d.ts +7 -0
- package/build/ts/_types/IGlobalKeyListenerRaw.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyListenerRaw.js +3 -0
- package/build/ts/_types/IGlobalKeyLookup.d.ts +9 -0
- package/build/ts/_types/IGlobalKeyLookup.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyLookup.js +3 -0
- package/build/ts/_types/IGlobalKeyResult.d.ts +12 -0
- package/build/ts/_types/IGlobalKeyResult.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyResult.js +3 -0
- package/build/ts/_types/IGlobalKeyServer.d.ts +16 -0
- package/build/ts/_types/IGlobalKeyServer.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyServer.js +3 -0
- package/build/ts/_types/IMacConfig.d.ts +10 -0
- package/build/ts/_types/IMacConfig.d.ts.map +1 -0
- package/build/ts/_types/IMacConfig.js +3 -0
- package/build/ts/_types/IWindowsConfig.d.ts +10 -0
- package/build/ts/_types/IWindowsConfig.d.ts.map +1 -0
- package/build/ts/_types/IWindowsConfig.js +3 -0
- package/build/ts/_types/IX11Config.d.ts +10 -0
- package/build/ts/_types/IX11Config.d.ts.map +1 -0
- package/build/ts/_types/IX11Config.js +3 -0
- package/build/ts/isSpawnEventSupported.d.ts +6 -0
- package/build/ts/isSpawnEventSupported.d.ts.map +1 -0
- package/build/ts/isSpawnEventSupported.js +18 -0
- package/package.json +80 -0
- package/scripts/download-binaries.js +191 -0
@@ -0,0 +1,191 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
const fs = require('node:fs');
|
4
|
+
const path = require('node:path');
|
5
|
+
const https = require('node:https');
|
6
|
+
const { execSync } = require('node:child_process');
|
7
|
+
|
8
|
+
const packageJson = require('../package.json');
|
9
|
+
const version = packageJson.version;
|
10
|
+
|
11
|
+
// Platform detection
|
12
|
+
const platform = process.platform;
|
13
|
+
const arch = process.arch;
|
14
|
+
|
15
|
+
// Binary mapping
|
16
|
+
const binaryMap = {
|
17
|
+
'darwin': {
|
18
|
+
'arm64': { file: 'MacKeyServer', archive: 'keyspy-darwin-arm64.tar.gz' },
|
19
|
+
'x64': { file: 'MacKeyServer', archive: 'keyspy-darwin-x64.tar.gz' }
|
20
|
+
},
|
21
|
+
'linux': {
|
22
|
+
'x64': { file: 'X11KeyServer', archive: 'keyspy-linux-x64.tar.gz' }
|
23
|
+
},
|
24
|
+
'win32': {
|
25
|
+
'x64': { file: 'WinKeyServer.exe', archive: 'keyspy-win32-x64.tar.gz' }
|
26
|
+
}
|
27
|
+
};
|
28
|
+
|
29
|
+
function log(message) {
|
30
|
+
console.log(`[keyspy] ${message}`);
|
31
|
+
}
|
32
|
+
|
33
|
+
function error(message) {
|
34
|
+
console.error(`[keyspy] ERROR: ${message}`);
|
35
|
+
}
|
36
|
+
|
37
|
+
function getPlatformInfo() {
|
38
|
+
const platformInfo = binaryMap[platform];
|
39
|
+
if (!platformInfo) {
|
40
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
41
|
+
}
|
42
|
+
|
43
|
+
const archInfo = platformInfo[arch];
|
44
|
+
if (!archInfo) {
|
45
|
+
throw new Error(`Unsupported architecture: ${arch} on ${platform}`);
|
46
|
+
}
|
47
|
+
|
48
|
+
return archInfo;
|
49
|
+
}
|
50
|
+
|
51
|
+
function downloadFile(url, dest) {
|
52
|
+
return new Promise((resolve, reject) => {
|
53
|
+
log(`Downloading ${url}`);
|
54
|
+
|
55
|
+
const file = fs.createWriteStream(dest);
|
56
|
+
|
57
|
+
https.get(url, (response) => {
|
58
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
59
|
+
// Handle redirect
|
60
|
+
return downloadFile(response.headers.location, dest).then(resolve).catch(reject);
|
61
|
+
}
|
62
|
+
|
63
|
+
if (response.statusCode !== 200) {
|
64
|
+
reject(new Error(`Download failed with status ${response.statusCode}`));
|
65
|
+
return;
|
66
|
+
}
|
67
|
+
|
68
|
+
response.pipe(file);
|
69
|
+
|
70
|
+
file.on('finish', () => {
|
71
|
+
file.close();
|
72
|
+
resolve();
|
73
|
+
});
|
74
|
+
|
75
|
+
file.on('error', (err) => {
|
76
|
+
fs.unlink(dest, () => {
|
77
|
+
// Ignore unlink errors - file cleanup is best effort
|
78
|
+
}); // Delete partial file
|
79
|
+
reject(err);
|
80
|
+
});
|
81
|
+
}).on('error', reject);
|
82
|
+
});
|
83
|
+
}
|
84
|
+
|
85
|
+
function extractTarGz(archivePath, extractDir) {
|
86
|
+
try {
|
87
|
+
// Try using tar command
|
88
|
+
execSync(`tar -xzf "${archivePath}" -C "${extractDir}"`, { stdio: 'inherit' });
|
89
|
+
return true;
|
90
|
+
} catch (_err) {
|
91
|
+
log('tar command failed, trying alternative extraction...');
|
92
|
+
return false;
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
async function downloadAndExtract() {
|
97
|
+
try {
|
98
|
+
const { file: binaryFile, archive } = getPlatformInfo();
|
99
|
+
|
100
|
+
// Create bin directory
|
101
|
+
const binDir = path.join(__dirname, '..', 'bin');
|
102
|
+
if (!fs.existsSync(binDir)) {
|
103
|
+
fs.mkdirSync(binDir, { recursive: true });
|
104
|
+
}
|
105
|
+
|
106
|
+
const binaryPath = path.join(binDir, binaryFile);
|
107
|
+
|
108
|
+
// Check if binary already exists
|
109
|
+
if (fs.existsSync(binaryPath)) {
|
110
|
+
log(`Binary already exists: ${binaryPath}`);
|
111
|
+
return;
|
112
|
+
}
|
113
|
+
|
114
|
+
// Download URL
|
115
|
+
const downloadUrl = `https://github.com/teomyth/keyspy/releases/download/v${version}/${archive}`;
|
116
|
+
const archivePath = path.join(binDir, archive);
|
117
|
+
|
118
|
+
log(`Platform: ${platform}-${arch}`);
|
119
|
+
log(`Binary: ${binaryFile}`);
|
120
|
+
|
121
|
+
try {
|
122
|
+
// Download archive
|
123
|
+
await downloadFile(downloadUrl, archivePath);
|
124
|
+
log(`Downloaded: ${archive}`);
|
125
|
+
|
126
|
+
// Extract archive
|
127
|
+
if (extractTarGz(archivePath, binDir)) {
|
128
|
+
log(`Extracted: ${archive}`);
|
129
|
+
|
130
|
+
// Make binary executable (Unix systems)
|
131
|
+
if (platform !== 'win32') {
|
132
|
+
try {
|
133
|
+
fs.chmodSync(binaryPath, 0o755);
|
134
|
+
log(`Made executable: ${binaryFile}`);
|
135
|
+
} catch (err) {
|
136
|
+
log(`Warning: Could not make binary executable: ${err.message}`);
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
// Clean up archive
|
141
|
+
fs.unlinkSync(archivePath);
|
142
|
+
log(`Cleaned up: ${archive}`);
|
143
|
+
|
144
|
+
log(`✅ Successfully installed binary: ${binaryFile}`);
|
145
|
+
} else {
|
146
|
+
throw new Error('Failed to extract archive');
|
147
|
+
}
|
148
|
+
|
149
|
+
} catch (downloadErr) {
|
150
|
+
error(`Failed to download binary: ${downloadErr.message}`);
|
151
|
+
log('');
|
152
|
+
log('📝 Manual installation options:');
|
153
|
+
log('1. Download from: https://github.com/teomyth/keyspy/releases');
|
154
|
+
log('2. Build from source:');
|
155
|
+
log(' - macOS: npm run build:swift');
|
156
|
+
log(' - Linux: npm run build:x11');
|
157
|
+
log(' - Windows: npm run build:win');
|
158
|
+
log('');
|
159
|
+
log('⚠️ KeySpy will not work without the platform-specific binary.');
|
160
|
+
|
161
|
+
// Don't fail the installation, just warn
|
162
|
+
process.exit(0);
|
163
|
+
}
|
164
|
+
|
165
|
+
} catch (err) {
|
166
|
+
error(err.message);
|
167
|
+
log('');
|
168
|
+
log('📋 Supported platforms:');
|
169
|
+
log('- macOS (ARM64, x64)');
|
170
|
+
log('- Linux (x64)');
|
171
|
+
log('- Windows (x64)');
|
172
|
+
log('');
|
173
|
+
log('If your platform should be supported, please report this issue:');
|
174
|
+
log('https://github.com/teomyth/keyspy/issues');
|
175
|
+
|
176
|
+
// Don't fail the installation for unsupported platforms
|
177
|
+
process.exit(0);
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
// Skip download in CI environments or if explicitly disabled
|
182
|
+
if (process.env.CI || process.env.KEYSPY_SKIP_DOWNLOAD) {
|
183
|
+
log('Skipping binary download (CI environment or explicitly disabled)');
|
184
|
+
process.exit(0);
|
185
|
+
}
|
186
|
+
|
187
|
+
// Run download
|
188
|
+
downloadAndExtract().catch((err) => {
|
189
|
+
error(`Unexpected error: ${err.message}`);
|
190
|
+
process.exit(0); // Don't fail npm install
|
191
|
+
});
|