diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..9175231 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["latest"] +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c7a329 --- /dev/null +++ b/.gitignore @@ -0,0 +1,102 @@ + +# Created by https://www.gitignore.io/api/node,webstorm + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + + +### WebStorm ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/ + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +### WebStorm Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# End of https://www.gitignore.io/api/node,webstorm +# All files tmp +tmp/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ce6e0b2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM rafakato/alpine-node-media:latest + +RUN apk add --virtual .build-dependencies --no-cache --update alpine-sdk git python + +WORKDIR /code + +EXPOSE 3000 + +CMD ["node", "index.js"] \ No newline at end of file diff --git a/controllers/series.js b/controllers/series.js new file mode 100644 index 0000000..825c052 --- /dev/null +++ b/controllers/series.js @@ -0,0 +1,6 @@ + +import * as db from '../helpers/db'; + +export const findAll = (request, reply) => { + reply('Series OK'); +}; \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..974e10c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +version: '2' +services: + mongodb: + image: mongo:3.4.2 + volumes: + - ./tmp/mongodb:/data/db + ports: + - "27017:27017" + restart: always \ No newline at end of file diff --git a/helpers/db.js b/helpers/db.js new file mode 100644 index 0000000..8c88f4a --- /dev/null +++ b/helpers/db.js @@ -0,0 +1,63 @@ + +import mongoose from 'mongoose'; +import Bluebird from 'bluebird'; +import Debug from 'debug'; + +mongoose.Promise = Bluebird; + +const debug = Debug('sofanerd.db.mongodb'); +const connections = {}; + +export const connect = (connectionName = Date.now().toString(), connectionUrl = process.env.MONGODB_URL, options = { server: { poolSize: 10 } }) => { + if(!connections.hasOwnProperty(connectionName)) { + debug('Connection to MongoDB'); + + const connection = mongoose.createConnection(connectionUrl, options); + + connections[connectionName] = connection; + + if(process.env.DEBUG) { + mongoose.set('debug', true); + } + + // Connection Open + connection.once('open', () => { + debug(`Connection open with ${connectionUrl}`); + }); + + // Connected + connection.once('connected', () => { + debug(`Connected to ${connectionUrl}`); + }); + + // Disconnect + connection.once('disconnected', () => { + debug(`Disconnected from ${connectionUrl}`); + }); + + // Error + connection.once('error', (error) => { + debug('Connection error', error); + }); + + process.on('SIGINT', () => { + connection.close(() => { + debug('Connection closed by ctrl+c command'); + process.exit(0); + }); + }); + } + + return { + name: connectionName, + connection: connections[connectionName] + }; +}; + +export const disconnect = async (connectionName) => { + if(connections.hasOwnProperty(connectionName) === false) { + throw new Error(`Connection name ${connectionName} does not exists`); + } + + await connections[connectionName].close(); +}; \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..7523186 --- /dev/null +++ b/index.js @@ -0,0 +1,46 @@ + +import Hapi from 'hapi'; +import dotenv from 'dotenv'; +import Debug from 'debug'; +import Routes from './plugins/routes'; + +dotenv.config(); + +const debug = Debug('sofanerd.server'); +const server = new Hapi.Server({ + debug: { + request: ['error', 'uncaught'] + } +}); + +server.connection({ + port: process.env.NODE_PORT || 3000 +}); + +let initializer = [ + Routes +]; + +try { + server.register(initializer, (error) => { + if(error) { + debug(error); + } else { + debug('Starting server'); + + server.start((err) => { + if(err) { + debug(err); + } else { + debug(`Server running at: ${server.info.uri}`); + } + }); + } + } + ); +} catch (err) { + debug(err); + throw err; +} + +export default server; \ No newline at end of file diff --git a/models/schemas/serie.js b/models/schemas/serie.js new file mode 100644 index 0000000..642baf0 --- /dev/null +++ b/models/schemas/serie.js @@ -0,0 +1,8 @@ + +import mongoose from 'mongoose'; + +const Schema = mongoose.Schema; + +const schema = new Schema(); + +export default schema; \ No newline at end of file diff --git a/models/schemas/user.js b/models/schemas/user.js new file mode 100644 index 0000000..642baf0 --- /dev/null +++ b/models/schemas/user.js @@ -0,0 +1,8 @@ + +import mongoose from 'mongoose'; + +const Schema = mongoose.Schema; + +const schema = new Schema(); + +export default schema; \ No newline at end of file diff --git a/models/serie.js b/models/serie.js new file mode 100644 index 0000000..bd1c70d --- /dev/null +++ b/models/serie.js @@ -0,0 +1,4 @@ + +import Debug from 'debug'; + +const debug = Debug('sofanerd.models.serie'); \ No newline at end of file diff --git a/models/user.js b/models/user.js new file mode 100644 index 0000000..206124d --- /dev/null +++ b/models/user.js @@ -0,0 +1,4 @@ + +import Debug from 'debug'; + +const debug = Debug('sofanerd.models.user'); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..2a5bc0e --- /dev/null +++ b/package.json @@ -0,0 +1,36 @@ +{ + "name": "sofanerd", + "version": "0.0.1", + "description": "Mediatracker Sofanerd", + "main": "index.js", + "scripts": { + "start": "DEBUG=sofanerd.* babel-node index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/AraanBranco/sofanerd.git" + }, + "keywords": [ + "nodejs", + "mediatracker", + "hapijs" + ], + "author": "Araan Branco ", + "license": "MIT", + "bugs": { + "url": "https://github.com/AraanBranco/sofanerd/issues" + }, + "homepage": "https://github.com/AraanBranco/sofanerd#readme", + "dependencies": { + "babel-cli": "^6.23.0", + "babel-preset-latest": "^6.22.0", + "bluebird": "^3.5.0", + "debug": "^2.6.1", + "dotenv": "^4.0.0", + "glob": "^7.1.1", + "hapi": "^16.1.0", + "joi": "^10.2.2", + "mongoose": "^4.8.6" + } +} diff --git a/plugins/routes.js b/plugins/routes.js new file mode 100644 index 0000000..027e7ac --- /dev/null +++ b/plugins/routes.js @@ -0,0 +1,27 @@ + +import Debug from 'debug'; +import Routes from '../routes'; + +const debug = Debug('sofanerd.routes'); + +const register = async (server, options, next) => { + try { + debug('Inicialize plugins'); + + let loadedRoutes = await Routes.load(); + + server.route(loadedRoutes); + + return next(); + } catch (err) { + debug(err); + } +}; + +register.attributes = { + name: 'routes' +}; + +export default { + register +} \ No newline at end of file diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..49214f8 --- /dev/null +++ b/routes/index.js @@ -0,0 +1,32 @@ + +import Debug from 'debug'; +import Bluebird from 'bluebird'; +import glob from 'glob'; +import path from 'path'; + +const debug = Debug('sofanerd.routes'); +const globAsync = Bluebird.promisify(glob); + +export default { + async load() { + try { + let routes = []; + debug('Load all routes'); + + let files = await globAsync('**/!(index).js', { + cwd: path.resolve(__dirname) + }); + + files.forEach((file) => { + let allRoutes = require(`./${file}`).default; + + routes.push(...allRoutes); + }); + + debug('Routes loaded'); + return routes; + } catch (err) { + debug(err); + } + } +} \ No newline at end of file diff --git a/routes/series.js b/routes/series.js new file mode 100644 index 0000000..acb7fe0 --- /dev/null +++ b/routes/series.js @@ -0,0 +1,13 @@ + +import Debug from 'debug'; +import * as Controller from '../controllers/series'; + +const debug = Debug('sofanerd.routes.serie'); + +export default [ + { + method: 'GET', + path: '/api/series', + handler: Controller.findAll + } +]; \ No newline at end of file