saferemove 0.1.2
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/bin/saferm +3 -0
- package/install.js +123 -0
- package/package.json +30 -0
package/bin/saferm
ADDED
package/install.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
const https = require("https");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const { execSync } = require("child_process");
|
|
5
|
+
|
|
6
|
+
const pkg = require("./package.json");
|
|
7
|
+
const version = pkg.version;
|
|
8
|
+
|
|
9
|
+
const PLATFORM_MAP = {
|
|
10
|
+
linux: "linux",
|
|
11
|
+
darwin: "darwin",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const ARCH_MAP = {
|
|
15
|
+
x64: "amd64",
|
|
16
|
+
arm64: "arm64",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function main() {
|
|
20
|
+
const osPlatform = process.platform;
|
|
21
|
+
const osArch = process.arch;
|
|
22
|
+
|
|
23
|
+
const os = PLATFORM_MAP[osPlatform];
|
|
24
|
+
const arch = ARCH_MAP[osArch];
|
|
25
|
+
|
|
26
|
+
if (!os || !arch) {
|
|
27
|
+
const label = !os && !arch
|
|
28
|
+
? `platform ${osPlatform} and architecture ${osArch}`
|
|
29
|
+
: !os
|
|
30
|
+
? `platform ${osPlatform}`
|
|
31
|
+
: `architecture ${osArch}`;
|
|
32
|
+
console.error(`Unsupported ${label}.`);
|
|
33
|
+
console.error(`Download manually from https://github.com/smm-h/saferm/releases`);
|
|
34
|
+
console.error(`Or install via Go: go install github.com/smm-h/saferm@latest`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const url = `https://github.com/smm-h/saferm/releases/download/v${version}/saferm_${version}_${os}_${arch}.tar.gz`;
|
|
39
|
+
|
|
40
|
+
const binName = "saferm";
|
|
41
|
+
const destPath = path.join(__dirname, "bin", binName);
|
|
42
|
+
|
|
43
|
+
console.log(`Downloading saferm v${version} for ${os}/${arch}...`);
|
|
44
|
+
|
|
45
|
+
download(url, (err, data) => {
|
|
46
|
+
if (err) {
|
|
47
|
+
console.error(`Failed to download saferm: ${err.message}`);
|
|
48
|
+
console.error(`URL: ${url}`);
|
|
49
|
+
console.error(`Download manually from https://github.com/smm-h/saferm/releases`);
|
|
50
|
+
console.error(`Or install via Go: go install github.com/smm-h/saferm@latest`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
extractTarGz(data, binName, destPath);
|
|
55
|
+
fs.chmodSync(destPath, 0o755);
|
|
56
|
+
console.log(`saferm v${version} installed successfully.`);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function download(url, callback, redirects) {
|
|
61
|
+
if (redirects === undefined) redirects = 0;
|
|
62
|
+
if (redirects > 5) {
|
|
63
|
+
callback(new Error("Too many redirects"));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const mod = url.startsWith("https") ? https : require("http");
|
|
68
|
+
|
|
69
|
+
mod.get(url, (res) => {
|
|
70
|
+
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
71
|
+
download(res.headers.location, callback, redirects + 1);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (res.statusCode !== 200) {
|
|
76
|
+
callback(new Error(`HTTP ${res.statusCode}: ${url}`));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const chunks = [];
|
|
81
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
82
|
+
res.on("end", () => callback(null, Buffer.concat(chunks)));
|
|
83
|
+
res.on("error", callback);
|
|
84
|
+
}).on("error", callback);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function extractTarGz(data, binName, destPath) {
|
|
88
|
+
const tmpArchive = path.join(__dirname, "_tmp_archive.tar.gz");
|
|
89
|
+
const tmpDir = path.join(__dirname, "_tmp_extract");
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
fs.writeFileSync(tmpArchive, data);
|
|
93
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
94
|
+
|
|
95
|
+
execSync(`tar xzf "${tmpArchive}" -C "${tmpDir}"`, { stdio: "pipe" });
|
|
96
|
+
|
|
97
|
+
const extracted = findFile(tmpDir, binName);
|
|
98
|
+
if (!extracted) {
|
|
99
|
+
throw new Error(`Binary "${binName}" not found in archive`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
fs.copyFileSync(extracted, destPath);
|
|
103
|
+
} finally {
|
|
104
|
+
try { fs.unlinkSync(tmpArchive); } catch (_) {}
|
|
105
|
+
try { fs.rmSync(tmpDir, { recursive: true }); } catch (_) {}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function findFile(dir, name) {
|
|
110
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
const fullPath = path.join(dir, entry.name);
|
|
113
|
+
if (entry.isDirectory()) {
|
|
114
|
+
const found = findFile(fullPath, name);
|
|
115
|
+
if (found) return found;
|
|
116
|
+
} else if (entry.name === name) {
|
|
117
|
+
return fullPath;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "saferemove",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "AI-first safe rm replacement",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/smm-h/saferm.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/smm-h/saferm",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"postinstall": "node install.js"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"saferm": "bin/saferm"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"install.js",
|
|
19
|
+
"bin/"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"rm",
|
|
23
|
+
"safe",
|
|
24
|
+
"delete",
|
|
25
|
+
"trash",
|
|
26
|
+
"undelete",
|
|
27
|
+
"cli",
|
|
28
|
+
"rlsbl"
|
|
29
|
+
]
|
|
30
|
+
}
|