diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f21b6a..2c00f5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## [2.0.0](https://github.com/Pradumnasaraf/LinkFree-CLI/compare/v1.4.2...v2.0.0) (2023-02-23) + +### Breaking Changes + +* The CLI now uses a diffent function/folder handling structure. This means the newer version features will not work with the older version of the CLI. Please update to the latest version of the CLI to use the new features. + +### Features + +* Added support to update the JSON function https://github.com/Pradumnasaraf/LinkFree-CLI/pull/24 +* Add support to add milestones, socials, and tags https://github.com/Pradumnasaraf/LinkFree-CLI/pull/26 +* Add support to create remove and update keys by https://github.com/Pradumnasaraf/LinkFree-CLI/pull/27 +* Add support to add events https://github.com/Pradumnasaraf/LinkFree-CLI/pull/30 +* Add supported to for optional key to Events and Milestone https://github.com/Pradumnasaraf/LinkFree-CLI/pull/32 https://github.com/Pradumnasaraf/LinkFree-CLI/pull/33 +* Support for reporting a bug from CLI https://github.com/Pradumnasaraf/LinkFree-CLI/pull/35 + +### Fix +* Removes empty keys from json when value is not there https://github.com/Pradumnasaraf/LinkFree-CLI/pull/34 + + ## [1.4.2](https://github.com/Pradumnasaraf/LinkFree-CLI/compare/v1.4.1...v1.4.2) (2023-02-15) diff --git a/README.md b/README.md index fa821d6..9240874 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,42 @@ -

LinkFree CLI

+

LinkFree CLI

-**LinkFree CLI** is a command line tool that helps you to create your **[LinkFree](https://github.com/EddieHubCommunity/LinkFree)** profile through CLI. +
+ + +**LinkFree CLI** is a command line tool that helps us to create and update your **[LinkFree](https://github.com/EddieHubCommunity/LinkFree)** profile through CLI. We can also give testimonials and events through it.
-
[![NPM Package](https://github.com/Pradumnasaraf/LinkFree-CLI/actions/workflows/publish.yml/badge.svg)](https://github.com/Pradumnasaraf/LinkFree-CLI/actions/workflows/publish.yml) [![Releases](https://github.com/Pradumnasaraf/LinkFree-CLI/actions/workflows/releases.yml/badge.svg)](https://github.com/Pradumnasaraf/LinkFree-CLI/actions/workflows/releases.yml) -[![.github/workflows/greetings.yml](https://github.com/Pradumnasaraf/LinkFree-CLI/actions/workflows/greetings.yml/badge.svg)](https://github.com/Pradumnasaraf/LinkFree-CLI/actions/workflows/greetings.yml) [![Npm package total downloads](https://badgen.net/npm/dt/linkfree-cli)](https://npmjs.com/package/linkfree-cli)
-## Demo +![LinkFree CLI demo GIF](https://user-images.githubusercontent.com/51878265/220831787-93c6b920-2961-4729-8a2c-0ac576658d83.gif) -![LinkFree CLI](https://user-images.githubusercontent.com/51878265/200193639-0e2d6d23-5f85-48e8-9563-8879b4efb18a.gif) +### ⭐️ Features -## Using the CLI (Commands) +- Creating a LinkFree profile. +- Updating a LinkFree profile. +- Giving a testimonial to a LinkFree profile. +- Adding events (conferences, meetups, etc). -> **Note** First fork the [LinkFree](https://github.com/EddieHubCommunity/LinkFree) repo before using it. -- **To install it globally.** +### 👨‍💻 Using the CLI tool -```bash -npm install -g linkfree-cli +Make sure you have cloned the [LinkFree](https://github.com/EddieHubCommunity/LinkFree) repo and in the root directory of the repo and installed the dependencies. -linkfree-Cli -``` - -It will then prompt you to questions. - -- **To execute the package directly, without installing it.** +- To trigger the CLI, run the following command in the bash terminal. ```bash npx linkfree-cli ``` -It will then prompt you to questions. +### 📝 License + +This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) for details. -## Contributions +### 🛡 Security -Feel free to contribute to the repo. Just make sure you Open an [Issue](https://github.com/Pradumnasaraf/LinkFree-CLI/issues) first before raising the Pull Request +If you discover a security vulnerability within this project, please check the [SECURITY](SECURITY.md) for more information. diff --git a/package-lock.json b/package-lock.json index 86a94a5..5406e82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,19 @@ { "name": "linkfree-cli", - "version": "1.4.2", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "linkfree-cli", - "version": "1.4.0", + "version": "2.0.0", "license": "MIT", "dependencies": { "axios": "^0.27.2", "chalk": "^4.1.2", "enquirer": "^2.3.6", - "json-format": "^1.0.1" + "json-format": "^1.0.1", + "open": "^8.4.2" }, "bin": { "linkfree-cli": "src/index.js" @@ -94,6 +95,14 @@ "node": ">= 0.8" } }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -151,6 +160,31 @@ "node": ">=8" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/json-format": { "version": "1.0.1", "license": "MIT" @@ -174,6 +208,22 @@ "node": ">= 0.6" } }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/prettier": { "version": "2.7.1", "dev": true, @@ -247,6 +297,11 @@ "delayed-stream": "~1.0.0" } }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -276,6 +331,19 @@ "has-flag": { "version": "4.0.0" }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "requires": { + "is-docker": "^2.0.0" + } + }, "json-format": { "version": "1.0.1" }, @@ -292,6 +360,16 @@ "mime-db": "1.52.0" } }, + "open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, "prettier": { "version": "2.7.1", "dev": true @@ -303,4 +381,4 @@ } } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 5f15114..b5eb253 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "linkfree-cli", - "version": "1.4.2", + "version": "2.0.0", "description": "Create LinkFree profile.json file though CLI", "main": "src/index.js", "bin": "src/index.js", @@ -25,7 +25,8 @@ "axios": "^0.27.2", "chalk": "^4.1.2", "enquirer": "^2.3.6", - "json-format": "^1.0.1" + "json-format": "^1.0.1", + "open": "^8.4.2" }, "devDependencies": { "prettier": "^2.7.1" @@ -37,4 +38,4 @@ "bugs": { "url": "https://github.com/Pradumnasaraf/LinkFRee-CLI.git/issues" } -} \ No newline at end of file +} diff --git a/src/addevent/addEvent.js b/src/addevent/addEvent.js new file mode 100644 index 0000000..39a169a --- /dev/null +++ b/src/addevent/addEvent.js @@ -0,0 +1,95 @@ +const enquirer = require("enquirer"); +const fs = require("fs"); +const chalk = require("chalk"); +const createEventFile = require("./helper/createEventFile"); + +const addEvent = async () => { + let answers = await enquirer.prompt([ + { + type: "input", + name: "githubUsername", + message: "What is your GitHub username? (case sensitive)", + }, + ]); + let eventWriter = answers.githubUsername; + + if (eventWriter === "") { + console.log(chalk.bgRed.bold(` Please enter a valid GitHub username. `)); + addEvent(); + } else if (!fs.existsSync(`./data/${eventWriter}.json`)) { + console.log( + chalk.bgYellow.bold( + ` You don't have a LinkFree JSON file!. Create an account first! ` + ) + ); + process.exit(0); + } else { + let answers = await enquirer.prompt([ + { + type: "select", + name: "userStatus", + message: + "Are you the event organizer or a participant? (This is optional.)", + choices: ["Organizer", "Participant", "None - Skip this question"], + }, + { + type: "input", + name: "speakerDetails", + message: + "Give your topic of your talk at the event. (This is optional. Press enter to skip.)", + }, + { + type: "confirm", + name: "isVirtual", + message: "Is the event virtual?", + }, + { + type: "confirm", + name: "isInPerson", + message: "Is the event in person?", + }, + { + type: "input", + name: "name", + message: "What is the name of the event?", + }, + { + type: "input", + name: "description", + message: "Give a description of the event", + }, + { + type: "input", + name: "url", + message: "Give associated URL for the event", + }, + { + type: "input", + name: "start", + message: + "Give event start date and time (Supported format: 2023-08-09T00:00:00.000+00:00)", + }, + { + type: "input", + name: "end", + message: + "Give event end date and time (Supported format: 2023-08-09T00:00:00.000+00:00)", + }, + { + type: "input", + name: "cfpClose", + message: + "Give CFP end date and time (Supported format: 2023-08-09T00:00:00.000+00:00) - (This is optional. Press enter to skip.)", + }, + { + type: "input", + name: "color", + message: "Give a color theme", + }, + ]); + + createEventFile(eventWriter, answers); + } +}; + +module.exports = addEvent; diff --git a/src/addevent/helper/createEventFile.js b/src/addevent/helper/createEventFile.js new file mode 100644 index 0000000..78a3514 --- /dev/null +++ b/src/addevent/helper/createEventFile.js @@ -0,0 +1,128 @@ +const fs = require("fs"); +const chalk = require("chalk"); +const jsonFormat = require("json-format"); + +function createEventFile(eventWriter, answers) { + const { + userStatus, + speakerDetails, + isVirtual, + isInPerson, + name, + description, + url, + start, + end, + cfpClose, + color, + } = answers; + + let jsonSchema = { + isVirtual: Boolean(isVirtual), + isInPerson: Boolean(isInPerson), + color: color, + name: name, + description: description, + date: { + start: start, + end: end, + }, + url: url, + }; + + if (cfpClose) { + jsonSchema.date.cfpClose = cfpClose; + } + + if (userStatus === "Organizer" || userStatus === "Participant") { + jsonSchema.userStatus = userStatus; + } + + if (speakerDetails) { + jsonSchema.speakerDetails = speakerDetails; + } + + const json = jsonFormat(jsonSchema, { type: "space", size: 2 }); + + if (fs.existsSync("./data")) { + if (fs.existsSync(`./data/${eventWriter}/events`)) { + fs.writeFile( + `./data/${eventWriter}/events/${start.split("T")[0]}-${name + .toLowerCase() + .split(" ") + .join("-")}.json`, + json, + (err) => { + if (err) { + console.log( + chalk.bgYellow.bold( + `Something went wrong while creating the file. Try again! part 1` + ) + ); + process.exit(0); + } else { + console.log( + chalk.bgWhite.bold( + ` File ${start.split("T")[0]}-${name + .toLowerCase() + .split(" ") + .join("-")}.json created successfully! ` + ) + ); + } + } + ); + } else { + // If the user doesn't have a "events" directory, create one. + fs.promises + .mkdir(`./data/${eventWriter}/events`, { + recursive: true, + }) + .then(() => { + fs.writeFile( + `./data/${eventWriter}/events/${start.split("T")[0]}-${name + .toLowerCase() + .split(" ") + .join("-")}.json`, + json, + (err) => { + if (err) { + console.log( + chalk.bgYellow.bold( + `Something went wrong while creating the file. Try again! part 2` + ) + ); + process.exit(0); + } else { + console.log( + chalk.bgWhite.bold( + ` File ${start.split("T")[0]}-${name + .toLowerCase() + .split(" ") + .join("-")}.json created successfully! ` + ) + ); + } + } + ); + }) + .catch(() => { + console.log( + chalk.bgYellow.bold( + `Something went wrong while creating the directory. Try again!` + ) + ); + process.exit(0); + }); + } + } else { + console.log( + chalk.bgYellow.bold( + ` You are not in the root directory of LinkFree. Try again! ` + ) + ); + process.exit(0); + } +} + +module.exports = createEventFile; diff --git a/src/createjson/createJson.js b/src/createjson/createJson.js new file mode 100644 index 0000000..3d4e686 --- /dev/null +++ b/src/createjson/createJson.js @@ -0,0 +1,128 @@ +#! /usr/bin/env node + +const chalk = require("chalk"); +const { prompt } = require("enquirer"); +const fs = require("fs"); +const createUser = require("./helper/createUser"); +const checkUser = require("../shared/checkUser"); +const { basics } = require("../shared/questions/basics"); +const { addlinks } = require("../shared/questions/links"); +const { addtags } = require("../shared/questions/tags"); +const { addmilestones } = require("../shared/questions/milestones"); +const { addsocials } = require("../shared/questions/socials"); +const updateJson = require("../updatejson/updateJson"); + +let json; + +const createJson = () => { + prompt([ + { + type: "input", + name: "githubUsername", + message: "What is your GitHub username? (case sensitive)", + }, + ]) + .then((answers) => { + const { githubUsername } = answers; + if (githubUsername === "") { + console.log( + chalk.bgRed.bold(` Please enter a valid GitHub username. `) + ); + createJson(); + } else if (fs.existsSync(`./data/${githubUsername}.json`)) { + console.log( + chalk.bgYellow.bold(` File ${githubUsername}.json already exists!`) + ); + prompt([ + { + type: "confirm", + name: "overwrite", + message: "Do you want to update the existing file?", + }, + ]).then((answers) => { + const { overwrite } = answers; + if (overwrite) { + console.log(chalk.bgGreen.bold(` Proceed with updating file... `)); + updateJson(githubUsername); + } else { + console.log(chalk.bgRed.bold(` File not updated! `)); + console.log("Restart the program to try again."); + process.exit(0); + } + }); + } else { + start(githubUsername); + } + }) + .catch((err) => { + console.log(err); + }); +}; + +async function start(githubUsername) { + await checkUser(githubUsername).then((result) => { + if (result === true) { + basics().then(async (answers) => { + json = answers; + await prompt([ + { + type: "confirm", + name: "addLink", + message: "Do you want to add a link?", + }, + ]).then(async (answers) => { + if (answers.addLink) { + json.links = await addlinks(true); + } + }); + + await prompt([ + { + type: "confirm", + name: "addTag", + message: "Do you want to add a tag?", + }, + ]).then(async (answers) => { + if (answers.addTag) { + json.tags = await addtags(true); + } + }); + + await prompt([ + { + type: "confirm", + name: "addSocial", + message: "Do you want to add a social?", + }, + ]).then(async (answers) => { + if (answers.addSocial) { + json.social = await addsocials(true); + } + }); + + await prompt([ + { + type: "confirm", + name: "addMilestone", + message: "Do you want to add a milestone?", + }, + ]).then(async (answers) => { + if (answers.addMilestone) { + json.milestones = await addmilestones(true); + } + }); + + createUser(githubUsername, json); + }); + } else { + console.log( + chalk.bgRed.bold( + ` User with username '${githubUsername}' does not exist on GitHub, try again! ` + ) + ); + createJson(); + } + }); +} + +module.exports = createJson; diff --git a/src/createjson/helper/createUser.js b/src/createjson/helper/createUser.js new file mode 100644 index 0000000..4e4bd6a --- /dev/null +++ b/src/createjson/helper/createUser.js @@ -0,0 +1,44 @@ +const jsonFormat = require("json-format"); +const chalk = require("chalk"); +const fs = require("fs"); + +async function createUser(githubUsername, answers) { + jsonSchema = { + name: `${answers.name}`, + type: `${answers.type}`, + bio: `${answers.bio}`, + }; + if (answers.links) { + jsonSchema.links = answers.links; + } + if (answers.milestones) { + jsonSchema.milestones = answers.milestones; + } + if (answers.tags) { + jsonSchema.tags = answers.tags; + } + + if (answers.social) { + jsonSchema.social = answers.social; + } + + const json = jsonFormat(jsonSchema, { type: "space", size: 2 }); + fs.writeFile(`./data/${githubUsername}.json`, json, (err) => { + if (err) { + console.log( + chalk.bgYellow.bold( + ` You are not in the root directory of LinkFree. Try again! ` + ) + ); + process.exit(0); + } else { + console.log( + chalk.bgWhite.bold( + ` File ${githubUsername}.json created successfully! ` + ) + ); + } + }); +} + +module.exports = createUser; diff --git a/src/givetestimonial/giveTestimonial.js b/src/givetestimonial/giveTestimonial.js new file mode 100644 index 0000000..6dd0ef5 --- /dev/null +++ b/src/givetestimonial/giveTestimonial.js @@ -0,0 +1,114 @@ +const enquirer = require("enquirer"); +const fs = require("fs"); +const chalk = require("chalk"); +const createtestimonialfile = require("./helper/createTestimonialFile"); +const checktestimonial = require("./helper/checkTestimonial"); + +let testimonialWriter; +let testimonialReceiver; + +async function givetestimonial() { + let answers = await enquirer.prompt([ + { + type: "input", + name: "githubUsername", + message: "What is your GitHub username? (case sensitive)", + }, + ]); + const { githubUsername } = answers; + testimonialWriter = githubUsername; + if (githubUsername === "") { + console.log(chalk.bgRed.bold(` Please enter a valid GitHub username. `)); + givetestimonial(); + } else if (!fs.existsSync(`./data/${githubUsername}.json`)) { + console.log( + chalk.bgYellow.bold( + ` You don't have a LinkFree JSON file!. Create an account first! ` + ) + ); + process.exit(0); + } else { + let answers = await enquirer.prompt([ + { + type: "input", + name: "githubUsername", + message: + "What is the GitHub username of the person you want to give a testimonial to? (case sensitive)", + }, + ]); + const { githubUsername } = answers; + testimonialReceiver = githubUsername; + if (githubUsername === "") { + console.log(chalk.bgRed.bold(` Please enter a valid GitHub username. `)); + givetestimonial(); + } else if (!fs.existsSync(`./data/${githubUsername}.json`)) { + console.log( + chalk.bgYellow.bold( + ` The person you want to give a testimonial to doesn't have a LinkFree JSON file!. Ask them to create an account first! ` + ) + ); + process.exit(0); + } else { + if (testimonialReceiver == testimonialWriter) { + console.log( + chalk.bgRed.bold(` You can't give a testimonial to yourself! `) + ); + process.exit(0); + } else if ( + await checktestimonial(testimonialWriter, testimonialReceiver) + ) { + console.log( + chalk.bgRed.bold( + ` You have already given a testimonial to this person! ` + ) + ); + process.exit(0); + } else { + let title = await testimonialtitle(); + let description = await testimonialdescription(); + createtestimonialfile( + testimonialWriter, + testimonialReceiver, + title, + description + ); + } + } + } +} + +async function testimonialtitle() { + let answers = await enquirer.prompt([ + { + type: "input", + name: "testimonialtitle", + message: "What is the title of your testimonial?", + }, + ]); + const { testimonialtitle } = answers; + if (testimonialtitle === "") { + console.log(chalk.bgRed.bold(` Please enter a valid testimonial title. `)); + testimonialtitle(); + } else { + return testimonialtitle; + } +} + +async function testimonialdescription() { + let answers = await enquirer.prompt([ + { + type: "input", + name: "testimonial", + message: "What is your testimonial?", + }, + ]); + const { testimonial } = answers; + if (testimonial === "") { + console.log(chalk.bgRed.bold(` Please enter a valid testimonial. `)); + testimonialdescription(); + } else { + return testimonial; + } +} + +module.exports = givetestimonial; diff --git a/src/givetestimonial/helper/checkTestimonial.js b/src/givetestimonial/helper/checkTestimonial.js new file mode 100644 index 0000000..60272a7 --- /dev/null +++ b/src/givetestimonial/helper/checkTestimonial.js @@ -0,0 +1,16 @@ +const fs = require("fs"); + +// Check if the user has already given a testimonial to the person +async function checktestimonial(testimonialWriter, testimonialReceiver) { + if ( + fs.existsSync( + `./data/${testimonialReceiver}/testimonials/${testimonialWriter}.json` + ) + ) { + return true; + } else { + return false; + } +} + +module.exports = checktestimonial; diff --git a/src/givetestimonial/helper/createTestimonialFile.js b/src/givetestimonial/helper/createTestimonialFile.js new file mode 100644 index 0000000..a57ffe8 --- /dev/null +++ b/src/givetestimonial/helper/createTestimonialFile.js @@ -0,0 +1,105 @@ +const fs = require("fs"); +const chalk = require("chalk"); +const jsonFormat = require("json-format"); + +async function createtestimonialfile( + testimonialWriter, + testimonialReceiver, + title, + description +) { + let jsonSchema = { + title: `${title}`, + description: `${description}`, + date: `${getdate()}`, + }; + + const json = jsonFormat(jsonSchema, { type: "space", size: 2 }); + + // Check if we are in the root directory of LinkFree + if (fs.existsSync("./data")) { + // Check if user reciving the testimonial has a "testimonials" directory. + if (fs.existsSync(`./data/${testimonialReceiver}/testimonials`)) { + fs.writeFile( + `./data/${testimonialReceiver}/testimonials/${testimonialWriter}.json`, + json, + (err) => { + if (err) { + console.log( + chalk.bgYellow.bold( + `Something went wrong while creating the file. Try again! part 1` + ) + ); + process.exit(0); + } else { + console.log( + chalk.bgWhite.bold( + ` File ${testimonialReceiver}.json created successfully! ` + ) + ); + } + } + ); + } else { + // If the user doesn't have a "testimonials" directory, create one. + fs.promises + .mkdir(`./data/${testimonialReceiver}/testimonials`, { + recursive: true, + }) + .then(() => { + fs.writeFile( + `./data/${testimonialReceiver}/testimonials/${testimonialWriter}.json`, + json, + (err) => { + if (err) { + console.log( + chalk.bgYellow.bold( + `Something went wrong while creating the file. Try again! part 2` + ) + ); + process.exit(0); + } else { + console.log( + chalk.bgWhite.bold( + ` File ${testimonialReceiver}.json created successfully! ` + ) + ); + } + } + ); + }) + .catch(() => { + console.log( + chalk.bgYellow.bold( + `Something went wrong while creating the directory. Try again!` + ) + ); + process.exit(0); + }); + } + } else { + console.log( + chalk.bgYellow.bold( + ` You are not in the root directory of LinkFree. Try again! ` + ) + ); + process.exit(0); + } +} + +function getdate() { + // get in the format of YYYY-MM-DD + let date = new Date(); + let year = date.getFullYear(); + let month = date.getMonth() + 1; + let day = date.getDate(); + if (month < 10) { + month = "0" + month; + } + if (day < 10) { + day = "0" + day; + } + return year + "-" + month + "-" + day; +} + +module.exports = createtestimonialfile; diff --git a/src/index.js b/src/index.js index a3130af..6dcc3d7 100755 --- a/src/index.js +++ b/src/index.js @@ -1,101 +1,55 @@ #! /usr/bin/env node - +const fs = require("fs"); const chalk = require("chalk"); const { prompt } = require("enquirer"); -const fs = require("fs"); -const createUser = require("./util/createUser"); -const checkUser = require("./util/checkUser"); -const { questions, addlinks } = require("./util/questions"); -let githubUsername; -let json; - +const createJson = require("./createjson/createJson"); +const checkUpdate = require("./updatejson/helper/checkUpdate"); +const giveTestimonial = require("./givetestimonial/giveTestimonial"); +const addEvent = require("./addevent/addEvent"); +const reportBug = require("./reportbug/reportBug"); console.log( - chalk.bgYellowBright.bold( - ` Welcome to LinkFree CLI! Let's get started by creating your JSON file. ` - ) + chalk.bgWhite.bold(` Welcome to LinkFree CLI! Let's get started. `) ); -init(); +const choices = [ + "Create a LinkFree JSON file", + "Update an existing JSON file", + "Provide a testimonial to a LinkFree user", + "Add an event", + "🐛 Report a bug", +]; -async function init() { - prompt([ - { - type: "input", - name: "githubUsername", - message: "What is your GitHub username? (case sensitive)", - }, - ]) - .then((answers) => { - githubUsername = answers.githubUsername; - if (githubUsername === "") { - console.log( - chalk.bgRed.bold(` Please enter a valid GitHub username. `) - ); - init(); - } else if (fs.existsSync(`./data/${githubUsername}.json`)) { - console.log( - chalk.bgYellow.bold(` File ${githubUsername}.json already exists!`) - ); - prompt([ - { - type: "confirm", - name: "overwrite", - message: "Do you want to overwrite the existing file?", - }, - ]).then((answers) => { - const { overwrite } = answers; - if (overwrite) { - console.log( - chalk.bgGreen.bold(` Proceed with overwriting file... `) - ); - start(githubUsername); - } else { - console.log(chalk.bgRed.bold(` File not overwritten! `)); - console.log("Restart the program to try again."); - process.exit(0); - } - }); - } else { - start(githubUsername); +prompt([ + { + type: "select", + name: "selectedtask", + choices: choices, + message: "Choose one option (Press down arrow to traverse the list)", + }, +]) + .then(async (answers) => { + const { selectedtask } = answers; + switch (selectedtask) { + case "Create a LinkFree JSON file": { + createJson(); + break; } - }) - .catch((err) => { - console.log(err); - }); -} - -async function start(githubUsername) { - await checkUser(githubUsername).then((result) => { - if (result === true) { - questions().then((answers) => { - json = answers; - prompt([ - { - type: "confirm", - name: "addLink", - message: "Do you want to add a link?", - }, - ]).then((answers) => { - const { addLink } = answers; - if (addLink) { - addlinkstojson(); - } else { - createUser(githubUsername, json); - } - }); - }); - } else { - console.log( - chalk.bgRed.bold( - ` User with username '${githubUsername}' does not exist on GitHub, try again! ` - ) - ); - init(); + case "Update an existing JSON file": { + checkUpdate(); + break; + } + case "Provide a testimonial to a LinkFree user": { + giveTestimonial(); + break; + } + case "Add an event": { + addEvent(); + break; + } + default: + reportBug(); } + }) + .catch((error) => { + console.error(error); }); -} - -async function addlinkstojson() { - json.links = await addlinks(true); - createUser(githubUsername, json); -} diff --git a/src/reportbug/reportBug.js b/src/reportbug/reportBug.js new file mode 100644 index 0000000..acac222 --- /dev/null +++ b/src/reportbug/reportBug.js @@ -0,0 +1,46 @@ +const open = require("open"); +const enquirer = require("enquirer"); + +async function reportBug() { + const questions = await enquirer.prompt([ + { + type: "input", + name: "username", + message: "What is your GitHub username?", + }, + { + type: "input", + name: "title", + message: "What is the title of the bug?", + }, + { + type: "input", + name: "description", + message: "Describe a description of the bug", + }, + ]); + const { username, title, description } = questions; + const url = urlBuilder(username, title, description); + + const openBrowser = await enquirer.prompt([ + { + type: "confirm", + name: "openBrowser", + message: + "Thank you for taking the time to report the bug. For submitting it, you will be redirected to GitHub Issues. Do you want to open the browser?", + }, + ]); + if (openBrowser.openBrowser) { + await open(url); + } +} + +function urlBuilder(username, title, description) { + title = title.replace(/\s/g, "+"); + description = description.replace(/\s/g, "+"); + + URL = `https://github.com/Pradumnasaraf/LinkFree-CLI/issues/new?assignees=&labels=bug&template=bug.yaml&title=${title}+Report+by+@${username}&description=${description}`; + return URL; +} + +module.exports = reportBug; diff --git a/src/shared/assets/icons.js b/src/shared/assets/icons.js new file mode 100644 index 0000000..51af6d2 --- /dev/null +++ b/src/shared/assets/icons.js @@ -0,0 +1,17 @@ +const axios = require("axios"); +let icons = []; +async function geticons() { + try { + const response = await axios.get( + `https://raw.githubusercontent.com/EddieHubCommunity/LinkFree/main/config/icons.json` + ); + icons = Object.keys(response.data); + return icons; + } catch (error) { + console.error(error); + } +} + +module.exports = { + geticons, +}; diff --git a/src/util/checkUser.js b/src/shared/checkUser.js similarity index 100% rename from src/util/checkUser.js rename to src/shared/checkUser.js diff --git a/src/shared/questions/basics.js b/src/shared/questions/basics.js new file mode 100644 index 0000000..ac92540 --- /dev/null +++ b/src/shared/questions/basics.js @@ -0,0 +1,27 @@ +const { prompt } = require("enquirer"); + +async function basics() { + const answers = await prompt([ + { + type: "input", + name: "name", + message: "What is your name (e.g. Jone Doe)?", + }, + { + type: "select", + name: "type", + message: "Your profile type?", + choices: ["Personal", "Community"], + }, + { + type: "input", + name: "bio", + message: "Add a short bio about yourself", + }, + ]); + return answers; +} + +module.exports = { + basics, +}; diff --git a/src/shared/questions/links.js b/src/shared/questions/links.js new file mode 100644 index 0000000..893a271 --- /dev/null +++ b/src/shared/questions/links.js @@ -0,0 +1,137 @@ +const { prompt } = require("enquirer"); +const { geticons } = require("../assets/icons"); +let links = []; +let icons = []; + +async function addlinks(bool) { + icons = await geticons(); + + while (bool) { + let answers = await prompt([ + { + type: "input", + name: "name", + message: "What is the name of the link?", + }, + { + type: "input", + name: "url", + message: "What is the URL of the link?", + }, + { + type: "select", + name: "icon", + choices: icons, + message: "Choose an icon (Press down arrow to see more options)", + }, + { + type: "confirm", + name: "addLink", + message: "Do you want to add another link?", + }, + ]); + links.push({ + name: answers.name, + url: answers.url, + icon: answers.icon, + }); + if (!answers.addLink) { + return links; + } + } +} + +async function removelinks(links) { + let choiceLinks = links; + let stop = false; + while (!stop) { + const answers = await prompt([ + { + type: "select", + name: "link", + choices: choiceLinks, + message: "Choose which one you want to remove", + }, + ]); + choiceLinks = choiceLinks.filter((link) => link.name !== answers.link); + if (choiceLinks.length !== 0) { + const res = await prompt([ + { + type: "confirm", + name: "removeLink", + message: "Do you want to remove another link?", + }, + ]); + if (!res.removeLink) { + let result = []; + choiceLinks.map((link) => { + const { name, url, icon } = link; + result.push({ name, url, icon }); + }); + return result; + } + } else { + return []; + } + } +} + +async function updatelinks(links) { + icons = await geticons(); + let choiceLinks = links; + let stop = false; + while (!stop) { + const answers = await prompt([ + { + type: "select", + name: "link", + choices: choiceLinks, + message: "Choose which one you want to update", + }, + ]); + const { name, url, icon, updateLink } = await prompt([ + { + type: "input", + name: "name", + message: "What is the new name of the link?", + }, + { + type: "input", + name: "url", + message: "What is the new URL of the link?", + }, + { + type: "select", + name: "icon", + choices: icons, + message: "Choose a new icon (Press down arrow to see more options)", + }, + { + type: "confirm", + name: "updateLink", + message: "Do you want to update another link?", + }, + ]); + choiceLinks.map((link) => { + if (link.name === answers.link) { + link.name = name; + link.url = url; + link.icon = icon; + } + }); + if (!updateLink) { + let result = []; + choiceLinks.map((link) => { + const { name, url, icon } = link; + result.push({ name, url, icon }); + }); + return result; + } + } +} + +module.exports = { + addlinks, + removelinks, + updatelinks, +}; diff --git a/src/shared/questions/milestones.js b/src/shared/questions/milestones.js new file mode 100644 index 0000000..bde8866 --- /dev/null +++ b/src/shared/questions/milestones.js @@ -0,0 +1,188 @@ +const { prompt } = require("enquirer"); +const { geticons } = require("../assets/icons"); + +let milestones = []; +let icons = []; + +async function addmilestones(bool) { + icons = await geticons(); + + while (bool) { + let answers = await prompt([ + { + type: "input", + name: "title", + message: "What is the title of your milestone?", + }, + { + type: "input", + name: "date", + message: "In which year you achieved it?", + }, + { + type: "select", + name: "icon", + choices: icons, + message: "Choose an icon (Press down arrow to see more options)", + }, + { + type: "input", + name: "description", + message: "Give a short description for your milestone", + }, + { + type: "input", + name: "url", + message: "Give a url related to your milestone", + }, + { + type: "input", + name: "color", + message: "Give a color theme", + }, + { + type: "select", + name: "isGoal", + message: "Is this a future goal? (This is optional question)", + choices: ["Yes", "Skip this question"], + }, + { + type: "confirm", + name: "addMilestone", + message: "Do you want to add another milestone?", + }, + ]); + milestones.push({ + title: answers.title, + url: answers.url, + icon: answers.icon, + date: answers.date, + description: answers.description, + color: answers.color, + }); + + if (answers.isGoal === "Yes") { + milestones[milestones.length - 1].isGoal = true; + } + if (!answers.addMilestone) { + return milestones; + } + } +} + +async function removemilestones(milestones) { + let choiceMilestones = milestones; + let stop = false; + while (!stop) { + const answers = await prompt([ + { + type: "select", + name: "milestone", + choices: choiceMilestones, + message: "Choose which one you want to remove", + }, + ]); + choiceMilestones = choiceMilestones.filter( + (milestone) => milestone.title !== answers.milestone + ); + if (choiceMilestones.length !== 0) { + const res = await prompt([ + { + type: "confirm", + name: "removeMilestone", + message: "Do you want to remove another milestone?", + }, + ]); + if (!res.removeMilestone) { + let result = []; + choiceMilestones.map((milestone) => { + const { title, url, icon, description, date, color } = milestone; + result.push({ title, url, icon, description, date, color }); + }); + return result; + } + } else { + return []; + } + } +} + +async function updatemilestones(milestones) { + icons = await geticons(); + let choiceMilestones = milestones; + let stop = false; + while (!stop) { + const answers = await prompt([ + { + type: "select", + name: "milestone", + choices: choiceMilestones, + message: "Choose which one you want to update", + }, + ]); + const { title, date, icon, description, url, color, updateMilestone } = + await prompt([ + { + type: "input", + name: "title", + message: "What is the new title of the milestone?", + }, + { + type: "input", + name: "date", + message: "What is the new date of the milestone?", + }, + { + type: "select", + name: "icon", + choices: icons, + message: "Choose a new icon (Press down arrow to see more options)", + }, + { + type: "input", + name: "description", + message: "What is the new description of the milestone?", + }, + { + type: "input", + name: "url", + message: "What is the new URL of the milestone?", + }, + { + type: "input", + name: "color", + message: "What is the new color theme of the milestone?", + }, + { + type: "confirm", + name: "updateMilestone", + message: "Do you want to update another milestone?", + }, + ]); + choiceMilestones.map((milestone) => { + if (milestone.title === answers.milestone) { + milestone.name = title; + milestone.title = title; + milestone.date = date; + milestone.url = url; + milestone.icon = icon; + milestone.description = description; + milestone.color = color; + } + }); + if (!updateMilestone) { + let result = []; + choiceMilestones.map((milestone) => { + const { title, url, icon, description, date, color } = milestone; + result.push({ title, url, icon, description, date, color }); + }); + return result; + } + } +} + +module.exports = { + addmilestones, + removemilestones, + updatemilestones, +}; diff --git a/src/shared/questions/socials.js b/src/shared/questions/socials.js new file mode 100644 index 0000000..be5cc69 --- /dev/null +++ b/src/shared/questions/socials.js @@ -0,0 +1,135 @@ +const { prompt } = require("enquirer"); +const { geticons } = require("../assets/icons"); + +let socials = []; +let icons = []; + +async function addsocials(bool) { + icons = await geticons(); + + while (bool) { + let answers = await prompt([ + { + type: "input", + name: "url", + message: "Add the url of your social media", + }, + { + type: "select", + name: "icon", + choices: icons, + message: "Choose an icon (Press down arrow to see more options)", + }, + { + type: "confirm", + name: "addsocials", + message: "Do you want to add another social media?", + }, + ]); + socials.push({ + icon: answers.icon, + url: answers.url, + }); + if (!answers.addsocials) { + return socials; + } + } +} + +async function removesocials(socials) { + let choiceSocials = socials; + let stop = false; + choiceSocials.map((social) => { + social.name = social.url; + }); + while (!stop) { + const answers = await prompt([ + { + type: "select", + name: "social", + choices: choiceSocials, + message: "Choose which one you want to remove", + }, + ]); + choiceSocials = choiceSocials.filter( + (social) => social.name !== answers.social + ); + if (choiceSocials.length !== 0) { + const res = await prompt([ + { + type: "confirm", + name: "removeSocial", + message: "Do you want to remove another social?", + }, + ]); + if (!res.removeSocial) { + let result = []; + choiceSocials.map((social) => { + const { url, icon } = social; + result.push({ url, icon }); + }); + return result; + } + } else { + return []; + } + } +} + +async function updatesocials(socials) { + icons = await geticons(); + let choiceSocials = socials; + let stop = false; + choiceSocials.map((social) => { + social.name = social.url; + }); + while (!stop) { + const answers = await prompt([ + { + type: "select", + name: "social", + choices: choiceSocials, + message: "Choose which one you want to update", + }, + ]); + const { url, icon, updateSocial } = await prompt([ + { + type: "input", + name: "url", + message: "What is the new URL of the social media?", + }, + { + type: "select", + name: "icon", + choices: icons, + message: "Choose a new icon (Press down arrow to see more options)", + }, + { + type: "confirm", + name: "updateSocial", + message: "Do you want to update another social?", + }, + ]); + choiceSocials.map((social) => { + if (social.name === answers.social) { + social.name = url; + social.url = url; + social.icon = icon; + } + }); + if (!updateSocial) { + let result = []; + choiceSocials.map((social) => { + const { url, icon } = social; + result.push({ url, icon }); + }); + return result; + } + } +} + +module.exports = { + addsocials, + removesocials, + updatesocials, +}; diff --git a/src/shared/questions/tags.js b/src/shared/questions/tags.js new file mode 100644 index 0000000..157c27b --- /dev/null +++ b/src/shared/questions/tags.js @@ -0,0 +1,105 @@ +const { prompt } = require("enquirer"); + +let tags = []; + +async function addtags(bool) { + while (bool) { + let answers = await prompt([ + { + type: "input", + name: "name", + message: "What is the name of the tag?", + }, + { + type: "confirm", + name: "addTag", + message: "Do you want to add another tag?", + }, + ]); + tags.push(answers.name); + if (!answers.addTag) { + return tags; + } + } +} + +async function removetags(tags) { + let choiceTags = tags; + let stop = false; + while (!stop) { + const answers = await prompt([ + { + type: "select", + name: "tag", + choices: choiceTags, + message: "Choose which one you want to remove", + }, + ]); + choiceTags = choiceTags.filter((tag) => tag.name !== answers.tag); + if (choiceTags.length !== 0) { + const res = await prompt([ + { + type: "confirm", + name: "removeTag", + message: "Do you want to remove another tag?", + }, + ]); + if (!res.removeTag) { + let result = []; + choiceTags.map((tag) => { + const { name } = tag; + result.push(name); + }); + return result; + } + } else { + return []; + } + } +} + +async function updatetags(tags) { + let choiceTags = tags; + let stop = false; + while (!stop) { + const answers = await prompt([ + { + type: "select", + name: "tag", + choices: choiceTags, + message: "Choose which one you want to update", + }, + ]); + const { name, updateTag } = await prompt([ + { + type: "input", + name: "name", + message: "What is the new name of the tag?", + }, + { + type: "confirm", + name: "updateTag", + message: "Do you want to update another tag?", + }, + ]); + choiceTags.map((tag) => { + if (tag.name === answers.tag) { + tag.name = name; + } + }); + if (!updateTag) { + let result = []; + choiceTags.map((tag) => { + const { name } = tag; + result.push(name); + }); + return result; + } + } +} + +module.exports = { + addtags, + removetags, + updatetags, +}; diff --git a/src/shared/questions/testimonials.js b/src/shared/questions/testimonials.js new file mode 100644 index 0000000..e303852 --- /dev/null +++ b/src/shared/questions/testimonials.js @@ -0,0 +1,106 @@ +const { prompt } = require("enquirer"); +let testimonials = []; + +async function addtestimonials(bool) { + while (bool) { + let answers = await prompt([ + { + type: "input", + name: "name", + message: "Who gave the testimonial?(write their username)", + }, + { + type: "confirm", + name: "addTestimonial", + message: "Do you want to add another testimonial?", + }, + ]); + testimonials.push(answers.name); + if (!answers.addTestimonial) { + return testimonials; + } + } +} + +async function removetestimonials(testimonials) { + let choiceTestimonials = testimonials; + let stop = false; + while (!stop) { + const answers = await prompt([ + { + type: "select", + name: "testimonial", + choices: choiceTestimonials, + message: "Choose which one you want to remove", + }, + ]); + choiceTestimonials = choiceTestimonials.filter( + (testimonial) => testimonial.name !== answers.testimonial + ); + if (choiceTestimonials.length !== 0) { + const res = await prompt([ + { + type: "confirm", + name: "removeTestimonial", + message: "Do you want to remove another testimonial?", + }, + ]); + if (!res.removeTestimonial) { + let result = []; + choiceTestimonials.map((testimonial) => { + const { name } = testimonial; + result.push(name); + }); + return result; + } + } else { + return []; + } + } +} + +async function updatetestimonials(testimonials) { + let choiceTestimonials = testimonials; + let stop = false; + while (!stop) { + const answers = await prompt([ + { + type: "select", + name: "testimonial", + choices: choiceTestimonials, + message: "Choose which one you want to update", + }, + ]); + const { name, updateTestimonial } = await prompt([ + { + type: "input", + name: "name", + message: "What is the new username?", + }, + { + type: "confirm", + name: "updateTestimonial", + message: "Do you want to update another testimonial?", + }, + ]); + choiceTestimonials.map((testimonial) => { + if (testimonial.name === answers.testimonial) { + testimonial.name = name; + } + }); + if (!updateTestimonial) { + let result = []; + choiceTestimonials.map((testimonial) => { + const { name } = testimonial; + result.push(name); + }); + return result; + } + } +} + +module.exports = { + addtestimonials, + removetestimonials, + updatetestimonials, +}; diff --git a/src/updatejson/helper/checkUpdate.js b/src/updatejson/helper/checkUpdate.js new file mode 100644 index 0000000..c396049 --- /dev/null +++ b/src/updatejson/helper/checkUpdate.js @@ -0,0 +1,37 @@ +const chalk = require("chalk"); +const fs = require("fs"); +const { prompt } = require("enquirer"); +const updateJson = require("../updateJson"); + +async function checkUpdate() { + const githubUsername = await getUsername(); + if (fs.existsSync(`./data/${githubUsername}.json`)) { + updateJson(githubUsername); + } else { + console.log( + chalk.bgYellow.bold( + ` File ${githubUsername}.json doesn't exist! Please enter valid username` + ) + ); + checkUpdate(); + } +} + +const getUsername = async () => { + const answers = await prompt([ + { + type: "input", + name: "name", + message: "What is your GitHub username? (case sensitive)", + }, + ]); + + if (answers.name === "") { + console.log(chalk.bgRed.bold(` Please enter a valid GitHub username. `)); + getUsername(); + } else { + return answers.name; + } +}; + +module.exports = checkUpdate; diff --git a/src/updatejson/updateJson.js b/src/updatejson/updateJson.js new file mode 100644 index 0000000..cfe37b8 --- /dev/null +++ b/src/updatejson/updateJson.js @@ -0,0 +1,390 @@ +const chalk = require("chalk"); +const { prompt } = require("enquirer"); +const fs = require("fs"); +const jsonFormat = require("json-format"); +const { + addlinks, + removelinks, + updatelinks, +} = require("../shared/questions/links"); +const { + addmilestones, + removemilestones, + updatemilestones, +} = require("../shared/questions/milestones"); +const { addtags, removetags, updatetags } = require("../shared/questions/tags"); +const { + addsocials, + removesocials, + updatesocials, +} = require("../shared/questions/socials"); +const { + addtestimonials, + removetestimonials, + updatetestimonials, +} = require("../shared/questions/testimonials"); + +let json; +const updateJson = async (githubUsername) => { + await fs.readFile(`./data/${githubUsername}.json`, function (error, content) { + if (error) { + console.log(chalk.bgRed.bold("You are not in the root folder!")); + console.log("Restart the program to try again."); + process.exit(0); + } + json = JSON.parse(content); + }); + + await prompt([ + { + type: "confirm", + name: "name", + message: "Do you want to change your name?", + }, + ]).then(async (answers) => { + if (answers.name) { + await prompt([ + { + type: "input", + name: "name", + message: "What is your new name?", + }, + ]).then((answers) => (json.name = answers.name)); + } + }); + + await prompt([ + { + type: "confirm", + name: "type", + message: "Do you want to change your profile type?", + }, + ]).then(async (answers) => { + if (answers.type) { + await prompt([ + { + type: "select", + name: "type", + message: "Your new profile type?", + choices: ["Personal", "Community"], + }, + ]).then((answers) => (json.type = answers.type)); + } + }); + + await prompt([ + { + type: "confirm", + name: "bio", + message: "Do you want to change your bio?", + }, + ]).then(async (answers) => { + if (answers.bio) { + await prompt([ + { + type: "input", + name: "bio", + message: "Your new bio?", + }, + ]).then((answers) => (json.bio = answers.bio)); + } + }); + + await prompt([ + { + type: "confirm", + name: "tag", + message: "Do you want to update your tags?", + }, + ]).then(async (answers) => { + if (answers.tag) { + await prompt([ + { + type: "select", + name: "operation", + message: "What you want to do?", + choices: ["add a tag?", "remove a tag?", "update a tag?"], + }, + ]).then(async (answers) => { + switch (answers.operation) { + case "add a tag?": { + if (json.tags) { + json.tags = [...json.tags, ...(await addtags(true))]; + } else { + json.tags = [...(await addtags(true))]; + } + break; + } + case "remove a tag?": { + if (json.tags) { + json.tags = [...(await removetags(json.tags))]; + if (json.tags.length === 0) { + delete json.tags; + } + } else { + console.log( + chalk.bgYellow.bold("You don't have any tags to remove!") + ); + } + break; + } + default: { + if (json.tags) { + json.tags = [...(await updatetags(json.tags))]; + } else { + console.log( + chalk.bgYellow.bold("You don't have any tags to update!") + ); + } + } + } + }); + } + }); + + await prompt([ + { + type: "confirm", + name: "social", + message: "Do you want to update your socials?", + }, + ]).then(async (answers) => { + if (answers.social) { + await prompt([ + { + type: "select", + name: "operation", + message: "What you want to do?", + choices: ["add a social?", "remove a social?", "update a social?"], + }, + ]).then(async (answers) => { + switch (answers.operation) { + case "add a social?": { + if (json.socials) { + json.socials = [...json.socials, ...(await addsocials(true))]; + } else { + json.socials = [...(await addsocials(true))]; + } + break; + } + case "remove a social?": { + if (json.socials) { + json.socials = [...(await removesocials(json.socials))]; + if (json.socials.length === 0) { + delete json.socials; + } + } else { + console.log( + chalk.bgYellow.bold("You don't have any socials to remove!") + ); + } + break; + } + default: { + if (json.socials) { + json.socials = [...(await updatesocials(json.socials))]; + } else { + console.log( + chalk.bgYellow.bold("You don't have any socials to update!") + ); + } + } + } + }); + } + }); + + await prompt([ + { + type: "confirm", + name: "link", + message: "Do you want to update your links?", + }, + ]).then(async (answers) => { + if (answers.link) { + await prompt([ + { + type: "select", + name: "operation", + message: "What you want to do?", + choices: ["add a link?", "remove a link?", "update a link?"], + }, + ]).then(async (answers) => { + switch (answers.operation) { + case "add a link?": { + if (json.links) { + json.links = [...json.links, ...(await addlinks(true))]; + } else { + json.links = [...(await addlinks(true))]; + } + break; + } + case "remove a link?": { + if (json.links) { + json.links = [...(await removelinks(json.links))]; + if (json.links.length === 0) { + delete json.links; + } + } else { + console.log( + chalk.bgYellow.bold("You don't have any links to remove!") + ); + } + break; + } + default: { + if (json.links) { + json.links = [...(await updatelinks(json.links))]; + } else { + console.log( + chalk.bgYellow.bold("You don't have any links to update!") + ); + } + } + } + }); + } + }); + + await prompt([ + { + type: "confirm", + name: "testimonial", + message: "Do you want to update your testimonials (usernames)?", + }, + ]).then(async (answers) => { + if (answers.testimonial) { + await prompt([ + { + type: "select", + name: "operation", + message: "What you want to do?", + choices: [ + "add a testimonial?", + "remove a testimonial?", + "update a testimonial?", + ], + }, + ]).then(async (answers) => { + switch (answers.operation) { + case "add a testimonial?": { + if (json.testimonials) { + json.testimonials = [ + ...json.testimonials, + ...(await addtestimonials(true)), + ]; + } else { + json.testimonials = [...(await addtestimonials(true))]; + } + break; + } + case "remove a testimonial?": { + if (json.testimonials) { + json.testimonials = [ + ...(await removetestimonials(json.testimonials)), + ]; + if (json.testimonials.length === 0) { + delete json.testimonials; + } + } else { + console.log( + chalk.bgYellow.bold( + "You don't have any testimonials to remove!" + ) + ); + } + break; + } + default: { + if (json.testimonials) { + json.testimonials = [ + ...(await updatetestimonials(json.testimonials)), + ]; + } else { + console.log( + chalk.bgYellow.bold( + "You don't have any testimonials to update!" + ) + ); + } + } + } + }); + } + }); + + await prompt([ + { + type: "confirm", + name: "milestone", + message: "Do you want to update your milestones?", + }, + ]).then(async (answers) => { + if (answers.milestone) { + await prompt([ + { + type: "select", + name: "operation", + message: "What you want to do?", + choices: [ + "add a milestone?", + "remove a milestone?", + "update a milestone?", + ], + }, + ]).then(async (answers) => { + switch (answers.operation) { + case "add a milestone?": { + if (json.milestones) { + json.milestones = [ + ...json.milestones, + ...(await addmilestones(true)), + ]; + } else { + json.milestones = [...(await addmilestones(true))]; + } + break; + } + case "remove a milestone?": { + if (json.milestones) { + json.milestones = [...(await removemilestones(json.milestones))]; + if (json.milestones.length === 0) { + delete json.milestones; + } + } else { + console.log( + chalk.bgYellow.bold("You don't have any milestones to remove!") + ); + } + break; + } + default: { + if (json.milestones) { + json.milestones = [...(await updatemilestones(json.milestones))]; + } else { + console.log( + chalk.bgYellow.bold("You don't have any milestones to update!") + ); + } + } + } + }); + } + }); + + json = jsonFormat(json, { type: "space", size: 2 }); + fs.writeFile(`./data/${githubUsername}.json`, json, (err) => { + if (err) { + console.log(chalk.bgYellow.bold(` Couldn't update file. Try again! `)); + process.exit(0); + } else { + console.log( + chalk.bgWhite.bold( + ` File ${githubUsername}.json updated successfully! ` + ) + ); + } + }); +}; + +module.exports = updateJson; diff --git a/src/util/createUser.js b/src/util/createUser.js deleted file mode 100644 index bfffae1..0000000 --- a/src/util/createUser.js +++ /dev/null @@ -1,32 +0,0 @@ -const jsonFormat = require("json-format"); -const chalk = require("chalk"); -const fs = require("fs"); - -async function createUserJson(githubUsername, answers) { - sampleJson = { - name: `${answers.name}`, - type: `${answers.type}`, - bio: `${answers.bio}`, - links: answers.links ? answers.links : [], - milestones: answers.milestones ? answers.milestones : [], - }; - - const json = jsonFormat(sampleJson, { type: "space", size: 2 }); - fs.writeFile(`./data/${githubUsername}.json`, json, (err) => { - if (err) { - console.log( - chalk.bgYellow.bold( - ` You are not in the root directory of LinkFree. Try again! ` - ) - ); - } else { - console.log( - chalk.bgWhite.bold( - ` File with ${githubUsername}.json created successfully! ` - ) - ); - } - }); -} - -module.exports = createUserJson; diff --git a/src/util/questions.js b/src/util/questions.js deleted file mode 100644 index 017f39b..0000000 --- a/src/util/questions.js +++ /dev/null @@ -1,80 +0,0 @@ -const { prompt } = require("enquirer"); -const chalk = require("chalk"); -const axios = require("axios"); - -let links = []; -let icons = []; - -async function questions() { - const answers = await prompt([ - { - type: "input", - name: "name", - message: "What is your name (e.g. Jone Doe)?", - }, - { - type: "select", - name: "type", - message: "Your profile type?", - choices: ["Personal", "Community"], - }, - { - type: "input", - name: "bio", - message: "Add a short bio about yourself", - }, - ]); - return answers; -} - -async function geticons() { - try { - const response = await axios.get( - `https://raw.githubusercontent.com/EddieHubCommunity/LinkFree/main/config/icons.json` - ); - icons = Object.keys(response.data); - } catch (error) { - console.error(error); - } -} - -async function addlinks(bool) { - // wait for the icons to be fetched - await geticons(); - - while (bool) { - let answers = await prompt([ - { - type: "input", - name: "name", - message: "What is the name of the link?", - }, - { - type: "input", - name: "url", - message: "What is the URL of the link?", - }, - { - type: "select", - name: "icon", - choices: icons, - message: "Choose an icon (Press down arrow to see more options)", - }, - { - type: "confirm", - name: "addLink", - message: "Do you want to add another link?", - }, - ]); - links.push({ - name: answers.name, - url: answers.url, - icon: answers.icon, - }); - if (!answers.addLink) { - return links; - } - } -} - -module.exports = { questions, addlinks };