Skip to content
This repository has been archived by the owner on Feb 25, 2024. It is now read-only.

Commit

Permalink
v2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
wdhdev authored Mar 19, 2023
1 parent 383359b commit 8a80f51
Show file tree
Hide file tree
Showing 13 changed files with 3,176 additions and 0 deletions.
2,698 changes: 2,698 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@is-a-dev/cli",
"version": "2.0.0",
"description": "Register your own is-a.dev subdomain from your command line!",
"main": "src/index.js",
"bin": {
"is-a-dev": "src/index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/wdhdev/is-a-dev-cli.git"
},
"keywords": [],
"author": "William Harrison <william@williamharrison.dev>",
"license": "MIT",
"bugs": {
"url": "https://github.com/wdhdev/is-a-dev-cli/issues"
},
"homepage": "https://www.npmjs.com/package/@is-a-dev/cli",
"dependencies": {
"@octokit/auth-oauth-device": "^4.0.4",
"@octokit/core": "^4.2.0",
"axios": "^1.3.4",
"cli-handle-unhandled": "^1.1.1",
"cli-meow-help": "^3.1.0",
"cli-welcome": "^2.2.2",
"conf": "^10.2.0",
"js-base64": "^3.7.2",
"meow": "^9.0.0",
"node-fetch": "^2.6.7",
"prompts": "^2.4.2"
}
}
17 changes: 17 additions & 0 deletions src/functions/account.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const Conf = require("conf");

const userAccount = new Conf();

module.exports = function account() {
const username = userAccount.get("username");
const email = userAccount.get("email");
const token = userAccount.get("token");

if(!username) {
console.log("You are not logged in!");
console.log("To log in, run the command: `is-a-dev login`");
return;
}

console.log(`Username: ${username}\nEmail: ${email}\nToken: ${token}`);
}
31 changes: 31 additions & 0 deletions src/functions/check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const axios = require("axios");
const prompts = require("prompts");

const questions = require("../util/questions").check;

module.exports = async function check() {
const response = await prompts(questions);

const subdomain = response.subdomain.toLowerCase();

let res;

try {
const request = await axios.get(`https://api.is-a.dev/check?domain=${subdomain}`);

res = request;
} catch(err) {
res = err.response;
}

if(res.status === 500) return console.log("An error occurred, please try again later.");

const message = res.data.message;

if(message === "DOMAIN_UNAVAILABLE") return console.log("\nSorry, that subdomain is taken!");

if(message === "DOMAIN_AVAILABLE") {
console.log("\nCongratulations, that subdomain is available!");
console.log("To register, run the command: `is-a-dev register`");
}
}
34 changes: 34 additions & 0 deletions src/functions/domains.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const axios = require("axios");
const Conf = require("conf");

const account = new Conf();

module.exports = async function domains() {
if(!account.has("username")) {
console.log("You are not logged in!");
console.log("To log in, run the command: `is-a-dev login`");
return;
}

console.log(`Username: ${account.get("username")}`);
console.log(`Email: ${account.get("email")}\n`);

const email = account.get("email");

let res;

try {
const request = await axios.get(`https://api.is-a.dev/lookup/user?email=${email}`);

res = request;
} catch(err) {
res = err.response;
}

if(res.status === 500) return console.log("An error occurred, please try again later.");
if(res.status === 404) return console.log("You do not own any domains.");

const domains = res.data.subdomains;

return console.log(`${domains.join(".is-a.dev\n")}.is-a.dev`);
}
66 changes: 66 additions & 0 deletions src/functions/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const Conf = require("conf");
const { createOAuthDeviceAuth } = require("@octokit/auth-oauth-device");
const { Octokit } = require("@octokit/core");
const prompts = require("prompts");

const account = new Conf();

module.exports = async function login() {
if(account.has("username")) {
console.log(`You are already logged in as ${account.get("username")}!`);
console.log("To log out, run the command: `is-a-dev logout`");
return;
}

const auth = createOAuthDeviceAuth({
clientType: "oauth-app",
clientId: "77432389afa6fe09b63e",
scopes: ["public_repo, user:email"],
onVerification(verification) {
console.log("Open the URL: %s", verification.verification_uri);
console.log("Enter code: %s", verification.user_code);
}
})

const tokenAuthentication = await auth({ type: "oauth" });

account.set("token", tokenAuthentication.token);

const octokit = new Octokit({ auth: tokenAuthentication.token });

const res1 = await octokit.request("GET /user", {});
account.set("username", res1.data.login);

const res2 = await octokit.request("GET /user/emails", {});

const emails = [];

res2.data.forEach(res => {
if(res.email.endsWith("@users.noreply.github.com") || !res.verified) return;

emails.push(res.email);
})

if(emails.length === 1) {
account.set("email", emails[0]);
} else {
const question = {
type: "select",
name: "email",
message: "Which email do you want to use?",
choices: []
}

for (const email of emails) {
question.choices.push({ value: email });
}

console.log(" ");

const response = await prompts(question);

account.set("email", response.email);
}

console.log(`\nLogged in as: ${account.get("username")} <${account.get("email")}>`);
}
16 changes: 16 additions & 0 deletions src/functions/logout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const Conf = require("conf");
const account = new Conf();

module.exports = function logout() {
if(!account.has("username")) {
console.log("You are not logged in!");
console.log("To log in, run the command: `is-a-dev login`")
return;
}

account.delete("email");
account.delete("token");
account.delete("username");

console.log("You have been logged out.");
}
97 changes: 97 additions & 0 deletions src/functions/register.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
const { Base64 } = require("js-base64");
const Conf = require("conf");
const fetch = require("node-fetch");
const { Octokit } = require("@octokit/core");
const prompts = require("prompts");

const account = new Conf();
const questions = require("../util/questions").register;

function delay(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}

module.exports = async function register() {
if(!account.has("username")) {
console.log("You are not logged in!");
console.log("To log in, run the command: `is-a-dev login`");
return;
}

console.log(`Username: ${account.get("username")}`);
console.log(`Email: ${account.get("email")}\n`);

const octokit = new Octokit({ auth: account.get("token") });

const response = await prompts(questions);

let forkName;

await octokit.request("POST /repos/{owner}/{repo}/forks", {
owner: "is-a-dev",
repo: "register",
default_branch_only: true
}).then(res => forkName = res.data.name)

const username = account.get("username");
const email = account.get("email");

const subdomain = response.subdomain.toLowerCase();
const recordType = response.record;
let recordValue = response.record_value.toLowerCase();

if(recordType === "A" || recordType === "AAAA" || recordType === "MX") {
recordValue = JSON.stringify(recordValue.split(",").map((s) => s.trim()));
} else {
recordValue = `"${recordValue.trim()}"`;
}

let fullContent = `{
"owner": {
"username": "${username}",
"email": "${email}"
},
"records": {
"${recordType}": ${recordValue}
}
}
`;

const contentEncoded = Base64.encode(fullContent);

fetch(
`https://api.github.com/repos/is-a-dev/register/contents/domains/${subdomain}.json`,
{
method: "GET",
headers: {
"User-Agent": username,
},
}
).then(async (res) => {
if(res.status && res.status == 404) {
octokit
.request("PUT /repos/{owner}/{repo}/contents/{path}", {
owner: username,
repo: forkName,
path: "domains/" + subdomain + ".json",
message: `feat(domain): add \`${subdomain}.is-a.dev\``,
content: contentEncoded
})
.catch((err) => { throw new Error(err); });
} else throw new Error("That subdomain is taken!");
})

await delay(2000);

const pr = await octokit.request("POST /repos/{owner}/{repo}/pulls", {
owner: "is-a-dev",
repo: "register",
title: `Register ${subdomain}.is-a.dev`,
body: `Added \`${subdomain}.is-a.dev\` using the [CLI](https://www.npmjs.com/package/@is-a-dev/cli).`,
head: username + ":main",
base: "main"
})

console.log(`\nYour pull request has been submitted.\nYou can check the status of your pull request here: ${pr.data.html_url}`);
}
24 changes: 24 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env node

const functions = require("./util/functions");

const cli = require("./util/cli");
const init = require("./util/init");

const input = cli.input;
const flags = cli.flags;
const { clear, debug } = flags;

(async () => {
init({ clear });

input.includes("account") && functions.account();
input.includes("check") && functions.check();
input.includes("domains") && functions.domains();
input.includes("help") && cli.showHelp(0);
input.includes("login") && functions.login();
input.includes("logout") && functions.logout();
input.includes("register") && functions.register();

debug && console.log(flags);
})();
52 changes: 52 additions & 0 deletions src/util/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const meow = require("meow");
const meowHelp = require("cli-meow-help");

const flags = {
clear: {
type: "boolean",
default: true,
alias: "c",
desc: "Clear the console"
},
debug: {
type: "boolean",
default: false,
alias: "d",
desc: "Print debug info"
},
noClear: {
type: "boolean",
default: false,
alias: "nc",
desc: "Don't clear the console"
},
version: {
type: "boolean",
alias: "v",
desc: "Print CLI version"
}
};

const commands = {
account: { desc: "Get information about your account." },
check: { desc: "Check if a subdomain is available." },
domains: { desc: "See a list of all of your subdomains." },
login: { desc: "Login to your GitHub account." },
logout: { desc: "Logout of your GitHub account." },
register: { desc: "Register a subdomain." }
}

const helpText = meowHelp({
name: "is-a-dev",
flags,
commands
})

const options = {
inferType: true,
description: false,
hardRejection: false,
flags
}

module.exports = meow(helpText, options);
8 changes: 8 additions & 0 deletions src/util/functions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
"account": require("../functions/account"),
"check": require("../functions/check"),
"domains": require("../functions/domains"),
"login": require("../functions/login"),
"logout": require("../functions/logout"),
"register": require("../functions/register")
}
Loading

0 comments on commit 8a80f51

Please sign in to comment.