st-registry-cli 1.3.2 → 1.4.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/index.js +88 -17
- package/package.json +3 -2
package/index.js
CHANGED
|
@@ -2,63 +2,54 @@
|
|
|
2
2
|
import { program } from "commander";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { download } from "./download.js";
|
|
5
|
+
import fetch from "node-fetch";
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import path from "path";
|
|
5
8
|
|
|
9
|
+
// --- INSTALL COMMAND (For individual downloads) ---
|
|
6
10
|
program
|
|
7
11
|
.command("install <name> [destination] [version]")
|
|
8
12
|
.description("Downloads package")
|
|
9
13
|
.action(async function (name, destination, version) {
|
|
10
14
|
try {
|
|
11
|
-
// 1. Fetch the registry
|
|
12
15
|
const response = await fetch("https://stoppedwumm-studios.github.io/st-registry/index.json");
|
|
13
16
|
const modulesData = await response.json();
|
|
14
17
|
const modules = modulesData.modules;
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
modules[key].name.toLowerCase() === name.toLowerCase()
|
|
19
|
+
const module = modules.find(m =>
|
|
20
|
+
m.name.toLowerCase() === name.toLowerCase()
|
|
19
21
|
);
|
|
20
22
|
|
|
21
|
-
if (!
|
|
23
|
+
if (!module) {
|
|
22
24
|
console.error(chalk.red(`Module "${name}" not found in registry.`));
|
|
23
25
|
return;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
const module = modules[moduleKey];
|
|
27
28
|
const mjson = await (await fetch(module["url"])).json();
|
|
28
29
|
console.log("Found module under path:", chalk.bold(module["path"]));
|
|
29
30
|
|
|
30
|
-
// 3. Determine which version to use
|
|
31
31
|
let selectedVersion;
|
|
32
|
-
|
|
33
32
|
if (Array.isArray(mjson["url"])) {
|
|
34
33
|
if (version) {
|
|
35
|
-
// Find specific version
|
|
36
34
|
selectedVersion = mjson["url"].find(v =>
|
|
37
35
|
v.versionRule.toLowerCase() === version.toLowerCase()
|
|
38
36
|
);
|
|
39
37
|
} else {
|
|
40
|
-
// Default to the first one if no version specified
|
|
41
38
|
selectedVersion = mjson["url"][0];
|
|
42
39
|
}
|
|
43
40
|
} else if (typeof mjson["url"] === "string") {
|
|
44
|
-
// Handle cases where "url" might just be a string instead of an array
|
|
45
41
|
selectedVersion = { url: mjson["url"] };
|
|
46
42
|
}
|
|
47
43
|
|
|
48
|
-
// 4. Execute download
|
|
49
44
|
if (selectedVersion) {
|
|
50
45
|
const downloadUrl = selectedVersion.url;
|
|
51
|
-
|
|
52
|
-
// Determine extension logic
|
|
53
46
|
const extension = downloadUrl.includes("zipball")
|
|
54
47
|
? ".zip"
|
|
55
|
-
: "." + downloadUrl.split(".").at(-1);
|
|
48
|
+
: "." + downloadUrl.split(".").at(-1).split('?')[0];
|
|
56
49
|
|
|
57
50
|
const finalDestination = destination || (module["name"] + extension);
|
|
58
51
|
|
|
59
52
|
console.log(chalk.blue(`Downloading to ${finalDestination}...`));
|
|
60
|
-
|
|
61
|
-
// Note: If download is async, you should probably 'await' it
|
|
62
53
|
await download(downloadUrl, finalDestination);
|
|
63
54
|
console.log(chalk.green("Download complete!"));
|
|
64
55
|
} else {
|
|
@@ -70,4 +61,84 @@ program
|
|
|
70
61
|
}
|
|
71
62
|
});
|
|
72
63
|
|
|
64
|
+
// --- CLONE COMMAND (Downloads everything using registry paths) ---
|
|
65
|
+
program
|
|
66
|
+
.command("clone")
|
|
67
|
+
.description("Clones the entire registry using defined paths and all versions")
|
|
68
|
+
.action(async function () {
|
|
69
|
+
try {
|
|
70
|
+
console.log(chalk.cyan("Fetching registry..."));
|
|
71
|
+
const response = await fetch("https://stoppedwumm-studios.github.io/st-registry/index.json");
|
|
72
|
+
const modulesData = await response.json();
|
|
73
|
+
const modules = modulesData.modules;
|
|
74
|
+
|
|
75
|
+
for (const module of modules) {
|
|
76
|
+
console.log(chalk.yellow(`\nProcessing module: ${module.name}`));
|
|
77
|
+
|
|
78
|
+
const mjson = await (await fetch(module.url)).json();
|
|
79
|
+
|
|
80
|
+
// Create the directory based on the "path" key (e.g., "m/minecraft")
|
|
81
|
+
const targetDir = module.path;
|
|
82
|
+
if (!fs.existsSync(targetDir)) {
|
|
83
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Handle modules that have multiple versions
|
|
87
|
+
const versions = Array.isArray(mjson.url)
|
|
88
|
+
? mjson.url
|
|
89
|
+
: [{ versionRule: "latest", url: mjson.url }];
|
|
90
|
+
|
|
91
|
+
for (const v of versions) {
|
|
92
|
+
const downloadUrl = v.url;
|
|
93
|
+
const versionName = v.versionRule || "default";
|
|
94
|
+
|
|
95
|
+
// --- SMART EXTENSION DETECTION ---
|
|
96
|
+
const urlObj = new URL(downloadUrl);
|
|
97
|
+
const lastSegment = urlObj.pathname.split('/').pop();
|
|
98
|
+
|
|
99
|
+
let extension = "";
|
|
100
|
+
const commonExts = ['zip', 'jar', 'exe', 'msi', 'dmg', 'json', 'apk', 'tar', 'gz', '7z'];
|
|
101
|
+
|
|
102
|
+
if (downloadUrl.includes("zipball") || downloadUrl.includes("/zip/")) {
|
|
103
|
+
extension = ".zip";
|
|
104
|
+
} else if (lastSegment.includes(".")) {
|
|
105
|
+
const parts = lastSegment.split('.');
|
|
106
|
+
const potentialExt = parts.pop().toLowerCase();
|
|
107
|
+
|
|
108
|
+
// Check if it's a real extension or just a version number (like .1)
|
|
109
|
+
if (commonExts.includes(potentialExt) || isNaN(potentialExt)) {
|
|
110
|
+
extension = "." + potentialExt;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// --- FALLBACK GUESSING ---
|
|
115
|
+
// If no extension found, check for keywords in the URL
|
|
116
|
+
if (!extension) {
|
|
117
|
+
if (downloadUrl.toLowerCase().includes("installer")) extension = ".exe";
|
|
118
|
+
else if (downloadUrl.toLowerCase().includes("mac") || downloadUrl.toLowerCase().includes("osx")) extension = ".dmg";
|
|
119
|
+
else if (downloadUrl.toLowerCase().includes("json")) extension = ".json";
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Sanitize version name (remove slashes) to keep files inside the module folder
|
|
123
|
+
const safeVersionName = versionName.replace(/[/\\?%*:|"<>]/g, '-');
|
|
124
|
+
const fileName = `${module.name}-${safeVersionName}${extension}`;
|
|
125
|
+
|
|
126
|
+
const finalDestination = path.join(targetDir, fileName);
|
|
127
|
+
|
|
128
|
+
console.log(chalk.blue(` -> Downloading version [${versionName}] to ${finalDestination}...`));
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
await download(downloadUrl, finalDestination);
|
|
132
|
+
} catch (dlErr) {
|
|
133
|
+
console.error(chalk.red(` Failed to download ${versionName}:`), dlErr.message);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
console.log(chalk.green(`Successfully processed all versions for ${module.name}`));
|
|
137
|
+
}
|
|
138
|
+
console.log(chalk.bold.green("\nRegistry cloning complete!"));
|
|
139
|
+
} catch (error) {
|
|
140
|
+
console.error(chalk.red("An error occurred during cloning:"), error.message);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
73
144
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "st-registry-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"type": "module",
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"chalk": "^5.6.2",
|
|
15
|
-
"commander": "^14.0.3"
|
|
15
|
+
"commander": "^14.0.3",
|
|
16
|
+
"node-fetch": "^3.3.2"
|
|
16
17
|
},
|
|
17
18
|
"bin": {
|
|
18
19
|
"spm": "index.js"
|