@bashlife/boxbox-beta 70.0.0 → 74.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/nibble-lock.json +128 -0
- package/package.json +6 -2
- package/src/commands/cd.sh +0 -0
- package/src/commands/info.js +8 -38
- package/src/commands/install.js +35 -0
- package/src/commands/nibble-lock.json +80 -0
- package/src/commands/nibble.js +249 -0
- package/src/index.js +6 -3
package/nibble-lock.json
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
{
|
|
2
|
+
"packages": {
|
|
3
|
+
"chalk": {
|
|
4
|
+
"version": "5.6.2",
|
|
5
|
+
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz"
|
|
6
|
+
},
|
|
7
|
+
"commander": {
|
|
8
|
+
"version": "15.0.0",
|
|
9
|
+
"resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz"
|
|
10
|
+
},
|
|
11
|
+
"run-applescript": {
|
|
12
|
+
"version": "7.1.0",
|
|
13
|
+
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz"
|
|
14
|
+
},
|
|
15
|
+
"bundle-name": {
|
|
16
|
+
"version": "4.1.0",
|
|
17
|
+
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz"
|
|
18
|
+
},
|
|
19
|
+
"default-browser-id": {
|
|
20
|
+
"version": "5.0.1",
|
|
21
|
+
"resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz"
|
|
22
|
+
},
|
|
23
|
+
"default-browser": {
|
|
24
|
+
"version": "5.5.0",
|
|
25
|
+
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz"
|
|
26
|
+
},
|
|
27
|
+
"define-lazy-prop": {
|
|
28
|
+
"version": "3.0.0",
|
|
29
|
+
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz"
|
|
30
|
+
},
|
|
31
|
+
"is-in-ssh": {
|
|
32
|
+
"version": "1.0.0",
|
|
33
|
+
"resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz"
|
|
34
|
+
},
|
|
35
|
+
"is-docker": {
|
|
36
|
+
"version": "3.0.0",
|
|
37
|
+
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz"
|
|
38
|
+
},
|
|
39
|
+
"is-inside-container": {
|
|
40
|
+
"version": "1.0.0",
|
|
41
|
+
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz"
|
|
42
|
+
},
|
|
43
|
+
"powershell-utils": {
|
|
44
|
+
"version": "0.2.0",
|
|
45
|
+
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.2.0.tgz"
|
|
46
|
+
},
|
|
47
|
+
"is-wsl": {
|
|
48
|
+
"version": "3.1.1",
|
|
49
|
+
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz"
|
|
50
|
+
},
|
|
51
|
+
"wsl-utils": {
|
|
52
|
+
"version": "0.4.0",
|
|
53
|
+
"resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.4.0.tgz"
|
|
54
|
+
},
|
|
55
|
+
"open": {
|
|
56
|
+
"version": "11.0.0",
|
|
57
|
+
"resolved": "https://registry.npmjs.org/open/-/open-11.0.0.tgz"
|
|
58
|
+
},
|
|
59
|
+
"mimic-function": {
|
|
60
|
+
"version": "5.0.1",
|
|
61
|
+
"resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz"
|
|
62
|
+
},
|
|
63
|
+
"onetime": {
|
|
64
|
+
"version": "7.0.0",
|
|
65
|
+
"resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz"
|
|
66
|
+
},
|
|
67
|
+
"signal-exit": {
|
|
68
|
+
"version": "4.1.0",
|
|
69
|
+
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz"
|
|
70
|
+
},
|
|
71
|
+
"restore-cursor": {
|
|
72
|
+
"version": "5.1.0",
|
|
73
|
+
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz"
|
|
74
|
+
},
|
|
75
|
+
"cli-cursor": {
|
|
76
|
+
"version": "5.0.0",
|
|
77
|
+
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz"
|
|
78
|
+
},
|
|
79
|
+
"cli-spinners": {
|
|
80
|
+
"version": "3.4.0",
|
|
81
|
+
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz"
|
|
82
|
+
},
|
|
83
|
+
"is-interactive": {
|
|
84
|
+
"version": "2.0.0",
|
|
85
|
+
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz"
|
|
86
|
+
},
|
|
87
|
+
"is-unicode-supported": {
|
|
88
|
+
"version": "2.1.0",
|
|
89
|
+
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz"
|
|
90
|
+
},
|
|
91
|
+
"yoctocolors": {
|
|
92
|
+
"version": "2.1.2",
|
|
93
|
+
"resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz"
|
|
94
|
+
},
|
|
95
|
+
"log-symbols": {
|
|
96
|
+
"version": "7.0.1",
|
|
97
|
+
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz"
|
|
98
|
+
},
|
|
99
|
+
"stdin-discarder": {
|
|
100
|
+
"version": "0.3.2",
|
|
101
|
+
"resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.3.2.tgz"
|
|
102
|
+
},
|
|
103
|
+
"get-east-asian-width": {
|
|
104
|
+
"version": "1.6.0",
|
|
105
|
+
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz"
|
|
106
|
+
},
|
|
107
|
+
"ansi-regex": {
|
|
108
|
+
"version": "6.2.2",
|
|
109
|
+
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz"
|
|
110
|
+
},
|
|
111
|
+
"strip-ansi": {
|
|
112
|
+
"version": "7.2.0",
|
|
113
|
+
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz"
|
|
114
|
+
},
|
|
115
|
+
"string-width": {
|
|
116
|
+
"version": "8.2.2",
|
|
117
|
+
"resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz"
|
|
118
|
+
},
|
|
119
|
+
"ora": {
|
|
120
|
+
"version": "9.4.1",
|
|
121
|
+
"resolved": "https://registry.npmjs.org/ora/-/ora-9.4.1.tgz"
|
|
122
|
+
},
|
|
123
|
+
"deploy-summit": {
|
|
124
|
+
"version": "1.0.0",
|
|
125
|
+
"resolved": "https://registry.npmjs.org/deploy-summit/-/deploy-summit-1.0.0.tgz"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bashlife/boxbox-beta",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "74.0.0",
|
|
4
4
|
"description": "A modern BusyBox-style CLI toolkit with custom commands.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "bashlife",
|
|
@@ -16,5 +16,9 @@
|
|
|
16
16
|
"bash",
|
|
17
17
|
"boxbox"
|
|
18
18
|
],
|
|
19
|
-
"license": "UNLICENSED"
|
|
19
|
+
"license": "UNLICENSED",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"boxbox-unfinished": "^65.0.2",
|
|
22
|
+
"tar": "^7.5.22"
|
|
23
|
+
}
|
|
20
24
|
}
|
package/src/commands/cd.sh
CHANGED
|
File without changes
|
package/src/commands/info.js
CHANGED
|
@@ -1,47 +1,17 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"package.json"
|
|
10
|
-
);
|
|
8
|
+
export default async function() {
|
|
9
|
+
const commandsDir = __dirname;
|
|
11
10
|
|
|
12
|
-
const
|
|
13
|
-
root,
|
|
14
|
-
"src",
|
|
15
|
-
"commands"
|
|
16
|
-
);
|
|
11
|
+
const commands = fs.readdirSync(commandsDir);
|
|
17
12
|
|
|
18
|
-
|
|
19
|
-
let commandCount = 0;
|
|
20
|
-
|
|
21
|
-
// Read version from package.json
|
|
22
|
-
if (fs.existsSync(packagePath)) {
|
|
23
|
-
try {
|
|
24
|
-
const pkg = JSON.parse(
|
|
25
|
-
fs.readFileSync(packagePath, "utf8")
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
version = pkg.version || "unknown";
|
|
29
|
-
} catch {
|
|
30
|
-
version = "unknown";
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Count commands (files + folders)
|
|
35
|
-
if (fs.existsSync(commandsDir)) {
|
|
36
|
-
const entries = fs.readdirSync(commandsDir);
|
|
37
|
-
|
|
38
|
-
commandCount = entries.filter((entry) => {
|
|
39
|
-
return !entry.startsWith(".");
|
|
40
|
-
}).length;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
console.log(`BoxBox ${version}`);
|
|
13
|
+
console.log("BoxBox v73.0.0");
|
|
44
14
|
console.log("Runtime: Node.js");
|
|
45
15
|
console.log(`Platform: ${process.platform}`);
|
|
46
|
-
console.log(`Commands: ${
|
|
16
|
+
console.log(`Commands: ${commands.length}`);
|
|
47
17
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
export default async function(args) {
|
|
5
|
+
if (args.length < 2) {
|
|
6
|
+
console.log("Usage: install <source> <destination>");
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const source = args[0];
|
|
11
|
+
const destination = args[1];
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
if (!fs.existsSync(source)) {
|
|
15
|
+
console.error(`install: ${source}: No such file`);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let target = destination;
|
|
20
|
+
|
|
21
|
+
// If destination is a directory, keep the filename
|
|
22
|
+
if (fs.existsSync(destination) && fs.statSync(destination).isDirectory()) {
|
|
23
|
+
target = path.join(destination, path.basename(source));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fs.copyFileSync(source, target);
|
|
27
|
+
|
|
28
|
+
// Default install behavior: executable permissions
|
|
29
|
+
fs.chmodSync(target, 0o755);
|
|
30
|
+
|
|
31
|
+
console.log(`installed ${source} -> ${target}`);
|
|
32
|
+
} catch (err) {
|
|
33
|
+
console.error(`install: ${err.message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"packages": {
|
|
3
|
+
"chalk": {
|
|
4
|
+
"version": "5.6.2",
|
|
5
|
+
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz"
|
|
6
|
+
},
|
|
7
|
+
"commander": {
|
|
8
|
+
"version": "15.0.0",
|
|
9
|
+
"resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz"
|
|
10
|
+
},
|
|
11
|
+
"run-applescript": {
|
|
12
|
+
"version": "7.1.0",
|
|
13
|
+
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz"
|
|
14
|
+
},
|
|
15
|
+
"bundle-name": {
|
|
16
|
+
"version": "4.1.0",
|
|
17
|
+
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz"
|
|
18
|
+
},
|
|
19
|
+
"default-browser-id": {
|
|
20
|
+
"version": "5.0.1",
|
|
21
|
+
"resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz"
|
|
22
|
+
},
|
|
23
|
+
"default-browser": {
|
|
24
|
+
"version": "5.5.0",
|
|
25
|
+
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz"
|
|
26
|
+
},
|
|
27
|
+
"define-lazy-prop": {
|
|
28
|
+
"version": "3.0.0",
|
|
29
|
+
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz"
|
|
30
|
+
},
|
|
31
|
+
"is-in-ssh": {
|
|
32
|
+
"version": "1.0.0",
|
|
33
|
+
"resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz"
|
|
34
|
+
},
|
|
35
|
+
"is-docker": {
|
|
36
|
+
"version": "3.0.0",
|
|
37
|
+
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz"
|
|
38
|
+
},
|
|
39
|
+
"is-inside-container": {
|
|
40
|
+
"version": "1.0.0",
|
|
41
|
+
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz"
|
|
42
|
+
},
|
|
43
|
+
"powershell-utils": {
|
|
44
|
+
"version": "0.2.0",
|
|
45
|
+
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.2.0.tgz"
|
|
46
|
+
},
|
|
47
|
+
"is-wsl": {
|
|
48
|
+
"version": "3.1.1",
|
|
49
|
+
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz"
|
|
50
|
+
},
|
|
51
|
+
"wsl-utils": {
|
|
52
|
+
"version": "0.4.0",
|
|
53
|
+
"resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.4.0.tgz"
|
|
54
|
+
},
|
|
55
|
+
"open": {
|
|
56
|
+
"version": "11.0.0",
|
|
57
|
+
"resolved": "https://registry.npmjs.org/open/-/open-11.0.0.tgz"
|
|
58
|
+
},
|
|
59
|
+
"mimic-function": {
|
|
60
|
+
"version": "5.0.1",
|
|
61
|
+
"resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz"
|
|
62
|
+
},
|
|
63
|
+
"onetime": {
|
|
64
|
+
"version": "7.0.0",
|
|
65
|
+
"resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz"
|
|
66
|
+
},
|
|
67
|
+
"signal-exit": {
|
|
68
|
+
"version": "4.1.0",
|
|
69
|
+
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz"
|
|
70
|
+
},
|
|
71
|
+
"restore-cursor": {
|
|
72
|
+
"version": "5.1.0",
|
|
73
|
+
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz"
|
|
74
|
+
},
|
|
75
|
+
"cli-cursor": {
|
|
76
|
+
"version": "5.0.0",
|
|
77
|
+
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import https from "https";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import os from "os";
|
|
5
|
+
import * as tar from "tar";
|
|
6
|
+
|
|
7
|
+
const HOME = os.homedir();
|
|
8
|
+
|
|
9
|
+
const NIBBLE_DIR = path.join(HOME, ".nibble");
|
|
10
|
+
const PACKAGES_DIR = path.join(NIBBLE_DIR, "packages");
|
|
11
|
+
const BIN_DIR = path.join(NIBBLE_DIR, "bin");
|
|
12
|
+
|
|
13
|
+
const DB_FILE = path.join(NIBBLE_DIR, "installed.json");
|
|
14
|
+
const LOCK_FILE = path.join(process.cwd(), "nibble-lock.json");
|
|
15
|
+
|
|
16
|
+
fs.mkdirSync(PACKAGES_DIR, { recursive: true });
|
|
17
|
+
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
18
|
+
|
|
19
|
+
const installing = new Set();
|
|
20
|
+
|
|
21
|
+
function fetchJSON(url) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
https.get(url, { headers: { "User-Agent": "Nibble" } }, res => {
|
|
24
|
+
let data = "";
|
|
25
|
+
res.on("data", chunk => data += chunk);
|
|
26
|
+
res.on("end", () => {
|
|
27
|
+
try {
|
|
28
|
+
resolve(JSON.parse(data));
|
|
29
|
+
} catch {
|
|
30
|
+
reject(new Error("Invalid JSON"));
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}).on("error", reject);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function download(url, file) {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
const output = fs.createWriteStream(file);
|
|
40
|
+
https.get(url, res => {
|
|
41
|
+
res.pipe(output);
|
|
42
|
+
output.on("finish", () => {
|
|
43
|
+
output.close();
|
|
44
|
+
resolve();
|
|
45
|
+
});
|
|
46
|
+
}).on("error", reject);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function loadJSON(file, fallback) {
|
|
51
|
+
if (!fs.existsSync(file)) return fallback;
|
|
52
|
+
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function saveJSON(file, data) {
|
|
56
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function safeName(name) {
|
|
60
|
+
return name.replaceAll("/", "__");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function parsePackage(input) {
|
|
64
|
+
if (input.startsWith("@")) {
|
|
65
|
+
const index = input.lastIndexOf("@");
|
|
66
|
+
if (index > 0) {
|
|
67
|
+
return { name: input.slice(0, index), version: input.slice(index + 1) };
|
|
68
|
+
}
|
|
69
|
+
return { name: input, version: null };
|
|
70
|
+
}
|
|
71
|
+
const parts = input.split("@");
|
|
72
|
+
return { name: parts[0], version: parts[1] || null };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function resolveVersion(meta, wanted) {
|
|
76
|
+
if (!wanted) return meta["dist-tags"].latest;
|
|
77
|
+
if (meta.versions[wanted]) return wanted;
|
|
78
|
+
|
|
79
|
+
const versions = Object.keys(meta.versions).reverse();
|
|
80
|
+
|
|
81
|
+
if (wanted.startsWith("^")) {
|
|
82
|
+
const major = wanted.slice(1).split(".")[0];
|
|
83
|
+
return versions.find(v => v.startsWith(`${major}.`));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (wanted.startsWith("~")) {
|
|
87
|
+
const base = wanted.slice(1).split(".").slice(0, 2).join(".");
|
|
88
|
+
return versions.find(v => v.startsWith(base));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return meta["dist-tags"].latest;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function linkBins(root, pkg) {
|
|
95
|
+
if (!pkg.bin) return;
|
|
96
|
+
const bins = typeof pkg.bin === "string" ? { [pkg.name]: pkg.bin } : pkg.bin;
|
|
97
|
+
|
|
98
|
+
for (const [name, file] of Object.entries(bins)) {
|
|
99
|
+
const target = path.join(root, file);
|
|
100
|
+
const link = path.join(BIN_DIR, name);
|
|
101
|
+
try { fs.unlinkSync(link); } catch {}
|
|
102
|
+
fs.symlinkSync(target, link);
|
|
103
|
+
console.log(`Linked ${name}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function install(input) {
|
|
108
|
+
const parsed = parsePackage(input);
|
|
109
|
+
const name = parsed.name;
|
|
110
|
+
|
|
111
|
+
if (installing.has(name)) return;
|
|
112
|
+
installing.add(name);
|
|
113
|
+
|
|
114
|
+
console.log(`Installing ${input}`);
|
|
115
|
+
|
|
116
|
+
const meta = await fetchJSON(`https://registry.npmjs.org/${name}`);
|
|
117
|
+
const version = resolveVersion(meta, parsed.version);
|
|
118
|
+
const info = meta.versions[version];
|
|
119
|
+
if (!info) throw new Error("Version not found");
|
|
120
|
+
|
|
121
|
+
const packageDir = path.join(PACKAGES_DIR, name);
|
|
122
|
+
const archive = path.join(NIBBLE_DIR, safeName(name) + ".tgz");
|
|
123
|
+
|
|
124
|
+
console.log(`Downloading ${name}@${version}`);
|
|
125
|
+
await download(info.dist.tarball, archive);
|
|
126
|
+
|
|
127
|
+
fs.mkdirSync(packageDir, { recursive: true });
|
|
128
|
+
await tar.x({ file: archive, cwd: packageDir });
|
|
129
|
+
|
|
130
|
+
// Delete the archive after extraction
|
|
131
|
+
try { fs.unlinkSync(archive); } catch {}
|
|
132
|
+
|
|
133
|
+
const root = path.join(packageDir, "package");
|
|
134
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
|
|
135
|
+
|
|
136
|
+
// Install dependencies recursively
|
|
137
|
+
if (pkg.dependencies) {
|
|
138
|
+
for (const [dep, range] of Object.entries(pkg.dependencies)) {
|
|
139
|
+
await install(`${dep}@${range}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Create node_modules and symlink dependencies
|
|
144
|
+
const nodeModules = path.join(root, "node_modules");
|
|
145
|
+
fs.mkdirSync(nodeModules, { recursive: true });
|
|
146
|
+
|
|
147
|
+
for (const dep of Object.keys(pkg.dependencies || {})) {
|
|
148
|
+
const depPath = path.join(nodeModules, dep);
|
|
149
|
+
try { fs.unlinkSync(depPath); } catch {}
|
|
150
|
+
fs.symlinkSync(path.join(PACKAGES_DIR, dep, "package"), depPath, "junction");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Link any executable bins
|
|
154
|
+
linkBins(root, pkg);
|
|
155
|
+
|
|
156
|
+
// Update installed database
|
|
157
|
+
const db = loadJSON(DB_FILE, {});
|
|
158
|
+
db[name] = { version, tarball: info.dist.tarball };
|
|
159
|
+
saveJSON(DB_FILE, db);
|
|
160
|
+
|
|
161
|
+
// Update lockfile
|
|
162
|
+
const lock = loadJSON(LOCK_FILE, { packages: {} });
|
|
163
|
+
lock.packages[name] = { version, resolved: info.dist.tarball };
|
|
164
|
+
saveJSON(LOCK_FILE, lock);
|
|
165
|
+
|
|
166
|
+
installing.delete(name);
|
|
167
|
+
console.log(`Installed ${name}@${version}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async function uninstall(name) {
|
|
171
|
+
const db = loadJSON(DB_FILE, {});
|
|
172
|
+
if (!db[name]) {
|
|
173
|
+
console.log("Not installed");
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
fs.rmSync(path.join(PACKAGES_DIR, name), { recursive: true, force: true });
|
|
177
|
+
delete db[name];
|
|
178
|
+
saveJSON(DB_FILE, db);
|
|
179
|
+
console.log(`Removed ${name}`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async function update(name) {
|
|
183
|
+
const db = loadJSON(DB_FILE, {});
|
|
184
|
+
if (!db[name]) {
|
|
185
|
+
console.log("Not installed");
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const meta = await fetchJSON(`https://registry.npmjs.org/${name}`);
|
|
189
|
+
const latest = meta["dist-tags"].latest;
|
|
190
|
+
if (latest === db[name].version) {
|
|
191
|
+
console.log("Already latest");
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
await uninstall(name);
|
|
195
|
+
await install(`${name}@${latest}`);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async function info(name) {
|
|
199
|
+
const data = await fetchJSON(`https://registry.npmjs.org/${name}`);
|
|
200
|
+
console.log(`
|
|
201
|
+
${data.name}
|
|
202
|
+
|
|
203
|
+
${data.description || ""}
|
|
204
|
+
|
|
205
|
+
Latest:
|
|
206
|
+
${data["dist-tags"].latest}
|
|
207
|
+
|
|
208
|
+
Versions:
|
|
209
|
+
${Object.keys(data.versions).length}
|
|
210
|
+
`);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function search(query) {
|
|
214
|
+
const data = await fetchJSON(`https://registry.npmjs.org/-/v1/search?text=${query}`);
|
|
215
|
+
for (const item of data.objects) {
|
|
216
|
+
console.log(item.package.name);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export default async function(args) {
|
|
221
|
+
switch(args[0]) {
|
|
222
|
+
case "search":
|
|
223
|
+
await search(args[1]);
|
|
224
|
+
break;
|
|
225
|
+
case "info":
|
|
226
|
+
await info(args[1]);
|
|
227
|
+
break;
|
|
228
|
+
case "install":
|
|
229
|
+
await install(args[1]);
|
|
230
|
+
break;
|
|
231
|
+
case "uninstall":
|
|
232
|
+
await uninstall(args[1]);
|
|
233
|
+
break;
|
|
234
|
+
case "update":
|
|
235
|
+
await update(args[1]);
|
|
236
|
+
break;
|
|
237
|
+
default:
|
|
238
|
+
console.log(`
|
|
239
|
+
Nibble Package Manager
|
|
240
|
+
|
|
241
|
+
Commands:
|
|
242
|
+
search <package>
|
|
243
|
+
info <package>
|
|
244
|
+
install <package>
|
|
245
|
+
uninstall <package>
|
|
246
|
+
update <package>
|
|
247
|
+
`);
|
|
248
|
+
}
|
|
249
|
+
}
|
package/src/index.js
CHANGED
|
@@ -6,6 +6,8 @@ const args = process.argv.slice(2);
|
|
|
6
6
|
const command = args[0];
|
|
7
7
|
|
|
8
8
|
const commands = {
|
|
9
|
+
nibble: "./commands/nibble.js",
|
|
10
|
+
install: "./commands/install.js",
|
|
9
11
|
base64: "./commands/base64.js",
|
|
10
12
|
rmdir: "./commands/rmdir.js",
|
|
11
13
|
javascript: "./commands/JavaScriptRun/index.js",
|
|
@@ -163,6 +165,7 @@ Commands:
|
|
|
163
165
|
rmdir Remove empty directories
|
|
164
166
|
nano create files write them edit them
|
|
165
167
|
base64 Encode or decode data using Base64
|
|
168
|
+
install - Copy files and set file permissions
|
|
166
169
|
`);
|
|
167
170
|
|
|
168
171
|
process.exit(0);
|
|
@@ -175,7 +178,7 @@ if (commands[command]) {
|
|
|
175
178
|
if (file.endsWith(".sh")) {
|
|
176
179
|
execFile("sh", [file, ...args.slice(1)], (err, stdout, stderr) => {
|
|
177
180
|
if (err) {
|
|
178
|
-
console.log(`boxbox
|
|
181
|
+
console.log(`boxbox Error: ${err.message}`);
|
|
179
182
|
return;
|
|
180
183
|
}
|
|
181
184
|
|
|
@@ -188,10 +191,10 @@ if (commands[command]) {
|
|
|
188
191
|
}
|
|
189
192
|
|
|
190
193
|
} catch (err) {
|
|
191
|
-
console.log(`boxbox
|
|
194
|
+
console.log(`boxbox Error: ${err.message}`);
|
|
192
195
|
}
|
|
193
196
|
|
|
194
197
|
} else {
|
|
195
198
|
console.log(`boxbox: unknown command '${command}'`);
|
|
196
|
-
console.log("Run 'boxbox
|
|
199
|
+
console.log("Run 'boxbox' for available commands.");
|
|
197
200
|
}
|