├── .babelrc ├── .editorconfig ├── .eslintrc.json ├── .gitignore ├── .travis.yml ├── appveyor.yaml ├── buildScripts ├── distServer.js ├── generateMockData.js ├── mockDataSchema.js ├── srcServer.js ├── startMessage.js └── testSetup.js ├── code └── buildScripts │ └── startMessage.js ├── package-lock.json ├── package.json ├── src ├── api │ ├── baseUrl.js │ ├── db.json │ └── userApi.js ├── index.css ├── index.html ├── index.js ├── index.test.js └── vendor.js ├── webpack.config.dev.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["latest"] 3 | } 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | #editor config 2 | root = true 3 | 4 | [*] 5 | indent_style = tab 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = true 13 | 14 | 15 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": [ 4 | "eslint:recommended", 5 | "plugin:import/errors", 6 | "plugin:import/warnings" 7 | ], 8 | "parserOptions": { 9 | "ecmaVersion": 7, 10 | "sourceType": "module" 11 | }, 12 | "env": { 13 | "browser": true, 14 | "node": true, 15 | "mocha": true 16 | }, 17 | "rules": { 18 | "no-console": 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "10" 4 | -------------------------------------------------------------------------------- /appveyor.yaml: -------------------------------------------------------------------------------- 1 | # Test against this version of Node.js 2 | environment: 3 | matrix: 4 | # node.js 5 | - nodejs_version: "10" 6 | 7 | # Install scripts. (runs after repo cloning) 8 | install: 9 | # Get the latest stable version of Node.js or io.js 10 | - ps: Install-Product node $env:nodejs_version 11 | # install modules 12 | - npm install 13 | 14 | # Post-install test scripts. 15 | test_script: 16 | # Output useful info for debugging. 17 | - node --version 18 | - npm --version 19 | # run tests 20 | - npm test 21 | 22 | # Don't actually build. 23 | build: off 24 | -------------------------------------------------------------------------------- /buildScripts/distServer.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import path from "path"; 3 | import open from "open"; 4 | import compression from "compression"; 5 | 6 | /*eslint-disable no-console */ 7 | 8 | const port = 3000; 9 | const app = express(); 10 | 11 | app.use(express.static("dist")); 12 | app.use(compression()); 13 | 14 | app.get("*", function (req, res) { 15 | res.sendFile(path.join(__dirname, "../dist/index.html")); 16 | }); 17 | 18 | app.listen(port, function (err) { 19 | if (err) { 20 | console.log(err); 21 | } else { 22 | open(`http://localhost:${port}`); 23 | } 24 | }); 25 | -------------------------------------------------------------------------------- /buildScripts/generateMockData.js: -------------------------------------------------------------------------------- 1 | import jsf from "json-schema-faker"; 2 | import { schema } from "./mockDataSchema"; 3 | import fs from "fs"; 4 | import chalk from "chalk"; 5 | 6 | // Extend JSF with the fake libs you want to use. 7 | jsf.extend("faker", () => require("faker")); 8 | 9 | const json = JSON.stringify(jsf.generate(schema)); 10 | 11 | fs.writeFile("./src/api/db.json", json, function (err) { 12 | if (err) { 13 | return console.log(chalk.red(err)); 14 | } else { 15 | console.log(chalk.green("Mock data generated.")); 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /buildScripts/mockDataSchema.js: -------------------------------------------------------------------------------- 1 | export const schema = { 2 | type: "object", 3 | properties: { 4 | users: { 5 | type: "array", 6 | minItems: 3, 7 | maxItems: 5, 8 | items: { 9 | type: "object", 10 | properties: { 11 | id: { 12 | type: "number", 13 | unique: true, 14 | minimum: 1, 15 | }, 16 | firstName: { 17 | type: "string", 18 | faker: "name.firstName", 19 | }, 20 | lastName: { 21 | type: "string", 22 | faker: "name.lastName", 23 | }, 24 | email: { 25 | type: "string", 26 | faker: "internet.email", 27 | }, 28 | }, 29 | required: ["id", "firstName", "lastName", "email"], 30 | }, 31 | }, 32 | }, 33 | required: ["users"], 34 | }; 35 | -------------------------------------------------------------------------------- /buildScripts/srcServer.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import path from "path"; 3 | import open from "open"; 4 | import webpack from "webpack"; 5 | import config from "../webpack.config.dev"; 6 | 7 | var port = 3000; 8 | var app = express(); 9 | const compiler = webpack(config); 10 | 11 | /* 12 | eslint-disable no-console 13 | */ 14 | app.use( 15 | require("webpack-dev-middleware")(compiler, { 16 | noInfo: true, 17 | publicPath: config.output.publicPath, 18 | }) 19 | ); 20 | 21 | app.get("/", function (req, res) { 22 | res.sendFile(path.join(__dirname, "../src/index.html")); 23 | }); 24 | 25 | app.get("/users", function (req, res) { 26 | // Hard coding for simplicity. Pretend this hits a real database 27 | res.json([ 28 | { id: 1, firstName: "Bob", lastName: "Smith", email: "bob@gmail.com" }, 29 | { id: 2, firstName: "Tammy", lastName: "Norton", email: "tno@yahoo.com" }, 30 | { 31 | id: 3, 32 | firstName: "Tina", 33 | lastName: "Lee", 34 | email: "lee.tina@hotmail.com", 35 | }, 36 | ]); 37 | }); 38 | 39 | app.listen(port, function (err) { 40 | if (err) { 41 | console.log(err); 42 | } else { 43 | open("http://localhost:" + port); 44 | } 45 | }); 46 | -------------------------------------------------------------------------------- /buildScripts/startMessage.js: -------------------------------------------------------------------------------- 1 | import chalk from "chalk"; 2 | console.log(chalk.green("Starting the App in Dev Mode...")); // eslint-disable-line no-console 3 | -------------------------------------------------------------------------------- /buildScripts/testSetup.js: -------------------------------------------------------------------------------- 1 | // Register babel to transpile before our tests run. 2 | require("@babel/register")(); 3 | 4 | // Disable webpack features that Mocha doesn't understand. 5 | require.extensions[".css"] = function () {}; 6 | -------------------------------------------------------------------------------- /code/buildScripts/startMessage.js: -------------------------------------------------------------------------------- 1 | import chalk from "chalk"; 2 | console.log(chalk.green("Starting the App in Dev Mode...")); // eslint-disable-line no-console 3 | ls 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "repository": { 3 | "type": "git", 4 | "url": "git://github.com/user/javascript-development-environment.git" 5 | }, 6 | "name": "javascript-development-environment", 7 | "version": "1.0.1", 8 | "description": "JavaScript development environment packages for use to build a Node.js project, obtained from: https://www.npmjs.com/search?q=", 9 | "scripts": { 10 | "prestart": "babel-node buildScripts/startMessage.js", 11 | "open:src": "babel-node buildScripts/srcServer.js", 12 | "ngrok": "ngrok http 3000", 13 | "start": "npm-run-all --parallel open:src lint:watch test:watch start-mockapi", 14 | "security-check": "npm audit --audit-level high", 15 | "lint": "esw webpack.config.* src buildScripts", 16 | "lint:watch": "npm run lint -- --watch", 17 | "share": "npm-run-all --parallel open:src ngrok", 18 | "test": "mocha --reporter progress buildScripts/testSetup.js \"src/**/*.test.js\"", 19 | "test:watch": "npm run test -- --watch", 20 | "generate-mock-data": "babel-node buildScripts/generateMockData", 21 | "prestart-mockapi": "npm run generate-mock-data", 22 | "start-mockapi": "json-server --watch src/api/db.json --port 3001", 23 | "clean-dist": "rimraf ./dist && mkdir dist", 24 | "prebuild": "npm-run-all clean-dist test lint", 25 | "build": "babel-node buildScripts/build.js", 26 | "postbuild": "babel-node buildScripts/distServer.js" 27 | }, 28 | "author": "Cory House", 29 | "license": "MIT", 30 | "dependencies": { 31 | "faker": "^4.1.0", 32 | "whatwg-fetch": "^3.0.0" 33 | }, 34 | "devDependencies": { 35 | "@babel/core": "^7.2.2", 36 | "@babel/register": "^7.10.1", 37 | "babel-cli": "^6.26.0", 38 | "babel-core": "^6.26.0", 39 | "babel-loader": "^7.1.4", 40 | "babel-preset-env": "^1.7.0", 41 | "babel-preset-latest": "^6.24.1", 42 | "babel-register": "^6.26.0", 43 | "chai": "^4.2.0", 44 | "chalk": "^2.4.1", 45 | "cheerio": "^1.0.0-rc.2", 46 | "compression": "^1.7.3", 47 | "cross-env": "^5.2.0", 48 | "css-loader": "^2.0.1", 49 | "duplicate-package-checker-webpack-plugin": "^3.0.0", 50 | "eslint": "^5.10.0", 51 | "eslint-plugin-import": "^2.14.0", 52 | "eslint-watch": "^4.0.2", 53 | "express": "^4.16.4", 54 | "extract-text-webpack-plugin": "^4.0.0-beta.0", 55 | "html-webpack-plugin": "^3.2.0", 56 | "jsdom": "^13.1.0", 57 | "json-schema-faker": "^0.5.0-rc16", 58 | "json-server": "^0.14.0", 59 | "localtunnel": "^1.9.1", 60 | "lodash": "^4.17.11", 61 | "mocha": "^5.2.0", 62 | "nock": "^10.0.4", 63 | "npm-run-all": "^4.1.5", 64 | "numeral": "^2.0.6", 65 | "open": "6.0.0", 66 | "rimraf": "^2.6.2", 67 | "style-loader": "^0.23.1", 68 | "uglifyjs-webpack-plugin": "^2.2.0", 69 | "webpack": "^4.28.0", 70 | "webpack-cli": "^3.3.11", 71 | "webpack-dev-middleware": "^3.4.0", 72 | "webpack-hot-middleware": "^2.24.3", 73 | "webpack-md5-hash": "0.0.6" 74 | }, 75 | "comments": { 76 | "babel-preset-latest": "deprecated and babel-preset-env replaced", 77 | "nsp": "deprecated, no alternate package, nsp built-in npm@6" 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/api/baseUrl.js: -------------------------------------------------------------------------------- 1 | export default function getBaseUrl() { 2 | return getQueryStringParameterByName("useMockApi") 3 | ? "http://localhost:3001/" 4 | : "https://blooming-harbor-61095.herokuapp.com/"; 5 | } 6 | 7 | function getQueryStringParameterByName(name, url) { 8 | if (!url) url = window.location.href; 9 | name = name.replace(/[[\]]/g, "\\$&"); 10 | var regex = new RegExp("[?&]" + name + "(=([^]*)|&|#|$)"), 11 | results = regex.exec(url); 12 | if (!results) return null; 13 | if (!results[2]) return ""; 14 | return decodeURIComponent(results[2].replace(/\+/g, " ")); 15 | } 16 | -------------------------------------------------------------------------------- /src/api/db.json: -------------------------------------------------------------------------------- 1 | {"users":[{"id":87964685.06505004,"firstName":"Quentin","lastName":"Zemlak","email":"Dominique_Kris11@yahoo.com"},{"id":85126881.03165741,"firstName":"Aric","lastName":"Schinner","email":"Desiree.Yost47@hotmail.com"},{"id":48648707.852175,"firstName":"Baby","lastName":"Kub","email":"Mathias82@yahoo.com"},{"id":50790627.25905984,"firstName":"Velda","lastName":"Rowe","email":"Betty72@gmail.com"}]} -------------------------------------------------------------------------------- /src/api/userApi.js: -------------------------------------------------------------------------------- 1 | import "whatwg-fetch"; 2 | import getBaseUrl from "./baseUrl"; 3 | 4 | const baseUrl = getBaseUrl(); 5 | 6 | export function getUsers() { 7 | return get("users"); 8 | } 9 | 10 | export function deleteUser(id) { 11 | return del(`users/${id}`); 12 | } 13 | 14 | function get(url) { 15 | return fetch(baseUrl + url).then(onSuccess, onError); 16 | } 17 | 18 | // Can't call func delete since reserved word. 19 | function del(url) { 20 | const request = new Request(baseUrl + url, { 21 | method: "DELETE", 22 | }); 23 | 24 | return fetch(request).then(onSuccess, onError); 25 | } 26 | 27 | function onSuccess(response) { 28 | return response.json(); 29 | } 30 | 31 | function onError(error) { 32 | console.log(error); // eslint-disable-line no-console 33 | } 34 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Sans-Serif; 3 | } 4 | 5 | table th { 6 | padding: 5px; 7 | } 8 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |13 | | Id | 14 |First Name | 15 |Last Name | 16 |
---|