├── .editorconfig ├── .gitattributes ├── .gitignore ├── .travis.yml ├── app ├── index.js └── templates │ ├── _package.json │ ├── cli.js │ ├── editorconfig │ ├── gitignore │ ├── index.js │ ├── license.md │ ├── readme.md │ ├── test.js │ └── travis.yml ├── license.md ├── package.json ├── readme.md └── test └── app.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [{package.json,*.yml}] 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '7' 4 | - '6' 5 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Generator = require('yeoman-generator'); 4 | const kebabcase = require('lodash.kebabcase'); 5 | const superb = require('superb'); 6 | 7 | module.exports = class extends Generator { 8 | constructor(a, b) { 9 | super(a, b); 10 | 11 | this.option('cli', { 12 | type: Boolean, 13 | desc: 'Add a CLI' 14 | }); 15 | } 16 | 17 | prompting() { 18 | return this.prompt([ 19 | { 20 | name: 'appName', 21 | message: 'What do you want to name your app?', 22 | default: kebabcase(this.appname) 23 | }, 24 | { 25 | name: 'description', 26 | message: 'What is your app description?', 27 | default: `My ${superb()} microservice` 28 | }, 29 | { 30 | name: 'username', 31 | message: 'What is your GitHub username?', 32 | store: true, 33 | validate: username => username.length > 0 ? true : 'You have to provide a username' 34 | }, 35 | { 36 | name: 'cli', 37 | message: 'Do you need a CLI?', 38 | type: 'confirm', 39 | default: Boolean(this.options.cli), 40 | when: () => this.options.cli === undefined 41 | } 42 | ]).then(props => { 43 | const cli = this.options.cli || props.cli; 44 | const appName = kebabcase(props.appName); 45 | 46 | this.props = Object.assign({ 47 | name: this.user.git.name(), 48 | email: this.user.git.email() 49 | }, props, {appName, cli}); 50 | }); 51 | } 52 | 53 | writing() { 54 | const mv = (from, to) => { 55 | this.fs.move(this.destinationPath(from), this.destinationPath(to)); 56 | }; 57 | 58 | this.fs.copyTpl([ 59 | `${this.templatePath()}/**`, 60 | '!**/cli.js' 61 | ], this.destinationPath(), this.props); 62 | 63 | if (this.props.cli) { 64 | this.fs.copy(this.templatePath('cli.js'), this.destinationPath('cli.js')); 65 | } 66 | 67 | mv('editorconfig', '.editorconfig'); 68 | mv('gitignore', '.gitignore'); 69 | mv('travis.yml', '.travis.yml'); 70 | mv('_package.json', 'package.json'); 71 | } 72 | 73 | install() { 74 | this.installDependencies({bower: false}); 75 | } 76 | }; 77 | -------------------------------------------------------------------------------- /app/templates/_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= appName %>", 3 | "version": "1.0.0", 4 | "description": "<%= description %>", 5 | "author": "<%= name %> <<%= email %>>", 6 | "repository": "<%= username %>/<%= appName %>", 7 | "license": "MIT", 8 | "scripts": { 9 | "start": "micro", 10 | "test": "xo && ava" 11 | }, 12 | "engines": { 13 | "node": ">= 6" 14 | }, 15 | "files": [ 16 | "index.js"<% if (cli) { %>, 17 | "cli.js"<% } %> 18 | ],<% if (cli) { %> 19 | "bin": "cli.js",<% } %> 20 | "main": "index.js", 21 | "dependencies": { 22 | "micro": "^7.0.0"<% if (cli) { %>, 23 | "update-notifier": "^1.0.3"<% } %> 24 | }, 25 | "devDependencies": { 26 | "async-to-gen": "^1.3.2", 27 | "ava": "^0.18.1", 28 | "got": "^6.7.1", 29 | "test-listen": "^1.0.1", 30 | "xo": "^0.17.1" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/templates/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | const {spawn} = require('child_process'); 6 | const updateNotifier = require('update-notifier'); 7 | const pkg = require('./package.json'); 8 | 9 | updateNotifier({pkg}).notify(); 10 | 11 | const args = process.argv.slice(2); 12 | spawn('npm', ['start', '--'].concat(args), { 13 | cwd: __dirname, 14 | stdio: 'inherit' 15 | }); 16 | -------------------------------------------------------------------------------- /app/templates/editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [{package.json,*.yml}] 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /app/templates/gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /app/templates/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const {json} = require('micro'); 4 | 5 | module.exports = async req => { 6 | const body = await json(req); 7 | 8 | // let's echo the text 9 | return {text: body.text}; 10 | }; 11 | -------------------------------------------------------------------------------- /app/templates/license.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) <%= name %> <<%= email %>> 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/templates/readme.md: -------------------------------------------------------------------------------- 1 | # <%= appName %> [![Build Status](https://travis-ci.org/<%= username %>/<%= appName %>.svg?branch=master)](https://travis-ci.org/<%= username %>/<%= appName %>) 2 | 3 | > <%= description %> 4 | 5 | [![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/<%= username %>/<%= appName %>) 6 | 7 | 8 | ## Usage 9 | <% if (cli) { %> 10 | ```bash 11 | $ npm install --global <%= appName %> 12 | $ <%= appName %> 13 | ```<% } else { %> 14 | ```bash 15 | $ git clone <%= username %>/<%= appName %>.git 16 | $ cd <%= appName %> 17 | $ npm start 18 | ``` 19 | <% } %> 20 | 21 | 22 | ## Deployment 23 | 24 | This microservice can be deployed to [now](https://zeit.co/now) by Zeit. 25 | Assuming you've got `now` installed and set up: 26 | 27 | ```bash 28 | $ now <%= username %>/<%= appName %> 29 | ``` 30 | 31 | Alternative, deploy right now without even leaving the browser: 32 | 33 | [![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/<%= username %>/<%= appName %>) 34 | 35 | 36 | ## License 37 | 38 | MIT © <%= name %> 39 | -------------------------------------------------------------------------------- /app/templates/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const listen = require('test-listen'); 4 | const micro = require('micro'); 5 | const test = require('ava'); 6 | const got = require('got'); 7 | 8 | require('async-to-gen/register')({includes: /index\.js$/}); 9 | const app = require('./'); // eslint-disable-line import/order 10 | 11 | test('echo back the text', async t => { 12 | const service = micro(app); 13 | const url = await listen(service); 14 | 15 | const res = await got(url, { 16 | method: 'post', 17 | json: true, 18 | headers: {'content-type': 'application/json'}, 19 | body: JSON.stringify({text: 'Hello!'}) 20 | }); 21 | 22 | t.is(res.body.text, 'Hello!'); 23 | }); 24 | -------------------------------------------------------------------------------- /app/templates/travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '7' 4 | - '6' 5 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Vadim Demedes (https://vadimdemedes.com) 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-micro-service", 3 | "version": "1.0.0", 4 | "description": "Kickstart your microservice with `micro` and `ava`!", 5 | "license": "MIT", 6 | "repository": "vadimdemedes/generator-micro-service", 7 | "author": { 8 | "name": "Vadim Demedes", 9 | "email": "vdemedes@gmail.com", 10 | "url": "https://vadimdemedes.com" 11 | }, 12 | "keywords": [ 13 | "micro", 14 | "microservice", 15 | "yeoman-generator" 16 | ], 17 | "scripts": { 18 | "test": "xo && ava" 19 | }, 20 | "files": [ 21 | "app" 22 | ], 23 | "main": "app/index.js", 24 | "dependencies": { 25 | "lodash.kebabcase": "^4.1.1", 26 | "superb": "^1.3.0", 27 | "yeoman-generator": "^1.0.0" 28 | }, 29 | "devDependencies": { 30 | "ava": "^0.18.1", 31 | "xo": "^0.17.1", 32 | "yeoman-assert": "^2.2.1", 33 | "yeoman-test": "^1.6.0" 34 | }, 35 | "xo": { 36 | "ignores": "app/templates/**" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # generator-micro-service [![Build Status](https://travis-ci.org/vadimdemedes/generator-micro-service.svg?branch=master)](https://travis-ci.org/vadimdemedes/generator-micro-service) 2 | 3 | 🚀 Kick-start your microservice with `micro` and `ava`! 4 | 5 | *Based on [generator-nm](https://github.com/sindresorhus/generator-nm) by Sindre Sorhus.* 6 | 7 | ## Features 8 | 9 | -   Build using [micro](https://github.com/zeit/micro) 10 | - 🚀 Test with [AVA](https://ava.li) 11 | - ❤️ Lint using [XO](https://github.com/sindresorhus/xo) 12 | - 📜 Get a readme with buttons for instant deployment to [now](https://zeit.co/now) 13 | - 💲 Generate a CLI (optional) 14 | 15 | 16 | ## Installation 17 | 18 | First, install [Yeoman](http://yeoman.io) and generator-micro-service using [npm](https://www.npmjs.com/) (we assume you have pre-installed [node.js](https://nodejs.org/)). 19 | 20 | ```bash 21 | $ npm install --global yo 22 | $ npm install --global generator-micro-service 23 | ``` 24 | 25 | 26 | ## Usage 27 | 28 | ```bash 29 | $ yo micro-service 30 | ``` 31 | 32 | Answer a few questions and you are ready to go! 33 | 34 | 35 | ## License 36 | 37 | MIT © [Vadim Demedes](https://vadimdemedes.com) 38 | -------------------------------------------------------------------------------- /test/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import path from 'path'; 4 | import helpers from 'yeoman-test'; 5 | import assert from 'yeoman-assert'; 6 | import test from 'ava'; 7 | 8 | const generator = path.join(__dirname, '../app'); 9 | 10 | test.serial('generates expected files', async () => { 11 | await helpers 12 | .run(generator) 13 | .withPrompts({ 14 | appName: 'test', 15 | username: 'test', 16 | cli: false 17 | }) 18 | .toPromise(); 19 | 20 | assert.file([ 21 | '.editorconfig', 22 | '.gitignore', 23 | '.travis.yml', 24 | 'index.js', 25 | 'package.json', 26 | 'test.js', 27 | 'license.md', 28 | 'readme.md' 29 | ]); 30 | 31 | assert.noFile('cli.js'); 32 | }); 33 | 34 | test.serial('CLI option', async () => { 35 | await helpers 36 | .run(generator) 37 | .withPrompts({ 38 | appName: 'test', 39 | username: 'test', 40 | cli: true 41 | }) 42 | .toPromise(); 43 | 44 | assert.file('cli.js'); 45 | assert.fileContent('package.json', /"bin": "cli.js"/); 46 | }); 47 | --------------------------------------------------------------------------------