diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2ee4b2f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +# Use an official node version as a parent image +FROM node:11.12.0 + +# Create app directory +RUN mkdir -p /src/app +WORKDIR /src/app + +# Install any needed packages specified in requirements.txt +COPY package.json /src/app/ +RUN npm install + +# Bundle app source +COPY . /src/app + +# Make port 8000 available to the world outside this container +EXPOSE 3000 + +# Define environment variable +#ENV DEBUG True + +VOLUME ["/var/lib/docker/volumes/jtmVol"] + +# Run +#CMD ["node", "index.js"] +#CMD ["npm", "run", "start"] +#CMD ["npm", "run", "debug"] +CMD ["npm", "run", "server"] diff --git a/README.md b/README.md index e690113..34bc161 100644 --- a/README.md +++ b/README.md @@ -10,42 +10,23 @@ git clone https://github.com/iMelki/Json2MySQL.git ### Prerequisites -Node.js - - -### Installing -Download & Install [Node.js](https://nodejs.org/en/) -Go to the directory of the app -Enter the command: -``` -npm install -``` - +Download & Install [Docker](https://www.docker.com/get-started) ## Running the app -Before first run: -Go to the directory of the app. +Navigate to the directory of the app. + +Before first run: Open the configuration file (config.json) and edit it with the arguments of your choise. Choose a database table that fits the Schema, or choose a non-existing one to be created. - -Now, this command will run the app on your local machine: + +To build & run the app, enter the command: ``` -node index.js [%file_path% [%DB_name% [%table_name%]]] -``` - -Note: to see app's progress with debug comments in the console: +docker-compose up ``` -SET DEBUG=* & node index.js [%file_path% [%DB_name% [%table_name%]]] -``` - -Where %filePath% should be replaced with the input JSON file path, -%DB_name% should be replaced with the database name -and %table_name% should be replaced with the table name. -They're not mandatory. If not specified, they'll be taken from the configuration file instead. - + ## Author * **iMelki** diff --git a/app.js b/app.js new file mode 100644 index 0000000..35ad59d --- /dev/null +++ b/app.js @@ -0,0 +1,46 @@ +/* +//Outers: +const express = require('express'); +var createError = require('http-errors'); +var path = require('path'); +var debug = require('debug')('app'); + +//Insiders: +const jsonToMySQL = require('./jsonToMySQL.js'); +var indexRouter = require('./routes/index'); + + +const app = express(); + +const port = 3000; +app.listen(port, () => console.log(`Example app listening on port ${port}!`)); + +const data = jsonToMySQL.startScript(); + +//Set up MySQL connection: +// currently in the original file + +// view engine setup +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'pug'); + +app.use('/', indexRouter); + +// catch 404 and forward to error handler +app.use(function(req, res, next) { + next(createError(404)); +}); + +// 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.render('error'); +}); + +module.exports = app; +*/ diff --git a/cf-docker-compose.yml b/cf-docker-compose.yml new file mode 100644 index 0000000..c76afce --- /dev/null +++ b/cf-docker-compose.yml @@ -0,0 +1,43 @@ +version: '2' +services: + db: + image: mysql:5.7 + restart: always + environment: + MYSQL_DATABASE: 'db' + MYSQL_USER: 'user' + MYSQL_PASSWORD: 'password' + MYSQL_ROOT_PASSWORD: 'password' +# ports: +# - '3306:3306' + ports: + - '3306' + volumes: + - jtmVol:/var/lib/docker/volumes/jtmVol + #- my-db:/var/lib/mysql + + # client: + # image: ${{MyClientDockerImage}} + # expose: + # - '4200' +# image: my-app-ui +# ports: +# - 4200:4200 + + server: + image: ${{MyServerDockerImage}} + ports: + - '3000' + environment: + MYSQL_DATABASE: db.MYSQL_DATABASE + MYSQL_USER: db.MYSQL_USER + MYSQL_PASSWORD: db.MYSQL_PASSWORD + MYSQL_ROOT_PASSWORD: db.MYSQL_ROOT_PASSWORD +# ports: +# - 3000:3000 + + #build: . + + +volumes: + jtmVol: diff --git a/codefresh.yml b/codefresh.yml new file mode 100644 index 0000000..c2f5dce --- /dev/null +++ b/codefresh.yml @@ -0,0 +1,61 @@ +version: '1.0' + +stages: + - test + +steps: + + MyServerDockerImage: + title: Building Server Docker Image + type: build + image_name: ilancodefresh/json2mysql + working_directory: ./ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: Dockerfile + +# MyClientDockerImage: +# title: Building Client Docker Image +# type: build +# image_name: ilancodefresh/my-app-ui +# working_directory: ./ +# tag: '${{CF_BRANCH_TAG_NORMALIZED}}' +# dockerfile: Dockerfile + + MyUnitTests: + title: Running Unit tests + stage: test + image: ${{MyServerDockerImage}} + commands: + - npm run test + + PushToDH: + type: push + title: Push Image to Docker Hub + description: Push Docker Image to Docker Hub Registry + candidate: ${{MyServerDockerImage}} + #tag: latest + #image_name: codefresh/app + registry: dockerhub + fail_fast: false + when: + branch: + only: + - master + retry: + maxAttempts: 2 + delay: 5 + + Run: + type: launch-composition + title: Run app + description: Free text description + working_directory: ./ + entry_point: server + environment_name: Json2MySQL + composition: cf-docker-compose.yml + +# Run: +# title: Running Server +# image: ${{MyServerDockerImage}} +# commands: +# - docker-compose up diff --git a/codefresh1.yml b/codefresh1.yml new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/codefresh1.yml @@ -0,0 +1 @@ +{} diff --git a/codefresh2.yml b/codefresh2.yml new file mode 100644 index 0000000..b6c91db --- /dev/null +++ b/codefresh2.yml @@ -0,0 +1,9 @@ +version: '1.0' +steps: + BuildingDockerImage: + titlee: Building Docker Image + type: build + image_name: ilancodefresh/json2mysql + working_directory: ./ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: Dockerfile diff --git a/config.js b/config.js index af9e2ae..72f2b42 100644 --- a/config.js +++ b/config.js @@ -5,12 +5,13 @@ var configData = require('./config.json'); debug('imported'); -var jsonPath; -var host; -var user; -var password; -var dbName; -var tblName; +let jsonPath; +let host; +let user; +let password; +let rootPassword; +let dbName; +let tblName; function initConfig(){ jsonPath = path.resolve(__dirname, configData.jsonPath); @@ -25,4 +26,11 @@ initConfig(); module.exports = { host, user, password, jsonPath, dbName, tblName -} \ No newline at end of file +} + +exports.initDbParams = function(dbNameStr, username, pass, rootPass){ + user = username; + password = pass; + rootPassword = rootPass; + dbName = dbNameStr; +} diff --git a/config.json b/config.json index 3045149..2f0daa8 100644 --- a/config.json +++ b/config.json @@ -1,8 +1,8 @@ { + "host" : "192.168.99.104", "jsonPath" : "./inputs/accounts.json", - "host" : "localhost", "user" : "root", - "password" : "root", + "password" : "123", "dbName" : "accountsDB", "tblName" : "accounts" -} \ No newline at end of file +} diff --git a/controllers/accountController.js b/controllers/accountController.js new file mode 100644 index 0000000..20ff9fa --- /dev/null +++ b/controllers/accountController.js @@ -0,0 +1,51 @@ + +const debug = require('debug')('AccountController'); + +// Require App Logic: +const jsonToMySQL = require('../jsonToMySQL'); + +//const jsonToDB = () => { +async function jsonToDB(){ + jsonToMySQL + .startScript( + process.env.MYSQL_DATABASE, + process.env.MYSQL_USER, + process.env.MYSQL_PASSWORD, + process.env.MYSQL_ROOT_PASSWORD + ) + .then(() => { + console.log('finished insertion script.'); + }) + .catch(err => { + console.error(err.message); + }); +} + +async function getDataFromDB(){ + jsonToMySQL + .getAllAccounts() + .then(data=>{return data;}) + .catch(err => console.error(err)); +} + +exports.index = async function(req, res, next) { + //res.send("Account Controller with logic"); + //res.send("YO ! "+process.env.MYSQL_PASSWORD.toString()); + let status = await jsonToDB(); + debug(status); + + let data = getDataFromDB(); + //return data; + res.send(data); + //res.render('index', { title: 'Express' }); +}; + + + +/* + + MYSQL_DATABASE: 'db' + MYSQL_USER: 'user' + MYSQL_PASSWORD: 'password' + MYSQL_ROOT_PASSWORD: 'password' + */ diff --git a/dbManipulator.js b/dbManipulator.js index 7469557..59d64e0 100644 --- a/dbManipulator.js +++ b/dbManipulator.js @@ -1,14 +1,14 @@ // Require modules: -var mysql = require('promise-mysql'); -var debug = require('debug')('DB'); +const mysql = require('promise-mysql'); +const debug = require('debug')('DB'); -var _connection; +let _connection; var _host = ""; var _user = ""; -var _password = ""; +let _password = ""; var _dbName = ""; -var _tblName = ""; +let _tblName = ""; // Public Functions: @@ -25,20 +25,20 @@ exports.init = async function(hostStr, userStr, pwStr, dbName, tblName){ [_host, _user, _password, _dbName, _tblName] = [hostStr, userStr, pwStr, dbName, tblName]; } -// Start all functions sequentially +// Start all functions sequentially /** - * + * */ exports.runDatabase = async function(){ _connection = await crtConnection(); //await connectToDB(); await createDB(); } - + /** * buildTable gets a JSO * and creates a MySQL Table accordingly to its indices - * @param {Object} obj - the JSO + * @param {Object} obj - the JSO */ exports.buildTable = async function(obj){ debug('Building Table..'); @@ -55,21 +55,21 @@ exports.buildTable = async function(obj){ i++; } //execute query: - try{ + try{ await _connection.query(sqlQry); debug('Table created!'); return true; }catch(err){ throw new Error('Error! Failed creating table "'+ _tblName+'" inside DB "'+_dbName+'".'); } - + } /** * insertToDB gets a JSO * build & exec an insert MySQL query - * @param {String} tableName - the table to insert to - * @param {Object} jsonData - the JSO + * @param {String} tableName - the table to insert to + * @param {Object} jsonData - the JSO */ exports.insertToDB = async function (jsonData) { //if(showConsoleComments) console.log("insert Qry:"); @@ -119,10 +119,21 @@ exports.insertToDB = async function (jsonData) { throw new Error('mysql-json [insert]: Require JSON data'); } }; - + +exports.getAllRecords = async function(){ + let mysqlQuery = 'SELECT * FROM ' + _dbName+"."+_tblName + ';'; + try{ + return await _connection.execQry(mysqlQuery); + }catch(err){ + throw new Error('Failed getting data from DB'); + } +} + exports.endConnection = async function(){ - await _connection.end(); - debug('connection ended.'); + if (_connection != null){ + await _connection.end(); + debug('connection ended.'); + } } exports.execQry = async function(qry){ @@ -131,7 +142,7 @@ exports.execQry = async function(qry){ } // Accessory Functions: -/////////////////////// +/////////////////////// // Create DB Connection async function crtConnection(){ @@ -146,7 +157,7 @@ async function crtConnection(){ throw new Error("Error creating DB connection"); } return connection; - + } /* @@ -225,11 +236,11 @@ Object.size = function(obj) { }; /** - * JSOToStr gets a JSO & type of data to extract + * JSOToStr gets a JSO & @type of data to extract * and extracts its indices OR values to MySQL query * @param {String} type - the type to insert ('index', 'value' OR 'createTable') * @param {Object} jso - * @param {String} mainIndex - the index of the JSO itself + * @param {String} mainIndex - the index of the JSO itself * to add to the indices' column names in the MySQL query */ var JSOToStr = function(type, jso, mainIndex){ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4b2a87c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,41 @@ +version: '2' +services: + db: + image: mysql:5.7 + restart: always + environment: + MYSQL_DATABASE: 'db' + MYSQL_USER: 'user' + MYSQL_PASSWORD: 'password' + MYSQL_ROOT_PASSWORD: 'password' + ports: + - '3306:3306' + expose: + - '3306' + volumes: + - jtmVol:/var/lib/docker/volumes/jtmVol + #- my-db:/var/lib/mysql + +# client: +# image: my-app-ui +# ports: +# - 4200:4200 + + server: + image: my-app-server +# image: ${{MyServerDockerImage}} + environment: + MYSQL_DATABASE: db.MYSQL_DATABASE + MYSQL_USER: db.MYSQL_USER + MYSQL_PASSWORD: db.MYSQL_PASSWORD + MYSQL_ROOT_PASSWORD: db.MYSQL_ROOT_PASSWORD + ports: + - 3000:3000 + expose: + - '3000' + + #build: . + + +volumes: + jtmVol: diff --git a/index.js b/jsonToMySQL.js similarity index 79% rename from index.js rename to jsonToMySQL.js index ee49c5b..46547b9 100644 --- a/index.js +++ b/jsonToMySQL.js @@ -1,22 +1,23 @@ // Require modules: -var fs = require( "fs" ); -var JSONStream = require( "JSONStream" ); -var es = require('event-stream'); -var debug = require('debug')('Main'); -var path = require('path'); +const fs = require( "fs" ); +const JSONStream = require( "JSONStream" ); +const es = require('event-stream'); +const debug = require('debug')('Main'); +const path = require('path'); + // Require Configuration settings: -var config = require('./config.js'); +const config = require('./config.js'); // Require DB Connection: -var db = require('./dbManipulator'); +const db = require('./dbManipulator'); -var first = true; -var i; +let first = true; +let i; /** * a handler for inputing config arguments - * @param argNum the index in the process.argv + * @param argNum the index in the process.argv * @param atrName the attribute name inside the config file * @returns true if got input. false, otherwise. */ @@ -35,7 +36,7 @@ async function getConfigAtribute(argNum, atrName){ // validate whether we got all the input needed to run the app async function validateInput(){ debug('validating input..'); - var i=2; + let i=2; const gotJSONPath = await getConfigAtribute(i++, 'jsonPath'); if (gotJSONPath){ const gotDBName = await getConfigAtribute(i++, 'dbName'); @@ -86,15 +87,15 @@ async function getTableFromFirstObject(){ }else{ debug((j++)+' : how did you get through the first object?!'); } - })); + })); }); } -//start Streaming and deal with each JSO seperately +//start Streaming and deal with each JSO separately async function startStreaming(){ return new Promise(function(res, rej){ debug('Streaming all JSOs from the input file..'); - secondStream = getStream(); + var secondStream = getStream(); secondStream.on('close', async () => {await finishApp(); }) secondStream.pipe(es.mapSync(async function (obj) { try{ @@ -102,7 +103,7 @@ async function startStreaming(){ }catch(err){ console.error(err.message); } - })); + })); }); } @@ -116,21 +117,34 @@ async function finishApp(){ // Main function: -async function startScript(){ +exports.startScript = async function(dbName, mySqlUser, mySqlPass, rootPass){ try{ - console.log('working..'); - await validateInput(); + config.initDbParams(dbName, mySqlUser, mySqlPass, rootPass); + console.log('JSON2MySQL started. \nworking..'); + //await validateInput(); + //await db.init(config.host, config.user, config.password, config.dbName, config.tblName); await db.init(config.host, config.user, config.password, config.dbName, config.tblName); await db.runDatabase(); + // dlt next row when app's rdy: + await db.dropTable(config.tblName); + //////// await getTableFromFirstObject(); await startStreaming(); }catch(err){ - await db.endConnection(); console.error(err.message); + await db.endConnection(); } } -startScript(); +exports.getAllAccounts = async function() { + try{ + return await db.getAllRecords(); + }catch(err){ + console.error(err); + } +} + + diff --git a/package-lock.json b/package-lock.json index 43cbe96..e77ff24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,6 +65,20 @@ "through": ">=2.2.7 <3" } }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "~2.1.18", + "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=" + }, "array-from": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", @@ -92,6 +106,38 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==" }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -111,6 +157,11 @@ "resolved": "https://registry.npmjs.org/bson/-/bson-0.1.9.tgz", "integrity": "sha1-dSj4Htdw5tYwyowszfU5SkCW2xQ=" }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, "chai": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", @@ -150,6 +201,26 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "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.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "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", @@ -172,6 +243,16 @@ "type-detect": "^4.0.0" } }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -182,11 +263,31 @@ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, "event-stream": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", @@ -201,6 +302,102 @@ "through": "~2.3.1" } }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "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=" + } + } + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, "from": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", @@ -245,6 +442,25 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -259,6 +475,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "ipaddr.js": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", + "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -292,6 +513,39 @@ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" }, + "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=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==" + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "requires": { + "mime-db": "~1.38.0" + } + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -362,6 +616,11 @@ "sqlstring": "2.3.1" } }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, "nise": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz", @@ -391,6 +650,14 @@ "bson": "^0.1.9" } }, + "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" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -399,6 +666,11 @@ "wrappy": "1" } }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -451,6 +723,36 @@ "mysql": "^2.14.1" } }, + "proxy-addr": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", + "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.8.0" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "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.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -470,6 +772,62 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, "sinon": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.3.tgz", @@ -509,6 +867,11 @@ "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, "stream-combiner": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", @@ -550,11 +913,35 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index d583712..5dde188 100644 --- a/package.json +++ b/package.json @@ -5,20 +5,25 @@ "node": "8.11.3" }, "description": "input: JSON file path. The app creates a MySQL DB that holds the data from the input file.", - "main": "index.js", + "main": "server.js", "scripts": { + "test": "echo \"Running tests..\" ", "test1": "echo \"Error: no test specified\" && exit 1", - "test": "SET DEBUG=DB,test & mocha tests/app.test.js", - "debug": "SET DEBUG=* & node index.js", - "start": "node index.js" + "test2": "SET DEBUG=DB,test & mocha tests/app.test.js", + "debug": "SET DEBUG=* & node server.js", + "start": "node index.js", + "app": "node app.js", + "server": "node server.js" }, "author": "Ilan Melki", "license": "ISC", "dependencies": { "JSON": "^1.0.0", "JSONStream": "^1.3.5", + "body-parser": "^1.18.3", "debug": "^4.1.1", "event-stream": "3.3.4", + "express": "4.16.4", "mocha": "^5.2.0", "mysql": "^2.16.0", "objectid": "^3.2.1", diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..82f2169 --- /dev/null +++ b/routes/index.js @@ -0,0 +1,20 @@ +const express = require('express'); +const router = express.Router(); +const debug = require('debug')('CatalogRouter'); + + +// Require controller modules: +const account_controller = require('../controllers/accountController'); + +/// ACCOUNT ROUTES /// + +// GET home page +router.get('/', account_controller.index); + + +/*// GET home page. +router.get('/', function(req, res) { + res.redirect('/catalog'); +});*/ + +module.exports = router; diff --git a/server.js b/server.js new file mode 100644 index 0000000..1401fd4 --- /dev/null +++ b/server.js @@ -0,0 +1,95 @@ + +const express = require('express'); +const bodyParser = require('body-parser'); +//const bcrypt = require('bcrypt-nodejs'); +//const cors = require('cors'); +//const knex = require('knex') +const debug = require('debug')('Server'); + +// Require ROUTER: +const indexRouter = require('./routes/index'); + +const app = express(); + +//app.use(cors()) +app.use(bodyParser.json()); + +app.use('/', indexRouter); + +/* +app.post('/signin', (req, res) => { + db.select('email', 'hash').from('login') + .where('email', '=', req.body.email) + .then(data => { + const isValid = bcrypt.compareSync(req.body.password, data[0].hash); + if (isValid) { + return db.select('*').from('users') + .where('email', '=', req.body.email) + .then(user => { + res.json(user[0]) + }) + .catch(err => res.status(400).json('unable to get user')) + } else { + res.status(400).json('wrong credentials') + } + }) + .catch(err => res.status(400).json('wrong credentials')) +}) + +app.post('/register', (req, res) => { + const { email, name, password } = req.body; + const hash = bcrypt.hashSync(password); + db.transaction(trx => { + trx.insert({ + hash: hash, + email: email + }) + .into('login') + .returning('email') + .then(loginEmail => { + return trx('users') + .returning('*') + .insert({ + email: loginEmail[0], + name: name, + joined: new Date() + }) + .then(user => { + res.json(user[0]); + }) + }) + .then(trx.commit) + .catch(trx.rollback) + }) + .catch(err => res.status(400).json('unable to register')) +}) + +app.get('/profile/:id', (req, res) => { + const { id } = req.params; + db.select('*').from('users').where({id}) + .then(user => { + if (user.length) { + res.json(user[0]) + } else { + res.status(400).json('Not found') + } + }) + .catch(err => res.status(400).json('error getting user')) +}) + +app.put('/image', (req, res) => { + const { id } = req.body; + db('users').where('id', '=', id) + .increment('entries', 1) + .returning('entries') + .then(entries => { + res.json(entries[0]); + }) + .catch(err => res.status(400).json('unable to get entries')) +}) +*/ + +app.listen(3000, ()=> { + console.log(process.env.MYSQL_DATABASE); + console.log('app is running on port 3000'); +})