Init
This commit is contained in:
parent
90ac261702
commit
c96350f10c
145
index.js
Executable file
145
index.js
Executable file
@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const https = require("https");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const os = require("os");
|
||||
const { URL } = require("url");
|
||||
const yaml = require("yaml");
|
||||
|
||||
// CLI flags
|
||||
const args = process.argv.slice(2);
|
||||
const asJSON = args.includes("--json");
|
||||
const asMarkdown = args.includes("--markdown");
|
||||
|
||||
// === STEP 1: Load config from tea YAML ===
|
||||
function findTeaConfig() {
|
||||
const xdg = process.env.XDG_CONFIG_HOME;
|
||||
const home = os.homedir();
|
||||
const platform = process.platform;
|
||||
|
||||
const paths = [];
|
||||
|
||||
// 1. XDG_CONFIG_HOME override
|
||||
if (xdg) {
|
||||
paths.push(path.join(xdg, "tea", "config.yml"));
|
||||
}
|
||||
|
||||
// 2. Platform-specific default
|
||||
if (platform === "darwin") {
|
||||
// macOS: ~/Library/Application Support/tea/config.yml
|
||||
paths.push(path.join(home, "Library", "Application Support", "tea", "config.yml"));
|
||||
} else {
|
||||
// Linux/others: ~/.config/tea/config.yml
|
||||
paths.push(path.join(home, ".config", "tea", "config.yml"));
|
||||
}
|
||||
|
||||
// 3. Legacy fallback
|
||||
paths.push(path.join(home, ".tea", "tea.yml"));
|
||||
|
||||
// 4. First existing config wins
|
||||
for (const p of paths) {
|
||||
if (fs.existsSync(p)) return p;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function loadGiteaLogin() {
|
||||
const configPath = findTeaConfig();
|
||||
if (!configPath) {
|
||||
console.error("❌ Could not find tea config.yml or tea.yml");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const file = fs.readFileSync(configPath, "utf8");
|
||||
const parsed = yaml.parse(file);
|
||||
const logins = parsed.logins || [];
|
||||
|
||||
if (logins.length === 0) {
|
||||
console.error("❌ No logins found in config");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const login = logins.find((l) => l.default) || logins[0];
|
||||
return {
|
||||
baseUrl: login.url.replace(/\/$/, ""),
|
||||
token: login.token,
|
||||
user: login.user,
|
||||
};
|
||||
}
|
||||
|
||||
// === STEP 2: Fetch package list from Gitea ===
|
||||
function fetchJSON(baseUrl, path, token) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const url = new URL(path, baseUrl);
|
||||
const options = {
|
||||
headers: {
|
||||
Authorization: `token ${token}`,
|
||||
Accept: "application/json",
|
||||
},
|
||||
};
|
||||
|
||||
https.get(url, options, (res) => {
|
||||
let body = "";
|
||||
res.on("data", (chunk) => (body += chunk));
|
||||
res.on("end", () => {
|
||||
try {
|
||||
const json = JSON.parse(body);
|
||||
resolve(json);
|
||||
} catch (err) {
|
||||
reject(new Error("Failed to parse JSON: " + err.message));
|
||||
}
|
||||
});
|
||||
}).on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
// === STEP 3: Output functions ===
|
||||
function printPlain(packages) {
|
||||
packages.forEach(pkg => {
|
||||
console.log(`${pkg.name}@${pkg.version} — ${pkg.created_at}`);
|
||||
});
|
||||
}
|
||||
|
||||
function printMarkdown(packages) {
|
||||
console.log(`| Package | Version | Created At |`);
|
||||
console.log(`|---------|---------|------------|`);
|
||||
packages.forEach(pkg => {
|
||||
const name = `\`${pkg.name}\``;
|
||||
const version = `\`${pkg.version}\``;
|
||||
const created = new Date(pkg.created_at).toISOString().split("T")[0];
|
||||
console.log(`| ${name} | ${version} | ${created} |`);
|
||||
});
|
||||
}
|
||||
|
||||
function printJSON(packages) {
|
||||
console.log(JSON.stringify(packages, null, 2));
|
||||
}
|
||||
|
||||
// === STEP 4: Main logic ===
|
||||
async function listPackages() {
|
||||
const { baseUrl, token, user } = loadGiteaLogin();
|
||||
|
||||
const isOrg = false; // You can change this or extend to CLI option
|
||||
const endpoint = isOrg
|
||||
? `/api/v1/orgs/${user}/packages/npm`
|
||||
: `/api/v1/users/${user}/packages/npm`;
|
||||
|
||||
try {
|
||||
const packages = await fetchJSON(baseUrl, endpoint, token);
|
||||
if (!Array.isArray(packages)) throw new Error("Unexpected response");
|
||||
|
||||
if (asJSON) {
|
||||
printJSON(packages);
|
||||
} else if (asMarkdown) {
|
||||
printMarkdown(packages);
|
||||
} else {
|
||||
printPlain(packages);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("❌ Error:", err.message);
|
||||
}
|
||||
}
|
||||
|
||||
listPackages();
|
||||
20
package.json
Normal file
20
package.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "gitea-npm",
|
||||
"version": "1.0.0",
|
||||
"description": "Manage npm packages stored on gitea",
|
||||
"main": "index.js",
|
||||
"bin": "npm-gitea",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
"npm",
|
||||
"git",
|
||||
"gitea"
|
||||
],
|
||||
"author": "William Ross <wnross@gwhc.net>",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"yaml": "^2.7.1"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user