├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_proposal.md
├── release-drafter.yml
└── workflows
│ ├── auto-approve.yml
│ ├── npm-publish.yml
│ └── release-drafter.yml
├── .gitignore
├── .travis.yml
├── .woloxci
├── Dockerfile
└── config.yml
├── CHANGELOG.md
├── CODEOWNERS
├── Jenkinsfile
├── LICENSE.md
├── README.md
├── generators
└── app
│ ├── command.js
│ ├── constants.js
│ ├── dependencies
│ ├── package-lock.json
│ └── package.json
│ ├── index.js
│ ├── prompts.js
│ ├── templates
│ ├── .ebextensions
│ │ └── cloudwatch.config
│ ├── .env.example
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── .github
│ │ └── ISSUE_TEMPLATE
│ │ │ ├── bug_report.md
│ │ │ └── feature_proposal.md
│ ├── .nvmrc
│ ├── .sequelizerc
│ ├── .travis.yml
│ ├── .woloxci
│ │ ├── Dockerfile
│ │ └── config.yml
│ ├── CHANGELOG.md
│ ├── Dockerfile
│ ├── Dockerrun.aws.json
│ ├── Jenkinsfile
│ ├── LICENSE.md
│ ├── Procfile
│ ├── README.md
│ ├── app.ejs
│ ├── app
│ │ ├── controllers
│ │ │ └── healthCheck.js
│ │ ├── errors.js
│ │ ├── logger
│ │ │ └── index.js
│ │ ├── middlewares
│ │ │ ├── apiInfo.js
│ │ │ ├── docsAuth.ejs
│ │ │ └── errors.js
│ │ ├── models
│ │ │ └── index.js
│ │ ├── routes.js
│ │ └── services
│ │ │ └── .keep
│ ├── config
│ │ ├── db.ejs
│ │ ├── development.ejs
│ │ ├── index.ejs
│ │ ├── production.ejs
│ │ └── testing.ejs
│ ├── console.ejs
│ ├── documentation
│ │ ├── index.js
│ │ ├── paths
│ │ │ ├── index.js
│ │ │ └── user.js
│ │ └── schemas
│ │ │ ├── index.js
│ │ │ └── user.js
│ ├── gitignore
│ ├── migrations
│ │ ├── index.js
│ │ └── migrations
│ │ │ └── .keep
│ ├── package.json
│ ├── pull_request_template.md
│ ├── server.ejs
│ └── test
│ │ ├── app.spec.ejs
│ │ ├── factory
│ │ └── factory_by_models.ejs
│ │ └── setup.js
│ └── utils.js
├── img
├── demo.gif
└── demo.yml
├── package-lock.json
├── package.json
├── pull_request_template.md
└── test
├── __snapshots__
├── ci.spec.js.snap
├── deploy.spec.js.snap
├── general.spec.js.snap
├── mongoose.spec.js.snap
├── optionals.spec.js.snap
├── sequelize.spec.js.snap
└── testing.spec.js.snap
├── ci.spec.js
├── deploy.spec.js
├── general.spec.js
├── helpers
├── constants.js
├── mocks.js
└── utils.js
├── linter.spec.js
├── mongoose.spec.js
├── optionals.spec.js
├── sequelize.spec.js
├── testing.spec.js
└── training.spec.js
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('eslint-config-wolox-node');
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🐛 Bug Report
3 | about: Create a report to bug fixing
4 | title: 🐛 Bug Report
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## 🐛 Bug Report
11 |
12 | A clear and concise description of what the bug is.
13 |
14 | ## Steps to Reproduce
15 |
16 | Steps to reproduce the behavior:
17 |
18 | ## Expected behavior
19 |
20 | A clear and concise description of what you expected to happen.
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_proposal.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🚀 Feature Proposal
3 | about: Submit a proposal for a new feature
4 | title: 🚀 Feature Proposal
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## 🚀 Feature Proposal
11 |
12 | A clear and concise description of what the feature is.
13 |
14 | ## Motivation
15 |
16 | Please outline the motivation for the proposal.
17 |
18 | ## Example
19 |
20 | Please provide an example for how this feature would be used.
21 |
22 | ## Pitch
23 |
24 | Why does this feature should be implemented?
25 |
--------------------------------------------------------------------------------
/.github/release-drafter.yml:
--------------------------------------------------------------------------------
1 | name-template: "v$NEXT_PATCH_VERSION 🌈"
2 | tag-template: "v$NEXT_PATCH_VERSION"
3 | categories:
4 | - title: "🚀 Features"
5 | labels:
6 | - "feature"
7 | - title: "🐛 Bug Fixes"
8 | labels:
9 | - "fix"
10 | - "bugfix"
11 | - "bug"
12 | - title: "🧰 Maintenance"
13 | labels:
14 | - "chore"
15 | change-template: "- $TITLE @$AUTHOR (#$NUMBER)"
16 | template: |
17 | # What's changed (changelog)
18 | $CHANGES
19 |
20 | ## 👍 Thanks to
21 | $CONTRIBUTORS
22 |
--------------------------------------------------------------------------------
/.github/workflows/auto-approve.yml:
--------------------------------------------------------------------------------
1 | name: Auto approve
2 |
3 | on: [pull_request]
4 |
5 | jobs:
6 | auto-approve:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: hmarr/auto-approve-action@v2.0.0
10 | if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]'
11 | with:
12 | github-token: "${{ secrets.GITHUB_TOKEN }}"
13 |
--------------------------------------------------------------------------------
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
1 | name: Npm Publish
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | publish-npm:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v1
12 | - uses: actions/setup-node@v1
13 | with:
14 | node-version: 12
15 | - run: npm install
16 | - run: npm test
17 | - uses: JS-DevTools/npm-publish@v1
18 | with:
19 | token: ${{ secrets.NPM_TOKEN }}
20 |
--------------------------------------------------------------------------------
/.github/workflows/release-drafter.yml:
--------------------------------------------------------------------------------
1 | name: Release Drafter
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | update_release_draft:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: release-drafter/release-drafter@v5
13 | env:
14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Frontend Dist Files
2 | app/dist
3 |
4 | # Mac Files
5 | .DS_Store
6 | */DS_Store
7 |
8 | # Logs
9 | logs
10 | *.log
11 | npm-debug.log*
12 |
13 | # Runtime data
14 | pids
15 | *.pid
16 | *.seed
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 |
24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
25 | .grunt
26 |
27 | # node-waf configuration
28 | .lock-wscript
29 |
30 | # Compiled binary addons (http://nodejs.org/api/addons.html)
31 | build/Release
32 |
33 | # Dependency directory
34 | node_modules
35 |
36 | # Optional npm cache directory
37 | .npm
38 |
39 | # Optional REPL history
40 | .node_repl_history
41 |
42 | # Code coverage
43 | ./coverage
44 |
45 | # dotenv
46 | .env
47 |
48 | # VS Code
49 | .vscode/
50 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - "10.13.0"
5 |
6 | sudo: true
7 |
8 | env:
9 | - CXX=g++-4.8 NODE_ENV=testing
10 | addons:
11 | apt:
12 | sources:
13 | - ubuntu-toolchain-r-test
14 | packages:
15 | - g++-4.8
16 |
--------------------------------------------------------------------------------
/.woloxci/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:10.13.0
2 |
3 | WORKDIR /usr/src/app
4 |
5 | ENV NODE_ENV testing
6 |
7 | ENV HOME /usr/src/app
8 |
9 | ENV BABEL_DISABLE_CACHE 1
10 |
11 | RUN mkdir -p /install
12 |
13 | ENV NODE_PATH=/install/node_modules
14 |
15 | # Install app dependencies
16 | # A wildcard is used to ensure both package.json AND package-lock.json are copied
17 | # where available (npm@5+)
18 | COPY package*.json /install/
19 |
20 | WORKDIR /install
21 |
22 | RUN npm install
23 | RUN npm install -g gulp
24 | # If you are building your code for production
25 | # RUN npm install --only=production
26 |
27 | RUN chmod a+r /usr/src/app
28 |
29 | WORKDIR /usr/src/app
30 |
31 | # Bundle app source
32 | COPY . .
33 |
--------------------------------------------------------------------------------
/.woloxci/config.yml:
--------------------------------------------------------------------------------
1 | config:
2 | dockerfile: .woloxci/Dockerfile
3 | project_name: express-js-bootstrap
4 |
5 | steps:
6 | copy_node_modules:
7 | - cp -r $NODE_PATH/ ./
8 | lint:
9 | - npm run lint
10 | test:
11 | - npm run test
12 |
13 | environment:
14 | GIT_COMMITTER_NAME: a
15 | GIT_COMMITTER_EMAIL: b
16 | LANG: C.UTF-8
17 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | This project adheres to [Semantic Versioning](http://semver.org/).
4 |
5 | From version 2.0.0+ changelog is in https://github.com/Wolox/express-js-bootstrap/releases
6 |
7 | ## 2.0.0
8 |
9 | * Changelog added.
10 | * Add start-dev option and change behavior of npm start (#121)
11 | * Replace 'assignObject' method in configuration for an immutable alternative (#153).
12 | * Add the scrips to create the seeds in the template (#163).
13 | * Updated linters: eslint-config-wolox to 3.0.2 and eslint-config-wolox-node to 2.2.0 (#124).
14 | * Added documentation authentication. It was implemented using Token authentication (#123).
15 | * Added .env.example file (#123).
16 | * Fixed code coverage script (#184).
17 | * Update dependencies (#202)
18 | * Add cloudwatch monitor (#201)
19 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @node-bootstrap-devs
--------------------------------------------------------------------------------
/Jenkinsfile:
--------------------------------------------------------------------------------
1 | @Library('wolox-ci') _
2 |
3 | node {
4 |
5 | checkout scm
6 |
7 | woloxCi('.woloxci/config.yml');
8 | }
9 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 Wolox
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ExpressJS Bootstrap [](https://travis-ci.org/Wolox/express-js-bootstrap)
2 |
3 | Yeoman generator for [ExpressJS](expressjs.com) applications.
4 |
5 |

6 |
7 | ## Prerequisites
8 |
9 | - [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
10 | - [Node with npm](https://github.com/creationix/nvm#install-script)
11 | - [Yeoman](https://yeoman.io)
12 | - Install `npm install -g yo`
13 |
14 | ## Getting Started
15 |
16 | 1. Install `npm install -g generator-w-express-js`
17 | 2. Run `yo w-express-js`
18 | 3. Pick your options
19 |
20 | At the end, a folder will be created in the current path with your project files, also a branch called `kickoff` will be generated with a commit message `Kickoff project`.
21 |
22 | ## Running Local
23 |
24 | 1. Clone this repository
25 | 2. Move to root folder and run `npm link`
26 | 3. Run `yo w-express-js`
27 |
28 | (Note: Any local changes are automatically refreshed)
29 |
30 | ## Contributing
31 |
32 | 1. Fork it
33 | 2. Create your feature branch (`git checkout -b my-new-feature`)
34 | 3. Run the tests (`npm test`)
35 | 4. Commit your changes (`git commit -am 'Add some feature'`)
36 | 5. Push to the branch (`git push origin my-new-feature`)
37 | 6. Create new Pull Request
38 |
39 | ## About
40 |
41 | This project is maintained by [Wolox](https://github.com/wolox) and it was written by [Wolox](http://www.wolox.com.ar).
42 |
43 | 
44 |
45 | ## License
46 |
47 | **express-js-bootstrap** is available under the MIT [license](LICENSE.md).
48 |
49 | Copyright (c) 2020 Wolox
50 |
51 | Permission is hereby granted, free of charge, to any person obtaining a copy
52 | of this software and associated documentation files (the "Software"), to deal
53 | in the Software without restriction, including without limitation the rights
54 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55 | copies of the Software, and to permit persons to whom the Software is
56 | furnished to do so, subject to the following conditions:
57 |
58 | The above copyright notice and this permission notice shall be included in
59 | all copies or substantial portions of the Software.
60 |
61 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
64 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
65 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
66 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
67 | THE SOFTWARE.
68 |
--------------------------------------------------------------------------------
/generators/app/command.js:
--------------------------------------------------------------------------------
1 | const { spawn } = require('child_process');
2 | const ora = require('ora');
3 |
4 | exports.runCommand = ({ name, args, description = name, options = { verbose: false }, spawnOptions }) =>
5 | new Promise((resolve, reject) => {
6 | const command = spawn(name, args, spawnOptions);
7 | const spinner = ora(options.spinner || { text: description }).start();
8 | const result = [];
9 |
10 | const handleDataResponse = data => {
11 | const dataAsString = data.toString();
12 | result.push(dataAsString);
13 | if (options.verbose) {
14 | spinner.info(dataAsString);
15 | }
16 | };
17 |
18 | command.stdout.on('data', handleDataResponse);
19 | command.stderr.on('data', handleDataResponse);
20 |
21 | command.on('close', code => {
22 | if (code === 0) {
23 | spinner.succeed(options.successMessage);
24 | resolve(result);
25 | } else {
26 | spinner.fail(options.failMessage);
27 | reject(result);
28 | }
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/generators/app/constants.js:
--------------------------------------------------------------------------------
1 | const templatePackageJson = require('./dependencies/package.json');
2 |
3 | const { engines } = require('./dependencies/package.json');
4 |
5 | exports.NODE_DEFAULT_VERSION = engines.node;
6 | exports.NPM_DEFAULT_VERSION = engines.npm;
7 | exports.ORM_OPTIONS = ['sequelize', 'mongoose'];
8 | exports.SEQUELIZE_DEFAULT_VERSION = templatePackageJson.dependencies.sequelize;
9 | exports.SEQUELIZE_DEFAULT_DIALECT = 'postgres';
10 | exports.SEQUELIZE_DIALECTS = ['mysql', 'sqlite', 'postgres', 'mssql'];
11 | exports.MONGOOSE_DEFAULT_VERSION = templatePackageJson.dependencies.mongoose;
12 | exports.MONGOOSE_DEFAULT_DIALECT = 'mongoDB';
13 | exports.MONGOOSE_DIALECTS = ['mongoDB'];
14 | exports.DEPLOY_STRATEGIES = ['aws', 'heroku'];
15 | exports.OPTIONALS_FEATURES = ['coveralls', 'rollbar', 'cors', 'helmet'];
16 | exports.CI_OPTIONS = ['jenkins', 'travis'];
17 | exports.TESTING_OPTIONS = ['jest-supertest', 'mocha-chai'];
18 |
19 | exports.TRAINING_CONFIG = {
20 | projectName: 'w-training',
21 | projectDescription: 'w-training',
22 | nodeVersion: exports.NODE_DEFAULT_VERSION,
23 | npmVersion: exports.NPM_DEFAULT_VERSION,
24 | documentationRequiresAuth: false,
25 | database: true,
26 | orm: { sequelize: true },
27 | sequelizeVersion: exports.SEQUELIZE_DEFAULT_VERSION,
28 | sequelizeDialect: exports.SEQUELIZE_DEFAULT_DIALECT,
29 | deployStrategy: { heroku: true },
30 | optionalsFeatures: {},
31 | ci: 'travis',
32 | testing: 'jest-supertest'
33 | };
34 |
35 | // eslint-disable-next-line
36 | exports.URL_REGEX = /(?:git|ssh|https?|git@[-\w.]+):(\/\/)?(.*?)(\.git)?(\/?|\#[-\d\w._]+?)$/;
37 | exports.VERSION_REGEX = /[0-9]+.[0-9]+.[0-9]+/;
38 | exports.APP_NAME_REGEX = /^[\w-]+$/;
39 |
40 | exports.TUTORIALS = {
41 | GIT: 'https://git-scm.com/book/en/v2/Getting-Started-Installing-Git',
42 | NPM: 'https://github.com/creationix/nvm#install-script'
43 | };
44 |
45 | exports.files = [
46 | {
47 | name: 'Jenkinsfile',
48 | condition: answers => answers.ci === 'jenkins'
49 | },
50 | {
51 | directory: '.woloxci',
52 | name: 'config.yml',
53 | condition: answers => answers.ci === 'jenkins'
54 | },
55 | {
56 | directory: '.woloxci',
57 | name: 'Dockerfile',
58 | condition: answers => answers.ci === 'jenkins'
59 | },
60 | {
61 | name: 'Procfile',
62 | condition: answers => answers.deployStrategy.heroku
63 | },
64 | {
65 | name: 'Dockerfile',
66 | condition: answers => answers.docker
67 | },
68 | {
69 | name: 'Dockerrun.aws.json',
70 | condition: answers => answers.docker && answers.deployStrategy.aws
71 | },
72 | {
73 | name: '.travis.yml',
74 | condition: answers => answers.ci === 'travis'
75 | },
76 | {
77 | name: '.sequelizerc',
78 | condition: answers => answers.orm && answers.orm.sequelize
79 | },
80 | {
81 | directory: 'migrations',
82 | name: 'index.js',
83 | condition: answers => answers.orm && answers.orm.sequelize
84 | },
85 | {
86 | directory: 'migrations/migrations',
87 | name: '.keep',
88 | condition: answers => answers.orm && answers.orm.sequelize
89 | },
90 | {
91 | directory: 'config',
92 | name: 'db.ejs',
93 | condition: answers => answers.orm && (answers.orm.sequelize || answers.orm.mongoose)
94 | },
95 | {
96 | directory: 'app/models',
97 | name: 'index.js',
98 | condition: answers => answers.orm && answers.orm.sequelize
99 | },
100 | {
101 | directory: 'test/factory',
102 | name: 'factory_by_models.ejs',
103 | condition: answers => answers.orm && answers.orm.sequelize && answers.testing === 'jest-supertest'
104 | },
105 | {
106 | directory: 'app/middlewares',
107 | name: 'docsAuth.ejs',
108 | condition: answers => answers.documentationRequiresAuth
109 | },
110 | {
111 | directory: 'test',
112 | name: 'setup.js',
113 | condition: answers => answers.orm && answers.orm.sequelize && answers.testing === 'jest-supertest'
114 | },
115 | {
116 | directory: 'test',
117 | name: 'app.spec.ejs',
118 | condition: answers => answers.testing === 'mocha-chai'
119 | },
120 | {
121 | directory: '.ebextensions',
122 | name: 'cloudwatch.config',
123 | condition: answers => answers.deployStrategy.aws
124 | },
125 | {
126 | name: 'README.md'
127 | },
128 | {
129 | name: 'pull_request_template.md'
130 | },
131 | {
132 | name: 'package.json'
133 | },
134 | {
135 | name: 'LICENSE.md'
136 | },
137 | {
138 | name: 'console.ejs'
139 | },
140 | {
141 | name: 'app.ejs'
142 | },
143 | {
144 | name: 'server.ejs'
145 | },
146 | {
147 | directory: 'documentation',
148 | name: 'index.js'
149 | },
150 | {
151 | directory: 'documentation/schemas',
152 | name: 'index.js'
153 | },
154 | {
155 | directory: 'documentation/schemas',
156 | name: 'user.js'
157 | },
158 | {
159 | directory: 'documentation/paths',
160 | name: 'index.js'
161 | },
162 | {
163 | directory: 'documentation/paths',
164 | name: 'user.js'
165 | },
166 | {
167 | name: '.nvmrc'
168 | },
169 | {
170 | name: 'gitignore',
171 | newName: '.gitignore'
172 | },
173 | {
174 | name: '.eslintrc.js'
175 | },
176 | {
177 | name: '.eslintignore'
178 | },
179 | {
180 | name: '.env.example'
181 | },
182 | {
183 | directory: 'config',
184 | name: 'development.ejs'
185 | },
186 | {
187 | directory: 'config',
188 | name: 'production.ejs'
189 | },
190 | {
191 | directory: 'config',
192 | name: 'testing.ejs'
193 | },
194 | {
195 | directory: 'config',
196 | name: 'index.ejs'
197 | },
198 | {
199 | directory: 'app/controllers',
200 | name: 'healthCheck.js'
201 | },
202 | {
203 | directory: 'app/services',
204 | name: '.keep'
205 | },
206 | {
207 | directory: 'app',
208 | name: 'errors.js'
209 | },
210 | {
211 | directory: 'app',
212 | name: 'routes.js'
213 | },
214 | {
215 | directory: 'app/middlewares',
216 | name: 'errors.js'
217 | },
218 | {
219 | directory: 'app/logger',
220 | name: 'index.js'
221 | },
222 | {
223 | directory: 'app/middlewares',
224 | name: 'apiInfo.js'
225 | }
226 | ];
227 |
--------------------------------------------------------------------------------
/generators/app/dependencies/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Fake",
3 | "version": "0.1.0",
4 | "description": "Fake package json used for keep updated version of packages",
5 | "cacheDirectories": [
6 | "node_modules"
7 | ],
8 | "engines": {
9 | "node": "14.17.0",
10 | "npm": "6.14.13"
11 | },
12 | "main": "app.js",
13 | "author": "Wolox",
14 | "homepage": "",
15 | "license": "MIT",
16 | "repository": {
17 | "type": "git",
18 | "url": ""
19 | },
20 | "bugs": {
21 | "url": "",
22 | "email": "tls@wolox.com.ar"
23 | },
24 | "dependencies": {
25 | "axios": "^0.24.0",
26 | "bcryptjs": "^2.4.3",
27 | "body-parser": "^1.19.0",
28 | "cors": "^2.8.5",
29 | "express": "^4.17.1",
30 | "express-wolox-logger": "^2.0.0",
31 | "factory-girl": "^5.0.4",
32 | "helmet": "^4.6.0",
33 | "jwt-simple": "^0.5.6",
34 | "mongodb": "^4.1.3",
35 | "mongoose": "^6.0.12",
36 | "mysql2": "^2.3.2",
37 | "pg": "^8.7.1",
38 | "rollbar": "^2.24.0",
39 | "sequelize": "^6.8.0",
40 | "sqlite3": "^5.0.2",
41 | "swagger-ui-express": "^4.1.6",
42 | "tedious": "^14.0.0",
43 | "umzug": "^2.3.0"
44 | },
45 | "devDependencies": {
46 | "babel": "6.23.0",
47 | "babel-core": "^6.26.3",
48 | "babel-eslint": "^10.1.0",
49 | "babel-jest": "^27.3.1",
50 | "babel-preset-es2015": "6.24.1",
51 | "chai": "^4.3.4",
52 | "chai-http": "^4.3.0",
53 | "coveralls": "^3.1.1",
54 | "dotenv": "^10.0.0",
55 | "eslint": "^6.8.0",
56 | "eslint-config-wolox": "^4.0.0",
57 | "eslint-config-wolox-node": "^3.0.0",
58 | "eslint-plugin-import": "^2.25.2",
59 | "eslint-plugin-prettier": "^3.0.1",
60 | "husky": "^7.0.4",
61 | "istanbul": "^0.4.3",
62 | "jest": "^27.3.1",
63 | "mocha": "^9.1.3",
64 | "mocha-lcov-reporter": "^1.3.0",
65 | "nodemon": "^2.0.14",
66 | "prettier": "^1.15.3",
67 | "prettier-eslint": "^9.0.1",
68 | "prompt": "^1.2.0",
69 | "sequelize-cli": "^6.2.0",
70 | "supertest": "^6.1.6"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/generators/app/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-underscore-dangle */
2 | const Generator = require('yeoman-generator');
3 | const cfonts = require('cfonts');
4 | const terminalLink = require('terminal-link');
5 | const { camelCase } = require('camel-case');
6 | const { TRAINING_CONFIG, files, TUTORIALS } = require('./constants');
7 | const { runCommand } = require('./command');
8 | const prompts = require('./prompts');
9 | const packageJsonTemplate = require('./dependencies/package.json');
10 |
11 | const getDependenciesVersions = () => {
12 | const appendVersion = dependencies =>
13 | Object.keys(dependencies).reduce((mappedDependencies, dependency) => {
14 | mappedDependencies[`${camelCase(dependency)}Version`] = dependencies[dependency];
15 | return mappedDependencies;
16 | }, {});
17 | const dependencies = {
18 | ...appendVersion(packageJsonTemplate.dependencies),
19 | ...appendVersion(packageJsonTemplate.devDependencies)
20 | };
21 | return dependencies;
22 | };
23 |
24 | const nodeGenerator = class extends Generator {
25 | constructor(args, opts) {
26 | super(args, opts);
27 | this.option('verbose');
28 | }
29 |
30 | _checkInstalled(name, link, command) {
31 | return this._runCommand({
32 | description: `Checking if ${name} is installed`,
33 | name: command || name,
34 | args: ['--version'],
35 | options: {
36 | failMessage: `${name} is required to run this generator, check ${terminalLink('this', link)}`
37 | }
38 | });
39 | }
40 |
41 | async initializing() {
42 | try {
43 | cfonts.say('NODE JS|KICKOFF', {
44 | font: 'block',
45 | align: 'center',
46 | colors: ['green', 'green'],
47 | background: 'transparent',
48 | letterSpacing: 1,
49 | lineHeight: 1,
50 | space: true,
51 | maxLength: '0'
52 | });
53 |
54 | await this._checkInstalled('git', TUTORIALS.GIT);
55 | await this._checkInstalled('npm', TUTORIALS.NPM);
56 | } catch (e) {
57 | this.env.error(e);
58 | }
59 | }
60 |
61 | async prompting() {
62 | this.answers = await this.prompt(prompts);
63 | this.useGit = this.answers.urlRepository !== '';
64 |
65 | if (this.answers.inTraining) {
66 | this.answers = { ...this.answers, ...TRAINING_CONFIG };
67 | }
68 | }
69 |
70 | _destinationPath(fileName) {
71 | return this.destinationPath(`${this.answers.projectName}/${fileName}`);
72 | }
73 |
74 | _copyTplPromise(templatePath, filePath, options) {
75 | return new Promise((resolve, reject) => {
76 | try {
77 | this.fs.copyTpl(this.templatePath(templatePath), this._destinationPath(filePath), options);
78 | resolve();
79 | } catch (err) {
80 | reject(err);
81 | }
82 | });
83 | }
84 |
85 | _runCommand(params) {
86 | if (!params.options || params.options.verbose === undefined) {
87 | params.options = { ...params.options, verbose: this.options.verbose };
88 | }
89 | return runCommand(params);
90 | }
91 |
92 | async _copyTemplate(file) {
93 | const newName = file.name.endsWith('.ejs')
94 | ? `${file.name.substr(0, file.name.lastIndexOf('.'))}.js`
95 | : file.newName || file.name;
96 | const filePath = file.directory ? `${file.directory}/${newName}` : newName;
97 | const templatePath = file.directory ? `${file.directory}/${file.name}` : file.name;
98 | const options =
99 | newName === 'package.json' ? { ...getDependenciesVersions(), ...this.answers } : this.answers;
100 | await this._copyTplPromise(templatePath, filePath, options);
101 | }
102 |
103 | async writing() {
104 | try {
105 | if (this.useGit) {
106 | await this._runCommand({
107 | description: `Cloning repository from ${this.answers.urlRepository}`,
108 | name: 'git',
109 | args: ['clone', this.answers.urlRepository, this.answers.projectName]
110 | });
111 | }
112 |
113 | files
114 | .filter(file => !file.condition || file.condition(this.answers))
115 | .map(file => this._copyTemplate(file));
116 | } catch (e) {
117 | this.env.error(e);
118 | }
119 | }
120 |
121 | async install() {
122 | try {
123 | const spawnOptions = { cwd: this.destinationPath(this.answers.projectName) };
124 | await this._runCommand({
125 | description: 'Installing dependencies',
126 | name: 'npm',
127 | args: ['install'],
128 | spawnOptions
129 | });
130 | await this._runCommand({
131 | description: 'Running linter',
132 | name: 'npm',
133 | args: ['run', 'lint-fix'],
134 | spawnOptions
135 | });
136 | if (this.useGit) {
137 | await this._runCommand({
138 | description: 'Creating branch kickoff',
139 | name: 'git',
140 | args: ['checkout', '-b', 'kickoff'],
141 | spawnOptions
142 | });
143 | await this._runCommand({
144 | description: 'Add changes to git',
145 | name: 'git',
146 | args: ['add', '.'],
147 | spawnOptions
148 | });
149 | await this._runCommand({
150 | description: 'Commit changes to git',
151 | name: 'git',
152 | args: ['commit', '-m', 'Kickoff project'],
153 | spawnOptions
154 | });
155 | }
156 | } catch (e) {
157 | this.env.error(e);
158 | }
159 | }
160 | };
161 |
162 | module.exports = nodeGenerator;
163 |
--------------------------------------------------------------------------------
/generators/app/prompts.js:
--------------------------------------------------------------------------------
1 | const {
2 | checkboxReducer,
3 | flattenPrompts,
4 | validateUrl,
5 | validateVersionNumber,
6 | validateAppName
7 | } = require('./utils');
8 | const {
9 | NODE_DEFAULT_VERSION,
10 | NPM_DEFAULT_VERSION,
11 | ORM_OPTIONS,
12 | SEQUELIZE_DEFAULT_VERSION,
13 | SEQUELIZE_DEFAULT_DIALECT,
14 | SEQUELIZE_DIALECTS,
15 | MONGOOSE_DEFAULT_VERSION,
16 | MONGOOSE_DEFAULT_DIALECT,
17 | MONGOOSE_DIALECTS,
18 | DEPLOY_STRATEGIES,
19 | OPTIONALS_FEATURES,
20 | CI_OPTIONS,
21 | TESTING_OPTIONS
22 | } = require('./constants');
23 |
24 | module.exports = flattenPrompts([
25 | {
26 | type: 'input',
27 | name: 'urlRepository',
28 | message: 'Enter git repository for this project',
29 | validate: validateUrl
30 | },
31 | {
32 | type: 'confirm',
33 | name: 'inTraining',
34 | message: 'Are you in w-training ?',
35 | promptsNegative: [
36 | {
37 | type: 'input',
38 | name: 'projectName',
39 | message: 'Enter Project Name',
40 | validate: validateAppName
41 | },
42 | {
43 | type: 'input',
44 | name: 'projectDescription',
45 | message: 'Enter Project Description',
46 | default: ({ projectName }) => projectName,
47 | validate: value => value.trim().length !== 0 || 'Please enter a valid description'
48 | },
49 | {
50 | type: 'input',
51 | name: 'nodeVersion',
52 | message: 'Enter NodeJS Version',
53 | default: NODE_DEFAULT_VERSION,
54 | validate: validateVersionNumber
55 | },
56 | {
57 | type: 'input',
58 | name: 'npmVersion',
59 | message: 'Enter NPM Version',
60 | default: NPM_DEFAULT_VERSION,
61 | validate: validateVersionNumber
62 | },
63 | {
64 | type: 'confirm',
65 | name: 'documentationRequiresAuth',
66 | message: 'Would you like the documentation to require authentication?',
67 | default: false
68 | },
69 | {
70 | type: 'confirm',
71 | name: 'database',
72 | message: 'Will you use a database?',
73 | promptsPositive: [
74 | {
75 | type: 'checkbox',
76 | name: 'orm',
77 | message: 'Select the ORM for your project',
78 | filter: checkboxReducer,
79 | choices: ORM_OPTIONS,
80 | chosen: [
81 | {
82 | condition: 'sequelize',
83 | prompts: [
84 | {
85 | type: 'input',
86 | name: 'sequelizeVersion',
87 | message: 'Enter Sequelize Version',
88 | default: SEQUELIZE_DEFAULT_VERSION,
89 | validate: validateVersionNumber
90 | },
91 | {
92 | type: 'list',
93 | name: 'sequelizeDialect',
94 | message: 'Enter Database Dialect',
95 | default: SEQUELIZE_DEFAULT_DIALECT,
96 | choices: SEQUELIZE_DIALECTS
97 | }
98 | ]
99 | },
100 | {
101 | condition: 'mongoose',
102 | prompts: [
103 | {
104 | type: 'input',
105 | name: 'mongooseVersion',
106 | message: 'Enter Mongoose Version',
107 | default: MONGOOSE_DEFAULT_VERSION,
108 | validate: validateVersionNumber
109 | },
110 | {
111 | type: 'list',
112 | name: 'mongooseDialect',
113 | message: 'Enter Database Dialect',
114 | default: MONGOOSE_DEFAULT_DIALECT,
115 | choices: MONGOOSE_DIALECTS
116 | }
117 | ]
118 | }
119 | ]
120 | }
121 | ]
122 | },
123 | {
124 | type: 'checkbox',
125 | name: 'deployStrategy',
126 | message: 'Select Deploy strategy for your project',
127 | filter: checkboxReducer,
128 | choices: DEPLOY_STRATEGIES
129 | },
130 | {
131 | type: 'confirm',
132 | name: 'docker',
133 | message: 'Are you going to use docker for the deploy?'
134 | },
135 | {
136 | type: 'checkbox',
137 | name: 'optionalsFeatures',
138 | message: 'Choose optionals features for your project',
139 | filter: checkboxReducer,
140 | choices: OPTIONALS_FEATURES
141 | },
142 | {
143 | type: 'list',
144 | name: 'ci',
145 | message: 'Choose CI for your project',
146 | choices: CI_OPTIONS
147 | },
148 | {
149 | type: 'list',
150 | name: 'testing',
151 | message: 'Choose your testing option',
152 | choices: TESTING_OPTIONS
153 | }
154 | ]
155 | }
156 | ]);
157 |
--------------------------------------------------------------------------------
/generators/app/templates/.ebextensions/cloudwatch.config:
--------------------------------------------------------------------------------
1 | packages:
2 | yum:
3 | perl-DateTime: []
4 | perl-Sys-Syslog: []
5 | perl-LWP-Protocol-https: []
6 | perl-Switch: []
7 | perl-URI: []
8 | perl-Bundle-LWP: []
9 | sources:
10 | /opt/cloudwatch: https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.1.zip
11 |
12 | container_commands:
13 | 01-setupcron:
14 | command: |
15 | echo '*/5 * * * * root perl /opt/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl `{"Fn::GetOptionSetting" : { "OptionName" : "CloudWatchMetrics", "DefaultValue" : "--mem-util --disk-space-util --disk-path=/" }}` >> /var/log/cwpump.log 2>&1' > /etc/cron.d/cwpump
16 | 02-changeperm:
17 | command: chmod 644 /etc/cron.d/cwpump
18 | 03-changeperm:
19 | command: chmod u+x /opt/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl
20 | option_settings:
21 | "aws:autoscaling:launchconfiguration" :
22 | IamInstanceProfile : "aws-elasticbeanstalk-ec2-role"
23 | "aws:elasticbeanstalk:customoption" :
24 | CloudWatchMetrics : "--mem-util --mem-used --mem-avail --disk-space-util --disk-space-used --disk-space-avail --disk-path=/ --auto-scaling"
25 |
--------------------------------------------------------------------------------
/generators/app/templates/.env.example:
--------------------------------------------------------------------------------
1 | PORT=8081
2 |
3 | DB_HOST=localhost
4 | DB_PORT=5432
5 | DB_USERNAME=set_your_db_username
6 | DB_PASSWORD=set_your_db_password
7 | DB_NAME=db_<%=projectName%>
8 | DB_NAME_DEV=db_<%=projectName%>_dev
9 | DB_NAME_TEST=db_<%=projectName%>_test
10 | API_DATE=X-API-Date
11 | PACKAGE_VERSION=X-Package-Version
12 | NODE_VERSION=X-Node-Version
13 |
14 | #API_BODY_SIZE_LIMIT
15 | #API_PARAMETER_LIMIT
16 |
17 | NODE_ENV = development
18 |
19 | <% if(optionalsFeatures.rollbar) {%>ROLLBAR_ACCESS_TOKEN=
20 | ROLLBAR_ENV=<%}%>
21 |
22 | <% if(documentationRequiresAuth) {%>DOCUMENTATION_TOKEN=
23 | DOCUMENTATION_TOKEN_HEADER=<%}%>
24 |
--------------------------------------------------------------------------------
/generators/app/templates/.eslintignore:
--------------------------------------------------------------------------------
1 | app/dist
2 |
--------------------------------------------------------------------------------
/generators/app/templates/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('eslint-config-wolox-node');
2 |
--------------------------------------------------------------------------------
/generators/app/templates/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🐛 Bug Report
3 | about: Create a report to bug fixing
4 | title: 🐛 Bug Report
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## 🐛 Bug Report
11 |
12 | A clear and concise description of what the bug is.
13 |
14 | ## Steps to Reproduce
15 |
16 | Steps to reproduce the behavior:
17 |
18 | ## Expected behavior
19 |
20 | A clear and concise description of what you expected to happen.
21 |
--------------------------------------------------------------------------------
/generators/app/templates/.github/ISSUE_TEMPLATE/feature_proposal.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🚀 Feature Proposal
3 | about: Submit a proposal for a new feature
4 | title: 🚀 Feature Proposal
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## 🚀 Feature Proposal
11 |
12 | A clear and concise description of what the feature is.
13 |
14 | ## Motivation
15 |
16 | Please outline the motivation for the proposal.
17 |
18 | ## Example
19 |
20 | Please provide an example for how this feature would be used.
21 |
22 | ## Pitch
23 |
24 | Why does this feature should be implemented?
25 |
--------------------------------------------------------------------------------
/generators/app/templates/.nvmrc:
--------------------------------------------------------------------------------
1 | <%= nodeVersion %>
--------------------------------------------------------------------------------
/generators/app/templates/.sequelizerc:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = {
4 | 'config': path.resolve('config', 'db.js'),
5 | 'migrations-path': path.resolve('migrations', 'migrations'),
6 | 'models-path': path.resolve('app', 'models')
7 | };
8 |
--------------------------------------------------------------------------------
/generators/app/templates/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - "<%= nodeVersion %>"
5 |
6 | sudo: true
7 |
8 | env:
9 | - CXX=g++-4.8 NODE_ENV=testing
10 | addons:
11 | apt:
12 | sources:
13 | - ubuntu-toolchain-r-test
14 | packages:
15 | - g++-4.8
16 | <% if(database && orm.sequelize) {%>
17 | services:
18 | - postgresql
19 |
20 | before_script:
21 | - psql -c "CREATE DATABASE bookstest;" -U postgres
22 | - npm run migrations-test
23 | <%}%>
--------------------------------------------------------------------------------
/generators/app/templates/.woloxci/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:<%= nodeVersion %>
2 |
3 | WORKDIR /usr/src/app
4 |
5 | ENV NODE_ENV testing
6 |
7 | ENV HOME /usr/src/app
8 |
9 | ENV BABEL_DISABLE_CACHE 1
10 |
11 | RUN mkdir -p /install
12 |
13 | ENV NODE_PATH=/install/node_modules
14 |
15 | # Install app dependencies
16 | # A wildcard is used to ensure both package.json AND package-lock.json are copied
17 | # where available (npm@5+)
18 | COPY package*.json /install/
19 |
20 | WORKDIR /install
21 |
22 | RUN npm install
23 | RUN npm install -g gulp
24 | # If you are building your code for production
25 | # RUN npm install --only=production
26 |
27 | RUN chmod a+r /usr/src/app
28 |
29 | WORKDIR /usr/src/app
30 |
31 | # Bundle app source
32 | COPY . .
33 |
--------------------------------------------------------------------------------
/generators/app/templates/.woloxci/config.yml:
--------------------------------------------------------------------------------
1 | config:
2 | dockerfile: .woloxci/Dockerfile
3 | project_name: <%= projectName %>
4 | <% if(database && orm.sequelize) {%>
5 | services:
6 | - <%= sequelizeDialect %>
7 | <%}%>
8 | steps:
9 | copy_node_modules:
10 | - cp -r $NODE_PATH/ ./<% if(database && orm.sequelize) {%>
11 | migrate_db:
12 | - node_modules/.bin/sequelize db:migrate<%}%>
13 | lint:
14 | - npm run lint
15 | test:
16 | - npm run test
17 |
18 | environment:
19 | GIT_COMMITTER_NAME: a
20 | GIT_COMMITTER_EMAIL: b
21 | LANG: C.UTF-8
22 |
--------------------------------------------------------------------------------
/generators/app/templates/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | This project adheres to [Semantic Versioning](http://semver.org/).
4 |
5 | ## 0.1.0
6 |
7 | * First version.
8 |
--------------------------------------------------------------------------------
/generators/app/templates/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:<%= nodeVersion %>
2 |
3 | WORKDIR /home/node/app
4 |
5 | COPY package.json .
6 | COPY package-lock.json .
7 | COPY .nvmrc .
8 |
9 | RUN npm install
10 |
11 | COPY . .
12 |
13 | EXPOSE 8080
14 | ENV NODE_ENV production
15 | CMD ["node", "server.js"]
16 |
--------------------------------------------------------------------------------
/generators/app/templates/Dockerrun.aws.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSEBDockerrunVersion": "1",
3 | "Ports": [
4 | {
5 | "ContainerPort": "8080"
6 | }
7 | ],
8 | "Volumes": [],
9 | "Logging": "/home/node/app/app/logger/logs"
10 | }
11 |
--------------------------------------------------------------------------------
/generators/app/templates/Jenkinsfile:
--------------------------------------------------------------------------------
1 | @Library('wolox-ci') _
2 |
3 | node {
4 |
5 | checkout scm
6 |
7 | woloxCi('.woloxci/config.yml');
8 | }
9 |
--------------------------------------------------------------------------------
/generators/app/templates/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 Wolox
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 |
--------------------------------------------------------------------------------
/generators/app/templates/Procfile:
--------------------------------------------------------------------------------
1 | web: node server.js
2 |
--------------------------------------------------------------------------------
/generators/app/templates/README.md:
--------------------------------------------------------------------------------
1 | # <%= projectName %>
2 |
3 | <%= projectDescription %>
4 |
5 | ## First steps
6 |
7 | #### Installing node
8 |
9 | Get the latest version of node from the [official website](https://nodejs.org/) or using [nvm](https://github.com/creationix/nvm)
10 | Nvm approach is preferred.
11 |
12 | #### Getting dependencies
13 |
14 | Run `npm install` or `yarn` from rootpath of the project.
15 | <% if(database && orm.sequelize) {%>
16 |
17 | #### Database configuration
18 |
19 | Before running the app, make sure you have [postgresql installed](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-14-04) and a db created, to create it run the following steps inside a psql terminal:
20 |
21 | 1. CREATE DATABASE db_project_name;
22 | 2. \c db_project_name
23 | 3. CREATE ROLE "project_name" LOGIN CREATEDB PASSWORD 'project_name';
24 |
25 | Then, set in `.env` some variables:
26 |
27 | - DB_HOST=localhost
28 | - DB_PORT=5432
29 | - DB_USERNAME=project_name
30 | - DB_PASSWORD=project_name
31 | - DB_NAME=db_project_name
32 | - DB_NAME_DEV=db_project_name_dev
33 | - DB_NAME_TEST=db_project_name_test
34 | - API_DATE=X-API-Date
35 | - PACKAGE_VERSION=X-Package-Version
36 | - NODE_VERSION=X-Node-Version
37 |
38 | ### Migrations
39 |
40 | To create a migration, run `./node_modules/.bin/sequelize migration:create --name="my-migration-name" --config ./migrations/config.js --migrations-path ./migrations/migrations`.
41 |
42 | To run them, execute `npm run migrations`.
43 | <%}%><% if(database && orm.mongoose) {%>
44 | #### Database configuration
45 |
46 | Before running the app, make sure you have [mongoDB installed](https://hevodata.com/blog/install-mongodb-on-ubuntu/) and a db created, to create it run the following steps inside a terminal:
47 |
48 | 1. mongo
49 | 2. use db_project_name
50 | 3. db.createUser({user:"root", pwd:"superpass", roles:[{role:"root", db:"db_project_name"}]})
51 | 4. *exit from mongo*
52 | 5. mongo -u root -p superpass --authenticationDatabase db_project_name
53 |
54 | Then, set in `.env` some variables:
55 |
56 | - DB_HOST=localhost
57 | - DB_PORT=5432
58 | - DB_USERNAME=project_name
59 | - DB_PASSWORD=project_name
60 | - DB_NAME=db_project_name
61 | - DB_NAME_DEV=db_project_name_dev
62 | - DB_NAME_TEST=db_project_name_test
63 | - API_DATE=X-API-Date
64 | - PACKAGE_VERSION=X-Package-Version
65 | - NODE_VERSION=X-Node-Version
66 | <%}%>
67 |
68 | #### Starting your app
69 |
70 | Now, we have two ways to start an app. To start your app in production mode run `npm start` in the root path of your project. To start your app in development mode (nodemon) run `npm run start-dev`. Then access your app at **localhost:port**. The port is logged in the console where you ran the start script.
71 |
72 | ## Development
73 |
74 | #### Environments
75 |
76 | By default, the environment will be **development**, but you can easily change it using the **NODE_ENV** environmental variable.
77 |
78 | #### Environment variables
79 |
80 | `Dotenv` is used for managing environment variables. They are stored in the `/.env` file. Take into account that the variables defined in the `bashrc` are not overrided.
81 |
82 | The environment variables should be added to the `.env` file in the form of `NAME=VALUE`, as the following example:
83 |
84 | ```
85 | DB_USERNAME=root
86 | DB_PASS=superpass
87 | DB_PASSWORD=superpass
88 | PORT=8081
89 | CLIENTS_API=http://api.clients.example.org/
90 | ```
91 |
92 | **Remember not to push nor commit the `.env` file.**
93 |
94 | #### Logging
95 |
96 | To log useful information of your program to the console you just need to import the logger located at `app/logger`. There are two possible types of logging: `info` and `error`. You should use them depending on the type of message you want to show.
97 |
98 | Here is an example snippet:
99 |
100 | ```
101 | const logger = require('/app/logger');
102 | ...
103 | if (error) {
104 | logger.error('There is an error);
105 | } else {
106 | logger.info('There is no error);
107 | }
108 | ```
109 |
110 | #### Testing
111 |
112 | To run your tests you first need to config your testing database by setting the env var `DB_NAME_TEST`. as explained
113 | before in [Database configuration](#database-configuration). Also you need to run the migrations in this exclusive
114 | testing database each time you have new ones, you can do this by running the command `npm run migrations-test`.
115 | Once you have all the above done you can run your tests with the following command: `npm test`. For more information refeer to the documentation of <% if(testing === 'mocha-chai') {%>[Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/).<%}%><% if(testing === 'jest-supertest') {%>[Jest](https://jestjs.io/docs/en/getting-started).<%}%>
116 | <% if(database && orm.sequelize && testing === 'jest-supertest') {%>
117 | #### Factory Girl
118 |
119 | To simplify your tests, you can call the `factoryByModel('nameOfModel')` function in `factory_by_models.js` on your code, then, `factory.build('nameOfModel')` and it will define a json object with the attributes form the model you've passed as parameter taking random values. If you want to acceed to the object created, the values created will be on its `dataValues` field.
120 | Remember that you have to create a model before, and the `nameOfModel` will be the one you will have on the database (which is the first parameter on `sequelize.define()`).
121 |
122 | Factory By Models have also two additional functions, `factoryAllModels()` and `factoryWithPredeterminatedValue('nameOfModel', 'nameOfAttribute', 'value')`. The first one will define factories for ALL the models you have, so you don't have to worry to declare a factory every time you want to build another. The second one, maybe you have a customized attribute in your model, or with some values we don't know. So you may use it, you will have to pass the name of the model, the attribute name and the value you want it to have.
123 |
124 | Also, it takes values predefined in the `type` field (Sequelize Datatype) and the validations you have in your MODEL (`validate` field),so if you want to validate those values on middlewares or somewhere else, factoryByModel won't take this in count. We strongly recommend to check if those validations cover the cases you expect, and if it doesn't, you can add your own code on this file (or just define a new factory).
125 | <%}%>
126 |
127 | #### Debugging
128 |
129 | As we know, a NodeJS application is not something easy to debug and because of that we've added the `--inspect` flag to make it simpler. You can download a node inspection manager for Chrome, so Chrome DevTools will automatically start when you run your app using `npm run start-dev`, making your debugging easier. You can read more about the different inspector clients here:
130 |
131 | #### REPL console
132 |
133 | We can use a node console with `npm run console`. There your service objects are exposed as _servicename_ + "Service". Let's suppose that we have a service `users` which has a function `getAll`. In your console you can call `usersService.getAll()` and see the result. Note that this works also with functions that return promises! To exit the console use `.exit`.
134 |
135 | #### Documentation
136 |
137 | Documentation will be served at `/docs`. We use [OpenAPI](https://github.com/OAI/OpenAPI-Specification) A.K.A `Swagger`. Check [this link](https://medium.com/wolox-driving-innovation/documenting-a-nodejs-rest-api-with-openapi-3-swagger-5deee9f50420) for more details on how to use it.
138 |
139 | ## Deploy
140 |
141 | #### Heroku
142 |
143 | Pushing the desired branch to heroku should be enough.
144 | For more information check: https://devcenter.heroku.com/articles/getting-started-with-nodejs#define-a-procfile.
145 |
146 | ## Contributing
147 |
148 | 1. Fork it
149 | 2. Create your feature branch (`git checkout -b my-new-feature`)
150 | 3. Run the tests (`npm test`)
151 | 4. Commit your changes (`git commit -am 'Add some feature'`)
152 | 5. Push to the branch (`git push origin my-new-feature`)
153 | 6. Create new Pull Request
154 |
155 | ## About
156 |
157 | This project is maintained by [Wolox](https://github.com/wolox) and it was written by [Wolox](http://www.wolox.com.ar).
158 |
159 | 
160 |
161 | ## License
162 |
163 | **<%= projectName %>** is available under the MIT [license](LICENSE.md).
164 |
165 | Copyright (c) 2019 Wolox
166 |
167 | Permission is hereby granted, free of charge, to any person obtaining a copy
168 | of this software and associated documentation files (the "Software"), to deal
169 | in the Software without restriction, including without limitation the rights
170 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
171 | copies of the Software, and to permit persons to whom the Software is
172 | furnished to do so, subject to the following conditions:
173 |
174 | The above copyright notice and this permission notice shall be included in
175 | all copies or substantial portions of the Software.
176 |
177 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
179 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
180 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
181 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
182 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
183 | THE SOFTWARE.
184 |
--------------------------------------------------------------------------------
/generators/app/templates/app.ejs:
--------------------------------------------------------------------------------
1 | const { expressMiddleware, expressRequestIdMiddleware } = require('express-wolox-logger');
2 | const express = require('express');
3 | const bodyParser = require('body-parser');
4 | const swaggerUi = require('swagger-ui-express');<% if(optionalsFeatures.cors) {%>
5 | const cors = require('cors');<%}%><% if(optionalsFeatures.helmet) {%>
6 | const helmet = require('helmet');<%}%>
7 | const config = require('./config');
8 | const routes = require('./app/routes');
9 | const errors = require('./app/middlewares/errors');
10 | const documentation = require('./documentation');
11 | const logger = require('./app/logger');
12 | <% if(documentationRequiresAuth) {%> const { verifyDocumentationToken } = require('./app/middlewares/docsAuth'); <%}%>
13 |
14 | const DEFAULT_BODY_SIZE_LIMIT = 1024 * 1024 * 10;
15 | const DEFAULT_PARAMETER_LIMIT = 10000;
16 |
17 | const bodyParserJsonConfig = () => ({
18 | parameterLimit: config.common.api.parameterLimit || DEFAULT_PARAMETER_LIMIT,
19 | limit: config.common.api.bodySizeLimit || DEFAULT_BODY_SIZE_LIMIT
20 | });
21 |
22 | const bodyParserUrlencodedConfig = () => ({
23 | extended: true,
24 | parameterLimit: config.common.api.parameterLimit || DEFAULT_PARAMETER_LIMIT,
25 | limit: config.common.api.bodySizeLimit || DEFAULT_BODY_SIZE_LIMIT
26 | });
27 |
28 | const app = express();
29 | <% if(optionalsFeatures.cors) {%>
30 | app.use(cors());<%}%>
31 |
32 | <% if(optionalsFeatures.helmet) {%>
33 | app.use(helmet());<%}%>
34 |
35 | // Client must send "Content-Type: application/json" header
36 | app.use(bodyParser.json(bodyParserJsonConfig()));
37 | app.use(bodyParser.urlencoded(bodyParserUrlencodedConfig()));
38 | app.use(expressRequestIdMiddleware());
39 | app.use('/docs', <% if(documentationRequiresAuth) {%>
40 | verifyDocumentationToken,
41 | <%}%> swaggerUi.serve, swaggerUi.setup(documentation));
42 |
43 | if (!config.isTesting) app.use(expressMiddleware({ loggerFn: logger.info }));
44 |
45 | routes.init(app);
46 |
47 | app.use(errors.handle);
48 |
49 | module.exports = app;
50 |
--------------------------------------------------------------------------------
/generators/app/templates/app/controllers/healthCheck.js:
--------------------------------------------------------------------------------
1 | exports.healthCheck = (_, res) => res.status(200).send({ uptime: process.uptime() });
2 |
--------------------------------------------------------------------------------
/generators/app/templates/app/errors.js:
--------------------------------------------------------------------------------
1 | const internalError = (message, internalCode) => ({
2 | message,
3 | internalCode
4 | });
5 |
6 | exports.DATABASE_ERROR = 'database_error';
7 | exports.databaseError = message => internalError(message, exports.DATABASE_ERROR);
8 |
9 | exports.DEFAULT_ERROR = 'default_error';
10 | exports.defaultError = message => internalError(message, exports.DEFAULT_ERROR);
11 |
--------------------------------------------------------------------------------
/generators/app/templates/app/logger/index.js:
--------------------------------------------------------------------------------
1 | const { logger } = require('express-wolox-logger');
2 |
3 | module.exports = logger;
4 |
--------------------------------------------------------------------------------
/generators/app/templates/app/middlewares/apiInfo.js:
--------------------------------------------------------------------------------
1 | const pjson = require('../../package.json');
2 | const config = require('../../config').common.headers;
3 |
4 | exports.apiInformation = (req, res, next) => {
5 | try {
6 | if (!res.headers) {
7 | res.headers = {};
8 | }
9 | res.headers[config.apiDate] = new Date();
10 | res.headers[config.packageVersion] = pjson.version;
11 | res.headers[config.nodeVersion] = pjson.engines.node;
12 | return next();
13 | } catch (err) {
14 | return next(err);
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/generators/app/templates/app/middlewares/docsAuth.ejs:
--------------------------------------------------------------------------------
1 | const logger = require('../logger');
2 | const { documentationTokenHeader } = require('../../config').common.headers;
3 | const { documentationToken } = require('../../config').common.session;
4 |
5 | exports.verifyDocumentationToken = (req, res, next) => {
6 | const receivedDocumentationToken = req.headers[documentationTokenHeader];
7 |
8 | if (!receivedDocumentationToken) {
9 | return next({ internalCode: 401, message: 'The documentation token was not given' });
10 | }
11 |
12 | if (receivedDocumentationToken !== documentationToken) {
13 | return next({ internalCode: 401, message: 'The given documentation token was incorrect' });
14 | }
15 |
16 | logger.info('Successful Authentication.');
17 | return next();
18 | };
19 |
--------------------------------------------------------------------------------
/generators/app/templates/app/middlewares/errors.js:
--------------------------------------------------------------------------------
1 | const errors = require('../errors');
2 | const logger = require('../logger');
3 |
4 | const DEFAULT_STATUS_CODE = 500;
5 |
6 | const statusCodes = {
7 | [errors.DATABASE_ERROR]: 503,
8 | [errors.DEFAULT_ERROR]: 500
9 | };
10 |
11 | exports.handle = (error, req, res, next) => {
12 | if (error.internalCode) res.status(statusCodes[error.internalCode] || DEFAULT_STATUS_CODE);
13 | else {
14 | // Unrecognized error, notifying it to rollbar.
15 | next(error);
16 | res.status(DEFAULT_STATUS_CODE);
17 | }
18 | logger.error(error);
19 | return res.send({ message: error.message, internal_code: error.internalCode });
20 | };
21 |
--------------------------------------------------------------------------------
/generators/app/templates/app/models/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const Sequelize = require('sequelize');
4 | const config = require('../../config');
5 | const dbConfig = require('../../config/db')[config.environment];
6 |
7 | const basename = path.basename(__filename);
8 | const db = {};
9 | const sequelize = new Sequelize(dbConfig.database, dbConfig.username, dbConfig.password, dbConfig);
10 |
11 | fs.readdirSync(__dirname)
12 | .filter(file => file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js')
13 | .forEach(file => {
14 | // eslint-disable-next-line global-require
15 | const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
16 | db[model.name] = model;
17 | });
18 |
19 | Object.keys(db).forEach(modelName => {
20 | if (db[modelName].associate) db[modelName].associate(db);
21 | });
22 |
23 | db.sequelize = sequelize;
24 | db.Sequelize = Sequelize;
25 |
26 | module.exports = db;
27 |
--------------------------------------------------------------------------------
/generators/app/templates/app/routes.js:
--------------------------------------------------------------------------------
1 | // const controller = require('./controllers/controller');
2 | const { healthCheck } = require('./controllers/healthCheck');
3 |
4 | exports.init = app => {
5 | app.get('/health', healthCheck);
6 | // app.get('/endpoint/get/path', [], controller.methodGET);
7 | // app.put('/endpoint/put/path', [], controller.methodPUT);
8 | // app.post('/endpoint/post/path', [], controller.methodPOST);
9 | };
10 |
--------------------------------------------------------------------------------
/generators/app/templates/app/services/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wolox/express-js-bootstrap/0dcd68b8717f30e9841215e28c060320a2479fe3/generators/app/templates/app/services/.keep
--------------------------------------------------------------------------------
/generators/app/templates/config/db.ejs:
--------------------------------------------------------------------------------
1 | <% if(orm.mongoose && mongooseDialect === 'mongoDB') {%>const mongoose = require('mongoose');
2 | <%}%>const config = require('../config').common.database;
3 | <% if(orm.sequelize) {%>
4 | module.exports = {
5 | development: {
6 | username: config.username,
7 | password: config.password,
8 | database: config.name,
9 | host: config.host,
10 | port: config.port,
11 | dialect: '<%= sequelizeDialect %>'
12 | },
13 | testing: {
14 | username: config.username,
15 | password: config.password,
16 | database: config.name,
17 | host: config.host,
18 | port: config.port,
19 | dialect: '<%= sequelizeDialect %>',
20 | logging: false
21 | },
22 | production: {
23 | username: config.username,
24 | password: config.password,
25 | database: config.name,
26 | host: config.host,
27 | port: config.port,
28 | dialect: '<%= sequelizeDialect %>',
29 | logging: false
30 | }
31 | };<%}%>
32 | <% if(orm.mongoose && mongooseDialect === 'mongoDB') {%> const host = config.host;
33 | const port = config.port;
34 | const name = config.name;
35 | const connectionString = `mongodb://${host}:${port}/${name}`;
36 | module.exports = mongoose.connect(connectionString);
37 |
38 | <%}%>
39 |
--------------------------------------------------------------------------------
/generators/app/templates/config/development.ejs:
--------------------------------------------------------------------------------
1 | exports.config = {
2 | environment: 'development',<% if(database && (orm.sequelize || orm.mongoose)) {%>
3 | common: {
4 | database: {
5 | name: process.env.DB_NAME_DEV
6 | }
7 | }, <%}%>
8 | isDevelopment: true
9 | };
10 |
--------------------------------------------------------------------------------
/generators/app/templates/config/index.ejs:
--------------------------------------------------------------------------------
1 | const ENVIRONMENT = process.env.NODE_ENV || 'development';
2 |
3 | // eslint-disable-next-line global-require
4 | if (ENVIRONMENT !== 'production') require('dotenv').config();
5 |
6 | const configFile = `./${ENVIRONMENT}`;
7 |
8 | const isObject = variable => variable instanceof Object && !(variable instanceof Array);
9 |
10 | /*
11 | * Deep immutable copy of source object into tarjet object and returns a new object.
12 | */
13 | const deepMerge = (target, source) => {
14 | if (isObject(target) && isObject(source)) {
15 | return Object.keys(source).reduce(
16 | (output, key) => ({
17 | ...output,
18 | [key]: isObject(source[key]) && key in target ? deepMerge(target[key], source[key]) : source[key]
19 | }),
20 | { ...target }
21 | );
22 | }
23 | return target;
24 | };
25 |
26 | const config = {
27 | common: {
28 | database: {
29 | host: process.env.DB_HOST,
30 | port: process.env.DB_PORT,
31 | username: process.env.DB_USERNAME,
32 | password: process.env.DB_PASSWORD
33 | },
34 | api: {
35 | bodySizeLimit: process.env.API_BODY_SIZE_LIMIT,
36 | parameterLimit: process.env.API_PARAMETER_LIMIT,
37 | port: process.env.PORT
38 | },<% if(optionalsFeatures.rollbar) {%>
39 | rollbar: {
40 | accessToken: process.env.ROLLBAR_ACCESS_TOKEN,
41 | environment: process.env.ROLLBAR_ENV
42 | },<%}%>
43 | session: {
44 | header_name: 'authorization',
45 | secret: process.env.NODE_API_SESSION_SECRET,<% if(documentationRequiresAuth) {%>
46 | documentationToken: process.env.DOCUMENTATION_TOKEN<%}%>
47 | },
48 | headers: {
49 | apiDate: process.env.API_DATE || 'X-API-Date',
50 | packageVersion: process.env.PACKAGE_VERSION || 'X-Package-Version',
51 | nodeVersion: process.env.NODE_VERSION || 'X-Node-Version',<% if(documentationRequiresAuth) {%>
52 | documentationTokenHeader: process.env.DOCUMENTATION_TOKEN_HEADER || 'X-documentation-token'<%}%>
53 | }
54 | }
55 | };
56 |
57 | const customConfig = require(configFile).config;
58 | module.exports = deepMerge(config, customConfig);
59 |
--------------------------------------------------------------------------------
/generators/app/templates/config/production.ejs:
--------------------------------------------------------------------------------
1 | exports.config = {
2 | environment: 'production',<% if(database && (orm.sequelize || orm.mongoose)) {%>
3 | common: {
4 | database: {
5 | name: process.env.DB_NAME
6 | }
7 | }, <%}%>
8 | isProduction: true
9 | };
10 |
--------------------------------------------------------------------------------
/generators/app/templates/config/testing.ejs:
--------------------------------------------------------------------------------
1 | exports.config = {
2 | environment: 'testing',
3 | isTesting: true,
4 | common: {<% if(database && (orm.sequelize || orm.mongoose)) {%>
5 | database: {
6 | name: process.env.DB_NAME_TEST
7 | },
8 | <%}%>
9 | session: {
10 | secret: 'some-super-secret'
11 | }
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/generators/app/templates/console.ejs:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 | const repl = require('repl');
3 | const fs = require('fs');
4 | <% if(database && orm.sequelize) {%>const models = require('./app/models');<%}%>
5 | const pjson = require('./package.json');
6 |
7 | const convertFunctionToAsync = f => async (...args) => {
8 | const result = await f(...args);
9 | console.log(JSON.stringify(result, null, 2)); // eslint-disable-line no-console
10 | return result;
11 | };
12 |
13 | const convertObjectFunctionsToAsync = serviceMethods => {
14 | const asyncServiceMethods = {};
15 | Object.keys(serviceMethods).forEach(key => {
16 | if (typeof serviceMethods[key] === 'function') {
17 | asyncServiceMethods[key] = convertFunctionToAsync(serviceMethods[key]);
18 | } else asyncServiceMethods[key] = serviceMethods[key];
19 | });
20 | return asyncServiceMethods;
21 | };
22 |
23 | Promise.resolve().then(() => {
24 | const replServer = repl.start({
25 | prompt: `${pjson.name}> `
26 | });<% if(database && orm.sequelize) {%>
27 | replServer.context.models = models;<%}%>
28 | const servicesPath = './app/services/';
29 | fs.readdir(servicesPath, (err, files) => {
30 | files.forEach(file => {
31 | const serviceMethods = require(`${servicesPath}${file}`);
32 | const asyncServiceMethods = convertObjectFunctionsToAsync(serviceMethods);
33 | replServer.context[`${file.split('.')[0]}Service`] = asyncServiceMethods;
34 | });
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/generators/app/templates/documentation/index.js:
--------------------------------------------------------------------------------
1 | const config = require('../config');
2 | const schemas = require('./schemas');
3 | const paths = require('./paths');
4 |
5 | const port = config.common.api.port || 8080;
6 |
7 | module.exports = {
8 | openapi: '3.0.1',
9 | info: {
10 | version: '0.1.0',
11 | title: '<%= projectName %>',
12 | description: '<%= projectDescription %>',
13 | termsOfService: '',
14 | contact: {
15 | name: 'Wolox',
16 | email: 'tls@wolox.com.ar',
17 | url: 'https://www.wolox.com.ar/'
18 | },
19 | license: {
20 | name: 'MIT'
21 | }
22 | },
23 | servers: [
24 | {
25 | url: `http://localhost:${port}/`,
26 | description: 'Local server'
27 | },
28 | {
29 | url: 'https://api_url_testing',
30 | description: 'Testing server'
31 | }
32 | ],
33 | security: [],
34 | tags: [
35 | {
36 | name: 'CRUD operations'
37 | }
38 | ],
39 | paths,
40 | components: {
41 | schemas,
42 | securitySchemes: {}
43 | }
44 | };
45 |
--------------------------------------------------------------------------------
/generators/app/templates/documentation/paths/index.js:
--------------------------------------------------------------------------------
1 | const user = require('./user');
2 |
3 | module.exports = user;
4 |
--------------------------------------------------------------------------------
/generators/app/templates/documentation/paths/user.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | '/users': {
3 | get: {
4 | tags: ['CRUD operations'],
5 | description: 'Get users',
6 | operationId: 'getUsers',
7 | parameters: [
8 | {
9 | name: 'page',
10 | in: 'query',
11 | schema: {
12 | type: 'integer',
13 | default: 1
14 | },
15 | required: false
16 | }
17 | ],
18 | responses: {
19 | 200: {
20 | description: 'Users were obtained',
21 | content: {
22 | 'application/json': {
23 | schema: {
24 | $ref: '#/components/schemas/Users'
25 | }
26 | }
27 | }
28 | }
29 | }
30 | },
31 | post: {
32 | tags: ['CRUD operations'],
33 | description: 'Create user',
34 | operationId: 'createUser',
35 | parameters: [],
36 | requestBody: {
37 | content: {
38 | 'application/json': {
39 | schema: {
40 | $ref: '#/components/schemas/User'
41 | }
42 | }
43 | },
44 | required: true
45 | },
46 | responses: {
47 | 200: {
48 | description: 'New user was created'
49 | },
50 | 400: {
51 | description: 'Invalid parameters',
52 | content: {
53 | 'application/json': {
54 | schema: {
55 | $ref: '#/components/schemas/Error'
56 | },
57 | example: {
58 | message: 'User´s email already exists',
59 | internal_code: 'invalid_parameters'
60 | }
61 | }
62 | }
63 | }
64 | }
65 | }
66 | }
67 | };
68 |
--------------------------------------------------------------------------------
/generators/app/templates/documentation/schemas/index.js:
--------------------------------------------------------------------------------
1 | const user = require('./user');
2 |
3 | module.exports = {
4 | ...user,
5 | Error: {
6 | type: 'object',
7 | properties: {
8 | message: {
9 | type: 'string'
10 | },
11 | internal_code: {
12 | type: 'string'
13 | }
14 | }
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/generators/app/templates/documentation/schemas/user.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | userId: {
3 | type: 'integer',
4 | example: 7
5 | },
6 | username: {
7 | type: 'string',
8 | example: 'tom99'
9 | },
10 | userEmail: {
11 | type: 'string',
12 | example: 'tom.engels@wolox.com.ar'
13 | },
14 | User: {
15 | type: 'object',
16 | properties: {
17 | id: {
18 | $ref: '#/components/schemas/userId'
19 | },
20 | username: {
21 | $ref: '#/components/schemas/username'
22 | },
23 | email: {
24 | $ref: '#/components/schemas/userEmail'
25 | },
26 | }
27 | },
28 | Users: {
29 | type: 'object',
30 | properties: {
31 | users: {
32 | type: 'array',
33 | items: {
34 | $ref: '#/components/schemas/User'
35 | }
36 | }
37 | }
38 | }
39 | };
40 |
--------------------------------------------------------------------------------
/generators/app/templates/gitignore:
--------------------------------------------------------------------------------
1 | # Frontend Dist Files
2 | app/dist
3 |
4 | # Mac Files
5 | .DS_Store
6 | */DS_Store
7 |
8 | # Logs
9 | logs
10 | *.log
11 | npm-debug.log*
12 |
13 | # Runtime data
14 | pids
15 | *.pid
16 | *.seed
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 |
24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
25 | .grunt
26 |
27 | # node-waf configuration
28 | .lock-wscript
29 |
30 | # Compiled binary addons (http://nodejs.org/api/addons.html)
31 | build/Release
32 |
33 | # Dependency directory
34 | node_modules
35 |
36 | # Optional npm cache directory
37 | .npm
38 |
39 | # Optional REPL history
40 | .node_repl_history
41 |
42 | # Code coverage
43 | ./coverage
44 |
45 | # dotenv
46 | .env
47 |
48 | # VS Code
49 | .vscode/
50 |
--------------------------------------------------------------------------------
/generators/app/templates/migrations/index.js:
--------------------------------------------------------------------------------
1 | const Umzug = require('umzug');
2 | const config = require('./../config/');
3 | const { sequelize } = require('../app/models');
4 | const logger = require('../app/logger');
5 |
6 | exports.check = () => {
7 | const umzug = new Umzug({
8 | logging: logger.info,
9 | storage: 'sequelize',
10 | storageOptions: { sequelize },
11 | migrations: {
12 | params: [
13 | sequelize.getQueryInterface(),
14 | sequelize.constructor,
15 | () => {
16 | throw new Error('Migration tried to use old style "done" callback.upgrade');
17 | }
18 | ],
19 | path: `${__dirname}/migrations`,
20 | pattern: /\.js$/
21 | }
22 | });
23 | return umzug.pending().then(migrations => {
24 | if (migrations.length) {
25 | if (!config.isProduction) {
26 | return Promise.reject(new Error('Pending migrations, run: npm run migrations'));
27 | }
28 |
29 | return umzug.up().catch(err => {
30 | logger.error(err);
31 | return Promise.reject(new Error('There are pending migrations that could not be executed'));
32 | });
33 | }
34 | return Promise.resolve();
35 | });
36 | };
37 |
--------------------------------------------------------------------------------
/generators/app/templates/migrations/migrations/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wolox/express-js-bootstrap/0dcd68b8717f30e9841215e28c060320a2479fe3/generators/app/templates/migrations/migrations/.keep
--------------------------------------------------------------------------------
/generators/app/templates/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "<%= projectName %>",
3 | "version": "0.1.0",
4 | "description": "<%= projectDescription %>",
5 | "engines": {
6 | "node": "<%= nodeVersion %>",
7 | "npm": "<%= npmVersion %>"
8 | },
9 | "scripts": {
10 | "console": "node console.js",<% if(testing === 'mocha-chai') {%>
11 | "cover": "NODE_ENV=testing istanbul cover ./node_modules/mocha/bin/_mocha test/app.spec.js",
12 | "test": "NODE_ENV=testing ./node_modules/mocha/bin/_mocha --timeout 6000 --exit test/app.spec.js",
13 | "test-inspect": "NODE_ENV=testing node --inspect-brk ./node_modules/mocha/bin/_mocha test/app.spec.js",<%} if(testing === 'jest-supertest') {%>
14 | "cover": "npm run test -- --coverage",
15 | "test": "NODE_ENV=testing jest --runInBand --forceExit --detectOpenHandles",
16 | "test-inspect": "NODE_ENV=testing node --inspect --debug-brk jest",<%} if(optionalsFeatures.coveralls) {%>
17 | "coveralls": "npm run cover -- --report lcovonly && cat ./coverage/lcov.info | coveralls",<%}%>
18 | "eslint-check": "eslint --print-config .eslintrc.js --ignore-pattern ./.eslintrc.js | eslint-config-prettier-check",
19 | "lint": "eslint \"**/*.js\" --ignore-pattern ./.eslintrc.js",
20 | "lint-diff": "git diff --diff-filter=ACM --name-only --cached --relative | grep \\\\.js$ | xargs eslint",
21 | "lint-fix": "npm run lint -- --fix",
22 | "outdated": "npm outdated --depth 0",
23 | "pretest": "npm run lint",
24 | "start-dev": "nodemon --inspect server.js",
25 | "prestart-dev": "npm run lint",<% if(database && orm.sequelize) {%>
26 | "migrations": "sequelize db:migrate",<% if(!inTraining) {%>
27 | "migrations-test": "NODE_ENV=testing sequelize db:migrate",<%}}%>
28 | "start": "node server.js",
29 | "seed": "sequelize db:seed:all",
30 | "create-seed": "sequelize seed:generate --name",
31 | "create-migration": "sequelize migration:generate --name"
32 | },
33 | "cacheDirectories": [
34 | "node_modules"
35 | ],
36 | "main": "app.js",
37 | "author": "Wolox",
38 | "homepage": "<%= urlRepository %>",
39 | "license": "MIT",
40 | "repository": {
41 | "type": "git",
42 | "url": "<%= urlRepository %>.git"
43 | },
44 | "bugs": {
45 | "url": "<%= urlRepository %>/issues",
46 | "email": "tls@wolox.com.ar"
47 | },<% if(testing === 'jest-supertest') {%>
48 | "jest": {
49 | "coverageThreshold": {
50 | "global": {
51 | "branches": 80,
52 | "functions": 80,
53 | "lines": 80,
54 | "statements": 80
55 | }
56 | },
57 | "collectCoverageFrom": [
58 | "**/*.js",
59 | "!**/console.js",
60 | "!**/node_modules/**",
61 | "!**/build/**",
62 | "!**/migrations/**",
63 | "!**/config/**",
64 | "!**/scripts/**"
65 | ],
66 | "setupFilesAfterEnv": [
67 | "/test/setup.js"
68 | ],
69 | "testEnvironment": "node",
70 | "transform": {
71 | "^.+\\.js$": "babel-jest"
72 | }
73 | },<%}%>
74 | "dependencies": {
75 | "bcryptjs": "<%= bcryptjsVersion %>",<% if(database && orm.mongoose){%>
76 | "mongoose": "<%= mongooseVersion %>",<%} if(database && orm.mongoose && mongooseDialect === 'mongoDB') {%>
77 | "mongodb" : "<%= mongodbVersion %>", <%}%>
78 | "body-parser": "<%= bodyParserVersion %>",<% if(optionalsFeatures.cors) {%>
79 | "cors": "<%= corsVersion %>",<%}%>
80 | "express": "<%= expressVersion %>",<% if(optionalsFeatures.helmet) {%>
81 | "helmet": "<%= helmetVersion %>",<%
82 | }%>
83 | "jwt-simple": "<%= jwtSimpleVersion %>",<% if(optionalsFeatures.rollbar) {%>
84 | "rollbar": "<%= rollbarVersion %>",<%} if(database && orm.sequelize) {%>
85 | "sequelize": "<%= sequelizeVersion %>",<%} if(database && orm.sequelize && testing === 'jest-supertest') {%>
86 | "factory-girl": "<%= factoryGirlVersion %>",<%} if(database && orm.sequelize && sequelizeDialect === 'postgres') {%>
87 | "pg": "<%= pgVersion %>",<%} if(database && orm.sequelize && sequelizeDialect === 'mysql') {%>
88 | "mysql2": "<%= mysql2Version %>",<%} if(database && orm.sequelize && sequelizeDialect === 'sqlite') {%>
89 | "sqlite3": "<%= sqlite3Version %>",<%} if(database && orm.sequelize && sequelizeDialect === 'mssql') {%>
90 | "tedious": "<%= tediousVersion %>",<%}%>
91 | "umzug": "<%= umzugVersion %>",
92 | "express-wolox-logger": "<%= expressWoloxLoggerVersion %>",
93 | "axios": "<%= axiosVersion %>",
94 | "swagger-ui-express": "<%= swaggerUiExpressVersion %>"
95 | },
96 | "devDependencies": {
97 | "babel": "<%= babelVersion %>",
98 | "babel-core": "<%= babelCoreVersion %>",
99 | "babel-eslint": "<%= babelEslintVersion %>",<% if(testing === 'jest-supertest') {%>
100 | "babel-jest": "<%= babelJestVersion %>",
101 | "jest": "<%= jestVersion %>",
102 | "supertest": "<%= supertestVersion %>",<%}%>
103 | "babel-preset-es2015": "<%= babelPresetEs2015Version %>",<% if(testing === 'mocha-chai') {%>
104 | "chai": "<%= chaiVersion %>",
105 | "chai-http": "<%= chaiHttpVersion %>",<%} if(optionalsFeatures.coveralls) {%>
106 | "coveralls": "<%= coverallsVersion %>",<%}%>
107 | "dotenv": "<%= dotenvVersion %>",
108 | "eslint": "<%= eslintVersion %>",
109 | "eslint-config-wolox": "<%= eslintConfigWoloxVersion %>",
110 | "eslint-config-wolox-node": "<%= eslintConfigWoloxNodeVersion %>",
111 | "eslint-plugin-import": "<%= eslintPluginImportVersion %>",
112 | "eslint-plugin-prettier": "<%= eslintPluginPrettierVersion %>",
113 | "husky": "<%= huskyVersion %>",
114 | "istanbul": "<%= istanbulVersion %>",
115 | "mocha": "<%= mochaVersion %>",
116 | "mocha-lcov-reporter": "<%= mochaLcovReporterVersion %>",
117 | "nodemon": "<%= nodemonVersion %>",
118 | "prettier": "<%= prettierVersion %>",
119 | "prettier-eslint": "<%= prettierEslintVersion %>",<% if(database && orm.sequelize) {%>
120 | "sequelize-cli": "<%= sequelizeCliVersion %>",<%}%>
121 | "prompt": "<%= promptVersion %>"
122 | },
123 | "husky": {
124 | "hooks": {
125 | "pre-commit": "npm run lint-diff",
126 | "pre-push": "npm test"
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/generators/app/templates/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Summary
2 |
3 | [Change!] Describe your feature, problems you had, notes, improvements and others.
4 |
5 | ## Known Issues
6 |
7 | [Change!] List any known issue of the feature you are implementing.
8 |
9 | ## Trello Card
10 |
11 | [Change!] Link to the associated Trello card.
12 |
--------------------------------------------------------------------------------
/generators/app/templates/server.ejs:
--------------------------------------------------------------------------------
1 | const app = require('./app');<% if(optionalsFeatures.rollbar) {%>
2 | const Rollbar = require('rollbar');<%} if(database && orm.sequelize) {%>
3 | const migrationsManager = require('./migrations');<%}%>
4 | const config = require('./config');
5 | const logger = require('./app/logger');
6 |
7 | const port = config.common.api.port || 8080;
8 |
9 | Promise.resolve()
10 | <% if(database && orm.sequelize) {%>.then(() => migrationsManager.check()) <%}%>
11 | .then(() => {
12 | <% if(optionalsFeatures.rollbar) {%>
13 | const rollbar = new Rollbar({
14 | accessToken: config.common.rollbar.accessToken,
15 | enabled: !!config.common.rollbar.accessToken,
16 | environment: config.common.rollbar.environment || config.environment
17 | });
18 | app.use(rollbar.errorHandler());<%}%>
19 |
20 | app.listen(port);
21 |
22 | logger.info(`Listening on port: ${port}`);
23 | })
24 | .catch(logger.error);
--------------------------------------------------------------------------------
/generators/app/templates/test/app.spec.ejs:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 | 'use strict';
3 |
4 | const fs = require('fs');
5 | const path = require('path');<% if(testing === 'mocha-chai') {%>
6 | const chaiHttp = require('chai-http');
7 | const chai = require('chai');<%} if(database && orm.sequelize) {%>
8 | const models = require('../app/models');<%}%>
9 | <% if(testing === 'mocha-chai') {%>
10 | chai.use(chaiHttp);<%}%>
11 | <% if(database && orm.sequelize) {%>
12 | const tables = Object.values(models.sequelize.models);
13 | const truncateTable = model =>
14 | model.destroy({ truncate: true, cascade: true, force: true, restartIdentity: true });
15 | const truncateDatabase = () => Promise.all(tables.map(truncateTable));
16 | beforeEach(done => {
17 | truncateDatabase()
18 | .then(() => done());
19 | });
20 | <%}%>
21 | // including all test files
22 | const normalizedPath = path.join(__dirname, '.');
23 |
24 | const requireAllTestFiles = pathToSearch => {
25 | fs.readdirSync(pathToSearch).forEach(file => {
26 | if (fs.lstatSync(`${pathToSearch}/${file}`).isDirectory()) requireAllTestFiles(`${pathToSearch}/${file}`);
27 | else require(`${pathToSearch}/${file}`);
28 | });
29 | };
30 |
31 | requireAllTestFiles(normalizedPath);
32 |
--------------------------------------------------------------------------------
/generators/app/templates/test/factory/factory_by_models.ejs:
--------------------------------------------------------------------------------
1 | const { factory } = require('factory-girl');
2 | const Chance = require('chance');
3 | const db = require('../../app/models');
4 |
5 | const INTEGER = 'INTEGER';
6 | const STRING = 'STRING';
7 | const BOOLEAN = 'BOOLEAN';
8 | const TEXT = 'TEXT';
9 | const DATE = 'DATE';
10 | const DATEONLY = 'DATEONLY';
11 | const JSONTYPE = 'JSON';
12 | const FLOAT = 'FLOAT';
13 |
14 | const IS_NUMERIC = 'isNumeric';
15 | const IS_ALPHANUMERIC = 'isAlphanumeric';
16 | const IS_LOWERCASE = 'isLowercase';
17 | const IS_UPPERCASE = 'isUppercase';
18 | const IS_IP = 'isIP';
19 | const MAX = 'max';
20 | const MIN = 'min';
21 | const LEN = 'len';
22 |
23 | const modelsByName = Object.keys(db)
24 | .filter(modelName => modelName !== 'sequelize' && modelName !== 'Sequelize')
25 | .reduce((models, modelName) => {
26 | models[modelName] = db[modelName];
27 | return models;
28 | }, {});
29 |
30 | const generatorIntByValidations = (key, validate) => {
31 | if (key === LEN) {
32 | return factory.chance('integer', { min: validate.len[0], max: validate.len[1] });
33 | }
34 | return {
35 | [MAX]: factory.chance('integer', { max: validate.max }),
36 | [MIN]: factory.chance('integer', { min: validate.min })
37 | }[key];
38 | };
39 |
40 | const generatorStringByValidations = key =>
41 | ({
42 | [IS_ALPHANUMERIC]: factory.chance('string', { pool: 'abcde6546' }),
43 | [IS_NUMERIC]: factory.chance('string', { pool: '123456789' }),
44 | [IS_LOWERCASE]: factory.chance('string', { pool: 'abcdefghijklmnopqrstuvwxyz' }),
45 | [IS_UPPERCASE]: factory.chance('string', { pool: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' }),
46 | [IS_IP]: factory.chance('ip')
47 | }[key]);
48 |
49 | const generateStringByValidations = validate =>
50 | Object.keys(validate).map(key => generatorStringByValidations(key))[0];
51 |
52 | const generateIntByValidations = validate =>
53 | Object.keys(validate).map(key => generatorIntByValidations(key, validate))[0];
54 |
55 | const intValidation = (model, key) => {
56 | if (model.rawAttributes[key].unique) {
57 | return factory.sequence(`${model.name}.${key}`, n => n);
58 | }
59 | if (model.rawAttributes[key].validate) {
60 | const { validate } = model.rawAttributes[key];
61 | return generateIntByValidations(validate) || factory.chance('integer');
62 | }
63 | return factory.chance('integer');
64 | };
65 |
66 | const emailFactory = (model, key) => {
67 | if (model.rawAttributes[key].validate.isEmail) {
68 | if (model.rawAttributes[key].unique) {
69 | return factory.sequence(`${model.name}.email`, n => `dummy-user-${n}@wolox.com.ar`);
70 | }
71 | return factory.chance('email', { domain: 'wolox.com.ar' });
72 | }
73 | return false;
74 | };
75 |
76 | const stringValidation = (model, key) => {
77 | const chance = new Chance();
78 | if (model.rawAttributes[key].validate) {
79 | const { validate } = model.rawAttributes[key];
80 | if (emailFactory(model, key)) {
81 | return emailFactory(model, key);
82 | }
83 | if (validate.contains) {
84 | const word = chance.string({ pool: 'abcdefghi' });
85 | return factory.sequence(`${model.name}`, n => `${validate.contains}${word}${n}`);
86 | }
87 | return generateStringByValidations(validate);
88 | }
89 | return factory.chance('word');
90 | };
91 |
92 | const randomJsonCreate = () => {
93 | const chance = new Chance();
94 | const attributeName = chance.string({ pool: 'abcdefghi' });
95 | const value = factory.chance('string', { pool: 'abcdefghi' });
96 | return {
97 | [attributeName]: value
98 | };
99 | };
100 |
101 | const generatorByDatatype = (type, model, key) => {
102 | const chance = new Chance();
103 | return {
104 | [INTEGER]: intValidation(model, key),
105 | [STRING]: stringValidation(model, key),
106 | [BOOLEAN]: factory.chance('bool'),
107 | [TEXT]: factory.chance('paragraph'),
108 | [DATE]: factory.chance('date', { string: true }),
109 | [DATEONLY]: new Date(chance.date({ string: true })),
110 | [JSONTYPE]: randomJsonCreate(),
111 | [FLOAT]: factory.chance('floating')
112 | }[type];
113 | };
114 |
115 | const generateByDatatypes = (model, key, attribute, predeterminatedValue = false) => {
116 | if (predeterminatedValue && key === predeterminatedValue.attribute) {
117 | return predeterminatedValue.value;
118 | }
119 | if (model.rawAttributes[key].defaultValue !== undefined) {
120 | return model.rawAttributes[key].defaultValue;
121 | }
122 | return generatorByDatatype(attribute[key], model, key) || factory.chance('word');
123 | };
124 |
125 | const buildByModel = (model, predeterminatedValue = false) => {
126 | const attributeType = {};
127 | const factorCreated = {};
128 | for (const key in model.rawAttributes) {
129 | if (key) {
130 | attributeType[key] = model.rawAttributes[key].type.key;
131 | if (!model.rawAttributes[key].primaryKey) {
132 | factorCreated[key] = generateByDatatypes(model, key, attributeType, predeterminatedValue);
133 | }
134 | }
135 | }
136 | return factorCreated;
137 | };
138 |
139 | exports.factoryByModel = (modelRequired, predeterminatedValue = false) => {
140 | const modelRequested = modelsByName[modelRequired];
141 | const factorCreated = buildByModel(modelRequested, predeterminatedValue);
142 | return factory.define(modelRequested.name, db[modelRequested.name], factorCreated);
143 | };
144 |
145 | exports.factoryAllModels = () => {
146 | const models = modelsByName;
147 | return Object.keys(models).forEach(model => this.factoryByModel(model));
148 | };
149 |
150 | exports.factoryWithCustomizedValue = (modelRequired, attribute, value) => {
151 | const predeterminatedValue = {
152 | attribute,
153 | value
154 | };
155 | return this.factoryByModel(modelRequired, predeterminatedValue);
156 | };
157 |
--------------------------------------------------------------------------------
/generators/app/templates/test/setup.js:
--------------------------------------------------------------------------------
1 | const models = require('../app/models');
2 |
3 | const tables = Object.values(models.sequelize.models);
4 |
5 | const truncateTable = model =>
6 | model.destroy({ truncate: true, cascade: true, force: true, restartIdentity: true });
7 |
8 | const truncateDatabase = () => Promise.all(tables.map(truncateTable));
9 |
10 | global.beforeEach(async () => {
11 | await truncateDatabase();
12 | });
13 |
--------------------------------------------------------------------------------
/generators/app/utils.js:
--------------------------------------------------------------------------------
1 | const { flatten } = require('lodash');
2 | const { URL_REGEX, VERSION_REGEX, APP_NAME_REGEX } = require('./constants');
3 |
4 | exports.checkboxReducer = values =>
5 | values.reduce((answer, optional) => {
6 | answer[optional] = true;
7 | return answer;
8 | }, {});
9 |
10 | exports.flattenPrompts = prompts =>
11 | prompts.reduce((listPrompts, actualPrompt) => {
12 | listPrompts.push(actualPrompt);
13 | if (actualPrompt.promptsNegative || actualPrompt.promptsPositive || actualPrompt.chosen) {
14 | const newPrompts = [];
15 | const generateNewPrompt = (prompt, positive, hasSelected = false) => ({
16 | ...prompt,
17 | when: answers => {
18 | if (hasSelected && answers[actualPrompt.name] && answers[actualPrompt.name][hasSelected]) {
19 | return answers[actualPrompt.name][hasSelected];
20 | }
21 | return (
22 | (actualPrompt.when ? actualPrompt.when(answers) : true) &&
23 | answers[actualPrompt.name] === positive &&
24 | (prompt.when ? prompt.when(answers) : true)
25 | );
26 | }
27 | });
28 |
29 | if (actualPrompt.promptsNegative) {
30 | newPrompts.push(
31 | ...actualPrompt.promptsNegative.map(promptNegative => generateNewPrompt(promptNegative, false))
32 | );
33 | }
34 | if (actualPrompt.promptsPositive) {
35 | newPrompts.push(
36 | ...actualPrompt.promptsPositive.map(promptPositive => generateNewPrompt(promptPositive, true))
37 | );
38 | }
39 | if (actualPrompt.chosen) {
40 | newPrompts.push(
41 | ...flatten(
42 | actualPrompt.chosen.map(seqOption => {
43 | const lift = seqOption.prompts;
44 | return lift.map(prom => generateNewPrompt(prom, true, seqOption.condition));
45 | })
46 | )
47 | );
48 | }
49 | listPrompts.push(...exports.flattenPrompts(newPrompts));
50 | }
51 | return listPrompts;
52 | }, []);
53 |
54 | const validateRegex = (regex, message) => value => regex.test(value) || message;
55 |
56 | exports.validateUrl = value => !value || validateRegex(URL_REGEX, 'Please enter a valid url')(value);
57 | exports.validateVersionNumber = validateRegex(
58 | VERSION_REGEX,
59 | 'Please enter a valid version number (e.g. 1.2.3)'
60 | );
61 | exports.validateAppName = validateRegex(APP_NAME_REGEX, 'Please enter a valid app name (alphanumeric)');
62 |
--------------------------------------------------------------------------------
/img/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Wolox/express-js-bootstrap/0dcd68b8717f30e9841215e28c060320a2479fe3/img/demo.gif
--------------------------------------------------------------------------------
/img/demo.yml:
--------------------------------------------------------------------------------
1 | # The configurations that used for the recording, feel free to edit them
2 | config:
3 |
4 | # Specify a command to be executed
5 | # like `/bin/bash -l`, `ls`, or any other commands
6 | # the default is bash for Linux
7 | # or powershell.exe for Windows
8 | command: zsh
9 |
10 | # Specify the current working directory path
11 | # the default is the current working directory path
12 | cwd: /demo
13 |
14 | # Export additional ENV variables
15 | env:
16 | recording: true
17 |
18 | # Explicitly set the number of columns
19 | # or use `auto` to take the current
20 | # number of columns of your shell
21 | cols: 96
22 |
23 | # Explicitly set the number of rows
24 | # or use `auto` to take the current
25 | # number of rows of your shell
26 | rows: 20
27 |
28 | # Amount of times to repeat GIF
29 | # If value is -1, play once
30 | # If value is 0, loop indefinitely
31 | # If value is a positive number, loop n times
32 | repeat: 0
33 |
34 | # Quality
35 | # 1 - 100
36 | quality: 100
37 |
38 | # Delay between frames in ms
39 | # If the value is `auto` use the actual recording delays
40 | frameDelay: auto
41 |
42 | # Maximum delay between frames in ms
43 | # Ignored if the `frameDelay` isn't set to `auto`
44 | # Set to `auto` to prevent limiting the max idle time
45 | maxIdleTime: 2000
46 |
47 | # The surrounding frame box
48 | # The `type` can be null, window, floating, or solid`
49 | # To hide the title use the value null
50 | # Don't forget to add a backgroundColor style with a null as type
51 | frameBox:
52 | type: floating
53 | title: null
54 | style:
55 | border: 0px black solid
56 | # boxShadow: none
57 | # margin: 0px
58 |
59 | # Add a watermark image to the rendered gif
60 | # You need to specify an absolute path for
61 | # the image on your machine or a URL, and you can also
62 | # add your own CSS styles
63 | watermark:
64 | imagePath: null
65 | style:
66 | position: absolute
67 | right: 15px
68 | bottom: 15px
69 | width: 100px
70 | opacity: 0.9
71 |
72 | # Cursor style can be one of
73 | # `block`, `underline`, or `bar`
74 | cursorStyle: block
75 |
76 | # Font family
77 | # You can use any font that is installed on your machine
78 | # in CSS-like syntax
79 | fontFamily: "Monaco, Lucida Console, Ubuntu Mono, Monospace"
80 |
81 | # The size of the font
82 | fontSize: 12
83 |
84 | # The height of lines
85 | lineHeight: 1
86 |
87 | # The spacing between letters
88 | letterSpacing: 0
89 |
90 | # Theme
91 | theme:
92 | background: "transparent"
93 | foreground: "#afafaf"
94 | cursor: "#c7c7c7"
95 | black: "#232628"
96 | red: "#fc4384"
97 | green: "#5FC245"
98 | yellow: "#ffa727"
99 | blue: "#75dff2"
100 | magenta: "#ae89fe"
101 | cyan: "#708387"
102 | white: "#d5d5d0"
103 | brightBlack: "#626566"
104 | brightRed: "#ff7fac"
105 | brightGreen: "#c8ed71"
106 | brightYellow: "#ebdf86"
107 | brightBlue: "#75dff2"
108 | brightMagenta: "#ae89fe"
109 | brightCyan: "#b1c6ca"
110 | brightWhite: "#f9f9f4"
111 |
112 | # Records, feel free to edit them
113 | records:
114 | - delay: 100
115 | content: "\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;wolox@wolox: ~/test\a\e]1;~/test\a"
116 | - delay: 39
117 | content: "\r\e[0m\e[27m\e[24m\e[J\e[35mwolox\e[00m\e[36m@\e[00m\e[33mwolox\e[00m\e[31m:\e[00m\e[36m~/test\e[00m\e[31m|\e[00m\e[36m⇒\e[00m \e[K\e[?1h\e=\e[?2004h"
118 | - delay: 80
119 | content: 'y'
120 | - delay: 50
121 | content: "\byo"
122 | - delay: 50
123 | content: ' '
124 | - delay: 50
125 | content: w
126 | - delay: 50
127 | content: '-'
128 | - delay: 50
129 | content: e
130 | - delay: 50
131 | content: x
132 | - delay: 50
133 | content: p
134 | - delay: 50
135 | content: r
136 | - delay: 50
137 | content: e
138 | - delay: 50
139 | content: s
140 | - delay: 50
141 | content: s
142 | - delay: 50
143 | content: '-'
144 | - delay: 50
145 | content: j
146 | - delay: 50
147 | content: s
148 | - delay: 50
149 | content: "\e[?1l\e>\e[?2004l\r\r\n\e]2;yo w-express-js\a\e]1;yo\a"
150 | - delay: 80
151 | content: "\r\n\r\n \e[32m███\e[39m\e[32m╗\e[39m\e[32m ██\e[39m\e[32m╗\e[39m \e[32m██████\e[39m\e[32m╗ \e[39m \e[32m██████\e[39m\e[32m╗ \e[39m \e[32m███████\e[39m\e[32m╗\e[39m \e[32m ██\e[39m\e[32m╗\e[39m \e[32m███████\e[39m\e[32m╗\e[39m \r\n \e[32m████\e[39m\e[32m╗\e[39m\e[32m ██\e[39m\e[32m║\e[39m \e[32m██\e[39m\e[32m╔═══\e[39m\e[32m██\e[39m\e[32m╗\e[39m \e[32m██\e[39m\e[32m╔══\e[39m\e[32m██\e[39m\e[32m╗\e[39m \e[32m██\e[39m\e[32m╔════╝\e[39m \e[32m ██\e[39m\e[32m║\e[39m \e[32m██\e[39m\e[32m╔════╝\e[39m \r\n \e[32m██\e[39m\e[32m╔\e[39m\e[32m██\e[39m\e[32m╗\e[39m\e[32m ██\e[39m\e[32m║\e[39m \e[32m██\e[39m\e[32m║\e[39m\e[32m ██\e[39m\e[32m║\e[39m \e[32m██\e[39m\e[32m║\e[39m\e[32m ██\e[39m\e[32m║\e[39m \e[32m█████\e[39m\e[32m╗ \e[39m \e[32m ██\e[39m\e[32m║\e[39m \e[32m███████\e[39m\e[32m╗\e[39m \r\n \e[32m██\e[39m\e[32m║╚\e[39m\e[32m██\e[39m\e[32m╗\e[39m\e[32m██\e[39m\e[32m║\e[39m \e[32m██\e[39m\e[32m║\e[39m\e[32m ██\e[39m\e[32m║\e[39m \e[32m██\e[39m\e[32m║\e[39m\e[32m ██\e[39m\e[32m║\e[39m \e[32m██\e[39m\e[32m╔══╝ \e[39m \e[32m██ ██\e[39m\e[32m║\e[39m \e[32m╚════\e[39m\e[32m██\e[39m\e[32m║\e[39m \r\n \e[32m██\e[39m\e[32m║ ╚\e[39m\e[32m████\e[39m\e[32m║\e[39m \e[32m╚\e[39m\e[32m██████\e[39m\e[32m╔╝\e[39m \e[32m██████\e[39m\e[32m╔╝\e[39m \e[32m███████\e[39m\e[32m╗\e[39m \e[32m╚\e[39m\e[32m█████\e[39m\e[32m╔╝\e[39m \e[32m███████\e[39m\e[32m║\e[39m \r\n \e[32m╚═╝ ╚═══╝\e[39m \e[32m ╚═════╝ \e[39m \e[32m╚═════╝ \e[39m \e[32m╚══════╝\e[39m \e[32m ╚════╝ \e[39m \e[32m╚══════╝\e[39m \r\n\r\n \e[32m██\e[39m\e[32m╗\e[39m\e[32m ██\e[39m\e[32m╗\e[39m \e[32m██\e[39m\e[32m╗\e[39m \e[32m██████\e[39m\e[32m╗\e[39m \e[32m██\e[39m\e[32m╗\e[39m\e[32m ██\e[39m\e[32m╗\e[39m \e[32m██████\e[39m\e[32m╗ \e[39m \e[32m███████\e[39m\e[32m╗\e[39m \e[32m███████\e[39m\e[32m╗\e[39m \r\n \e[32m██\e[39m\e[32m║\e[39m\e[32m ██\e[39m\e[32m╔╝\e[39m \e[32m██\e[39m\e[32m║\e[39m \e[32m██\e[39m\e[32m╔════╝\e[39m \e[32m██\e[39m\e[32m║\e[39m\e[32m ██\e[39m\e[32m╔╝\e[39m \e[32m██\e[39m\e[32m╔═══\e[39m\e[32m██\e[39m\e[32m╗\e[39m \e[32m██\e[39m\e[32m╔════╝\e[39m \e[32m██\e[39m\e[32m╔════╝\e[39m \r\n \e[32m█████\e[39m\e[32m╔╝ \e[39m \e[32m██\e[39m\e[32m║\e[39m \e[32m██\e[39m\e[32m║ \e[39m \e[32m█████\e[39m\e[32m╔╝ \e[39m \e[32m██\e[39m\e[32m║\e[39m\e[32m ██\e[39m\e[32m║\e[39m \e[32m█████\e[39m\e[32m╗ \e[39m \e[32m█████\e[39m\e[32m╗ \e[39m \r\n \e[32m██\e[39m\e[32m╔═\e[39m\e[32m██\e[39m\e[32m╗ \e[39m \e[32m██\e[39m\e[32m║\e[39m \e[32m██\e[39m\e[32m║ \e[39m \e[32m██\e[39m\e[32m╔═\e[39m\e[32m██\e[39m\e[32m╗ \e[39m \e[32m██\e[39m\e[32m║\e[39m\e[32m ██\e[39m\e[32m║\e[39m \e[32m██\e[39m\e[32m╔══╝ \e[39m \e[32m██\e[39m\e[32m╔══╝ \e[39m \r\n \e[32m██\e[39m\e[32m║\e[39m\e[32m ██\e[39m\e[32m╗\e[39m \e[32m██\e[39m\e[32m║\e[39m \e[32m╚\e[39m\e[32m██████\e[39m\e[32m╗\e[39m \e[32m██\e[39m\e[32m║\e[39m\e[32m ██\e[39m\e[32m╗\e[39m \e[32m╚\e[39m\e[32m██████\e[39m\e[32m╔╝\e[39m \e[32m██\e[39m\e[32m║ \e[39m \e[32m██\e[39m\e[32m║ \e[39m \r\n \e[32m╚═╝ ╚═╝\e[39m \e[32m╚═╝\e[39m \e[32m ╚═════╝\e[39m \e[32m╚═╝ ╚═╝\e[39m \e[32m ╚═════╝ \e[39m \e[32m╚═╝ \e[39m \e[32m╚═╝ \e[39m \r\n\r\n\r\n\e[?25l\e[36m⠋\e[39m Checking if git is installed"
152 | - delay: 7
153 | content: "\e[2K\e[1G\e[?25h\e[32m✔\e[39m Checking if git is installed\r\n\e[?25l\e[36m⠋\e[39m Checking if npm is installed"
154 | - delay: 81
155 | content: "\e[2K\e[1G\e[36m⠙\e[39m Checking if npm is installed"
156 | - delay: 80
157 | content: "\e[2K\e[1G\e[36m⠹\e[39m Checking if npm is installed"
158 | - delay: 34
159 | content: "\e[2K\e[1G\e[?25h\e[32m✔\e[39m Checking if npm is installed\r\n"
160 | - delay: 12
161 | content: "\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0m\e[40D\e[40C"
162 | - delay: 200
163 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mh\e[41D\e[41C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mht\e[42D\e[42C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhtt\e[43D\e[43C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttp\e[44D\e[44C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps\e[45D\e[45C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps:\e[46D\e[46C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps:/\e[47D\e[47C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://\e[48D\e[48C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://g\e[49D\e[49C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://gi\e[50D\e[50C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://git\e[51D\e[51C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://gith\e[52D\e[52C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://githu\e[53D\e[53C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github\e[54D\e[54C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.\e[55D\e[55C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.c\e[56D\e[56C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.co\e[57D\e[57C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com\e[58D\e[58C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/\e[59D\e[59C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/m\e[60D\e[60C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/mp\e[61D\e[61C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/mpi\e[62D\e[62C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/mpic\e[63D\e[63C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/mpico\e[64D\e[64C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/mpicol\e[65D\e[65C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/mpicoll\e[66D\e[66C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox\e[67D\e[67C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-\e[68D\e[68C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-w\e[69D\e[69C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wo\e[70D\e[70C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wol\e[71D\e[71C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolo\e[72D\e[72C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox\e[73D\e[73C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/\e[74D\e[74C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/t\e[75D\e[75C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/te\e[76D\e[76C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/tes\e[77D\e[77C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test\e[78D\e[78C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-\e[79D\e[79C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-k\e[80D\e[80C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-ki\e[81D\e[81C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-kic\e[82D\e[82C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-kick\e[83D\e[83C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-kicko\e[84D\e[84C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-kickof\e[85D\e[85C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-kickoff\e[86D\e[86C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-kickoff-\e[87D\e[87C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-kickoff-r\e[88D\e[88C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-kickoff-re\e[89D\e[89C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-kickoff-rep\e[90D\e[90C\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0mhttps://github.com/wolox-wolox/test-kickoff-repo\e[91D\e[91C"
164 | - delay: 712
165 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter git repository for this project\e[22m\e[0m \e[0m\e[36mhttps://github.com/wolox-wolox/test-kickoff-repo\e[39m\e[91D\e[91C\r\n\e[32m?\e[39m \e[1mAre you in WTraining ?\e[22m\e[0m \e[0m\e[2m(Y/n) \e[22m\e[31D\e[31C"
166 | - delay: 200
167 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mAre you in WTraining ?\e[22m\e[0m \e[0m\e[2m(Y/n) \e[22mn\e[32D\e[32C"
168 | - delay: 275
169 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mAre you in WTraining ?\e[22m\e[0m \e[0m\e[36mNo\e[39m\e[27D\e[27C\r\n\e[32m?\e[39m \e[1mEnter Project Name\e[22m\e[0m \e[0m\e[21D\e[21C"
170 | - delay: 201
171 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Name\e[22m\e[0m \e[0mt\e[22D\e[22C"
172 | - delay: 68
173 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Name\e[22m\e[0m \e[0mte\e[23D\e[23C"
174 | - delay: 148
175 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Name\e[22m\e[0m \e[0mtes\e[24D\e[24C"
176 | - delay: 119
177 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Name\e[22m\e[0m \e[0mtest\e[25D\e[25C"
178 | - delay: 200
179 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Name\e[22m\e[0m \e[0m\e[36mtest\e[39m\e[25D\e[25C\r\n\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0m\e[2m(test) \e[22m\e[35D\e[35C"
180 | - delay: 200
181 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mT\e[29D\e[29C"
182 | - delay: 258
183 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mTe\e[30D\e[30C"
184 | - delay: 171
185 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mTes\e[31D\e[31C"
186 | - delay: 129
187 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mTest\e[32D\e[32C"
188 | - delay: 120
189 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mTest \e[33D\e[33C"
190 | - delay: 356
191 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mTest p\e[34D\e[34C"
192 | - delay: 121
193 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mTest pr\e[35D\e[35C"
194 | - delay: 99
195 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mTest pro\e[36D\e[36C"
196 | - delay: 294
197 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mTest proj\e[37D\e[37C"
198 | - delay: 76
199 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mTest proje\e[38D\e[38C"
200 | - delay: 204
201 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mTest projec\e[39D\e[39C"
202 | - delay: 72
203 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0mTest project\e[40D\e[40C"
204 | - delay: 529
205 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Project Description\e[22m\e[0m \e[0m\e[36mTest project\e[39m\e[40D\e[40C\r\n\e[32m?\e[39m \e[1mEnter NodeJS Version\e[22m\e[0m \e[0m\e[2m(10.14.1) \e[22m\e[33D\e[33C"
206 | - delay: 200
207 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter NodeJS Version\e[22m\e[0m \e[0m\e[36m10.14.1\e[39m\e[30D\e[30C\r\n\e[32m?\e[39m \e[1mEnter NPM Version\e[22m\e[0m \e[0m\e[2m(6.4.1) \e[22m\e[28D\e[28C"
208 | - delay: 373
209 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter NPM Version\e[22m\e[0m \e[0m\e[36m6.4.1\e[39m\e[25D\e[25C\r\n\e[32m?\e[39m \e[1mDo you want to use Sequelize as your ORM?\e[22m\e[0m \e[0m\e[2m(Y/n) \e[22m\e[50D\e[50C"
210 | - delay: 200
211 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mDo you want to use Sequelize as your ORM?\e[22m\e[0m \e[0m\e[2m(Y/n) \e[22mY\e[51D\e[51C"
212 | - delay: 363
213 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mDo you want to use Sequelize as your ORM?\e[22m\e[0m \e[0m\e[36mYes\e[39m\e[47D\e[47C\r\n\e[32m?\e[39m \e[1mEnter Sequelize Version\e[22m\e[0m \e[0m\e[2m(4.34.0) \e[22m\e[35D\e[35C"
214 | - delay: 200
215 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mEnter Sequelize Version\e[22m\e[0m \e[0m\e[36m4.34.0\e[39m\e[32D\e[32C\r\n\e[?25l\e[32m?\e[39m \e[1mEnter Database Dialect\e[22m\e[0m \e[0m\e[2m(Use arrow keys)\e[22m\r\n mysql \r\n sqlite \r\n\e[36m❯ postgres\e[39m \r\n mssql \e[8D\e[8C"
216 | - delay: 220
217 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mEnter Database Dialect\e[22m\e[0m \e[0m\e[36mpostgres\e[39m\e[33D\e[33C\r\n\e[?25h\e[?25l\e[32m?\e[39m \e[1mSelect Deploy strategy for your project\e[22m\e[0m \e[0m(Press \e[36m\e[1m\e[22m\e[39m to select, \e[36m\e[1m\e[22m\e[39m to toggle all, \e[36m\e[1m\e[22m\e[39m to in\r\nvert selection)\r\n\e[36m❯◯ aws\e[39m\r\n ◯ heroku\e[9D\e[9C"
218 | - delay: 930
219 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mSelect Deploy strategy for your project\e[22m\e[0m \e[0m\r\n\e[36m❯\e[32m◉\e[36m aws\e[39m\r\n ◯ heroku\e[9D\e[9C"
220 | - delay: 215
221 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mSelect Deploy strategy for your project\e[22m\e[0m \e[0m\r\n \e[32m◉\e[39m aws\r\n\e[36m❯◯ heroku\e[39m\e[9D\e[9C"
222 | - delay: 187
223 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mSelect Deploy strategy for your project\e[22m\e[0m \e[0m\r\n \e[32m◉\e[39m aws\r\n\e[36m❯\e[32m◉\e[36m heroku\e[39m\e[9D\e[9C"
224 | - delay: 262
225 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mSelect Deploy strategy for your project\e[22m\e[0m \e[0m\e[36maws, heroku\e[39m\e[53D\e[53C\r\n\e[?25h\e[32m?\e[39m \e[1mAre you going to use docker for the deploy?\e[22m\e[0m \e[0m\e[2m(Y/n) \e[22m\e[52D\e[52C"
226 | - delay: 200
227 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mAre you going to use docker for the deploy?\e[22m\e[0m \e[0m\e[2m(Y/n) \e[22mY\e[53D\e[53C"
228 | - delay: 546
229 | content: "\e[2K\e[G\e[32m?\e[39m \e[1mAre you going to use docker for the deploy?\e[22m\e[0m \e[0m\e[36mYes\e[39m\e[49D\e[49C\r\n\e[?25l\e[32m?\e[39m \e[1mChoose optionals features for your project\e[22m\e[0m \e[0m(Press \e[36m\e[1m\e[22m\e[39m to select, \e[36m\e[1m\e[22m\e[39m to toggle all, \e[36m\e[1m\e[22m\e[39m to\r\n invert selection)\r\n\e[36m❯◯ coveralls\e[39m\r\n ◯ rollbar\r\n ◯ cors\e[7D\e[7C"
230 | - delay: 200
231 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose optionals features for your project\e[22m\e[0m \e[0m\r\n\e[36m❯\e[32m◉\e[36m coveralls\e[39m\r\n ◯ rollbar\r\n ◯ cors\e[7D\e[7C"
232 | - delay: 215
233 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose optionals features for your project\e[22m\e[0m \e[0m\r\n \e[32m◉\e[39m coveralls\r\n\e[36m❯◯ rollbar\e[39m\r\n ◯ cors\e[7D\e[7C"
234 | - delay: 200
235 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose optionals features for your project\e[22m\e[0m \e[0m\r\n \e[32m◉\e[39m coveralls\r\n\e[36m❯\e[32m◉\e[36m rollbar\e[39m\r\n ◯ cors\e[7D\e[7C"
236 | - delay: 139
237 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose optionals features for your project\e[22m\e[0m \e[0m\r\n \e[32m◉\e[39m coveralls\r\n \e[32m◉\e[39m rollbar\r\n\e[36m❯◯ cors\e[39m\e[7D\e[7C"
238 | - delay: 171
239 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose optionals features for your project\e[22m\e[0m \e[0m\r\n \e[32m◉\e[39m coveralls\r\n \e[32m◉\e[39m rollbar\r\n\e[36m❯\e[32m◉\e[36m cors\e[39m\e[7D\e[7C"
240 | - delay: 333
241 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose optionals features for your project\e[22m\e[0m \e[0m\e[36mcoveralls, rollbar, cors\e[39m\e[69D\e[69C\r\n\e[?25h\e[?25l\e[32m?\e[39m \e[1mChoose CI for your project\e[22m\e[0m \e[0m\e[2m(Use arrow keys)\e[22m\r\n\e[36m❯ jenkins\e[39m \r\n travis \e[9D\e[9C"
242 | - delay: 200
243 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose CI for your project\e[22m\e[0m \e[0m\r\n jenkins \r\n\e[36m❯ travis\e[39m \e[9D\e[9C"
244 | - delay: 364
245 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose CI for your project\e[22m\e[0m \e[0m\r\n\e[36m❯ jenkins\e[39m \r\n travis \e[9D\e[9C"
246 | - delay: 200
247 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose CI for your project\e[22m\e[0m \e[0m\r\n jenkins \r\n\e[36m❯ travis\e[39m \e[9D\e[9C"
248 | - delay: 200
249 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose CI for your project\e[22m\e[0m \e[0m\e[36mtravis\e[39m\e[35D\e[35C\r\n\e[?25h\e[?25l\e[32m?\e[39m \e[1mChoose your testing option\e[22m\e[0m \e[0m\e[2m(Use arrow keys)\e[22m\r\n\e[36m❯ mocha-chai\e[39m \r\n jest-supertest \e[17D\e[17C"
250 | - delay: 200
251 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose your testing option\e[22m\e[0m \e[0m\r\n mocha-chai \r\n\e[36m❯ jest-supertest\e[39m \e[17D\e[17C"
252 | - delay: 241
253 | content: "\e[2K\e[1A\e[2K\e[1A\e[2K\e[G\e[32m?\e[39m \e[1mChoose your testing option\e[22m\e[0m \e[0m\e[36mjest-supertest\e[39m\e[43D\e[43C\r\n\e[?25h"
254 | - delay: 5
255 | content: "\e[?25l\e[36m⠋\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
256 | - delay: 81
257 | content: "\e[2K\e[1G\e[36m⠙\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
258 | - delay: 83
259 | content: "\e[2K\e[1G\e[36m⠹\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
260 | - delay: 81
261 | content: "\e[2K\e[1G\e[36m⠸\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
262 | - delay: 85
263 | content: "\e[2K\e[1G\e[36m⠼\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
264 | - delay: 82
265 | content: "\e[2K\e[1G\e[36m⠴\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
266 | - delay: 81
267 | content: "\e[2K\e[1G\e[36m⠦\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
268 | - delay: 83
269 | content: "\e[2K\e[1G\e[36m⠧\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
270 | - delay: 83
271 | content: "\e[2K\e[1G\e[36m⠇\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
272 | - delay: 81
273 | content: "\e[2K\e[1G\e[36m⠏\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
274 | - delay: 80
275 | content: "\e[2K\e[1G\e[36m⠋\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
276 | - delay: 81
277 | content: "\e[2K\e[1G\e[36m⠙\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo"
278 | - delay: 81
279 | content: "\e[2K\e[1G\e[36m⠹\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo\e[2K\e[1G\e[?25h\e[32m✔\e[39m Cloning repository from https://github.com/wolox-wolox/test-kickoff-repo\r\n"
280 | - delay: 140
281 | content: "\e[32m create\e[39m test/Procfile\r\n\e[32m create\e[39m test/Dockerfile\r\n\e[32m create\e[39m test/Dockerrun.aws.json\r\n\e[32m create\e[39m test/.travis.yml\r\n\e[32m create\e[39m test/.sequelizerc\r\n\e[33m force\e[39m test/README.md\r\n\e[32m create\e[39m test/pull_request_template.md\r\n\e[32m create\e[39m test/package.json\r\n\e[32m create\e[39m test/LICENSE.md\r\n\e[32m create\e[39m test/console.js\r\n\e[32m create\e[39m test/app.js\r\n\e[32m create\e[39m test/server.js\r\n\e[32m create\e[39m test/.nvmrc\r\n\e[32m create\e[39m test/.gitignore\r\n\e[32m create\e[39m test/.eslintrc.js\r\n\e[32m create\e[39m test/.eslintignore\r\n\e[32m create\e[39m test/migrations/index.js\r\n\e[32m create\e[39m test/migrations/migrations/.keep\r\n\e[32m create\e[39m test/config/db.js\r\n\e[32m create\e[39m test/test/app.spec.js\r\n\e[32m create\e[39m test/docs/.keep\r\n\e[32m create\e[39m test/app/routes.js\r\n\e[32m create\e[39m test/app/logger/index.js\r\n\e[32m create\e[39m test/config/development.js\r\n\e[32m create\e[39m test/config/production.js\r\n\e[32m create\e[39m test/config/testing.js\r\n\e[32m create\e[39m test/config/index.js\r\n\e[32m create\e[39m test/app/errors.js\r\n"
282 | - delay: 21
283 | content: "\e[32m create\e[39m test/app/models/index.js\r\n\e[32m create\e[39m test/app/services/.keep\r\n\e[32m create\e[39m test/app/controllers/healthCheck.js\r\n\e[32m create\e[39m test/app/middlewares/errors.js\r\n\e[?25l\e[36m⠋\e[39m Installing dependencies"
284 | - delay: 83
285 | content: "\e[2K\e[1G\e[36m⠙\e[39m Installing dependencies"
286 | - delay: 85
287 | content: "\e[2K\e[1G\e[36m⠹\e[39m Installing dependencies"
288 | - delay: 80
289 | content: "\e[2K\e[1G\e[36m⠸\e[39m Installing dependencies"
290 | - delay: 84
291 | content: "\e[2K\e[1G\e[36m⠼\e[39m Installing dependencies"
292 | - delay: 81
293 | content: "\e[2K\e[1G\e[36m⠴\e[39m Installing dependencies"
294 | - delay: 81
295 | content: "\e[2K\e[1G\e[36m⠦\e[39m Installing dependencies"
296 | - delay: 81
297 | content: "\e[2K\e[1G\e[36m⠧\e[39m Installing dependencies"
298 | - delay: 85
299 | content: "\e[2K\e[1G\e[36m⠇\e[39m Installing dependencies"
300 | - delay: 81
301 | content: "\e[2K\e[1G\e[?25h\e[32m✔\e[39m Installing dependencies\r\n\e[?25l\e[36m⠋\e[39m Running linter"
302 | - delay: 81
303 | content: "\e[2K\e[1G\e[36m⠙\e[39m Running linter"
304 | - delay: 82
305 | content: "\e[2K\e[1G\e[36m⠹\e[39m Running linter"
306 | - delay: 82
307 | content: "\e[2K\e[1G\e[36m⠸\e[39m Running linter"
308 | - delay: 81
309 | content: "\e[2K\e[1G\e[36m⠼\e[39m Running linter"
310 | - delay: 80
311 | content: "\e[2K\e[1G\e[36m⠴\e[39m Running linter"
312 | - delay: 83
313 | content: "\e[2K\e[1G\e[36m⠦\e[39m Running linter"
314 | - delay: 9
315 | content: "\e[2K\e[1G\e[?25h\e[32m✔\e[39m Running linter\r\n\e[?25l\e[36m⠋\e[39m Creating branch kickoff"
316 | - delay: 24
317 | content: "\e[2K\e[1G\e[?25h\e[32m✔\e[39m Creating branch kickoff\r\n\e[?25l\e[36m⠋\e[39m Add changes to git"
318 | - delay: 34
319 | content: "\e[2K\e[1G\e[?25h\e[32m✔\e[39m Add changes to git\r\n\e[?25l\e[36m⠋\e[39m Commit changes to git"
320 | - delay: 84
321 | content: "\e[2K\e[1G\e[36m⠙\e[39m Commit changes to git"
322 | - delay: 81
323 | content: "\e[2K\e[1G\e[36m⠹\e[39m Commit changes to git"
324 | - delay: 85
325 | content: "\e[2K\e[1G\e[36m⠸\e[39m Commit changes to git"
326 | - delay: 85
327 | content: "\e[2K\e[1G\e[36m⠼\e[39m Commit changes to git"
328 | - delay: 83
329 | content: "\e[2K\e[1G\e[36m⠴\e[39m Commit changes to git"
330 | - delay: 80
331 | content: "\e[2K\e[1G\e[36m⠦\e[39m Commit changes to git"
332 | - delay: 81
333 | content: "\e[2K\e[1G\e[36m⠋\e[39m Commit changes to git\e[2K\e[1G\e[?25h\e[32m✔\e[39m Commit changes to git\r\n\e[?25h\e[?25h"
334 | - delay: 8
335 | content: "\e[1m\e[7m%\e[27m\e[1m\e[0m \r \r\e]2;wolox@wolox: ~/test\a\e]1;~/test\a"
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "generator-w-express-js",
3 | "version": "3.0.1",
4 | "description": "Yeoman Kickoff for ExpressJS applications",
5 | "engines": {
6 | "node": "14.17.0",
7 | "npm": "6.14.13"
8 | },
9 | "files": [
10 | "generators"
11 | ],
12 | "scripts": {
13 | "test": "jest --silent",
14 | "eslint-check": "eslint --print-config .eslintrc.js",
15 | "lint": "eslint --ignore-pattern 'generators/app/templates/' \"**/*.js\"",
16 | "lint-diff": "git diff --name-only --cached --relative | grep \\\\.js$ | xargs eslint",
17 | "lint-fix": "npm run lint -- --fix",
18 | "precommit": "npm run lint",
19 | "prepush": "npm test",
20 | "outdated": "npm outdated --depth 0",
21 | "pretest": "npm run lint",
22 | "prestart": "npm run lint",
23 | "lint-external": "eslint -c .eslintrc.js"
24 | },
25 | "repository": {
26 | "type": "git",
27 | "url": "https://github.com/Wolox/express-js-bootstrap.git"
28 | },
29 | "author": "Wolox",
30 | "license": "MIT",
31 | "bugs": {
32 | "url": "https://github.com/Wolox/express-js-bootstrap/issues",
33 | "email": "tls@wolox.com.ar"
34 | },
35 | "cacheDirectories": [
36 | "node_modules"
37 | ],
38 | "homepage": "https://github.com/Wolox/express-js-bootstrap#readme",
39 | "dependencies": {
40 | "camel-case": "^4.1.1",
41 | "cfonts": "^2.4.5",
42 | "faker": "^4.1.0",
43 | "ora": "^4.0.3",
44 | "terminal-link": "^2.1.1",
45 | "yeoman-generator": "^4.13.0"
46 | },
47 | "devDependencies": {
48 | "babel-eslint": "^10.0.3",
49 | "eslint": "^6.8.0",
50 | "eslint-config-wolox": "^4.0.0",
51 | "eslint-config-wolox-node": "^3.0.0",
52 | "eslint-plugin-import": "^2.20.1",
53 | "eslint-plugin-jest": "^23.7.0",
54 | "eslint-plugin-prettier": "^3.1.2",
55 | "jest": "^27.3.1",
56 | "lodash": "^4.17.21",
57 | "prettier": "^1.19.1",
58 | "prettier-eslint": "^12.0.0",
59 | "yeoman-assert": "^3.1.1",
60 | "yeoman-test": "^2.1.0"
61 | },
62 | "jest": {
63 | "testEnvironment": "node",
64 | "testMatch": [
65 | "**/test/**/*.spec.js?(x)"
66 | ],
67 | "modulePathIgnorePatterns": [
68 | "/generators/app/templates"
69 | ],
70 | "clearMocks": true
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Summary
2 |
3 | [Change!] Describe your feature, problems you had, notes, improvements and others.
4 |
5 | ## Known Issues
6 |
7 | [Change!] List any known issue of the feature you are implementing.
8 |
9 | ## Trello Card
10 |
11 | [Change!] Link to the associated Trello card.
12 |
--------------------------------------------------------------------------------
/test/__snapshots__/ci.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`jenkins project creates expected .woloxci/Dockerfile 1`] = `
4 | "FROM node:8.9.12
5 |
6 | WORKDIR /usr/src/app
7 |
8 | ENV NODE_ENV testing
9 |
10 | ENV HOME /usr/src/app
11 |
12 | ENV BABEL_DISABLE_CACHE 1
13 |
14 | RUN mkdir -p /install
15 |
16 | ENV NODE_PATH=/install/node_modules
17 |
18 | # Install app dependencies
19 | # A wildcard is used to ensure both package.json AND package-lock.json are copied
20 | # where available (npm@5+)
21 | COPY package*.json /install/
22 |
23 | WORKDIR /install
24 |
25 | RUN npm install
26 | RUN npm install -g gulp
27 | # If you are building your code for production
28 | # RUN npm install --only=production
29 |
30 | RUN chmod a+r /usr/src/app
31 |
32 | WORKDIR /usr/src/app
33 |
34 | # Bundle app source
35 | COPY . .
36 | "
37 | `;
38 |
39 | exports[`jenkins project creates expected .woloxci/config.yml 1`] = `
40 | "config:
41 | dockerfile: .woloxci/Dockerfile
42 | project_name: CIProject
43 |
44 | steps:
45 | copy_node_modules:
46 | - cp -r $NODE_PATH/ ./
47 | lint:
48 | - npm run lint
49 | test:
50 | - npm run test
51 |
52 | environment:
53 | GIT_COMMITTER_NAME: a
54 | GIT_COMMITTER_EMAIL: b
55 | LANG: C.UTF-8
56 | "
57 | `;
58 |
59 | exports[`jenkins project creates expected Jenkinsfile 1`] = `
60 | "@Library('wolox-ci') _
61 |
62 | node {
63 |
64 | checkout scm
65 |
66 | woloxCi('.woloxci/config.yml');
67 | }
68 | "
69 | `;
70 |
71 | exports[`travis project creates expected .travis.yml 1`] = `
72 | "language: node_js
73 |
74 | node_js:
75 | - \\"8.9.12\\"
76 |
77 | sudo: true
78 |
79 | env:
80 | - CXX=g++-4.8 NODE_ENV=testing
81 | addons:
82 | apt:
83 | sources:
84 | - ubuntu-toolchain-r-test
85 | packages:
86 | - g++-4.8
87 | "
88 | `;
89 |
--------------------------------------------------------------------------------
/test/__snapshots__/deploy.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Deploy with aws creates expected .ebextensions/cloudwatch.config 1`] = `
4 | "packages:
5 | yum:
6 | perl-DateTime: []
7 | perl-Sys-Syslog: []
8 | perl-LWP-Protocol-https: []
9 | perl-Switch: []
10 | perl-URI: []
11 | perl-Bundle-LWP: []
12 | sources:
13 | /opt/cloudwatch: https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.1.zip
14 |
15 | container_commands:
16 | 01-setupcron:
17 | command: |
18 | echo '*/5 * * * * root perl /opt/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl \`{\\"Fn::GetOptionSetting\\" : { \\"OptionName\\" : \\"CloudWatchMetrics\\", \\"DefaultValue\\" : \\"--mem-util --disk-space-util --disk-path=/\\" }}\` >> /var/log/cwpump.log 2>&1' > /etc/cron.d/cwpump
19 | 02-changeperm:
20 | command: chmod 644 /etc/cron.d/cwpump
21 | 03-changeperm:
22 | command: chmod u+x /opt/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl
23 | option_settings:
24 | \\"aws:autoscaling:launchconfiguration\\" :
25 | IamInstanceProfile : \\"aws-elasticbeanstalk-ec2-role\\"
26 | \\"aws:elasticbeanstalk:customoption\\" :
27 | CloudWatchMetrics : \\"--mem-util --mem-used --mem-avail --disk-space-util --disk-space-used --disk-space-avail --disk-path=/ --auto-scaling\\"
28 | "
29 | `;
30 |
31 | exports[`Deploy with docker and aws creates expected .ebextensions/cloudwatch.config 1`] = `
32 | "packages:
33 | yum:
34 | perl-DateTime: []
35 | perl-Sys-Syslog: []
36 | perl-LWP-Protocol-https: []
37 | perl-Switch: []
38 | perl-URI: []
39 | perl-Bundle-LWP: []
40 | sources:
41 | /opt/cloudwatch: https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.1.zip
42 |
43 | container_commands:
44 | 01-setupcron:
45 | command: |
46 | echo '*/5 * * * * root perl /opt/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl \`{\\"Fn::GetOptionSetting\\" : { \\"OptionName\\" : \\"CloudWatchMetrics\\", \\"DefaultValue\\" : \\"--mem-util --disk-space-util --disk-path=/\\" }}\` >> /var/log/cwpump.log 2>&1' > /etc/cron.d/cwpump
47 | 02-changeperm:
48 | command: chmod 644 /etc/cron.d/cwpump
49 | 03-changeperm:
50 | command: chmod u+x /opt/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl
51 | option_settings:
52 | \\"aws:autoscaling:launchconfiguration\\" :
53 | IamInstanceProfile : \\"aws-elasticbeanstalk-ec2-role\\"
54 | \\"aws:elasticbeanstalk:customoption\\" :
55 | CloudWatchMetrics : \\"--mem-util --mem-used --mem-avail --disk-space-util --disk-space-used --disk-space-avail --disk-path=/ --auto-scaling\\"
56 | "
57 | `;
58 |
59 | exports[`Deploy with docker and aws creates expected Dockerfile 1`] = `
60 | "FROM node:8.9.12
61 |
62 | WORKDIR /home/node/app
63 |
64 | COPY package.json .
65 | COPY package-lock.json .
66 | COPY .nvmrc .
67 |
68 | RUN npm install
69 |
70 | COPY . .
71 |
72 | EXPOSE 8080
73 | ENV NODE_ENV production
74 | CMD [\\"node\\", \\"server.js\\"]
75 | "
76 | `;
77 |
78 | exports[`Deploy with docker and aws creates expected Dockerrun.aws.json 1`] = `
79 | "{
80 | \\"AWSEBDockerrunVersion\\": \\"1\\",
81 | \\"Ports\\": [
82 | {
83 | \\"ContainerPort\\": \\"8080\\"
84 | }
85 | ],
86 | \\"Volumes\\": [],
87 | \\"Logging\\": \\"/home/node/app/app/logger/logs\\"
88 | }
89 | "
90 | `;
91 |
92 | exports[`Deploy with docker creates expected Dockerfile 1`] = `
93 | "FROM node:8.9.12
94 |
95 | WORKDIR /home/node/app
96 |
97 | COPY package.json .
98 | COPY package-lock.json .
99 | COPY .nvmrc .
100 |
101 | RUN npm install
102 |
103 | COPY . .
104 |
105 | EXPOSE 8080
106 | ENV NODE_ENV production
107 | CMD [\\"node\\", \\"server.js\\"]
108 | "
109 | `;
110 |
111 | exports[`Deploy with heroku creates expected Procfile 1`] = `
112 | "web: node server.js
113 | "
114 | `;
115 |
--------------------------------------------------------------------------------
/test/__snapshots__/mongoose.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Mongoose project creates expected README.md 1`] = `
4 | "# MongooseProject
5 |
6 | MongooseProject
7 |
8 | ## First steps
9 |
10 | #### Installing node
11 |
12 | Get the latest version of node from the [official website](https://nodejs.org/) or using [nvm](https://github.com/creationix/nvm)
13 | Nvm approach is preferred.
14 |
15 | #### Getting dependencies
16 |
17 | Run \`npm install\` or \`yarn\` from rootpath of the project.
18 |
19 | #### Database configuration
20 |
21 | Before running the app, make sure you have [mongoDB installed](https://hevodata.com/blog/install-mongodb-on-ubuntu/) and a db created, to create it run the following steps inside a terminal:
22 |
23 | 1. mongo
24 | 2. use db_project_name
25 | 3. db.createUser({user:\\"root\\", pwd:\\"superpass\\", roles:[{role:\\"root\\", db:\\"db_project_name\\"}]})
26 | 4. *exit from mongo*
27 | 5. mongo -u root -p superpass --authenticationDatabase db_project_name
28 |
29 | Then, set in \`.env\` some variables:
30 |
31 | - DB_HOST=localhost
32 | - DB_PORT=5432
33 | - DB_USERNAME=project_name
34 | - DB_PASSWORD=project_name
35 | - DB_NAME=db_project_name
36 | - DB_NAME_DEV=db_project_name_dev
37 | - DB_NAME_TEST=db_project_name_test
38 | - API_DATE=X-API-Date
39 | - PACKAGE_VERSION=X-Package-Version
40 | - NODE_VERSION=X-Node-Version
41 |
42 |
43 | #### Starting your app
44 |
45 | Now, we have two ways to start an app. To start your app in production mode run \`npm start\` in the root path of your project. To start your app in development mode (nodemon) run \`npm run start-dev\`. Then access your app at **localhost:port**. The port is logged in the console where you ran the start script.
46 |
47 | ## Development
48 |
49 | #### Environments
50 |
51 | By default, the environment will be **development**, but you can easily change it using the **NODE_ENV** environmental variable.
52 |
53 | #### Environment variables
54 |
55 | \`Dotenv\` is used for managing environment variables. They are stored in the \`/.env\` file. Take into account that the variables defined in the \`bashrc\` are not overrided.
56 |
57 | The environment variables should be added to the \`.env\` file in the form of \`NAME=VALUE\`, as the following example:
58 |
59 | \`\`\`
60 | DB_USERNAME=root
61 | DB_PASS=superpass
62 | DB_PASSWORD=superpass
63 | PORT=8081
64 | CLIENTS_API=http://api.clients.example.org/
65 | \`\`\`
66 |
67 | **Remember not to push nor commit the \`.env\` file.**
68 |
69 | #### Logging
70 |
71 | To log useful information of your program to the console you just need to import the logger located at \`app/logger\`. There are two possible types of logging: \`info\` and \`error\`. You should use them depending on the type of message you want to show.
72 |
73 | Here is an example snippet:
74 |
75 | \`\`\`
76 | const logger = require('/app/logger');
77 | ...
78 | if (error) {
79 | logger.error('There is an error);
80 | } else {
81 | logger.info('There is no error);
82 | }
83 | \`\`\`
84 |
85 | #### Testing
86 |
87 | To run your tests you first need to config your testing database by setting the env var \`DB_NAME_TEST\`. as explained
88 | before in [Database configuration](#database-configuration). Also you need to run the migrations in this exclusive
89 | testing database each time you have new ones, you can do this by running the command \`npm run migrations-test\`.
90 | Once you have all the above done you can run your tests with the following command: \`npm test\`. For more information refeer to the documentation of [Jest](https://jestjs.io/docs/en/getting-started).
91 |
92 |
93 | #### Debugging
94 |
95 | As we know, a NodeJS application is not something easy to debug and because of that we've added the \`--inspect\` flag to make it simpler. You can download a node inspection manager for Chrome, so Chrome DevTools will automatically start when you run your app using \`npm run start-dev\`, making your debugging easier. You can read more about the different inspector clients here:
96 |
97 | #### REPL console
98 |
99 | We can use a node console with \`npm run console\`. There your service objects are exposed as _servicename_ + \\"Service\\". Let's suppose that we have a service \`users\` which has a function \`getAll\`. In your console you can call \`usersService.getAll()\` and see the result. Note that this works also with functions that return promises! To exit the console use \`.exit\`.
100 |
101 | #### Documentation
102 |
103 | Documentation will be served at \`/docs\`. We use [OpenAPI](https://github.com/OAI/OpenAPI-Specification) A.K.A \`Swagger\`. Check [this link](https://medium.com/wolox-driving-innovation/documenting-a-nodejs-rest-api-with-openapi-3-swagger-5deee9f50420) for more details on how to use it.
104 |
105 | ## Deploy
106 |
107 | #### Heroku
108 |
109 | Pushing the desired branch to heroku should be enough.
110 | For more information check: https://devcenter.heroku.com/articles/getting-started-with-nodejs#define-a-procfile.
111 |
112 | ## Contributing
113 |
114 | 1. Fork it
115 | 2. Create your feature branch (\`git checkout -b my-new-feature\`)
116 | 3. Run the tests (\`npm test\`)
117 | 4. Commit your changes (\`git commit -am 'Add some feature'\`)
118 | 5. Push to the branch (\`git push origin my-new-feature\`)
119 | 6. Create new Pull Request
120 |
121 | ## About
122 |
123 | This project is maintained by [Wolox](https://github.com/wolox) and it was written by [Wolox](http://www.wolox.com.ar).
124 |
125 | 
126 |
127 | ## License
128 |
129 | **MongooseProject** is available under the MIT [license](LICENSE.md).
130 |
131 | Copyright (c) 2019 Wolox
132 |
133 | Permission is hereby granted, free of charge, to any person obtaining a copy
134 | of this software and associated documentation files (the \\"Software\\"), to deal
135 | in the Software without restriction, including without limitation the rights
136 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
137 | copies of the Software, and to permit persons to whom the Software is
138 | furnished to do so, subject to the following conditions:
139 |
140 | The above copyright notice and this permission notice shall be included in
141 | all copies or substantial portions of the Software.
142 |
143 | THE SOFTWARE IS PROVIDED \\"AS IS\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
144 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
145 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
146 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
147 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
148 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
149 | THE SOFTWARE.
150 | "
151 | `;
152 |
153 | exports[`Mongoose project creates expected config/db.js 1`] = `
154 | "const mongoose = require('mongoose');
155 | const config = require('../config').common.database;
156 |
157 | const host = config.host;
158 | const port = config.port;
159 | const name = config.name;
160 | const connectionString = \`mongodb://\${host}:\${port}/\${name}\`;
161 | module.exports = mongoose.connect(connectionString);
162 |
163 |
164 | "
165 | `;
166 |
167 | exports[`Mongoose project creates expected console.js 1`] = `
168 | "/* eslint-disable global-require */
169 | const repl = require('repl');
170 | const fs = require('fs');
171 |
172 | const pjson = require('./package.json');
173 |
174 | const convertFunctionToAsync = f => async (...args) => {
175 | const result = await f(...args);
176 | console.log(JSON.stringify(result, null, 2)); // eslint-disable-line no-console
177 | return result;
178 | };
179 |
180 | const convertObjectFunctionsToAsync = serviceMethods => {
181 | const asyncServiceMethods = {};
182 | Object.keys(serviceMethods).forEach(key => {
183 | if (typeof serviceMethods[key] === 'function') {
184 | asyncServiceMethods[key] = convertFunctionToAsync(serviceMethods[key]);
185 | } else asyncServiceMethods[key] = serviceMethods[key];
186 | });
187 | return asyncServiceMethods;
188 | };
189 |
190 | Promise.resolve().then(() => {
191 | const replServer = repl.start({
192 | prompt: \`\${pjson.name}> \`
193 | });
194 | const servicesPath = './app/services/';
195 | fs.readdir(servicesPath, (err, files) => {
196 | files.forEach(file => {
197 | const serviceMethods = require(\`\${servicesPath}\${file}\`);
198 | const asyncServiceMethods = convertObjectFunctionsToAsync(serviceMethods);
199 | replServer.context[\`\${file.split('.')[0]}Service\`] = asyncServiceMethods;
200 | });
201 | });
202 | });
203 | "
204 | `;
205 |
206 | exports[`Mongoose project creates expected package.json 1`] = `
207 | "{
208 | \\"name\\": \\"MongooseProject\\",
209 | \\"version\\": \\"0.1.0\\",
210 | \\"description\\": \\"MongooseProject\\",
211 | \\"engines\\": {
212 | \\"node\\": \\"8.9.12\\",
213 | \\"npm\\": \\"6.4.1\\"
214 | },
215 | \\"scripts\\": {
216 | \\"console\\": \\"node console.js\\",
217 | \\"cover\\": \\"npm run test -- --coverage\\",
218 | \\"test\\": \\"NODE_ENV=testing jest --runInBand --forceExit --detectOpenHandles\\",
219 | \\"test-inspect\\": \\"NODE_ENV=testing node --inspect --debug-brk jest\\",
220 | \\"eslint-check\\": \\"eslint --print-config .eslintrc.js --ignore-pattern ./.eslintrc.js | eslint-config-prettier-check\\",
221 | \\"lint\\": \\"eslint \\\\\\"**/*.js\\\\\\" --ignore-pattern ./.eslintrc.js\\",
222 | \\"lint-diff\\": \\"git diff --diff-filter=ACM --name-only --cached --relative | grep \\\\\\\\\\\\\\\\.js$ | xargs eslint\\",
223 | \\"lint-fix\\": \\"npm run lint -- --fix\\",
224 | \\"outdated\\": \\"npm outdated --depth 0\\",
225 | \\"pretest\\": \\"npm run lint\\",
226 | \\"start-dev\\": \\"nodemon --inspect server.js\\",
227 | \\"prestart-dev\\": \\"npm run lint\\",
228 | \\"start\\": \\"node server.js\\",
229 | \\"seed\\": \\"sequelize db:seed:all\\",
230 | \\"create-seed\\": \\"sequelize seed:generate --name\\",
231 | \\"create-migration\\": \\"sequelize migration:generate --name\\"
232 | },
233 | \\"cacheDirectories\\": [
234 | \\"node_modules\\"
235 | ],
236 | \\"main\\": \\"app.js\\",
237 | \\"author\\": \\"Wolox\\",
238 | \\"homepage\\": \\"https://test.com.ar\\",
239 | \\"license\\": \\"MIT\\",
240 | \\"repository\\": {
241 | \\"type\\": \\"git\\",
242 | \\"url\\": \\"https://test.com.ar.git\\"
243 | },
244 | \\"bugs\\": {
245 | \\"url\\": \\"https://test.com.ar/issues\\",
246 | \\"email\\": \\"tls@wolox.com.ar\\"
247 | },
248 | \\"jest\\": {
249 | \\"coverageThreshold\\": {
250 | \\"global\\": {
251 | \\"branches\\": 80,
252 | \\"functions\\": 80,
253 | \\"lines\\": 80,
254 | \\"statements\\": 80
255 | }
256 | },
257 | \\"collectCoverageFrom\\": [
258 | \\"**/*.js\\",
259 | \\"!**/console.js\\",
260 | \\"!**/node_modules/**\\",
261 | \\"!**/build/**\\",
262 | \\"!**/migrations/**\\",
263 | \\"!**/config/**\\",
264 | \\"!**/scripts/**\\"
265 | ],
266 | \\"setupFilesAfterEnv\\": [
267 | \\"/test/setup.js\\"
268 | ],
269 | \\"testEnvironment\\": \\"node\\",
270 | \\"transform\\": {
271 | \\"^.+\\\\\\\\.js$\\": \\"babel-jest\\"
272 | }
273 | },
274 | \\"dependencies\\": {
275 | \\"bcryptjs\\": \\"^2.4.3\\",
276 | \\"mongoose\\": \\"^5.6.4\\",
277 | \\"mongodb\\" : \\"^4.1.3\\",
278 | \\"body-parser\\": \\"^1.19.0\\",
279 | \\"express\\": \\"^4.17.1\\",
280 | \\"jwt-simple\\": \\"^0.5.6\\",
281 | \\"umzug\\": \\"^2.3.0\\",
282 | \\"express-wolox-logger\\": \\"^2.0.0\\",
283 | \\"axios\\": \\"^0.24.0\\",
284 | \\"swagger-ui-express\\": \\"^4.1.6\\"
285 | },
286 | \\"devDependencies\\": {
287 | \\"babel\\": \\"6.23.0\\",
288 | \\"babel-core\\": \\"^6.26.3\\",
289 | \\"babel-eslint\\": \\"^10.1.0\\",
290 | \\"babel-jest\\": \\"^27.3.1\\",
291 | \\"jest\\": \\"^27.3.1\\",
292 | \\"supertest\\": \\"^6.1.6\\",
293 | \\"babel-preset-es2015\\": \\"6.24.1\\",
294 | \\"dotenv\\": \\"^10.0.0\\",
295 | \\"eslint\\": \\"^6.8.0\\",
296 | \\"eslint-config-wolox\\": \\"^4.0.0\\",
297 | \\"eslint-config-wolox-node\\": \\"^3.0.0\\",
298 | \\"eslint-plugin-import\\": \\"^2.25.2\\",
299 | \\"eslint-plugin-prettier\\": \\"^3.0.1\\",
300 | \\"husky\\": \\"^7.0.4\\",
301 | \\"istanbul\\": \\"^0.4.3\\",
302 | \\"mocha\\": \\"^9.1.3\\",
303 | \\"mocha-lcov-reporter\\": \\"^1.3.0\\",
304 | \\"nodemon\\": \\"^2.0.14\\",
305 | \\"prettier\\": \\"^1.15.3\\",
306 | \\"prettier-eslint\\": \\"^9.0.1\\",
307 | \\"prompt\\": \\"^1.2.0\\"
308 | },
309 | \\"husky\\": {
310 | \\"hooks\\": {
311 | \\"pre-commit\\": \\"npm run lint-diff\\",
312 | \\"pre-push\\": \\"npm test\\"
313 | }
314 | }
315 | }
316 | "
317 | `;
318 |
319 | exports[`Mongoose project creates expected server.js 1`] = `
320 | "const app = require('./app');
321 | const config = require('./config');
322 | const logger = require('./app/logger');
323 |
324 | const port = config.common.api.port || 8080;
325 |
326 | Promise.resolve()
327 |
328 | .then(() => {
329 |
330 |
331 | app.listen(port);
332 |
333 | logger.info(\`Listening on port: \${port}\`);
334 | })
335 | .catch(logger.error);"
336 | `;
337 |
--------------------------------------------------------------------------------
/test/__snapshots__/optionals.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Project with cors creates expected app.js 1`] = `
4 | "const { expressMiddleware, expressRequestIdMiddleware } = require('express-wolox-logger');
5 | const express = require('express');
6 | const bodyParser = require('body-parser');
7 | const swaggerUi = require('swagger-ui-express');
8 | const cors = require('cors');
9 | const config = require('./config');
10 | const routes = require('./app/routes');
11 | const errors = require('./app/middlewares/errors');
12 | const documentation = require('./documentation');
13 | const logger = require('./app/logger');
14 | const { verifyDocumentationToken } = require('./app/middlewares/docsAuth');
15 |
16 | const DEFAULT_BODY_SIZE_LIMIT = 1024 * 1024 * 10;
17 | const DEFAULT_PARAMETER_LIMIT = 10000;
18 |
19 | const bodyParserJsonConfig = () => ({
20 | parameterLimit: config.common.api.parameterLimit || DEFAULT_PARAMETER_LIMIT,
21 | limit: config.common.api.bodySizeLimit || DEFAULT_BODY_SIZE_LIMIT
22 | });
23 |
24 | const bodyParserUrlencodedConfig = () => ({
25 | extended: true,
26 | parameterLimit: config.common.api.parameterLimit || DEFAULT_PARAMETER_LIMIT,
27 | limit: config.common.api.bodySizeLimit || DEFAULT_BODY_SIZE_LIMIT
28 | });
29 |
30 | const app = express();
31 |
32 | app.use(cors());
33 |
34 |
35 |
36 | // Client must send \\"Content-Type: application/json\\" header
37 | app.use(bodyParser.json(bodyParserJsonConfig()));
38 | app.use(bodyParser.urlencoded(bodyParserUrlencodedConfig()));
39 | app.use(expressRequestIdMiddleware());
40 | app.use('/docs',
41 | verifyDocumentationToken,
42 | swaggerUi.serve, swaggerUi.setup(documentation));
43 |
44 | if (!config.isTesting) app.use(expressMiddleware({ loggerFn: logger.info }));
45 |
46 | routes.init(app);
47 |
48 | app.use(errors.handle);
49 |
50 | module.exports = app;
51 | "
52 | `;
53 |
54 | exports[`Project with cors creates expected package.json 1`] = `
55 | "{
56 | \\"name\\": \\"OptionalProject\\",
57 | \\"version\\": \\"0.1.0\\",
58 | \\"description\\": \\"Example\\",
59 | \\"engines\\": {
60 | \\"node\\": \\"8.9.12\\",
61 | \\"npm\\": \\"6.4.1\\"
62 | },
63 | \\"scripts\\": {
64 | \\"console\\": \\"node console.js\\",
65 | \\"cover\\": \\"npm run test -- --coverage\\",
66 | \\"test\\": \\"NODE_ENV=testing jest --runInBand --forceExit --detectOpenHandles\\",
67 | \\"test-inspect\\": \\"NODE_ENV=testing node --inspect --debug-brk jest\\",
68 | \\"eslint-check\\": \\"eslint --print-config .eslintrc.js --ignore-pattern ./.eslintrc.js | eslint-config-prettier-check\\",
69 | \\"lint\\": \\"eslint \\\\\\"**/*.js\\\\\\" --ignore-pattern ./.eslintrc.js\\",
70 | \\"lint-diff\\": \\"git diff --diff-filter=ACM --name-only --cached --relative | grep \\\\\\\\\\\\\\\\.js$ | xargs eslint\\",
71 | \\"lint-fix\\": \\"npm run lint -- --fix\\",
72 | \\"outdated\\": \\"npm outdated --depth 0\\",
73 | \\"pretest\\": \\"npm run lint\\",
74 | \\"start-dev\\": \\"nodemon --inspect server.js\\",
75 | \\"prestart-dev\\": \\"npm run lint\\",
76 | \\"start\\": \\"node server.js\\",
77 | \\"seed\\": \\"sequelize db:seed:all\\",
78 | \\"create-seed\\": \\"sequelize seed:generate --name\\",
79 | \\"create-migration\\": \\"sequelize migration:generate --name\\"
80 | },
81 | \\"cacheDirectories\\": [
82 | \\"node_modules\\"
83 | ],
84 | \\"main\\": \\"app.js\\",
85 | \\"author\\": \\"Wolox\\",
86 | \\"homepage\\": \\"https://test.com.ar\\",
87 | \\"license\\": \\"MIT\\",
88 | \\"repository\\": {
89 | \\"type\\": \\"git\\",
90 | \\"url\\": \\"https://test.com.ar.git\\"
91 | },
92 | \\"bugs\\": {
93 | \\"url\\": \\"https://test.com.ar/issues\\",
94 | \\"email\\": \\"tls@wolox.com.ar\\"
95 | },
96 | \\"jest\\": {
97 | \\"coverageThreshold\\": {
98 | \\"global\\": {
99 | \\"branches\\": 80,
100 | \\"functions\\": 80,
101 | \\"lines\\": 80,
102 | \\"statements\\": 80
103 | }
104 | },
105 | \\"collectCoverageFrom\\": [
106 | \\"**/*.js\\",
107 | \\"!**/console.js\\",
108 | \\"!**/node_modules/**\\",
109 | \\"!**/build/**\\",
110 | \\"!**/migrations/**\\",
111 | \\"!**/config/**\\",
112 | \\"!**/scripts/**\\"
113 | ],
114 | \\"setupFilesAfterEnv\\": [
115 | \\"/test/setup.js\\"
116 | ],
117 | \\"testEnvironment\\": \\"node\\",
118 | \\"transform\\": {
119 | \\"^.+\\\\\\\\.js$\\": \\"babel-jest\\"
120 | }
121 | },
122 | \\"dependencies\\": {
123 | \\"bcryptjs\\": \\"^2.4.3\\",
124 | \\"body-parser\\": \\"^1.19.0\\",
125 | \\"cors\\": \\"^2.8.5\\",
126 | \\"express\\": \\"^4.17.1\\",
127 | \\"jwt-simple\\": \\"^0.5.6\\",
128 | \\"umzug\\": \\"^2.3.0\\",
129 | \\"express-wolox-logger\\": \\"^2.0.0\\",
130 | \\"axios\\": \\"^0.24.0\\",
131 | \\"swagger-ui-express\\": \\"^4.1.6\\"
132 | },
133 | \\"devDependencies\\": {
134 | \\"babel\\": \\"6.23.0\\",
135 | \\"babel-core\\": \\"^6.26.3\\",
136 | \\"babel-eslint\\": \\"^10.1.0\\",
137 | \\"babel-jest\\": \\"^27.3.1\\",
138 | \\"jest\\": \\"^27.3.1\\",
139 | \\"supertest\\": \\"^6.1.6\\",
140 | \\"babel-preset-es2015\\": \\"6.24.1\\",
141 | \\"dotenv\\": \\"^10.0.0\\",
142 | \\"eslint\\": \\"^6.8.0\\",
143 | \\"eslint-config-wolox\\": \\"^4.0.0\\",
144 | \\"eslint-config-wolox-node\\": \\"^3.0.0\\",
145 | \\"eslint-plugin-import\\": \\"^2.25.2\\",
146 | \\"eslint-plugin-prettier\\": \\"^3.0.1\\",
147 | \\"husky\\": \\"^7.0.4\\",
148 | \\"istanbul\\": \\"^0.4.3\\",
149 | \\"mocha\\": \\"^9.1.3\\",
150 | \\"mocha-lcov-reporter\\": \\"^1.3.0\\",
151 | \\"nodemon\\": \\"^2.0.14\\",
152 | \\"prettier\\": \\"^1.15.3\\",
153 | \\"prettier-eslint\\": \\"^9.0.1\\",
154 | \\"prompt\\": \\"^1.2.0\\"
155 | },
156 | \\"husky\\": {
157 | \\"hooks\\": {
158 | \\"pre-commit\\": \\"npm run lint-diff\\",
159 | \\"pre-push\\": \\"npm test\\"
160 | }
161 | }
162 | }
163 | "
164 | `;
165 |
166 | exports[`Project with coveralls creates expected package.json 1`] = `
167 | "{
168 | \\"name\\": \\"OptionalProject\\",
169 | \\"version\\": \\"0.1.0\\",
170 | \\"description\\": \\"Example\\",
171 | \\"engines\\": {
172 | \\"node\\": \\"8.9.12\\",
173 | \\"npm\\": \\"6.4.1\\"
174 | },
175 | \\"scripts\\": {
176 | \\"console\\": \\"node console.js\\",
177 | \\"cover\\": \\"npm run test -- --coverage\\",
178 | \\"test\\": \\"NODE_ENV=testing jest --runInBand --forceExit --detectOpenHandles\\",
179 | \\"test-inspect\\": \\"NODE_ENV=testing node --inspect --debug-brk jest\\",
180 | \\"coveralls\\": \\"npm run cover -- --report lcovonly && cat ./coverage/lcov.info | coveralls\\",
181 | \\"eslint-check\\": \\"eslint --print-config .eslintrc.js --ignore-pattern ./.eslintrc.js | eslint-config-prettier-check\\",
182 | \\"lint\\": \\"eslint \\\\\\"**/*.js\\\\\\" --ignore-pattern ./.eslintrc.js\\",
183 | \\"lint-diff\\": \\"git diff --diff-filter=ACM --name-only --cached --relative | grep \\\\\\\\\\\\\\\\.js$ | xargs eslint\\",
184 | \\"lint-fix\\": \\"npm run lint -- --fix\\",
185 | \\"outdated\\": \\"npm outdated --depth 0\\",
186 | \\"pretest\\": \\"npm run lint\\",
187 | \\"start-dev\\": \\"nodemon --inspect server.js\\",
188 | \\"prestart-dev\\": \\"npm run lint\\",
189 | \\"start\\": \\"node server.js\\",
190 | \\"seed\\": \\"sequelize db:seed:all\\",
191 | \\"create-seed\\": \\"sequelize seed:generate --name\\",
192 | \\"create-migration\\": \\"sequelize migration:generate --name\\"
193 | },
194 | \\"cacheDirectories\\": [
195 | \\"node_modules\\"
196 | ],
197 | \\"main\\": \\"app.js\\",
198 | \\"author\\": \\"Wolox\\",
199 | \\"homepage\\": \\"https://test.com.ar\\",
200 | \\"license\\": \\"MIT\\",
201 | \\"repository\\": {
202 | \\"type\\": \\"git\\",
203 | \\"url\\": \\"https://test.com.ar.git\\"
204 | },
205 | \\"bugs\\": {
206 | \\"url\\": \\"https://test.com.ar/issues\\",
207 | \\"email\\": \\"tls@wolox.com.ar\\"
208 | },
209 | \\"jest\\": {
210 | \\"coverageThreshold\\": {
211 | \\"global\\": {
212 | \\"branches\\": 80,
213 | \\"functions\\": 80,
214 | \\"lines\\": 80,
215 | \\"statements\\": 80
216 | }
217 | },
218 | \\"collectCoverageFrom\\": [
219 | \\"**/*.js\\",
220 | \\"!**/console.js\\",
221 | \\"!**/node_modules/**\\",
222 | \\"!**/build/**\\",
223 | \\"!**/migrations/**\\",
224 | \\"!**/config/**\\",
225 | \\"!**/scripts/**\\"
226 | ],
227 | \\"setupFilesAfterEnv\\": [
228 | \\"/test/setup.js\\"
229 | ],
230 | \\"testEnvironment\\": \\"node\\",
231 | \\"transform\\": {
232 | \\"^.+\\\\\\\\.js$\\": \\"babel-jest\\"
233 | }
234 | },
235 | \\"dependencies\\": {
236 | \\"bcryptjs\\": \\"^2.4.3\\",
237 | \\"body-parser\\": \\"^1.19.0\\",
238 | \\"express\\": \\"^4.17.1\\",
239 | \\"jwt-simple\\": \\"^0.5.6\\",
240 | \\"umzug\\": \\"^2.3.0\\",
241 | \\"express-wolox-logger\\": \\"^2.0.0\\",
242 | \\"axios\\": \\"^0.24.0\\",
243 | \\"swagger-ui-express\\": \\"^4.1.6\\"
244 | },
245 | \\"devDependencies\\": {
246 | \\"babel\\": \\"6.23.0\\",
247 | \\"babel-core\\": \\"^6.26.3\\",
248 | \\"babel-eslint\\": \\"^10.1.0\\",
249 | \\"babel-jest\\": \\"^27.3.1\\",
250 | \\"jest\\": \\"^27.3.1\\",
251 | \\"supertest\\": \\"^6.1.6\\",
252 | \\"babel-preset-es2015\\": \\"6.24.1\\",
253 | \\"coveralls\\": \\"^3.1.1\\",
254 | \\"dotenv\\": \\"^10.0.0\\",
255 | \\"eslint\\": \\"^6.8.0\\",
256 | \\"eslint-config-wolox\\": \\"^4.0.0\\",
257 | \\"eslint-config-wolox-node\\": \\"^3.0.0\\",
258 | \\"eslint-plugin-import\\": \\"^2.25.2\\",
259 | \\"eslint-plugin-prettier\\": \\"^3.0.1\\",
260 | \\"husky\\": \\"^7.0.4\\",
261 | \\"istanbul\\": \\"^0.4.3\\",
262 | \\"mocha\\": \\"^9.1.3\\",
263 | \\"mocha-lcov-reporter\\": \\"^1.3.0\\",
264 | \\"nodemon\\": \\"^2.0.14\\",
265 | \\"prettier\\": \\"^1.15.3\\",
266 | \\"prettier-eslint\\": \\"^9.0.1\\",
267 | \\"prompt\\": \\"^1.2.0\\"
268 | },
269 | \\"husky\\": {
270 | \\"hooks\\": {
271 | \\"pre-commit\\": \\"npm run lint-diff\\",
272 | \\"pre-push\\": \\"npm test\\"
273 | }
274 | }
275 | }
276 | "
277 | `;
278 |
279 | exports[`Project with rollbar creates expected app.js 1`] = `
280 | "const { expressMiddleware, expressRequestIdMiddleware } = require('express-wolox-logger');
281 | const express = require('express');
282 | const bodyParser = require('body-parser');
283 | const swaggerUi = require('swagger-ui-express');
284 | const config = require('./config');
285 | const routes = require('./app/routes');
286 | const errors = require('./app/middlewares/errors');
287 | const documentation = require('./documentation');
288 | const logger = require('./app/logger');
289 | const { verifyDocumentationToken } = require('./app/middlewares/docsAuth');
290 |
291 | const DEFAULT_BODY_SIZE_LIMIT = 1024 * 1024 * 10;
292 | const DEFAULT_PARAMETER_LIMIT = 10000;
293 |
294 | const bodyParserJsonConfig = () => ({
295 | parameterLimit: config.common.api.parameterLimit || DEFAULT_PARAMETER_LIMIT,
296 | limit: config.common.api.bodySizeLimit || DEFAULT_BODY_SIZE_LIMIT
297 | });
298 |
299 | const bodyParserUrlencodedConfig = () => ({
300 | extended: true,
301 | parameterLimit: config.common.api.parameterLimit || DEFAULT_PARAMETER_LIMIT,
302 | limit: config.common.api.bodySizeLimit || DEFAULT_BODY_SIZE_LIMIT
303 | });
304 |
305 | const app = express();
306 |
307 |
308 |
309 |
310 | // Client must send \\"Content-Type: application/json\\" header
311 | app.use(bodyParser.json(bodyParserJsonConfig()));
312 | app.use(bodyParser.urlencoded(bodyParserUrlencodedConfig()));
313 | app.use(expressRequestIdMiddleware());
314 | app.use('/docs',
315 | verifyDocumentationToken,
316 | swaggerUi.serve, swaggerUi.setup(documentation));
317 |
318 | if (!config.isTesting) app.use(expressMiddleware({ loggerFn: logger.info }));
319 |
320 | routes.init(app);
321 |
322 | app.use(errors.handle);
323 |
324 | module.exports = app;
325 | "
326 | `;
327 |
328 | exports[`Project with rollbar creates expected package.json 1`] = `
329 | "{
330 | \\"name\\": \\"OptionalProject\\",
331 | \\"version\\": \\"0.1.0\\",
332 | \\"description\\": \\"Example\\",
333 | \\"engines\\": {
334 | \\"node\\": \\"8.9.12\\",
335 | \\"npm\\": \\"6.4.1\\"
336 | },
337 | \\"scripts\\": {
338 | \\"console\\": \\"node console.js\\",
339 | \\"cover\\": \\"npm run test -- --coverage\\",
340 | \\"test\\": \\"NODE_ENV=testing jest --runInBand --forceExit --detectOpenHandles\\",
341 | \\"test-inspect\\": \\"NODE_ENV=testing node --inspect --debug-brk jest\\",
342 | \\"eslint-check\\": \\"eslint --print-config .eslintrc.js --ignore-pattern ./.eslintrc.js | eslint-config-prettier-check\\",
343 | \\"lint\\": \\"eslint \\\\\\"**/*.js\\\\\\" --ignore-pattern ./.eslintrc.js\\",
344 | \\"lint-diff\\": \\"git diff --diff-filter=ACM --name-only --cached --relative | grep \\\\\\\\\\\\\\\\.js$ | xargs eslint\\",
345 | \\"lint-fix\\": \\"npm run lint -- --fix\\",
346 | \\"outdated\\": \\"npm outdated --depth 0\\",
347 | \\"pretest\\": \\"npm run lint\\",
348 | \\"start-dev\\": \\"nodemon --inspect server.js\\",
349 | \\"prestart-dev\\": \\"npm run lint\\",
350 | \\"start\\": \\"node server.js\\",
351 | \\"seed\\": \\"sequelize db:seed:all\\",
352 | \\"create-seed\\": \\"sequelize seed:generate --name\\",
353 | \\"create-migration\\": \\"sequelize migration:generate --name\\"
354 | },
355 | \\"cacheDirectories\\": [
356 | \\"node_modules\\"
357 | ],
358 | \\"main\\": \\"app.js\\",
359 | \\"author\\": \\"Wolox\\",
360 | \\"homepage\\": \\"https://test.com.ar\\",
361 | \\"license\\": \\"MIT\\",
362 | \\"repository\\": {
363 | \\"type\\": \\"git\\",
364 | \\"url\\": \\"https://test.com.ar.git\\"
365 | },
366 | \\"bugs\\": {
367 | \\"url\\": \\"https://test.com.ar/issues\\",
368 | \\"email\\": \\"tls@wolox.com.ar\\"
369 | },
370 | \\"jest\\": {
371 | \\"coverageThreshold\\": {
372 | \\"global\\": {
373 | \\"branches\\": 80,
374 | \\"functions\\": 80,
375 | \\"lines\\": 80,
376 | \\"statements\\": 80
377 | }
378 | },
379 | \\"collectCoverageFrom\\": [
380 | \\"**/*.js\\",
381 | \\"!**/console.js\\",
382 | \\"!**/node_modules/**\\",
383 | \\"!**/build/**\\",
384 | \\"!**/migrations/**\\",
385 | \\"!**/config/**\\",
386 | \\"!**/scripts/**\\"
387 | ],
388 | \\"setupFilesAfterEnv\\": [
389 | \\"/test/setup.js\\"
390 | ],
391 | \\"testEnvironment\\": \\"node\\",
392 | \\"transform\\": {
393 | \\"^.+\\\\\\\\.js$\\": \\"babel-jest\\"
394 | }
395 | },
396 | \\"dependencies\\": {
397 | \\"bcryptjs\\": \\"^2.4.3\\",
398 | \\"body-parser\\": \\"^1.19.0\\",
399 | \\"express\\": \\"^4.17.1\\",
400 | \\"jwt-simple\\": \\"^0.5.6\\",
401 | \\"rollbar\\": \\"^2.24.0\\",
402 | \\"umzug\\": \\"^2.3.0\\",
403 | \\"express-wolox-logger\\": \\"^2.0.0\\",
404 | \\"axios\\": \\"^0.24.0\\",
405 | \\"swagger-ui-express\\": \\"^4.1.6\\"
406 | },
407 | \\"devDependencies\\": {
408 | \\"babel\\": \\"6.23.0\\",
409 | \\"babel-core\\": \\"^6.26.3\\",
410 | \\"babel-eslint\\": \\"^10.1.0\\",
411 | \\"babel-jest\\": \\"^27.3.1\\",
412 | \\"jest\\": \\"^27.3.1\\",
413 | \\"supertest\\": \\"^6.1.6\\",
414 | \\"babel-preset-es2015\\": \\"6.24.1\\",
415 | \\"dotenv\\": \\"^10.0.0\\",
416 | \\"eslint\\": \\"^6.8.0\\",
417 | \\"eslint-config-wolox\\": \\"^4.0.0\\",
418 | \\"eslint-config-wolox-node\\": \\"^3.0.0\\",
419 | \\"eslint-plugin-import\\": \\"^2.25.2\\",
420 | \\"eslint-plugin-prettier\\": \\"^3.0.1\\",
421 | \\"husky\\": \\"^7.0.4\\",
422 | \\"istanbul\\": \\"^0.4.3\\",
423 | \\"mocha\\": \\"^9.1.3\\",
424 | \\"mocha-lcov-reporter\\": \\"^1.3.0\\",
425 | \\"nodemon\\": \\"^2.0.14\\",
426 | \\"prettier\\": \\"^1.15.3\\",
427 | \\"prettier-eslint\\": \\"^9.0.1\\",
428 | \\"prompt\\": \\"^1.2.0\\"
429 | },
430 | \\"husky\\": {
431 | \\"hooks\\": {
432 | \\"pre-commit\\": \\"npm run lint-diff\\",
433 | \\"pre-push\\": \\"npm test\\"
434 | }
435 | }
436 | }
437 | "
438 | `;
439 |
--------------------------------------------------------------------------------
/test/__snapshots__/testing.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`jest-supertest project creates expected package.json 1`] = `
4 | "{
5 | \\"name\\": \\"TestingProject\\",
6 | \\"version\\": \\"0.1.0\\",
7 | \\"description\\": \\"Example\\",
8 | \\"engines\\": {
9 | \\"node\\": \\"8.9.12\\",
10 | \\"npm\\": \\"6.4.1\\"
11 | },
12 | \\"scripts\\": {
13 | \\"console\\": \\"node console.js\\",
14 | \\"cover\\": \\"npm run test -- --coverage\\",
15 | \\"test\\": \\"NODE_ENV=testing jest --runInBand --forceExit --detectOpenHandles\\",
16 | \\"test-inspect\\": \\"NODE_ENV=testing node --inspect --debug-brk jest\\",
17 | \\"eslint-check\\": \\"eslint --print-config .eslintrc.js --ignore-pattern ./.eslintrc.js | eslint-config-prettier-check\\",
18 | \\"lint\\": \\"eslint \\\\\\"**/*.js\\\\\\" --ignore-pattern ./.eslintrc.js\\",
19 | \\"lint-diff\\": \\"git diff --diff-filter=ACM --name-only --cached --relative | grep \\\\\\\\\\\\\\\\.js$ | xargs eslint\\",
20 | \\"lint-fix\\": \\"npm run lint -- --fix\\",
21 | \\"outdated\\": \\"npm outdated --depth 0\\",
22 | \\"pretest\\": \\"npm run lint\\",
23 | \\"start-dev\\": \\"nodemon --inspect server.js\\",
24 | \\"prestart-dev\\": \\"npm run lint\\",
25 | \\"start\\": \\"node server.js\\",
26 | \\"seed\\": \\"sequelize db:seed:all\\",
27 | \\"create-seed\\": \\"sequelize seed:generate --name\\",
28 | \\"create-migration\\": \\"sequelize migration:generate --name\\"
29 | },
30 | \\"cacheDirectories\\": [
31 | \\"node_modules\\"
32 | ],
33 | \\"main\\": \\"app.js\\",
34 | \\"author\\": \\"Wolox\\",
35 | \\"homepage\\": \\"https://test.com.ar\\",
36 | \\"license\\": \\"MIT\\",
37 | \\"repository\\": {
38 | \\"type\\": \\"git\\",
39 | \\"url\\": \\"https://test.com.ar.git\\"
40 | },
41 | \\"bugs\\": {
42 | \\"url\\": \\"https://test.com.ar/issues\\",
43 | \\"email\\": \\"tls@wolox.com.ar\\"
44 | },
45 | \\"jest\\": {
46 | \\"coverageThreshold\\": {
47 | \\"global\\": {
48 | \\"branches\\": 80,
49 | \\"functions\\": 80,
50 | \\"lines\\": 80,
51 | \\"statements\\": 80
52 | }
53 | },
54 | \\"collectCoverageFrom\\": [
55 | \\"**/*.js\\",
56 | \\"!**/console.js\\",
57 | \\"!**/node_modules/**\\",
58 | \\"!**/build/**\\",
59 | \\"!**/migrations/**\\",
60 | \\"!**/config/**\\",
61 | \\"!**/scripts/**\\"
62 | ],
63 | \\"setupFilesAfterEnv\\": [
64 | \\"/test/setup.js\\"
65 | ],
66 | \\"testEnvironment\\": \\"node\\",
67 | \\"transform\\": {
68 | \\"^.+\\\\\\\\.js$\\": \\"babel-jest\\"
69 | }
70 | },
71 | \\"dependencies\\": {
72 | \\"bcryptjs\\": \\"^2.4.3\\",
73 | \\"body-parser\\": \\"^1.19.0\\",
74 | \\"express\\": \\"^4.17.1\\",
75 | \\"jwt-simple\\": \\"^0.5.6\\",
76 | \\"umzug\\": \\"^2.3.0\\",
77 | \\"express-wolox-logger\\": \\"^2.0.0\\",
78 | \\"axios\\": \\"^0.24.0\\",
79 | \\"swagger-ui-express\\": \\"^4.1.6\\"
80 | },
81 | \\"devDependencies\\": {
82 | \\"babel\\": \\"6.23.0\\",
83 | \\"babel-core\\": \\"^6.26.3\\",
84 | \\"babel-eslint\\": \\"^10.1.0\\",
85 | \\"babel-jest\\": \\"^27.3.1\\",
86 | \\"jest\\": \\"^27.3.1\\",
87 | \\"supertest\\": \\"^6.1.6\\",
88 | \\"babel-preset-es2015\\": \\"6.24.1\\",
89 | \\"dotenv\\": \\"^10.0.0\\",
90 | \\"eslint\\": \\"^6.8.0\\",
91 | \\"eslint-config-wolox\\": \\"^4.0.0\\",
92 | \\"eslint-config-wolox-node\\": \\"^3.0.0\\",
93 | \\"eslint-plugin-import\\": \\"^2.25.2\\",
94 | \\"eslint-plugin-prettier\\": \\"^3.0.1\\",
95 | \\"husky\\": \\"^7.0.4\\",
96 | \\"istanbul\\": \\"^0.4.3\\",
97 | \\"mocha\\": \\"^9.1.3\\",
98 | \\"mocha-lcov-reporter\\": \\"^1.3.0\\",
99 | \\"nodemon\\": \\"^2.0.14\\",
100 | \\"prettier\\": \\"^1.15.3\\",
101 | \\"prettier-eslint\\": \\"^9.0.1\\",
102 | \\"prompt\\": \\"^1.2.0\\"
103 | },
104 | \\"husky\\": {
105 | \\"hooks\\": {
106 | \\"pre-commit\\": \\"npm run lint-diff\\",
107 | \\"pre-push\\": \\"npm test\\"
108 | }
109 | }
110 | }
111 | "
112 | `;
113 |
114 | exports[`mocha-chai project creates expected package.json 1`] = `
115 | "{
116 | \\"name\\": \\"TestingProject\\",
117 | \\"version\\": \\"0.1.0\\",
118 | \\"description\\": \\"Example\\",
119 | \\"engines\\": {
120 | \\"node\\": \\"8.9.12\\",
121 | \\"npm\\": \\"6.4.1\\"
122 | },
123 | \\"scripts\\": {
124 | \\"console\\": \\"node console.js\\",
125 | \\"cover\\": \\"NODE_ENV=testing istanbul cover ./node_modules/mocha/bin/_mocha test/app.spec.js\\",
126 | \\"test\\": \\"NODE_ENV=testing ./node_modules/mocha/bin/_mocha --timeout 6000 --exit test/app.spec.js\\",
127 | \\"test-inspect\\": \\"NODE_ENV=testing node --inspect-brk ./node_modules/mocha/bin/_mocha test/app.spec.js\\",
128 | \\"eslint-check\\": \\"eslint --print-config .eslintrc.js --ignore-pattern ./.eslintrc.js | eslint-config-prettier-check\\",
129 | \\"lint\\": \\"eslint \\\\\\"**/*.js\\\\\\" --ignore-pattern ./.eslintrc.js\\",
130 | \\"lint-diff\\": \\"git diff --diff-filter=ACM --name-only --cached --relative | grep \\\\\\\\\\\\\\\\.js$ | xargs eslint\\",
131 | \\"lint-fix\\": \\"npm run lint -- --fix\\",
132 | \\"outdated\\": \\"npm outdated --depth 0\\",
133 | \\"pretest\\": \\"npm run lint\\",
134 | \\"start-dev\\": \\"nodemon --inspect server.js\\",
135 | \\"prestart-dev\\": \\"npm run lint\\",
136 | \\"start\\": \\"node server.js\\",
137 | \\"seed\\": \\"sequelize db:seed:all\\",
138 | \\"create-seed\\": \\"sequelize seed:generate --name\\",
139 | \\"create-migration\\": \\"sequelize migration:generate --name\\"
140 | },
141 | \\"cacheDirectories\\": [
142 | \\"node_modules\\"
143 | ],
144 | \\"main\\": \\"app.js\\",
145 | \\"author\\": \\"Wolox\\",
146 | \\"homepage\\": \\"https://test.com.ar\\",
147 | \\"license\\": \\"MIT\\",
148 | \\"repository\\": {
149 | \\"type\\": \\"git\\",
150 | \\"url\\": \\"https://test.com.ar.git\\"
151 | },
152 | \\"bugs\\": {
153 | \\"url\\": \\"https://test.com.ar/issues\\",
154 | \\"email\\": \\"tls@wolox.com.ar\\"
155 | },
156 | \\"dependencies\\": {
157 | \\"bcryptjs\\": \\"^2.4.3\\",
158 | \\"body-parser\\": \\"^1.19.0\\",
159 | \\"express\\": \\"^4.17.1\\",
160 | \\"jwt-simple\\": \\"^0.5.6\\",
161 | \\"umzug\\": \\"^2.3.0\\",
162 | \\"express-wolox-logger\\": \\"^2.0.0\\",
163 | \\"axios\\": \\"^0.24.0\\",
164 | \\"swagger-ui-express\\": \\"^4.1.6\\"
165 | },
166 | \\"devDependencies\\": {
167 | \\"babel\\": \\"6.23.0\\",
168 | \\"babel-core\\": \\"^6.26.3\\",
169 | \\"babel-eslint\\": \\"^10.1.0\\",
170 | \\"babel-preset-es2015\\": \\"6.24.1\\",
171 | \\"chai\\": \\"^4.3.4\\",
172 | \\"chai-http\\": \\"^4.3.0\\",
173 | \\"dotenv\\": \\"^10.0.0\\",
174 | \\"eslint\\": \\"^6.8.0\\",
175 | \\"eslint-config-wolox\\": \\"^4.0.0\\",
176 | \\"eslint-config-wolox-node\\": \\"^3.0.0\\",
177 | \\"eslint-plugin-import\\": \\"^2.25.2\\",
178 | \\"eslint-plugin-prettier\\": \\"^3.0.1\\",
179 | \\"husky\\": \\"^7.0.4\\",
180 | \\"istanbul\\": \\"^0.4.3\\",
181 | \\"mocha\\": \\"^9.1.3\\",
182 | \\"mocha-lcov-reporter\\": \\"^1.3.0\\",
183 | \\"nodemon\\": \\"^2.0.14\\",
184 | \\"prettier\\": \\"^1.15.3\\",
185 | \\"prettier-eslint\\": \\"^9.0.1\\",
186 | \\"prompt\\": \\"^1.2.0\\"
187 | },
188 | \\"husky\\": {
189 | \\"hooks\\": {
190 | \\"pre-commit\\": \\"npm run lint-diff\\",
191 | \\"pre-push\\": \\"npm test\\"
192 | }
193 | }
194 | }
195 | "
196 | `;
197 |
--------------------------------------------------------------------------------
/test/ci.spec.js:
--------------------------------------------------------------------------------
1 | const utils = require('./helpers/utils');
2 | const { mockCommand } = require('./helpers/mocks');
3 | const { basicFiles, jenkinsFiles, travisFiles, examplePrompts } = require('./helpers/constants');
4 |
5 | beforeAll(() => mockCommand());
6 |
7 | const ciOptions = [
8 | ['travis', travisFiles],
9 | ['jenkins', jenkinsFiles]
10 | ];
11 |
12 | describe.each(ciOptions)('%s project', (ciName, files) => {
13 | beforeAll(() =>
14 | utils.runKickoff({
15 | ...examplePrompts,
16 | projectName: 'CIProject',
17 | ci: ciName
18 | })
19 | );
20 |
21 | test(`creates files for ${ciName} project`, () => {
22 | utils.checkExistentFiles([basicFiles, files], 'CIProject');
23 | });
24 |
25 | test.each(files)('creates expected %s', file => {
26 | expect(utils.getFileContent(`CIProject/${file}`)).toMatchSnapshot();
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/test/deploy.spec.js:
--------------------------------------------------------------------------------
1 | const utils = require('./helpers/utils');
2 | const { mockCommand } = require('./helpers/mocks');
3 | const { examplePrompts } = require('./helpers/constants');
4 |
5 | beforeAll(() => mockCommand());
6 |
7 | const deployOptions = [
8 | ['docker', { files: ['Dockerfile'], kickoffOptions: { docker: true, deployStrategy: { aws: false } } }],
9 | [
10 | 'docker and aws',
11 | {
12 | files: ['Dockerfile', 'Dockerrun.aws.json', '.ebextensions/cloudwatch.config'],
13 | kickoffOptions: { docker: true, deployStrategy: { aws: true } }
14 | }
15 | ],
16 | [
17 | 'heroku',
18 | { files: ['Procfile'], kickoffOptions: { docker: false, deployStrategy: { aws: false, heroku: true } } }
19 | ],
20 | [
21 | 'aws',
22 | {
23 | files: ['.ebextensions/cloudwatch.config'],
24 | kickoffOptions: { docker: true, deployStrategy: { aws: true } }
25 | }
26 | ]
27 | ];
28 |
29 | describe.each(deployOptions)('Deploy with %s', (deployOption, { files, kickoffOptions }) => {
30 | beforeAll(() =>
31 | utils.runKickoff({
32 | ...examplePrompts,
33 | ...kickoffOptions,
34 | projectName: 'DeployProject'
35 | })
36 | );
37 |
38 | test(`creates files for ${deployOption}`, () => {
39 | utils.checkExistentFiles(files, 'DeployProject');
40 | });
41 |
42 | test.each(files)('creates expected %s', file => {
43 | expect(utils.getFileContent(`DeployProject/${file}`)).toMatchSnapshot();
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/test/general.spec.js:
--------------------------------------------------------------------------------
1 | const { flatten } = require('lodash');
2 | const utils = require('./helpers/utils');
3 | const { mockCommand } = require('./helpers/mocks');
4 | const { exampleProjects, basicFiles } = require('./helpers/constants');
5 |
6 | beforeAll(() => mockCommand());
7 |
8 | describe.each(exampleProjects)(
9 | 'Example project with %s',
10 | (projectName, { kickoffOptions, files, templateFiles }) => {
11 | beforeAll(() =>
12 | utils.runKickoff({
13 | ...kickoffOptions,
14 | nodeVersion: '8.9.12',
15 | npmVersion: '6.4.1',
16 | inTraining: false,
17 | projectName: 'Project',
18 | projectDescription: 'Project',
19 | urlRepository: 'https://test.com.ar'
20 | })
21 | );
22 |
23 | test(`creates basic files for ${projectName}`, () => {
24 | utils.checkExistentFiles(files, 'Project');
25 | utils.checkExistentFiles(basicFiles, 'Project');
26 | });
27 |
28 | test.each(flatten([...templateFiles, ...basicFiles]))('creates expected %s', file => {
29 | expect(utils.getFileContent(`Project/${file}`)).toMatchSnapshot();
30 | });
31 | }
32 | );
33 |
--------------------------------------------------------------------------------
/test/helpers/constants.js:
--------------------------------------------------------------------------------
1 | exports.sequelizeFiles = [
2 | '.sequelizerc',
3 | 'migrations/index.js',
4 | 'migrations/migrations/.keep',
5 | 'config/db.js',
6 | 'app/models/index.js'
7 | ];
8 |
9 | exports.documentationRequiresAuth = ['app/middlewares/docsAuth.js'];
10 |
11 | exports.sequelizeTemplateFiles = ['package.json', 'README.md', 'console.js', 'server.js', 'config/db.js'];
12 |
13 | exports.mongooseTemplateFiles = ['package.json', 'README.md', 'console.js', 'server.js', 'config/db.js'];
14 |
15 | exports.testingFiles = ['package.json'];
16 |
17 | exports.jenkinsFiles = ['Jenkinsfile', '.woloxci/config.yml', '.woloxci/Dockerfile'];
18 |
19 | exports.herokuFiles = ['Procfile'];
20 |
21 | exports.dockerFiles = ['Dockerfile', 'Dockerrun.aws.json'];
22 |
23 | exports.travisFiles = ['.travis.yml'];
24 |
25 | exports.basicFiles = [
26 | 'README.md',
27 | 'pull_request_template.md',
28 | 'package.json',
29 | 'LICENSE.md',
30 | 'console.js',
31 | 'app.js',
32 | 'server.js',
33 | '.nvmrc',
34 | '.gitignore',
35 | '.eslintrc.js',
36 | '.eslintignore',
37 | 'config/development.js',
38 | 'config/production.js',
39 | 'config/testing.js',
40 | 'config/index.js',
41 | 'app/controllers/healthCheck.js',
42 | 'app/services/.keep',
43 | 'app/errors.js',
44 | 'app/routes.js',
45 | 'app/middlewares/errors.js',
46 | 'app/logger/index.js'
47 | ];
48 |
49 | exports.examplePrompts = {
50 | inTraining: false,
51 | projectName: 'Example',
52 | projectDescription: 'Example',
53 | urlRepository: 'https://test.com.ar',
54 | nodeVersion: '8.9.12',
55 | npmVersion: '6.4.1',
56 | documentationRequiresAuth: true,
57 | database: true,
58 | orm: { sequelize: false },
59 | docker: false,
60 | deployStrategy: {},
61 | optionalsFeatures: {},
62 | ci: 'travis',
63 | testing: 'jest-supertest'
64 | };
65 |
66 | exports.jestAndSequelizeFiles = ['test/factory/factory_by_models.js'];
67 |
68 | exports.exampleProjects = [
69 | [
70 | 'Sequelize (Postgres), AWS, Docker, Jest, Jenkins and all optionals',
71 | {
72 | kickoffOptions: {
73 | documentationRequiresAuth: true,
74 | database: true,
75 | orm: { sequelize: true },
76 | sequelizeVersion: '^1.1.2',
77 | sequelizeDialect: 'postgres',
78 | docker: true,
79 | deployStrategy: { aws: true },
80 | optionalsFeatures: {
81 | cors: true,
82 | rollbar: true,
83 | coveralls: true
84 | },
85 | ci: 'jenkins',
86 | testing: 'jest-supertest'
87 | },
88 | templateFiles: [exports.dockerFiles, exports.sequelizeTemplateFiles, exports.jenkinsFiles],
89 | files: [
90 | exports.sequelizeFiles,
91 | exports.dockerFiles,
92 | exports.jenkinsFiles,
93 | exports.jestAndSequelizeFiles
94 | ]
95 | }
96 | ],
97 | [
98 | 'Sequelize (MySQL), AWS, Docker, Jest, Jenkins and non optionals',
99 | {
100 | kickoffOptions: {
101 | documentationRequiresAuth: true,
102 | database: true,
103 | orm: { sequelize: true },
104 | sequelizeVersion: '^1.1.2',
105 | sequelizeDialect: 'mysql',
106 | docker: true,
107 | deployStrategy: { aws: true },
108 | optionalsFeatures: {},
109 | ci: 'jenkins',
110 | testing: 'jest-supertest'
111 | },
112 | templateFiles: [exports.dockerFiles, exports.sequelizeTemplateFiles, exports.jenkinsFiles],
113 | files: [
114 | exports.sequelizeFiles,
115 | exports.dockerFiles,
116 | exports.jenkinsFiles,
117 | exports.jestAndSequelizeFiles
118 | ]
119 | }
120 | ],
121 | [
122 | 'Sequelize (mssql), AWS, Docker, Mocha, Travis and all optionals',
123 | {
124 | kickoffOptions: {
125 | documentationRequiresAuth: true,
126 | database: true,
127 | orm: { sequelize: true },
128 | sequelizeVersion: '^1.1.2',
129 | sequelizeDialect: 'postgres',
130 | docker: true,
131 | deployStrategy: { aws: true },
132 | optionalsFeatures: {
133 | cors: true,
134 | rollbar: true,
135 | coveralls: true
136 | },
137 | ci: 'travis',
138 | testing: 'mocha-chai'
139 | },
140 | templateFiles: [exports.dockerFiles, exports.sequelizeTemplateFiles, exports.travisFiles],
141 | files: [exports.sequelizeFiles, exports.dockerFiles, exports.travisFiles]
142 | }
143 | ],
144 | [
145 | 'Sequelize (sqlite), AWS, Docker, Mocha, Travis and non optionals',
146 | {
147 | kickoffOptions: {
148 | documentationRequiresAuth: true,
149 | database: true,
150 | orm: { sequelize: true },
151 | sequelizeVersion: '^1.1.2',
152 | sequelizeDialect: 'sqlite',
153 | docker: true,
154 | deployStrategy: { aws: true },
155 | optionalsFeatures: {},
156 | ci: 'travis',
157 | testing: 'mocha-chai'
158 | },
159 | templateFiles: [exports.dockerFiles, exports.sequelizeTemplateFiles, exports.travisFiles],
160 | files: [exports.sequelizeFiles, exports.dockerFiles, exports.travisFiles]
161 | }
162 | ],
163 | [
164 | 'AWS, Docker, Jest, Jenkins and all optionals',
165 | {
166 | kickoffOptions: {
167 | documentationRequiresAuth: true,
168 | database: true,
169 | orm: { sequelize: false },
170 | docker: true,
171 | deployStrategy: { aws: true },
172 | optionalsFeatures: {
173 | cors: true,
174 | rollbar: true,
175 | coveralls: true
176 | },
177 | ci: 'jenkins',
178 | testing: 'jest-supertest'
179 | },
180 | templateFiles: [exports.dockerFiles, exports.jenkinsFiles],
181 | files: [exports.dockerFiles, exports.jenkinsFiles]
182 | }
183 | ],
184 | [
185 | 'AWS, Docker, Jest, Jenkins and non optionals',
186 | {
187 | kickoffOptions: {
188 | documentationRequiresAuth: true,
189 | database: true,
190 | orm: { sequelize: false },
191 | docker: true,
192 | deployStrategy: { aws: true },
193 | optionalsFeatures: {},
194 | ci: 'jenkins',
195 | testing: 'jest-supertest'
196 | },
197 | templateFiles: [exports.dockerFiles, exports.jenkinsFiles],
198 | files: [exports.dockerFiles, exports.jenkinsFiles]
199 | }
200 | ],
201 | [
202 | 'AWS, Docker, Jest, Travis and all optionals',
203 | {
204 | kickoffOptions: {
205 | documentationRequiresAuth: true,
206 | database: true,
207 | orm: { sequelize: false },
208 | docker: true,
209 | deployStrategy: { aws: true },
210 | optionalsFeatures: {
211 | cors: true,
212 | rollbar: true,
213 | coveralls: true
214 | },
215 | ci: 'travis',
216 | testing: 'jest-supertest'
217 | },
218 | templateFiles: [exports.dockerFiles, exports.travisFiles],
219 | files: [exports.dockerFiles, exports.travisFiles]
220 | }
221 | ],
222 | [
223 | 'AWS, Docker, Jest, Travis and non optionals',
224 | {
225 | kickoffOptions: {
226 | documentationRequiresAuth: true,
227 | database: true,
228 | orm: { sequelize: false },
229 | docker: true,
230 | deployStrategy: { aws: true },
231 | optionalsFeatures: {},
232 | ci: 'travis',
233 | testing: 'jest-supertest'
234 | },
235 | templateFiles: [exports.dockerFiles, exports.travisFiles],
236 | files: [exports.dockerFiles, exports.travisFiles]
237 | }
238 | ]
239 | ];
240 |
241 | exports.linterCommands = [
242 | {
243 | description: 'Lint fix',
244 | name: 'npm',
245 | args: ['run', 'lint-external', '--', '--fix', '--no-eslintrc']
246 | },
247 | { description: 'Lint', name: 'npm', args: ['run', 'lint-external', '--', '--no-eslintrc'] }
248 | ];
249 |
--------------------------------------------------------------------------------
/test/helpers/mocks.js:
--------------------------------------------------------------------------------
1 | const command = require('../../generators/app/command');
2 |
3 | exports.mockCommand = (implementation = () => Promise.resolve()) =>
4 | jest.spyOn(command, 'runCommand').mockImplementation(implementation);
5 |
--------------------------------------------------------------------------------
/test/helpers/utils.js:
--------------------------------------------------------------------------------
1 | const { flatten } = require('lodash');
2 | const helpers = require('yeoman-test');
3 | const path = require('path');
4 | const fs = require('fs');
5 | const assert = require('yeoman-assert');
6 |
7 | let testDirectory = path.join(__dirname, 'tmp');
8 |
9 | exports.getTestDirectory = filePath => (filePath ? `${testDirectory}/${filePath}` : testDirectory);
10 |
11 | exports.runKickoff = options =>
12 | helpers
13 | .run(require.resolve('../../generators/app'))
14 | .inTmpDir(dir => {
15 | testDirectory = dir;
16 | })
17 | .withPrompts(options)
18 | .toPromise();
19 |
20 | const checkFiles = (checkFunction, files, directory) =>
21 | assert[checkFunction](flatten(files).map(file => exports.getTestDirectory(`${directory}/${file}`)));
22 |
23 | exports.checkNonExistentFiles = (files, directory) => checkFiles('noFile', files, directory);
24 |
25 | exports.checkExistentFiles = (files, directory) => checkFiles('file', files, directory);
26 |
27 | exports.getFileContent = filePath =>
28 | fs.readFileSync(exports.getTestDirectory(filePath), { encoding: 'utf-8' });
29 |
--------------------------------------------------------------------------------
/test/linter.spec.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const utils = require('./helpers/utils');
4 | const { mockCommand } = require('./helpers/mocks');
5 | const { runCommand } = require('../generators/app/command');
6 | const { exampleProjects, linterCommands } = require('./helpers/constants');
7 |
8 | const actualDirectory = path.resolve(__dirname);
9 |
10 | describe.each(exampleProjects)('Example project with %s', (projectName, { kickoffOptions }) => {
11 | beforeAll(() => {
12 | mockCommand();
13 | return utils.runKickoff({
14 | ...kickoffOptions,
15 | nodeVersion: '8.9.12',
16 | npmVersion: '6.4.1',
17 | inTraining: false,
18 | projectName: 'linter',
19 | projectDescription: 'Fake project to test linter',
20 | urlRepository: 'https://test.com.ar'
21 | });
22 | });
23 |
24 | test.each(linterCommands)('run the EsLinter for each project generated', command => {
25 | jest.setTimeout(30000);
26 | const tmpDirectory = utils.getTestDirectory('linter');
27 | const args = [...command.args, `${tmpDirectory}`];
28 | const projectRootDirectory = actualDirectory
29 | .split('/')
30 | .slice(0, -1)
31 | .join('/');
32 | return runCommand({
33 | ...command,
34 | args,
35 | spawnOptions: { cwd: projectRootDirectory }
36 | }).catch(err => {
37 | throw new Error(`Eslinter for project failed on command: ${command.description} with error: ${err}`);
38 | });
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/test/mongoose.spec.js:
--------------------------------------------------------------------------------
1 | const utils = require('./helpers/utils');
2 | const { mockCommand } = require('./helpers/mocks');
3 | const { basicFiles, mongooseTemplateFiles, examplePrompts } = require('./helpers/constants');
4 |
5 | const mongooseKickoff = options =>
6 | utils.runKickoff({
7 | ...examplePrompts,
8 | projectName: 'MongooseProject',
9 | projectDescription: 'MongooseProject',
10 | orm: { mongoose: true },
11 | mongooseVersion: '^5.6.4',
12 | mongooseDialect: 'mongoDB',
13 | ...options
14 | });
15 |
16 | beforeAll(() => mockCommand());
17 |
18 | describe('Mongoose project ', () => {
19 | beforeAll(() => mongooseKickoff());
20 |
21 | test('creates basic files and does not create sequelize files', () => {
22 | utils.checkExistentFiles([basicFiles], 'MongooseProject');
23 | utils.checkNonExistentFiles(
24 | [['.sequelizerc', 'migrations/index.js', 'migrations/migrations/.keep', 'app/models/index.js']],
25 | 'MongooseProject'
26 | );
27 | });
28 |
29 | test.each(mongooseTemplateFiles)('creates expected %s', file => {
30 | expect(utils.getFileContent(`MongooseProject/${file}`)).toMatchSnapshot();
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/test/optionals.spec.js:
--------------------------------------------------------------------------------
1 | const utils = require('./helpers/utils');
2 | const { mockCommand } = require('./helpers/mocks');
3 | const { examplePrompts } = require('./helpers/constants');
4 |
5 | beforeAll(() => mockCommand());
6 |
7 | const optionals = [
8 | ['rollbar', ['package.json', 'app.js']],
9 | ['cors', ['package.json', 'app.js']],
10 | ['coveralls', ['package.json']]
11 | ];
12 |
13 | describe.each(optionals)('Project with %s', (optionalFeature, files) => {
14 | beforeAll(() =>
15 | utils.runKickoff({
16 | ...examplePrompts,
17 | projectName: 'OptionalProject',
18 | optionalsFeatures: { [optionalFeature]: true }
19 | })
20 | );
21 |
22 | test.each(files)('creates expected %s', file => {
23 | expect(utils.getFileContent(`OptionalProject/${file}`)).toMatchSnapshot();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/test/sequelize.spec.js:
--------------------------------------------------------------------------------
1 | const utils = require('./helpers/utils');
2 | const { mockCommand } = require('./helpers/mocks');
3 | const {
4 | basicFiles,
5 | sequelizeFiles,
6 | sequelizeTemplateFiles,
7 | jenkinsFiles,
8 | examplePrompts
9 | } = require('./helpers/constants');
10 |
11 | const sequelizeKickoff = (dialect, options) =>
12 | utils.runKickoff({
13 | ...examplePrompts,
14 | projectName: 'SequelizeProject',
15 | projectDescription: 'SequelizeProject',
16 | orm: { sequelize: true },
17 | sequelizeVersion: '^1.1.2',
18 | sequelizeDialect: dialect,
19 | ...options
20 | });
21 |
22 | beforeAll(() => mockCommand());
23 |
24 | const availableDialects = ['mysql', 'postgres', 'mssql', 'sqlite'];
25 |
26 | describe.each(availableDialects)('Sequelize project (%s)', dialect => {
27 | beforeAll(() => sequelizeKickoff(dialect));
28 |
29 | test(`creates sequelize files for ${dialect}`, () => {
30 | utils.checkExistentFiles([basicFiles, sequelizeFiles], 'SequelizeProject');
31 | });
32 |
33 | test.each(sequelizeTemplateFiles)('creates expected %s', file => {
34 | expect(utils.getFileContent(`SequelizeProject/${file}`)).toMatchSnapshot();
35 | });
36 | });
37 |
38 | describe.each(availableDialects)('Sequelize project (%s) along with Jenkins', dialect => {
39 | beforeAll(() => sequelizeKickoff(dialect, { ci: 'jenkins' }));
40 |
41 | test(`creates sequelize files for ${dialect}`, () => {
42 | utils.checkExistentFiles([basicFiles, sequelizeFiles, jenkinsFiles], 'SequelizeProject');
43 | });
44 |
45 | test.each([...sequelizeTemplateFiles, '.woloxci/config.yml'])('creates expected %s', file => {
46 | expect(utils.getFileContent(`SequelizeProject/${file}`)).toMatchSnapshot();
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/test/testing.spec.js:
--------------------------------------------------------------------------------
1 | const utils = require('./helpers/utils');
2 | const { mockCommand } = require('./helpers/mocks');
3 | const { basicFiles, examplePrompts, testingFiles } = require('./helpers/constants');
4 |
5 | beforeAll(() => mockCommand());
6 |
7 | const ciOptions = ['mocha-chai', 'jest-supertest'];
8 |
9 | describe.each(ciOptions)('%s project', testing => {
10 | beforeAll(() =>
11 | utils.runKickoff({
12 | ...examplePrompts,
13 | projectName: 'TestingProject',
14 | testing
15 | })
16 | );
17 |
18 | test(`creates files for ${testing} project`, () => {
19 | utils.checkExistentFiles([basicFiles, testingFiles], 'TestingProject');
20 | });
21 |
22 | test.each(testingFiles)('creates expected %s', file => {
23 | expect(utils.getFileContent(`TestingProject/${file}`)).toMatchSnapshot();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/test/training.spec.js:
--------------------------------------------------------------------------------
1 | const utils = require('./helpers/utils');
2 | const { mockCommand } = require('./helpers/mocks');
3 | const {
4 | basicFiles,
5 | sequelizeFiles,
6 | travisFiles,
7 | herokuFiles,
8 | jenkisFiles,
9 | dockerFiles,
10 | examplePrompts
11 | } = require('./helpers/constants');
12 |
13 | describe('w-training project', () => {
14 | beforeAll(() => {
15 | mockCommand();
16 | return utils.runKickoff({ ...examplePrompts, inTraining: true });
17 | });
18 | test('creates training files', () => {
19 | utils.checkExistentFiles([basicFiles, sequelizeFiles, travisFiles, herokuFiles], 'w-training');
20 | utils.checkNonExistentFiles([jenkisFiles, dockerFiles], 'w-training');
21 | });
22 | });
23 |
--------------------------------------------------------------------------------