├── .npmrc ├── .eslintrc ├── images └── business-card.png ├── src ├── dividers.js ├── colors.js ├── constants.js ├── index.js ├── corners.js ├── generator │ ├── index.js │ └── questions.js ├── utils.js └── constructors.js ├── .eslintignore ├── .gitignore ├── .prettierrc ├── .github └── workflows │ └── release.yml ├── config.json ├── license ├── package.json ├── readme.md └── docs └── configuration.md /.npmrc: -------------------------------------------------------------------------------- 1 | legacy-peer-deps=true 2 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@bradgarropy/eslint-config" 3 | } 4 | -------------------------------------------------------------------------------- /images/business-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradgarropy/business-card/HEAD/images/business-card.png -------------------------------------------------------------------------------- /src/dividers.js: -------------------------------------------------------------------------------- 1 | const dividers = { 2 | normal: "─", 3 | triple: "┄", 4 | quadruple: "┈", 5 | } 6 | 7 | module.exports = dividers 8 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # editor 2 | .vscode 3 | 4 | # dependencies 5 | node_modules 6 | 7 | # build 8 | .cache 9 | dist 10 | 11 | # secrets 12 | .env* 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # editor 2 | .vscode 3 | 4 | # dependencies 5 | node_modules 6 | 7 | # build 8 | .cache 9 | dist 10 | 11 | # secrets 12 | .env* 13 | -------------------------------------------------------------------------------- /src/colors.js: -------------------------------------------------------------------------------- 1 | const chalk = require("chalk") 2 | const {style} = require("../config.json") 3 | 4 | const colors = { 5 | base: chalk[style.baseColor], 6 | accent: chalk[style.accentColor], 7 | } 8 | 9 | module.exports = colors 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 4, 4 | "useTabs": false, 5 | "semi": false, 6 | "singleQuote": false, 7 | "quoteProps": "consistent", 8 | "jsxSingleQuote": false, 9 | "trailingComma": "all", 10 | "bracketSpacing": false, 11 | "jsxBracketSameLine": false, 12 | "arrowParens": "avoid", 13 | "endOfLine": "lf" 14 | } 15 | -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | const marginTop = 1 2 | const marginRight = 4 3 | const marginBottom = 1 4 | const marginLeft = 4 5 | 6 | const paddingTop = 1 7 | const paddingRight = 8 8 | const paddingBottom = 1 9 | const paddingLeft = 4 10 | 11 | const indent = 4 12 | 13 | module.exports = { 14 | marginBottom, 15 | marginLeft, 16 | marginRight, 17 | marginTop, 18 | paddingBottom, 19 | paddingLeft, 20 | paddingRight, 21 | paddingTop, 22 | indent, 23 | } 24 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const {info, links, style} = require("../config.json") 4 | const { 5 | getTopBorder, 6 | getBottomBorder, 7 | getDividerLine, 8 | getBlankLine, 9 | getLink, 10 | getName, 11 | getTitle, 12 | getCommand, 13 | } = require("./constructors") 14 | 15 | const card = [ 16 | "", 17 | getTopBorder(style.corners), 18 | getBlankLine(), 19 | getName(info.name, info.handle), 20 | getTitle(info.title, info.company), 21 | getBlankLine(), 22 | ...links.map(link => getLink(link.name, link.url)), 23 | getBlankLine(), 24 | getDividerLine(style.divider), 25 | getCommand(info.handle), 26 | getBottomBorder(style.corners), 27 | "", 28 | ].join("\n") 29 | 30 | console.log(card) 31 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "🚀 release" 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | release: 9 | name: "🚀 release" 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: "📚 checkout" 13 | uses: actions/checkout@v2.3.4 14 | - name: "🟢 node" 15 | uses: actions/setup-node@v2.1.4 16 | with: 17 | node-version: 16 18 | registry-url: https://registry.npmjs.org/ 19 | - name: "📦 install" 20 | run: npm ci 21 | - name: "🧶 lint" 22 | run: npm run lint 23 | - name: "📦 publish" 24 | run: npm publish --access public 25 | env: 26 | NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}} 27 | -------------------------------------------------------------------------------- /src/corners.js: -------------------------------------------------------------------------------- 1 | const normal = { 2 | topLeft: "┌", 3 | topRight: "┐", 4 | bottomLeft: "└", 5 | bottomRight: "┘", 6 | } 7 | 8 | const rounded = { 9 | topLeft: "╭", 10 | topRight: "╮", 11 | bottomLeft: "╰", 12 | bottomRight: "╯", 13 | } 14 | 15 | const heavy = { 16 | topLeft: "┏", 17 | topRight: "┓", 18 | bottomLeft: "┗", 19 | bottomRight: "┛", 20 | } 21 | 22 | const double = { 23 | topLeft: "╔", 24 | topRight: "╗", 25 | bottomLeft: "╚", 26 | bottomRight: "╝", 27 | } 28 | 29 | const doubleTop = { 30 | topLeft: "╒", 31 | topRight: "╕", 32 | bottomLeft: "╘", 33 | bottomRight: "╛", 34 | } 35 | 36 | const doubleSide = { 37 | topLeft: "╓", 38 | topRight: "╖", 39 | bottomLeft: "╙", 40 | bottomRight: "╜", 41 | } 42 | 43 | const corners = { 44 | normal, 45 | rounded, 46 | heavy, 47 | double, 48 | doubleTop, 49 | doubleSide, 50 | } 51 | 52 | module.exports = corners 53 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "name": "Brad Garropy", 4 | "handle": "bradgarropy", 5 | "company": "Atlassian", 6 | "title": "Senior Software Engineer" 7 | }, 8 | "links": [ 9 | { 10 | "name": "Website", 11 | "url": "https://bradgarropy.com" 12 | }, 13 | { 14 | "name": "Twitch", 15 | "url": "https://twitch.tv/bradgarropy" 16 | }, 17 | { 18 | "name": "GitHub", 19 | "url": "https://github.com/bradgarropy" 20 | }, 21 | { 22 | "name": "Twitter", 23 | "url": "https://twitter.com/bradgarropy" 24 | }, 25 | { 26 | "name": "YouTube", 27 | "url": "https://youtube.com/bradgarropy" 28 | }, 29 | { 30 | "name": "LinkedIn", 31 | "url": "https://linkedin.com/in/bradgarropy" 32 | } 33 | ], 34 | "style": { 35 | "corners": "double", 36 | "divider": "triple", 37 | "baseColor": "white", 38 | "accentColor": "blue" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Brad Garropy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/generator/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs") 2 | const inquirer = require("inquirer") 3 | const {infoQuestions, linkQuestions, styleQuestions} = require("./questions") 4 | 5 | const generate = async () => { 6 | const config = { 7 | info: {}, 8 | links: [], 9 | style: {}, 10 | } 11 | 12 | console.log("--- Describe yourself ---\n") 13 | const infoAnswers = await inquirer.prompt(infoQuestions) 14 | config.info = infoAnswers 15 | 16 | console.log("\n\n--- Showcase links ---\n") 17 | 18 | let shouldContinue = true 19 | 20 | while (shouldContinue) { 21 | const {name} = await inquirer.prompt(linkQuestions[0]) 22 | const {url} = await inquirer.prompt(linkQuestions[1]) 23 | config.links.push({name, url}) 24 | 25 | const {more} = await inquirer.prompt(linkQuestions[2]) 26 | shouldContinue = more 27 | } 28 | 29 | console.log("\n\n--- Style your card ---\n") 30 | const styleAnswers = await inquirer.prompt(styleQuestions) 31 | config.style = styleAnswers 32 | 33 | fs.writeFileSync("config.json", JSON.stringify(config, null, 4)) 34 | } 35 | 36 | generate() 37 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | const colors = require("./colors") 2 | const {paddingLeft, indent, paddingRight} = require("./constants") 3 | const dividers = require("./dividers") 4 | const {links, style} = require("../config.json") 5 | 6 | const space = count => { 7 | return " ".repeat(count) 8 | } 9 | 10 | const divider = count => { 11 | return dividers[style.divider].repeat(count) 12 | } 13 | 14 | const verticalBorder = count => { 15 | return colors.base("│").repeat(count) 16 | } 17 | 18 | const horizontalBorder = count => { 19 | return colors.base("─").repeat(count) 20 | } 21 | 22 | const getLinkLength = link => { 23 | const length = `${link.name}: ${link.url}`.length 24 | return length 25 | } 26 | 27 | const getLongestLink = () => { 28 | const lengths = links.map(link => getLinkLength(link)) 29 | const longestLink = Math.max(...lengths) 30 | return longestLink 31 | } 32 | 33 | const getLongestLinkName = () => { 34 | const lengths = links.map(link => link.name.length) 35 | const longestLinkName = Math.max(...lengths) 36 | return longestLinkName 37 | } 38 | 39 | const getWidth = () => { 40 | const longestLink = getLongestLink() 41 | const width = paddingLeft + indent + longestLink + paddingRight 42 | return width 43 | } 44 | 45 | const getFill = content => { 46 | const width = getWidth(links) 47 | const fill = width - paddingLeft - paddingRight - content.length 48 | return fill 49 | } 50 | 51 | const getShift = name => { 52 | const longestLinkName = getLongestLinkName() 53 | const shift = longestLinkName - name.length 54 | 55 | return shift 56 | } 57 | 58 | module.exports = { 59 | space, 60 | divider, 61 | verticalBorder, 62 | horizontalBorder, 63 | getLinkLength, 64 | getLongestLink, 65 | getWidth, 66 | getFill, 67 | getShift, 68 | } 69 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bradgarropy", 3 | "version": "2.5.0", 4 | "description": "🃏 npx business card", 5 | "keywords": [ 6 | "npm", 7 | "npx", 8 | "eslint", 9 | "prettier", 10 | "chalk", 11 | "parcel", 12 | "business-card", 13 | "inquirer" 14 | ], 15 | "homepage": "https://github.com/bradgarropy/business-card", 16 | "bugs": { 17 | "url": "https://github.com/bradgarropy/business-card/issues" 18 | }, 19 | "license": "MIT", 20 | "author": { 21 | "name": "Brad Garropy", 22 | "email": "bradgarropy@gmail.com", 23 | "url": "https://bradgarropy.com" 24 | }, 25 | "files": [ 26 | "dist" 27 | ], 28 | "main": "dist/index.js", 29 | "bin": { 30 | "bradgarropy": "dist/index.js" 31 | }, 32 | "repository": { 33 | "type": "git", 34 | "url": "https://github.com/bradgarropy/business-card" 35 | }, 36 | "scripts": { 37 | "start": "node src/index.js", 38 | "dev": "nodemon src/index.js", 39 | "build": "parcel build src/index.js --target node --no-source-maps", 40 | "prepare": "npm run build", 41 | "lint": "eslint .", 42 | "lint:fix": "eslint . --fix", 43 | "generate": "node src/generator/index.js" 44 | }, 45 | "dependencies": { 46 | "chalk": "^4.1.0" 47 | }, 48 | "devDependencies": { 49 | "@babel/eslint-parser": "^7.19.1", 50 | "@bradgarropy/eslint-config": "^1.1.0", 51 | "eslint": "^7.16.0", 52 | "eslint-config-prettier": "^7.1.0", 53 | "eslint-plugin-simple-import-sort": "^7.0.0", 54 | "inquirer": "^7.3.3", 55 | "nodemon": "^2.0.6", 56 | "parcel-bundler": "^1.12.4", 57 | "parcel-plugin-clean-dist": "0.0.6", 58 | "parcel-plugin-shebang": "^1.3.1", 59 | "prettier": "^2.2.1" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 🃏 business card 2 | 3 | 4 | npm 5 | 6 | 7 | 8 | npm 9 | 10 | 11 | _Digital business card._ 12 | 13 | ![business card][card] 14 | 15 | ### 📦 Installation 16 | 17 | Installation is not required, as you can run this package with [`npx`][npx]. 18 | 19 | ### 🥑 Usage 20 | 21 | ``` 22 | npx bradgarropy 23 | ``` 24 | 25 | ### 🕺🏼 Create Your Own 26 | 27 | First, [fork][fork] this repository, clone it your machine, and install the dependencies. 28 | 29 | ```bash 30 | git clone https://github.com/bradgarropy/business-card.git 31 | cd business-card 32 | npm install 33 | ``` 34 | 35 | Next, use the `generator` to create your configuration. You can also [modify the configuration][configuration] manually if you prefer. 36 | 37 | ```bash 38 | npm run generate 39 | ``` 40 | 41 | Then, update the `name` field in [`package.json`][package]. I highly recommend that the `name` field matches your primary online username (ex: `bradgarropy`). 42 | 43 | Finally, [publish][publish] the package to `npm`. If you are new to this process, I created a [video][video] covering publishing a package. 44 | 45 | ```bash 46 | npm publish 47 | ``` 48 | 49 | Now anyone with `npm` installed can see your business card! 50 | 51 | ```bash 52 | npx bradgarropy 53 | ``` 54 | 55 | ### ❔ Questions 56 | 57 | 🐛 report bugs by filing [issues][issues] 58 | 📢 provide feedback with [issues][issues] or on [twitter][twitter] 59 | 🙋🏼‍♂️ use my [ama][ama] or [twitter][twitter] to ask any other questions 60 | 61 | ### 🎞 Credit 62 | 63 | ✨ inspired by [J.C. Hiatt][jc] 64 | 📖 accomplished with the help of this [article][article] 65 | 66 | [issues]: https://github.com/bradgarropy/business-card/issues 67 | [twitter]: https://twitter.com/bradgarropy 68 | [ama]: https://bradgarropy.com/ama 69 | [package]: https://github.com/bradgarropy/business-card/blob/master/package.json 70 | [fork]: https://github.com/bradgarropy/business-card/fork 71 | [card]: images/business-card.png 72 | [npx]: https://npmjs.com/package/npx 73 | [jc]: https://twitter.com/jchiatt/status/1251700185840918531 74 | [article]: https://medium.com/@natterstefan/how-to-create-your-personal-npm-business-card-816dfc66ca8 75 | [configuration]: docs/configuration.md 76 | [publish]: https://docs.npmjs.com/cli/v6/commands/npm-publish 77 | [video]: https://youtu.be/S_wvHDOrac0 78 | -------------------------------------------------------------------------------- /src/generator/questions.js: -------------------------------------------------------------------------------- 1 | const chalk = require("chalk") 2 | 3 | const infoQuestions = [ 4 | { 5 | type: "input", 6 | name: "name", 7 | message: "What is your name?", 8 | }, 9 | { 10 | type: "input", 11 | name: "handle", 12 | message: "What is your online handle?", 13 | }, 14 | { 15 | type: "input", 16 | name: "company", 17 | message: "What company do you work for?", 18 | }, 19 | { 20 | type: "input", 21 | name: "title", 22 | message: "What is your job title?", 23 | }, 24 | ] 25 | 26 | const linkQuestions = [ 27 | { 28 | type: "input", 29 | name: "name", 30 | message: "Enter a link name:", 31 | }, 32 | { 33 | type: "input", 34 | name: "url", 35 | message: "Enter a link url:", 36 | }, 37 | { 38 | type: "confirm", 39 | name: "more", 40 | message: "Do you want to add more links?", 41 | }, 42 | ] 43 | 44 | const styleQuestions = [ 45 | { 46 | type: "list", 47 | name: "corners", 48 | message: "Choose a corner style.", 49 | choices: [ 50 | {name: "┌─────┐", value: "normal"}, 51 | {name: "╭─────╮", value: "rounded"}, 52 | {name: "┏─────┓", value: "heavy"}, 53 | {name: "╔─────╗", value: "double"}, 54 | {name: "╒─────╕", value: "doubleTop"}, 55 | {name: "╓─────╖", value: "doubleSide"}, 56 | ], 57 | pageSize: 6, 58 | }, 59 | { 60 | type: "list", 61 | name: "divider", 62 | message: "Choose a divider style.", 63 | choices: [ 64 | {name: "──────────", value: "normal"}, 65 | {name: "┄┄┄┄┄┄┄┄┄┄", value: "triple"}, 66 | {name: "┈┈┈┈┈┈┈┈┈┈", value: "quadruple"}, 67 | ], 68 | pageSize: 3, 69 | }, 70 | { 71 | type: "list", 72 | name: "baseColor", 73 | message: "Choose a base color.", 74 | choices: [ 75 | {name: chalk.white("white"), value: "white"}, 76 | {name: chalk.black("black"), value: "black"}, 77 | {name: chalk.red("red"), value: "red"}, 78 | {name: chalk.green("green"), value: "green"}, 79 | {name: chalk.yellow("yellow"), value: "yellow"}, 80 | {name: chalk.blue("blue"), value: "blue"}, 81 | {name: chalk.magenta("magenta"), value: "magenta"}, 82 | {name: chalk.cyan("cyan"), value: "cyan"}, 83 | {name: chalk.gray("gray"), value: "gray"}, 84 | ], 85 | default: "white", 86 | pageSize: 9, 87 | }, 88 | { 89 | type: "list", 90 | name: "accentColor", 91 | message: "Choose an accent color.", 92 | choices: [ 93 | {name: chalk.white("white"), value: "white"}, 94 | {name: chalk.black("black"), value: "black"}, 95 | {name: chalk.red("red"), value: "red"}, 96 | {name: chalk.green("green"), value: "green"}, 97 | {name: chalk.yellow("yellow"), value: "yellow"}, 98 | {name: chalk.blue("blue"), value: "blue"}, 99 | {name: chalk.magenta("magenta"), value: "magenta"}, 100 | {name: chalk.cyan("cyan"), value: "cyan"}, 101 | {name: chalk.gray("gray"), value: "gray"}, 102 | ], 103 | default: "white", 104 | pageSize: 9, 105 | }, 106 | ] 107 | 108 | module.exports = {infoQuestions, linkQuestions, styleQuestions} 109 | -------------------------------------------------------------------------------- /docs/configuration.md: -------------------------------------------------------------------------------- 1 | # ⚙ configuration 2 | 3 | The [configuration][config] file is called `config.json` and is located at the root of the project. There are three main sections. 4 | 5 | - [`info`](#-info-configuration) 6 | - [`links`](#-link-configuration) 7 | - [`style`](#-style-configuration) 8 | 9 | Here is an example configuration file. 10 | 11 | ```json 12 | { 13 | "info": { 14 | "name": "Brad Garropy", 15 | "handle": "bradgarropy", 16 | "company": "Adobe", 17 | "title": "Senior Frontend Developer" 18 | }, 19 | "links": [ 20 | { 21 | "name": "Website", 22 | "url": "https://bradgarropy.com" 23 | } 24 | ], 25 | "style": { 26 | "corners": "double", 27 | "divider": "triple", 28 | "baseColor": "white", 29 | "accentColor": "blue" 30 | } 31 | } 32 | ``` 33 | 34 | ## 👤 Info Configuration 35 | 36 | The `info` section describes who you are and where you work. 37 | 38 | | Name | Example | Description | 39 | | --------- | --------------------------- | ------------------------ | 40 | | `name` | `Brad Garropy` | Full name. | 41 | | `handle` | `bradgarropy` | Primary online username. | 42 | | `company` | `Adobe` | Company name. | 43 | | `title` | `Senior Frontend Developer` | Job title. | 44 | 45 | Special characters used for the corners of the business card. 46 | 47 | ```json 48 | { 49 | "info": { 50 | "name": "Brad Garropy", 51 | "handle": "bradgarropy", 52 | "company": "Adobe", 53 | "title": "Senior Frontend Developer" 54 | } 55 | } 56 | ``` 57 | 58 | ## 🔗 Link Configuration 59 | 60 | The `links` section highlights your best websites or social media accounts. 61 | 62 | ### `links[link]` 63 | 64 | | Name | Example | Description | 65 | | ------ | --------------------------------- | ----------------- | 66 | | `name` | `Twitter` | Name of the link. | 67 | | `url` | `https://twitter.com/bradgarropy` | URL of the link. | 68 | 69 | It is an array of `link` objects with a `name` and `url`. Order is preserved when printed to the business card. 70 | 71 | ```json 72 | { 73 | "links": [{"name": "Twitter", "url": "https://twitter.com/bradgarropy"}] 74 | } 75 | ``` 76 | 77 | ## 🎨 Style Configuration 78 | 79 | The `style` configuration controls certain visual aspects of the business card. Each one comes with preset values for you to choose from. 80 | 81 | ### `style.corners` 82 | 83 | | Name | Example | 84 | | ------------ | --------- | 85 | | `normal` | `┌─────┐` | 86 | | `rounded` | `╭─────╮` | 87 | | `heavy` | `┏─────┓` | 88 | | `double` | `╔─────╗` | 89 | | `doubleTop` | `╒─────╕` | 90 | | `doubleSide` | `╓─────╖` | 91 | 92 | Special characters used for the corners of the business card. 93 | 94 | ```json 95 | { 96 | "style": {"corners": "heavy"} 97 | } 98 | ``` 99 | 100 | ### `style.dividers` 101 | 102 | | Name | Example | 103 | | ----------- | ------------ | 104 | | `normal` | `──────────` | 105 | | `triple` | `┄┄┄┄┄┄┄┄┄┄` | 106 | | `quadruple` | `┈┈┈┈┈┈┈┈┈┈` | 107 | 108 | Special characters used for the horizontal rule above the footer. 109 | 110 | ```json 111 | { 112 | "style": {"dividers": "triple"} 113 | } 114 | ``` 115 | 116 | ### `style.baseColor` 117 | 118 | | Name | 119 | | --------- | 120 | | `white` | 121 | | `black` | 122 | | `red` | 123 | | `green` | 124 | | `yellow` | 125 | | `blue` | 126 | | `magenta` | 127 | | `cyan` | 128 | | `gray` | 129 | 130 | The color of the borders, job line, and link labels. You can use any [`chalk`][chalk] color value. 131 | 132 | ```json 133 | { 134 | "style": {"baseColor": "white"} 135 | } 136 | ``` 137 | 138 | ### `style.accentColor` 139 | 140 | | Name | 141 | | --------- | 142 | | `white` | 143 | | `black` | 144 | | `red` | 145 | | `green` | 146 | | `yellow` | 147 | | `blue` | 148 | | `magenta` | 149 | | `cyan` | 150 | | `gray` | 151 | 152 | The color of the name link, link urls, and footer text. You can use any [`chalk`][chalk] color value. 153 | 154 | ```json 155 | { 156 | "style": {"accentColor": "blue"} 157 | } 158 | ``` 159 | 160 | [chalk]: https://github.com/chalk/chalk#readme 161 | [config]: https://github.com/bradgarropy/business-card/blob/master/config.json 162 | -------------------------------------------------------------------------------- /src/constructors.js: -------------------------------------------------------------------------------- 1 | const colors = require("./colors") 2 | const corners = require("./corners") 3 | const { 4 | space, 5 | divider, 6 | verticalBorder, 7 | getWidth, 8 | getFill, 9 | getShift, 10 | horizontalBorder, 11 | } = require("./utils") 12 | const {info} = require("../config.json") 13 | const { 14 | marginLeft, 15 | marginRight, 16 | paddingLeft, 17 | paddingRight, 18 | indent, 19 | } = require("./constants") 20 | 21 | const getTopBorder = cornerStyle => { 22 | const width = getWidth(info.links) 23 | const {topLeft, topRight} = corners[cornerStyle] 24 | 25 | const topBorder = [ 26 | space(marginLeft), 27 | colors.base(topLeft), 28 | colors.base(horizontalBorder(width)), 29 | colors.base(topRight), 30 | space(marginRight), 31 | ].join("") 32 | 33 | return topBorder 34 | } 35 | 36 | const getBottomBorder = cornerStyle => { 37 | const width = getWidth(info.links) 38 | const {bottomLeft, bottomRight} = corners[cornerStyle] 39 | 40 | const bottomBorder = [ 41 | space(marginLeft), 42 | colors.base(bottomLeft), 43 | colors.base(horizontalBorder(width)), 44 | colors.base(bottomRight), 45 | space(marginRight), 46 | ].join("") 47 | 48 | return bottomBorder 49 | } 50 | 51 | const getDividerLine = () => { 52 | const width = getWidth(info.links) 53 | 54 | const dividerLine = [ 55 | space(marginLeft), 56 | colors.base("├"), 57 | colors.base(divider(width)), 58 | colors.base("┤"), 59 | space(marginRight), 60 | ].join("") 61 | 62 | return dividerLine 63 | } 64 | 65 | const getBlankLine = () => { 66 | const width = getWidth(info.links) 67 | 68 | const blankLine = [ 69 | space(marginLeft), 70 | colors.base(verticalBorder(1)), 71 | space(width), 72 | colors.base(verticalBorder(1)), 73 | space(marginRight), 74 | ].join("") 75 | 76 | return blankLine 77 | } 78 | 79 | const getLine = content => { 80 | const line = [ 81 | space(marginLeft), 82 | colors.base(verticalBorder(1)), 83 | space(paddingLeft), 84 | content, 85 | space(paddingRight), 86 | colors.base(verticalBorder(1)), 87 | space(marginRight), 88 | ].join("") 89 | 90 | return line 91 | } 92 | 93 | const getName = (name, handle) => { 94 | const content = [name, " / ", handle].join("") 95 | const fill = getFill(content) 96 | 97 | const formattedContent = [ 98 | colors.accent(name), 99 | colors.base(" / "), 100 | colors.accent(handle), 101 | space(fill), 102 | ].join("") 103 | 104 | const line = getLine(formattedContent) 105 | return line 106 | } 107 | 108 | const getTitle = (title, company) => { 109 | const content = [title, " @ ", company].join("") 110 | const fill = getFill(content) 111 | 112 | const formattedContent = [ 113 | colors.base(title), 114 | colors.base(" @ "), 115 | colors.base(company), 116 | space(fill), 117 | ].join("") 118 | 119 | const line = getLine(formattedContent) 120 | return line 121 | } 122 | 123 | const getLink = (name, url) => { 124 | const shift = getShift(name) 125 | const content = [space(shift + indent), name, ": ", url].join("") 126 | const fill = getFill(content) 127 | 128 | const formattedContent = [ 129 | space(shift + indent), 130 | colors.base(name), 131 | colors.base(": "), 132 | colors.accent(url), 133 | space(fill), 134 | ].join("") 135 | 136 | const line = getLine(formattedContent) 137 | return line 138 | } 139 | 140 | const getCommand = handle => { 141 | const content = ["npx ", handle].join("") 142 | const formattedContent = colors.accent(`npx ${handle}`) 143 | 144 | const width = getWidth(info.links) 145 | 146 | const line = [ 147 | space(marginLeft), 148 | colors.base(verticalBorder(1)), 149 | space(width - content.length - 2), 150 | formattedContent, 151 | space(2), 152 | colors.base(verticalBorder(1)), 153 | space(marginRight), 154 | ].join("") 155 | 156 | return line 157 | } 158 | 159 | module.exports = { 160 | getTopBorder, 161 | getBottomBorder, 162 | getDividerLine, 163 | getBlankLine, 164 | getLine, 165 | getLink, 166 | getName, 167 | getTitle, 168 | getCommand, 169 | } 170 | --------------------------------------------------------------------------------