dokky 0.0.0-stage → 0.0.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/dokky.js +27 -0
- package/install.js +14 -0
- package/lib/binary.js +112 -0
- package/package.json +49 -4
- package/README.md +0 -3
package/bin/dokky.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
const { spawn } = require("node:child_process");
|
|
4
|
+
const os = require("node:os");
|
|
5
|
+
const path = require("node:path");
|
|
6
|
+
const { resolveBinary, recordInstall, stateDir } = require("../lib/binary");
|
|
7
|
+
|
|
8
|
+
(async () => {
|
|
9
|
+
const pkgDir = path.resolve(__dirname, "..");
|
|
10
|
+
const pkg = require("../package.json");
|
|
11
|
+
const home = os.homedir();
|
|
12
|
+
const platform = process.platform;
|
|
13
|
+
const bin = await resolveBinary({ pkg, home, platform, arch: process.arch });
|
|
14
|
+
try {
|
|
15
|
+
recordInstall(stateDir({ env: process.env, home, platform }), pkgDir);
|
|
16
|
+
} catch {}
|
|
17
|
+
const child = spawn(bin, process.argv.slice(2), { stdio: "inherit" });
|
|
18
|
+
for (const sig of ["SIGINT", "SIGTERM"]) process.on(sig, () => child.kill(sig));
|
|
19
|
+
child.on("error", (err) => {
|
|
20
|
+
console.error(`dokky: ${err.message}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
});
|
|
23
|
+
child.on("exit", (code, signal) => process.exit(code ?? (signal ? 1 : 0)));
|
|
24
|
+
})().catch((err) => {
|
|
25
|
+
console.error(`dokky: ${err.message}`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
});
|
package/install.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const os = require("node:os");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const { ensureBinary, recordInstall, stateDir } = require("./lib/binary");
|
|
5
|
+
|
|
6
|
+
(async () => {
|
|
7
|
+
const pkg = require("./package.json");
|
|
8
|
+
const home = os.homedir();
|
|
9
|
+
const platform = process.platform;
|
|
10
|
+
await ensureBinary({ pkg, home, platform, arch: process.arch });
|
|
11
|
+
recordInstall(stateDir({ env: process.env, home, platform }), path.resolve(__dirname));
|
|
12
|
+
})().catch((err) => {
|
|
13
|
+
console.warn(`dokky: ${err.message}`);
|
|
14
|
+
});
|
package/lib/binary.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const crypto = require("node:crypto");
|
|
3
|
+
const fs = require("node:fs");
|
|
4
|
+
const path = require("node:path");
|
|
5
|
+
|
|
6
|
+
const ARCHES = { x64: "amd64", arm64: "arm64" };
|
|
7
|
+
const OSES = { darwin: "darwin", linux: "linux", win32: "windows" };
|
|
8
|
+
|
|
9
|
+
function platformKey(platform, arch) {
|
|
10
|
+
const os = OSES[platform];
|
|
11
|
+
const cpu = ARCHES[arch];
|
|
12
|
+
return os && cpu ? `${os}-${cpu}` : null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function binaryPath(home, platform) {
|
|
16
|
+
const name = platform === "win32" ? "dokky.exe" : "dokky";
|
|
17
|
+
return path.join(home, ".local", "bin", name);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function stateDir({ env, home, platform }) {
|
|
21
|
+
if (platform === "darwin") return path.join(home, "Library", "Application Support", "dokky");
|
|
22
|
+
if (platform === "win32") return path.join(env.LocalAppData || path.join(home, "AppData", "Local"), "dokky");
|
|
23
|
+
return path.join(env.XDG_CONFIG_HOME || path.join(home, ".config"), "dokky");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function cmp(a, b) {
|
|
27
|
+
const x = String(a).split(/[.-]/).map(Number);
|
|
28
|
+
const y = String(b).split(/[.-]/).map(Number);
|
|
29
|
+
for (let i = 0; i < 3; i++) {
|
|
30
|
+
const d = (x[i] || 0) - (y[i] || 0);
|
|
31
|
+
if (d) return d;
|
|
32
|
+
}
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function installedVersion(dir) {
|
|
37
|
+
try {
|
|
38
|
+
return fs.readFileSync(path.join(dir, "version"), "utf8").trim();
|
|
39
|
+
} catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function ensureBinary({ pkg, home, platform, arch, env = process.env, fetchImpl = fetch, rename = fs.renameSync }) {
|
|
45
|
+
const bin = binaryPath(home, platform);
|
|
46
|
+
const dir = stateDir({ env, home, platform });
|
|
47
|
+
const have = installedVersion(dir);
|
|
48
|
+
const pinned = fs.existsSync(path.join(dir, "pin"));
|
|
49
|
+
if (fs.existsSync(bin) && (pinned || (have && cmp(have, pkg.version) >= 0))) return bin;
|
|
50
|
+
|
|
51
|
+
const key = platformKey(platform, arch);
|
|
52
|
+
const entry = key && pkg.dokky && pkg.dokky.binaries && pkg.dokky.binaries[key];
|
|
53
|
+
if (!entry) throw new Error(`dokky ${pkg.version} has no binary for ${platform}/${arch}`);
|
|
54
|
+
|
|
55
|
+
const res = await fetchImpl(entry.url);
|
|
56
|
+
if (!res.ok) throw new Error(`download failed: HTTP ${res.status}`);
|
|
57
|
+
const data = Buffer.from(await res.arrayBuffer());
|
|
58
|
+
const sum = crypto.createHash("sha256").update(data).digest("hex");
|
|
59
|
+
if (sum !== String(entry.sha256).toLowerCase()) throw new Error(`sha256 mismatch for ${entry.url}`);
|
|
60
|
+
|
|
61
|
+
fs.mkdirSync(path.dirname(bin), { recursive: true });
|
|
62
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
63
|
+
const tmp = `${bin}.${process.pid}.tmp`;
|
|
64
|
+
try {
|
|
65
|
+
fs.writeFileSync(tmp, data, { mode: 0o755 });
|
|
66
|
+
fs.chmodSync(tmp, 0o755);
|
|
67
|
+
replace(tmp, bin, path.join(dir, "dokky.old"), platform === "win32" && fs.existsSync(bin), rename);
|
|
68
|
+
} finally {
|
|
69
|
+
fs.rmSync(tmp, { force: true });
|
|
70
|
+
}
|
|
71
|
+
fs.writeFileSync(path.join(dir, "version"), pkg.version);
|
|
72
|
+
return bin;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Windows can rename a running exe but not replace it, so the old one moves aside first
|
|
76
|
+
function replace(tmp, bin, old, aside, rename) {
|
|
77
|
+
if (!aside) return rename(tmp, bin);
|
|
78
|
+
rename(bin, old);
|
|
79
|
+
try {
|
|
80
|
+
rename(tmp, bin);
|
|
81
|
+
} catch (err) {
|
|
82
|
+
rename(old, bin);
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function resolveBinary(opts, warn = console.warn) {
|
|
88
|
+
try {
|
|
89
|
+
return await ensureBinary(opts);
|
|
90
|
+
} catch (err) {
|
|
91
|
+
const bin = binaryPath(opts.home, opts.platform);
|
|
92
|
+
if (!fs.existsSync(bin)) throw err;
|
|
93
|
+
warn(`dokky: ${err.message}; using installed binary`);
|
|
94
|
+
return bin;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function recordInstall(dir, pkgDir) {
|
|
99
|
+
const file = path.join(dir, "installs.json");
|
|
100
|
+
let list = [];
|
|
101
|
+
try {
|
|
102
|
+
list = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
103
|
+
} catch {
|
|
104
|
+
list = [];
|
|
105
|
+
}
|
|
106
|
+
if (!Array.isArray(list)) list = [];
|
|
107
|
+
if (list.includes(pkgDir)) return;
|
|
108
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
109
|
+
fs.writeFileSync(file, JSON.stringify([...list, pkgDir], null, 2));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = { platformKey, binaryPath, stateDir, ensureBinary, resolveBinary, recordInstall };
|
package/package.json
CHANGED
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dokky",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Mount your cloud and NAS storage as local folders",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://dokky.ritik.me",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/itzzritik/Dokky.git"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"dokky": "bin/dokky.js"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"postinstall": "node install.js",
|
|
16
|
+
"test": "node --test"
|
|
17
|
+
},
|
|
18
|
+
"dokky": {
|
|
19
|
+
"binaries": {
|
|
20
|
+
"darwin-amd64": {
|
|
21
|
+
"url": "https://github.com/itzzritik/dokky/releases/download/v0.0.2/dokky-darwin-amd64",
|
|
22
|
+
"sha256": "b11ac63e9320f337ea62bb7ca083c196e38df4fc32c3063b647f4442a869873f"
|
|
23
|
+
},
|
|
24
|
+
"darwin-arm64": {
|
|
25
|
+
"url": "https://github.com/itzzritik/dokky/releases/download/v0.0.2/dokky-darwin-arm64",
|
|
26
|
+
"sha256": "265182a24e157e1ef010f2f19ccf0bce710a1bac90b8eaaa0942223242f7d033"
|
|
27
|
+
},
|
|
28
|
+
"linux-amd64": {
|
|
29
|
+
"url": "https://github.com/itzzritik/dokky/releases/download/v0.0.2/dokky-linux-amd64",
|
|
30
|
+
"sha256": "f4db73f5c28c809519a8399df41ce7376b4454b7652739f96b8d8ea642e45f63"
|
|
31
|
+
},
|
|
32
|
+
"linux-arm64": {
|
|
33
|
+
"url": "https://github.com/itzzritik/dokky/releases/download/v0.0.2/dokky-linux-arm64",
|
|
34
|
+
"sha256": "5e29c687baa2f64ce0fa0c5907430ac1f0a90fff52bbdefe46e339ea8ca019a2"
|
|
35
|
+
},
|
|
36
|
+
"windows-amd64": {
|
|
37
|
+
"url": "https://github.com/itzzritik/dokky/releases/download/v0.0.2/dokky-windows-amd64.exe",
|
|
38
|
+
"sha256": "d68acbb4ea7fa843165a911efbef5c06c34eb1ac42231c98a6b04d087b78b009"
|
|
39
|
+
},
|
|
40
|
+
"windows-arm64": {
|
|
41
|
+
"url": "https://github.com/itzzritik/dokky/releases/download/v0.0.2/dokky-windows-arm64.exe",
|
|
42
|
+
"sha256": "c5056c18886b85c2cdbb7699486a0eb51b2864a1c70b6675c0dd8393ee585b3d"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"bin",
|
|
48
|
+
"lib",
|
|
49
|
+
"install.js"
|
|
50
|
+
]
|
|
51
|
+
}
|
package/README.md
DELETED