diff --git a/.gitignore b/.gitignore index ee5c9d8..92bd67f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,8 @@ /out-tsc # dependencies -/node_modules - +client/node_modules +server/node_modules # IDEs and editors /.idea .project diff --git a/Client/.angulardoc.json b/Client/.angulardoc.json new file mode 100644 index 0000000..e021537 --- /dev/null +++ b/Client/.angulardoc.json @@ -0,0 +1,4 @@ +{ + "repoId": "4f4347a5-bd11-49b3-8119-4c44bab04a4d", + "lastSync": 0 +} \ No newline at end of file diff --git a/.editorconfig b/Client/.editorconfig similarity index 100% rename from .editorconfig rename to Client/.editorconfig diff --git a/Client/.gitignore b/Client/.gitignore new file mode 100644 index 0000000..ee5c9d8 --- /dev/null +++ b/Client/.gitignore @@ -0,0 +1,39 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp +/out-tsc + +# dependencies +/node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db diff --git a/LICENSE b/Client/LICENSE similarity index 100% rename from LICENSE rename to Client/LICENSE diff --git a/Client/README.md b/Client/README.md new file mode 100644 index 0000000..03b0901 --- /dev/null +++ b/Client/README.md @@ -0,0 +1,32 @@ +# Angular 6 HttpClient: Consume RESTful API Example + + +backend : NodeRestApi + +This source code is part of [Angular 6 HttpClient: Consume RESTful API Example](https://www.djamware.com/post/5b87894280aca74669894414/angular-6-httpclient-consume-restful-api-example) tutorial. + +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.1.5. + +## Development server + +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. + +## Running unit tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Running end-to-end tests + +Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). diff --git a/angular.json b/Client/angular.json similarity index 100% rename from angular.json rename to Client/angular.json diff --git a/e2e/protractor.conf.js b/Client/e2e/protractor.conf.js similarity index 100% rename from e2e/protractor.conf.js rename to Client/e2e/protractor.conf.js diff --git a/e2e/src/app.e2e-spec.ts b/Client/e2e/src/app.e2e-spec.ts similarity index 100% rename from e2e/src/app.e2e-spec.ts rename to Client/e2e/src/app.e2e-spec.ts diff --git a/e2e/src/app.po.ts b/Client/e2e/src/app.po.ts similarity index 100% rename from e2e/src/app.po.ts rename to Client/e2e/src/app.po.ts diff --git a/e2e/tsconfig.e2e.json b/Client/e2e/tsconfig.e2e.json similarity index 100% rename from e2e/tsconfig.e2e.json rename to Client/e2e/tsconfig.e2e.json diff --git a/package-lock.json b/Client/package-lock.json similarity index 99% rename from package-lock.json rename to Client/package-lock.json index 135197d..ccec712 100644 --- a/package-lock.json +++ b/Client/package-lock.json @@ -3741,12 +3741,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3761,17 +3763,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3888,7 +3893,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3900,6 +3906,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3914,6 +3921,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3921,12 +3929,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -3945,6 +3955,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -4025,7 +4036,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -4037,6 +4049,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -4158,6 +4171,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", diff --git a/package.json b/Client/package.json similarity index 100% rename from package.json rename to Client/package.json diff --git a/src/app/app.component.css b/Client/src/app/app.component.css similarity index 100% rename from src/app/app.component.css rename to Client/src/app/app.component.css diff --git a/src/app/app.component.html b/Client/src/app/app.component.html similarity index 100% rename from src/app/app.component.html rename to Client/src/app/app.component.html diff --git a/src/app/app.component.ts b/Client/src/app/app.component.ts similarity index 100% rename from src/app/app.component.ts rename to Client/src/app/app.component.ts diff --git a/src/app/app.module.ts b/Client/src/app/app.module.ts similarity index 100% rename from src/app/app.module.ts rename to Client/src/app/app.module.ts diff --git a/src/app/product-add/product-add.component.css b/Client/src/app/product-add/product-add.component.css similarity index 100% rename from src/app/product-add/product-add.component.css rename to Client/src/app/product-add/product-add.component.css diff --git a/src/app/product-add/product-add.component.html b/Client/src/app/product-add/product-add.component.html similarity index 100% rename from src/app/product-add/product-add.component.html rename to Client/src/app/product-add/product-add.component.html diff --git a/src/app/product-add/product-add.component.spec.ts b/Client/src/app/product-add/product-add.component.spec.ts similarity index 100% rename from src/app/product-add/product-add.component.spec.ts rename to Client/src/app/product-add/product-add.component.spec.ts diff --git a/src/app/product-add/product-add.component.ts b/Client/src/app/product-add/product-add.component.ts similarity index 86% rename from src/app/product-add/product-add.component.ts rename to Client/src/app/product-add/product-add.component.ts index 04fcb22..7325952 100644 --- a/src/app/product-add/product-add.component.ts +++ b/Client/src/app/product-add/product-add.component.ts @@ -18,7 +18,9 @@ export class ProductAddComponent implements OnInit { addProduct() { this.rest.addProduct(this.productData).subscribe((result) => { - this.router.navigate(['/product-details/'+result._id]); + // this.router.navigate(['/product-details/'+ result._id]); + this.router.navigate(['/products']); + }, (err) => { console.log(err); }); diff --git a/src/app/product-detail/product-detail.component.css b/Client/src/app/product-detail/product-detail.component.css similarity index 100% rename from src/app/product-detail/product-detail.component.css rename to Client/src/app/product-detail/product-detail.component.css diff --git a/src/app/product-detail/product-detail.component.html b/Client/src/app/product-detail/product-detail.component.html similarity index 100% rename from src/app/product-detail/product-detail.component.html rename to Client/src/app/product-detail/product-detail.component.html diff --git a/src/app/product-detail/product-detail.component.spec.ts b/Client/src/app/product-detail/product-detail.component.spec.ts similarity index 100% rename from src/app/product-detail/product-detail.component.spec.ts rename to Client/src/app/product-detail/product-detail.component.spec.ts diff --git a/src/app/product-detail/product-detail.component.ts b/Client/src/app/product-detail/product-detail.component.ts similarity index 100% rename from src/app/product-detail/product-detail.component.ts rename to Client/src/app/product-detail/product-detail.component.ts diff --git a/src/app/product-edit/product-edit.component.css b/Client/src/app/product-edit/product-edit.component.css similarity index 100% rename from src/app/product-edit/product-edit.component.css rename to Client/src/app/product-edit/product-edit.component.css diff --git a/src/app/product-edit/product-edit.component.html b/Client/src/app/product-edit/product-edit.component.html similarity index 100% rename from src/app/product-edit/product-edit.component.html rename to Client/src/app/product-edit/product-edit.component.html diff --git a/src/app/product-edit/product-edit.component.spec.ts b/Client/src/app/product-edit/product-edit.component.spec.ts similarity index 100% rename from src/app/product-edit/product-edit.component.spec.ts rename to Client/src/app/product-edit/product-edit.component.spec.ts diff --git a/src/app/product-edit/product-edit.component.ts b/Client/src/app/product-edit/product-edit.component.ts similarity index 74% rename from src/app/product-edit/product-edit.component.ts rename to Client/src/app/product-edit/product-edit.component.ts index bca5cd2..3d84a68 100644 --- a/src/app/product-edit/product-edit.component.ts +++ b/Client/src/app/product-edit/product-edit.component.ts @@ -9,9 +9,9 @@ import { ActivatedRoute, Router } from '@angular/router'; }) export class ProductEditComponent implements OnInit { - @Input() productData:any = { prod_name: '', prod_desc: '', prod_price:0 }; + @Input() productData: any = { prod_name: '', prod_desc: '', prod_price: 0 }; - constructor(public rest:RestService, private route: ActivatedRoute, private router: Router) { } + constructor(public rest: RestService, private route: ActivatedRoute, private router: Router) { } ngOnInit() { this.rest.getProduct(this.route.snapshot.params['id']).subscribe((data: {}) => { @@ -22,7 +22,7 @@ export class ProductEditComponent implements OnInit { updateProduct() { this.rest.updateProduct(this.route.snapshot.params['id'], this.productData).subscribe((result) => { - this.router.navigate(['/product-details/'+result._id]); + this.router.navigate(['/product-details/' + result._id]); }, (err) => { console.log(err); }); diff --git a/src/app/product/product.component.css b/Client/src/app/product/product.component.css similarity index 89% rename from src/app/product/product.component.css rename to Client/src/app/product/product.component.css index afbfdfe..254073a 100644 --- a/src/app/product/product.component.css +++ b/Client/src/app/product/product.component.css @@ -71,3 +71,11 @@ button.delete { background-color: gray !important; color: white; } + +button.edit { + position: relative; + left: 140px; + top: -32px; + background-color: rgb(29, 150, 99) !important; + color: white; +} diff --git a/src/app/product/product.component.html b/Client/src/app/product/product.component.html similarity index 80% rename from src/app/product/product.component.html rename to Client/src/app/product/product.component.html index 68b283d..9bda350 100644 --- a/src/app/product/product.component.html +++ b/Client/src/app/product/product.component.html @@ -13,5 +13,10 @@

Product List

+ + + + diff --git a/src/app/product/product.component.ts b/Client/src/app/product/product.component.ts similarity index 80% rename from src/app/product/product.component.ts rename to Client/src/app/product/product.component.ts index a96c57e..14b896d 100644 --- a/src/app/product/product.component.ts +++ b/Client/src/app/product/product.component.ts @@ -9,9 +9,9 @@ import { ActivatedRoute, Router } from '@angular/router'; }) export class ProductComponent implements OnInit { - products:any = []; + products: any = []; - constructor(public rest:RestService, private route: ActivatedRoute, private router: Router) { } + constructor(public rest: RestService, private route: ActivatedRoute, private router: Router) { } ngOnInit() { this.getProducts(); @@ -39,4 +39,8 @@ export class ProductComponent implements OnInit { ); } + edit(id) { + this.router.navigate(['/product-edit/' + id]); + } + } diff --git a/src/app/rest.service.ts b/Client/src/app/rest.service.ts similarity index 96% rename from src/app/rest.service.ts rename to Client/src/app/rest.service.ts index 628b9d3..8dc17d9 100644 --- a/src/app/rest.service.ts +++ b/Client/src/app/rest.service.ts @@ -18,7 +18,7 @@ export class RestService { constructor(private http: HttpClient) {} private extractData(res: Response) { - let body = res; + const body = res; return body || { }; } @@ -35,6 +35,7 @@ export class RestService { addProduct (product): Observable { console.log(product); return this.http.post(endpoint + 'products', JSON.stringify(product), httpOptions).pipe( + // tslint:disable-next-line:no-shadowed-variable tap((product) => console.log(`added product w/ id=${product.id}`)), catchError(this.handleError('addProduct')) ); diff --git a/src/assets/.gitkeep b/Client/src/assets/.gitkeep similarity index 100% rename from src/assets/.gitkeep rename to Client/src/assets/.gitkeep diff --git a/src/browserslist b/Client/src/browserslist similarity index 100% rename from src/browserslist rename to Client/src/browserslist diff --git a/src/environments/environment.prod.ts b/Client/src/environments/environment.prod.ts similarity index 100% rename from src/environments/environment.prod.ts rename to Client/src/environments/environment.prod.ts diff --git a/src/environments/environment.ts b/Client/src/environments/environment.ts similarity index 100% rename from src/environments/environment.ts rename to Client/src/environments/environment.ts diff --git a/src/favicon.ico b/Client/src/favicon.ico similarity index 100% rename from src/favicon.ico rename to Client/src/favicon.ico diff --git a/src/index.html b/Client/src/index.html similarity index 84% rename from src/index.html rename to Client/src/index.html index 961dead..7be2e81 100644 --- a/src/index.html +++ b/Client/src/index.html @@ -2,7 +2,7 @@ - Angular6Httpclient + Angular 6 Httpclient - rest demo diff --git a/src/karma.conf.js b/Client/src/karma.conf.js similarity index 100% rename from src/karma.conf.js rename to Client/src/karma.conf.js diff --git a/src/main.ts b/Client/src/main.ts similarity index 100% rename from src/main.ts rename to Client/src/main.ts diff --git a/src/polyfills.ts b/Client/src/polyfills.ts similarity index 100% rename from src/polyfills.ts rename to Client/src/polyfills.ts diff --git a/src/styles.css b/Client/src/styles.css similarity index 100% rename from src/styles.css rename to Client/src/styles.css diff --git a/src/test.ts b/Client/src/test.ts similarity index 100% rename from src/test.ts rename to Client/src/test.ts diff --git a/src/tsconfig.app.json b/Client/src/tsconfig.app.json similarity index 100% rename from src/tsconfig.app.json rename to Client/src/tsconfig.app.json diff --git a/src/tsconfig.spec.json b/Client/src/tsconfig.spec.json similarity index 100% rename from src/tsconfig.spec.json rename to Client/src/tsconfig.spec.json diff --git a/src/tslint.json b/Client/src/tslint.json similarity index 100% rename from src/tslint.json rename to Client/src/tslint.json diff --git a/tsconfig.json b/Client/tsconfig.json similarity index 100% rename from tsconfig.json rename to Client/tsconfig.json diff --git a/tslint.json b/Client/tslint.json similarity index 100% rename from tslint.json rename to Client/tslint.json diff --git a/README.md b/README.md index 6c5b2ca..c7b294f 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,3 @@ -# Angular 6 HttpClient: Consume RESTful API Example - -This source code is part of [Angular 6 HttpClient: Consume RESTful API Example](https://www.djamware.com/post/5b87894280aca74669894414/angular-6-httpclient-consume-restful-api-example) tutorial. - -This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.1.5. - -## Development server - -Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. - -## Code scaffolding - -Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. - -## Build - -Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. - -## Running unit tests - -Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). - -## Running end-to-end tests - -Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). - -## Further help - -To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). +# angular6-httpclient-example +Angular 6 HttpClient: Consume RESTful API Example +Made some adjustments - to complete the example.... client and server in the same git diff --git a/Server/LICENSE.txt b/Server/LICENSE.txt new file mode 100644 index 0000000..f7272cf --- /dev/null +++ b/Server/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Didin Jamaludin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Server/README.md b/Server/README.md new file mode 100644 index 0000000..56de5d5 --- /dev/null +++ b/Server/README.md @@ -0,0 +1,5 @@ +# NodeRestApi + +This source code is part of Node.js tutorial [How to create REST API easily using Node.js, Express.js and MongoDB](https://www.djamware.com/post/58a91cdf80aca748640ce353/how-to-create-rest-api-easily-using-nodejs-expressjs-mongoosejs-and-mongodb) + +Backend de angular6-httpclient-example \ No newline at end of file diff --git a/Server/app.js b/Server/app.js new file mode 100644 index 0000000..b9d8630 --- /dev/null +++ b/Server/app.js @@ -0,0 +1,67 @@ +var express = require('express'); +var path = require('path'); +var favicon = require('serve-favicon'); +var logger = require('morgan'); +var cookieParser = require('cookie-parser'); +var bodyParser = require('body-parser'); +var mongoose = require('mongoose'); +var restful = require('node-restful'); +var methodOverride = require('method-override'); +var cors = require('cors'); + +var index = require('./routes/index'); +var users = require('./routes/users'); +var products = require('./routes/products'); +var app = express(); + +mongoose.Promise = global.Promise; + +mongoose.connect('mongodb://localhost/product') + .then(() => console.log('connection successful')) + .catch((err) => console.error(err)); + +// view engine setup +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'ejs'); + +// uncomment after placing your favicon in /public +//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); +app.use(logger('dev')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({'extended':'true'})); +app.use(bodyParser.json({type:'application/vnd.api+json'})); +app.use(methodOverride()); +app.use(cookieParser()); +app.use(express.static(path.join(__dirname, 'public'))); + +app.use(cors()); +app.use('/', index); +app.use('/users', users); +app.use('/api/v1/products', products); + +var Category = app.resource = restful.model('category', mongoose.Schema({ + cat_name: String, +})) +.methods(['get', 'post', 'put', 'delete']); + +Category.register(app, '/category'); + +// catch 404 and forward to error handler +app.use(function(req, res, next) { + var err = new Error('Not Found'); + err.status = 404; + next(err); +}); + +// error handler +app.use(function(err, req, res, next) { + // set locals, only providing error in development + res.locals.message = err.message; + res.locals.error = req.app.get('env') === 'development' ? err : {}; + + // render the error page + res.status(err.status || 500); + res.json(err.message); +}); + +module.exports = app; diff --git a/Server/bin/www b/Server/bin/www new file mode 100644 index 0000000..3004d92 --- /dev/null +++ b/Server/bin/www @@ -0,0 +1,90 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var app = require('../app'); +var debug = require('debug')('node-rest-api:server'); +var http = require('http'); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || '3000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + debug('Listening on ' + bind); +} diff --git a/Server/models/Product.js b/Server/models/Product.js new file mode 100644 index 0000000..1907fcc --- /dev/null +++ b/Server/models/Product.js @@ -0,0 +1,10 @@ +var mongoose = require('mongoose'); + +var ProductSchema = new mongoose.Schema({ + prod_name: String, + prod_desc: String, + prod_price: Number, + updated_at: { type: Date, default: Date.now }, +}); + +module.exports = mongoose.model('Product', ProductSchema); diff --git a/Server/package-lock.json b/Server/package-lock.json new file mode 100644 index 0000000..50a1181 --- /dev/null +++ b/Server/package-lock.json @@ -0,0 +1,694 @@ +{ + "name": "node-rest-api", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", + "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", + "requires": { + "mime-types": "~2.1.11", + "negotiator": "0.6.1" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "async": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz", + "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=", + "requires": { + "lodash": "^4.14.0" + } + }, + "basic-auth": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.0.4.tgz", + "integrity": "sha1-Awk1sB3nyblKgksp8/zLdQ06UpA=" + }, + "bluebird": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.2.tgz", + "integrity": "sha1-AkpVFylTCIV/FPkfEQb8O1VfRGs=" + }, + "body-parser": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.16.1.tgz", + "integrity": "sha1-UVQNBFrfp6DGmVoBS7ax7ZuAIyk=", + "requires": { + "bytes": "2.4.0", + "content-type": "~1.0.2", + "debug": "2.6.1", + "depd": "~1.1.0", + "http-errors": "~1.5.1", + "iconv-lite": "0.4.15", + "on-finished": "~2.3.0", + "qs": "6.2.1", + "raw-body": "~2.2.0", + "type-is": "~1.6.14" + } + }, + "bson": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz", + "integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw=" + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "bytes": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", + "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz", + "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=", + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6" + } + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cors": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", + "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "debug": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz", + "integrity": "sha1-eYVQkLosTjEVzH2HaUkdWPBJE1E=", + "requires": { + "ms": "0.7.2" + } + }, + "depd": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz", + "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.6.tgz", + "integrity": "sha1-R5Y2v6P+Ox3r1SCH8KyyBLTxnIg=" + }, + "encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" + }, + "es6-promise": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz", + "integrity": "sha1-A9MLX2fdbmMtKUXTDWZScxo01dg=" + }, + "express": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.14.1.tgz", + "integrity": "sha1-ZGwjf3ZvFIwhIK/wc4F7nk1+DTM=", + "requires": { + "accepts": "~1.3.3", + "array-flatten": "1.1.1", + "content-disposition": "0.5.2", + "content-type": "~1.0.2", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "~2.2.0", + "depd": "~1.1.0", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "etag": "~1.7.0", + "finalhandler": "0.5.1", + "fresh": "0.3.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.1", + "path-to-regexp": "0.1.7", + "proxy-addr": "~1.1.3", + "qs": "6.2.0", + "range-parser": "~1.2.0", + "send": "0.14.2", + "serve-static": "~1.11.2", + "type-is": "~1.6.14", + "utils-merge": "1.0.0", + "vary": "~1.1.0" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + }, + "qs": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.0.tgz", + "integrity": "sha1-O3hIwDwt7OaalSKw+ujEEm10Xzs=" + } + } + }, + "finalhandler": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.1.tgz", + "integrity": "sha1-LEANjUUwk1vCMlScX6OF7Afeb80=", + "requires": { + "debug": "~2.2.0", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "statuses": "~1.3.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + } + } + }, + "forwarded": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz", + "integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M=" + }, + "fresh": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz", + "integrity": "sha1-ZR+DjiJCTnVm3hYdg1jKoZn4PU8=" + }, + "hooks-fixed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-1.2.0.tgz", + "integrity": "sha1-DSdy1NfWhf+SRHJKnwtbJVmqyWs=" + }, + "http-errors": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz", + "integrity": "sha1-eIwNLB3iyBuebowBhDtrl+uSB1A=", + "requires": { + "inherits": "2.0.3", + "setprototypeof": "1.0.2", + "statuses": ">= 1.3.1 < 2" + } + }, + "iconv-lite": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.2.0.tgz", + "integrity": "sha1-irpJyRknmVhb3WQ+DMtQ6K53e6Q=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "kareem": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-1.2.1.tgz", + "integrity": "sha1-rNuMgRmEWDSrv6WK3hz53qY9x1I=" + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "method-override": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.7.tgz", + "integrity": "sha1-jh1HrEgPsM2Hdwg/EciWkBFmsuU=", + "requires": { + "debug": "2.3.3", + "methods": "~1.1.2", + "parseurl": "~1.3.1", + "vary": "~1.1.0" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "requires": { + "ms": "0.7.2" + } + } + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", + "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" + }, + "mime-db": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz", + "integrity": "sha1-6v/NDk/Gk1z4E02iRuLmw1MFrf8=" + }, + "mime-types": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.14.tgz", + "integrity": "sha1-9+99l1g/yvO30oK2+LVnnaselO4=", + "requires": { + "mime-db": "~1.26.0" + } + }, + "mongodb": { + "version": "2.2.24", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.24.tgz", + "integrity": "sha1-gPQNbsW97A3ezw+c4BROeUxGRJo=", + "requires": { + "es6-promise": "3.2.1", + "mongodb-core": "2.1.8", + "readable-stream": "2.1.5" + } + }, + "mongodb-core": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.8.tgz", + "integrity": "sha1-sz4DcNClnZe2yx7GEFJ76elcosA=", + "requires": { + "bson": "~1.0.4", + "require_optional": "~1.0.0" + } + }, + "mongoose": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.8.3.tgz", + "integrity": "sha1-abxSn0m70gZ/B70sBOXmbmrksHk=", + "requires": { + "async": "2.1.4", + "bson": "~1.0.4", + "hooks-fixed": "1.2.0", + "kareem": "1.2.1", + "mongodb": "2.2.24", + "mpath": "0.2.1", + "mpromise": "0.5.5", + "mquery": "2.2.3", + "ms": "0.7.2", + "muri": "1.2.1", + "regexp-clone": "0.0.1", + "sliced": "1.0.1" + } + }, + "morgan": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.7.0.tgz", + "integrity": "sha1-6xDKjlDRq+D409rVwCAdBS2YHGI=", + "requires": { + "basic-auth": "~1.0.3", + "debug": "~2.2.0", + "depd": "~1.1.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + } + } + }, + "mpath": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.2.1.tgz", + "integrity": "sha1-Ok6Ck1mAHeljCcJ6ay4QLon56W4=" + }, + "mpromise": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mpromise/-/mpromise-0.5.5.tgz", + "integrity": "sha1-9bJCWddjrMIlewoMjG2Gb9UXMuY=" + }, + "mquery": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-2.2.3.tgz", + "integrity": "sha1-pHA7ZPtnNPzlHXhKTfCVyr8aj1c=", + "requires": { + "bluebird": "2.10.2", + "debug": "2.2.0", + "regexp-clone": "0.0.1", + "sliced": "0.0.5" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + }, + "sliced": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", + "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8=" + } + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" + }, + "muri": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/muri/-/muri-1.2.1.tgz", + "integrity": "sha1-7H6lzmympSPrGrNbrNpfqBbJqjw=" + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "node-restful": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/node-restful/-/node-restful-0.2.6.tgz", + "integrity": "sha1-Qqs63IwaX5TthkeZhF+O/jEeYy4=", + "requires": { + "underscore": "1.8.3" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" + }, + "parseurl": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", + "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "proxy-addr": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.3.tgz", + "integrity": "sha1-3JdQL1ci6IhGez+iKXp7H/R98HQ=", + "requires": { + "forwarded": "~0.1.0", + "ipaddr.js": "1.2.0" + } + }, + "qs": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz", + "integrity": "sha1-zgPF/wk1vB2daanxTL0Y5WjWdiU=" + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz", + "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=", + "requires": { + "bytes": "2.4.0", + "iconv-lite": "0.4.15", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", + "requires": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "regexp-clone": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", + "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" + }, + "require_optional": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.0.tgz", + "integrity": "sha1-UqhhN6hJco62ClVTNhf4+RT1mr8=", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "send": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.14.2.tgz", + "integrity": "sha1-ObBDiz9RC+Xcb2Z6EfcWiTaM3u8=", + "requires": { + "debug": "~2.2.0", + "depd": "~1.1.0", + "destroy": "~1.0.4", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "etag": "~1.7.0", + "fresh": "0.3.0", + "http-errors": "~1.5.1", + "mime": "1.3.4", + "ms": "0.7.2", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.3.1" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + }, + "dependencies": { + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + } + } + } + } + }, + "serve-favicon": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.3.2.tgz", + "integrity": "sha1-3UGeJo3gEqtysxnTN/IQUBP5OB8=", + "requires": { + "etag": "~1.7.0", + "fresh": "0.3.0", + "ms": "0.7.2", + "parseurl": "~1.3.1" + } + }, + "serve-static": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.11.2.tgz", + "integrity": "sha1-LPmIm9RDWjIMw2iVyapXvWYuasc=", + "requires": { + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "parseurl": "~1.3.1", + "send": "0.14.2" + } + }, + "setprototypeof": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz", + "integrity": "sha1-gaVSFB7BBLiOic44MQOtXGZWTQg=" + }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "type-is": { + "version": "1.6.14", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.14.tgz", + "integrity": "sha1-4hljnBfe0coHiQkt1UoDgmuBfLI=", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.13" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" + }, + "vary": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.0.tgz", + "integrity": "sha1-4eWv+70WrnaN0mdDlLmtMCJlMUA=" + } + } +} diff --git a/Server/package.json b/Server/package.json new file mode 100644 index 0000000..cc2c781 --- /dev/null +++ b/Server/package.json @@ -0,0 +1,21 @@ +{ + "name": "node-rest-api", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www" + }, + "dependencies": { + "body-parser": "~1.16.0", + "cookie-parser": "~1.4.3", + "cors": "^2.8.4", + "debug": "~2.6.0", + "ejs": "~2.5.5", + "express": "~4.14.1", + "method-override": "^2.3.7", + "mongoose": "^4.8.3", + "morgan": "~1.7.0", + "node-restful": "^0.2.6", + "serve-favicon": "~2.3.2" + } +} diff --git a/Server/public/stylesheets/style.css b/Server/public/stylesheets/style.css new file mode 100644 index 0000000..9453385 --- /dev/null +++ b/Server/public/stylesheets/style.css @@ -0,0 +1,8 @@ +body { + padding: 50px; + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; +} + +a { + color: #00B7FF; +} diff --git a/Server/routes/index.js b/Server/routes/index.js new file mode 100644 index 0000000..ecca96a --- /dev/null +++ b/Server/routes/index.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET home page. */ +router.get('/', function(req, res, next) { + res.render('index', { title: 'Express' }); +}); + +module.exports = router; diff --git a/Server/routes/products.js b/Server/routes/products.js new file mode 100644 index 0000000..ba6b0ff --- /dev/null +++ b/Server/routes/products.js @@ -0,0 +1,46 @@ +var express = require('express'); +var router = express.Router(); +var mongoose = require('mongoose'); +var Product = require('../models/Product.js'); + +/* GET ALL PRODUCTS */ +router.get('/', function(req, res, next) { + Product.find(function (err, products) { + if (err) return next(err); + res.json(products); + }); +}); + +/* GET SINGLE PRODUCT BY ID */ +router.get('/:id', function(req, res, next) { + Product.findById(req.params.id, function (err, post) { + if (err) return next(err); + res.json(post); + }); +}); + +/* SAVE PRODUCT */ +router.post('/', function(req, res, next) { + Product.create(req.body, function (err, post) { + if (err) return next(err); + res.json(post); + }); +}); + +/* UPDATE PRODUCT */ +router.put('/:id', function(req, res, next) { + Product.findByIdAndUpdate(req.params.id, req.body, function (err, post) { + if (err) return next(err); + res.json(post); + }); +}); + +/* DELETE PRODUCT */ +router.delete('/:id', function(req, res, next) { + Product.findByIdAndRemove(req.params.id, req.body, function (err, post) { + if (err) return next(err); + res.json(post); + }); +}); + +module.exports = router; diff --git a/Server/routes/users.js b/Server/routes/users.js new file mode 100644 index 0000000..623e430 --- /dev/null +++ b/Server/routes/users.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +router.get('/', function(req, res, next) { + res.send('respond with a resource'); +}); + +module.exports = router; diff --git a/Server/views/error.ejs b/Server/views/error.ejs new file mode 100644 index 0000000..7cf94ed --- /dev/null +++ b/Server/views/error.ejs @@ -0,0 +1,3 @@ +

<%= message %>

+

<%= error.status %>

+
<%= error.stack %>
diff --git a/Server/views/index.ejs b/Server/views/index.ejs new file mode 100644 index 0000000..7b7a1d6 --- /dev/null +++ b/Server/views/index.ejs @@ -0,0 +1,11 @@ + + + + <%= title %> + + + +

<%= title %>

+

Welcome to <%= title %>

+ + diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts deleted file mode 100644 index 5408353..0000000 --- a/src/app/app.component.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { TestBed, async } from '@angular/core/testing'; -import { AppComponent } from './app.component'; -describe('AppComponent', () => { - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ - AppComponent - ], - }).compileComponents(); - })); - it('should create the app', async(() => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app).toBeTruthy(); - })); - it(`should have as title 'angular6-httpclient'`, async(() => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('angular6-httpclient'); - })); - it('should render title in a h1 tag', async(() => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('Welcome to angular6-httpclient!'); - })); -}); diff --git a/src/app/product/product.component.spec.ts b/src/app/product/product.component.spec.ts deleted file mode 100644 index b1a99b0..0000000 --- a/src/app/product/product.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ProductComponent } from './product.component'; - -describe('ProductComponent', () => { - let component: ProductComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ ProductComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(ProductComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/rest.service.spec.ts b/src/app/rest.service.spec.ts deleted file mode 100644 index 235c8a2..0000000 --- a/src/app/rest.service.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { TestBed, inject } from '@angular/core/testing'; - -import { RestService } from './rest.service'; - -describe('RestService', () => { - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [RestService] - }); - }); - - it('should be created', inject([RestService], (service: RestService) => { - expect(service).toBeTruthy(); - })); -});