Skip to content
This repository was archived by the owner on Feb 28, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
77 changes: 76 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,76 @@
# generator-ibm-core-node-express
# IBM Cloud Enablement Generator

[![Bluemix powered][img-bluemix-powered]][url-bluemix]
[![Travis][img-travis-master]][url-travis-master]
[![Coveralls][img-coveralls-master]][url-coveralls-master]
[![Codacy][img-codacy]][url-codacy]
[![Version][img-version]][url-npm]
[![DownloadsMonthly][img-npm-downloads-monthly]][url-npm]
[![DownloadsTotal][img-npm-downloads-total]][url-npm]
[![License][img-license]][url-npm]

[img-bluemix-powered]: https://img.shields.io/badge/bluemix-powered-blue.svg
[url-bluemix]: http://bluemix.net
[url-npm]: https://www.npmjs.com/package/generator-ibm-core-node-express
[img-license]: https://img.shields.io/npm/l/generator-ibm-core-node-express.svg
[img-version]: https://img.shields.io/npm/v/generator-ibm-core-node-express.svg
[img-npm-downloads-monthly]: https://img.shields.io/npm/dm/generator-ibm-core-node-express.svg
[img-npm-downloads-total]: https://img.shields.io/npm/dt/generator-ibm-core-node-express.svg

[img-travis-master]: https://travis-ci.org/ibm-developer/generator-ibm-core-node-express.svg?branch=master
[url-travis-master]: https://travis-ci.org/ibm-developer/generator-ibm-core-node-express/branches

[img-coveralls-master]: https://coveralls.io/repos/github/ibm-developer/generator-ibm-core-node-express/badge.svg
[url-coveralls-master]: https://coveralls.io/github/ibm-developer/generator-ibm-core-node-express

[img-codacy]: https://api.codacy.com/project/badge/Grade/a5893a4622094dc8920c8a372a8d3588?branch=master
[url-codacy]: https://www.codacy.com/app/ibm-developer/generator-ibm-core-node-express

## Pre-requisites

Install [Yeoman](http://yeoman.io)

```bash
npm install -g yo
```

## Installation

``bash
npm install -g generator-ibm-core-node-express
``

## Usage

Following command line arguments are supported

* `--bluemix='{"name":\"<project name>","backendPlatform":"NODE"}'`.
* You will need at least a name and backendPlatform to run it locally.
* You can alternatively supply a local file containing compatible JSON object by using `--bluemix file:path/to/file.json`

## Development

Clone this repository and link it via npm

```
git clone https://github.com/ibm-developer/generator-ibm-core-node-express
cd generator-ibm-core-node-express
npm link
```

In a separate directory invoke the generator via

```
yo ibm-cloud-enablement --bluemix
```

## Publishing Changes

In order to publish changes, you will need to fork the repository or ask to join the `ibm-developer` org and branch off the development branch.

Once you are finished with your changes, run `npm test` to make sure all tests pass.

Do a pull request against `development`, make sure the build passes. A team member will review and merge your pull request.
Once merged to development, the version will be auto-incremented.
Do a pull request against master, once that PR is reviewed and merged, a new version will be published.

149 changes: 149 additions & 0 deletions app/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
Copyright 2017 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';
const Generator = require('yeoman-generator');
const Bundle = require("./../package.json")
const Log4js = require('log4js');
const logger = Log4js.getLogger("generator-core-node-express");
const helpers = require("../lib/helpers");
//const swaggerize = require('@arf/swaggerize');
const OPTION_BLUEMIX = "bluemix";
const OPTION_SPEC = "spec";

const REGEX_LEADING_ALPHA = /^[^a-zA-Z]*/;
const REGEX_ALPHA_NUM = /[^a-zA-Z0-9]/g;

module.exports = class extends Generator {

constructor(args, opts) {
super(args, opts);
logger.info("Package info ::", Bundle.name, Bundle.version);

// bluemix option for YaaS integration
this.argument(OPTION_BLUEMIX, {
desc: 'Option for deploying with Bluemix. Stringified JSON.',
required: false,
hide: true,
type: String
});

// spec as json
this.argument(OPTION_SPEC, {
desc: 'The generator specification. Stringified JSON.',
required: false,
hide: true,
type: String
});
}

initializing() {
this.skipPrompt = true;
let bluemix_ok= this._sanitizeOption(this.options, OPTION_BLUEMIX);
let spec_ok= this._sanitizeOption(this.options, OPTION_SPEC);
if ( ! (bluemix_ok || spec_ok )) throw ("Must specify either bluemix or spec parameter");
let appName = this.options.bluemix.name || this.options.spec.appname;
this.options.sanitizedAppName = this._sanitizeAppName(appName);

this.options.parsedSwagger = undefined;
let formatters = {
'pathFormatter': helpers.reformatPathToNodeExpress,
'resourceFormatter': helpers.resourceNameFromPath
}

if (this.options.bluemix && this.options.bluemix.openApiServers && this.options.bluemix.openApiServers[0].spec) {
let openApiDocumentBytes = typeof this.options.bluemix.openApiServers[0].spec === 'object'
? JSON.stringify(this.options.bluemix.openApiServers[0].spec)
: this.options.bluemix.openApiServers[0].spec;
return swaggerize.parse(openApiDocumentBytes, formatters)
.then(response => {
this.options.loadedApi = response.loaded;
this.options.parsedSwagger = response.parsed;
})
.catch(err => {
err.message = 'failed to parse document from bluemix.openApiServers ' + err.message;
throw err;
})
}
}

writing() {
this.fs.copyTpl(this.templatePath('server'), this.destinationPath('server'), this.options);

if (this.options.parsedSwagger) {
Object.keys(this.options.parsedSwagger.resources).forEach(function(resource) {
let context = {
'resource': resource,
'routes': this.options.parsedSwagger.resources[resource],
'basepath': this.options.parsedSwagger.basepath
}
this.fs.copyTpl(this.templatePath('fromswagger/routers/router.js'), this.destinationPath(`server/routers/${resource}.js`), context);
this.fs.copyTpl(this.templatePath('test/resource.js'), this.destinationPath(`test/${resource}.js`), context);
}.bind(this));
}

this.fs.copyTpl(this.templatePath('test/test-server.js'), this.destinationPath('test/test-server.js'), this.options);
this.fs.copyTpl(this.templatePath('test/test-demo.js'), this.destinationPath('test/test-demo.js'), this.options);
this.fs.copyTpl(this.templatePath('_gitignore'), this.destinationPath('.gitignore'), this.options);
this.fs.copyTpl(this.templatePath('cli-config.yml'), this.destinationPath('cli-config.yml'), this.options);
this.fs.copyTpl(this.templatePath('Dockerfile'), this.destinationPath('Dockerfile'), this.options);
this.fs.copyTpl(this.templatePath('Dockerfile-tools'), this.destinationPath('Dockerfile-tools'), this.options);
this.fs.copyTpl(this.templatePath('package.json'), this.destinationPath('package.json'), this.options);
this.fs.copyTpl(this.templatePath('_package-lock.json'), this.destinationPath('package-lock.json'), this.options);
this.fs.copyTpl(this.templatePath('README.md'), this.destinationPath('README.md'), this.options);

if(this.options.spec && this.options.spec.applicationType === 'MS') {
this.fs.copy(this.templatePath('public/swagger-ui'), this.destinationPath('public/swagger-ui'));
this.fs.copyTpl(this.templatePath('public/swagger.yaml'), this.destinationPath('public/swagger.yaml'), this.options);
this.fs.delete(this.destinationPath('server/routers/public.js'));
} else {
this.fs.copy(this.templatePath('public/index.html'), this.destinationPath('public/index.html'));
this.fs.delete(this.destinationPath('server/routers/swagger.js'));
}

if(this.options.spec && this.options.spec.applicationType === 'BLANK') {
this.fs.delete(this.destinationPath('server/routers/health.js'));
}
}

_sanitizeAppName(name) {
name = name || 'appname';
return name.toLowerCase().replace(REGEX_LEADING_ALPHA, '').replace(REGEX_ALPHA_NUM, '');
}

// return true if 'sanitized', false if missing, exception if bad data
_sanitizeOption(options, name) {
let optionValue = options[name];
if (!optionValue) {
logger.error("Missing", name, "parameter");
return false;
}

if (optionValue.indexOf("file:") === 0) {
let fileName = optionValue.replace("file:", "");
let filePath = this.destinationPath("./" + fileName);
logger.info("Reading", name, "parameter from local file", filePath);
this.options[name] = this.fs.readJSON(filePath);
return true;
}

try {
this.options[name] = typeof(this.options[name]) === "string" ?
JSON.parse(this.options[name]) : this.options[name];
return true;
} catch (e) {
logger.error(e);
throw name + " parameter is expected to be a valid stringified JSON object";
}
}
};
16 changes: 16 additions & 0 deletions app/templates/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM ibmcom/ibmnode

ENV NODE_ENV production
ENV PORT 3000

WORKDIR "/app"

# Install app dependencies
COPY package.json package-lock.json /app/
RUN cd /app; npm install

# Bundle app source
COPY . /app

EXPOSE 3000
CMD ["npm", "start"]
22 changes: 22 additions & 0 deletions app/templates/Dockerfile-tools
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM ibmcom/ibmnode

ENV PORT 3000

WORKDIR "/app"

# Install app dependencies
COPY package.json package-lock.json /app/
RUN cd /app; npm install

# Bundle app source
COPY . /app

EXPOSE 3000

CMD ["/bin/bash"]

ARG bx_dev_user=root
ARG bx_dev_userid=1000
RUN BX_DEV_USER=$bx_dev_user
RUN BX_DEV_USERID=$bx_dev_userid
RUN if [ $bx_dev_user != "root" ]; then useradd -ms /bin/bash -u $bx_dev_userid $bx_dev_user; fi
12 changes: 12 additions & 0 deletions app/templates/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# <%= bluemix.name || spec.appname -%>

A generated Bluemix application

[![](https://img.shields.io/badge/bluemix-powered-blue.svg)](https://bluemix.net)

## Run locally as Node.js application
```bash
npm install
npm test
npm start
```
1 change: 1 addition & 0 deletions app/templates/_gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
5 changes: 5 additions & 0 deletions app/templates/_package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions app/templates/cli-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version : 0.0.3

container-name-run : "<%= bluemix.name.toLowerCase() %>-express-run"
container-name-tools : "<%= bluemix.name.toLowerCase() %>-express-tools"

host-path-run : .
host-path-tools : .

container-path-run : "/app"
container-path-tools : "/app"

container-mounts-run:
- "./node_modules_linux": "/app/node_modules"
container-mounts-tools:
- "./node_modules_linux": "/app/node_modules"

container-port-map : "3000:3000"
container-port-map-debug : "5858:5858"

dockerfile-run : "Dockerfile"
dockerfile-tools : "Dockerfile-tools"

image-name-run : "<%= bluemix.name.toLowerCase() %>-express-run"
image-name-tools : "<%= bluemix.name.toLowerCase() %>-express-tools"

build-cmd-run : "npm install"
test-cmd : "npm run test"
build-cmd-debug : "npm install"

run-cmd : ""
debug-cmd : "npm run debug"
stop-cmd : "npm stop"

chart-path: "chart/<%= bluemix.name.toLowerCase()%>"
16 changes: 16 additions & 0 deletions app/templates/fromswagger/routers/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var express = require('express');

module.exports = function(app, basepath) {
var router = express.Router();

<% if (routes) { -%>
<% routes.forEach(function (route) { -%>
router.<%- route.method %>('<%- route.route %>', function (req, res, next) {
res.json({});
})

<% }); -%>
app.use(basepath, router);
<% } -%>
}

26 changes: 26 additions & 0 deletions app/templates/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "<%= sanitizedAppName %>",
"version": "1.0.0",
"description": "A generated Bluemix application",
"private": true,
"engines": {
"node": "^6.9.0"
},
"scripts": {
"start": "node server/server.js",
"debug": "node --debug server/server.js",
"test": "nyc mocha"
},
"dependencies": {
"appmetrics": "^3.0.1",
"body-parser": "^1.17.2",
"express": "^4.15.3",
"log4js": "^1.1.1"
},
"devDependencies": {
"chai": "^4.0.0",
"mocha": "^3.4.2",
"nyc": "^10.3.2",
"proxyquire": "^1.8.0"
}
}
12 changes: 12 additions & 0 deletions app/templates/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>StarterKit</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Hello world! This is a StarterKit!</h1>
</body>
</html>
1 change: 1 addition & 0 deletions app/templates/public/swagger-ui/css/print.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions app/templates/public/swagger-ui/css/reset.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/templates/public/swagger-ui/css/screen.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions app/templates/public/swagger-ui/css/style.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file.
Binary file not shown.
Binary file not shown.
Binary file added app/templates/public/swagger-ui/images/collapse.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/templates/public/swagger-ui/images/expand.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading