├── .DS_Store ├── README.md ├── app ├── .eslintrc.js ├── .gitignore ├── README.md ├── package.json ├── public │ ├── index.html │ └── main.js └── src │ ├── App.css │ ├── App.jsx │ ├── Global │ ├── actionTypes.js │ └── context │ │ ├── AppContext.jsx │ │ └── MainContainerContext.jsx │ ├── __tests__ │ ├── body.test.js │ ├── button.test.js │ ├── method.test.js │ ├── navcontainer.test.js │ ├── tab.test.js │ └── url.test.js │ ├── components │ ├── MainContainer.jsx │ ├── Nav │ │ ├── Body.jsx │ │ ├── Login.jsx │ │ ├── Method.jsx │ │ ├── NavContainer.jsx │ │ ├── Signup.jsx │ │ └── Url.jsx │ ├── Performance │ │ └── Performance.jsx │ ├── Response │ │ ├── Middleware │ │ │ ├── FunctionContainer.jsx │ │ │ ├── MiddlewareChain.jsx │ │ │ ├── MiddlewareContainer.jsx │ │ │ └── ResponseObject.jsx │ │ └── ResponseContainer.jsx │ ├── Sidebar │ │ ├── Button.jsx │ │ ├── Buttons.jsx │ │ ├── Help.jsx │ │ ├── Settings.jsx │ │ └── SidebarContainer.jsx │ ├── Tab │ │ ├── Tab.jsx │ │ └── TabContainer.jsx │ ├── Testing │ │ ├── AddTestModal.jsx │ │ ├── IndividualTestView.jsx │ │ ├── RunTestsComponent.jsx │ │ ├── TestComponent.jsx │ │ ├── TestContainer.jsx │ │ ├── TestControls.jsx │ │ └── TestMenuBar.jsx │ ├── Tree │ │ ├── Graph │ │ │ ├── AppNode.jsx │ │ │ ├── Graph.jsx │ │ │ ├── MiddlewareNode.jsx │ │ │ ├── NodeText.jsx │ │ │ ├── RouteNode.jsx │ │ │ └── useForceUpdate.jsx │ │ ├── Tree.jsx │ │ └── TreeRect.jsx │ └── common │ │ └── CodeBlock.jsx │ ├── img │ ├── dashboard1.png │ ├── dashboard3.png │ ├── logo.png │ └── require.png │ ├── index.css │ └── index.jsx ├── npm ├── .editorconfig ├── .eslintignore ├── .eslintrc.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── appveyor.yml ├── benchmarks │ ├── Makefile │ ├── middleware.js │ └── run ├── examples │ ├── auth │ │ ├── index.js │ │ └── views │ │ │ ├── foot.ejs │ │ │ ├── head.ejs │ │ │ └── login.ejs │ ├── content-negotiation │ │ ├── db.js │ │ ├── index.js │ │ └── users.js │ ├── cookie-sessions │ │ └── index.js │ ├── cookies │ │ └── index.js │ ├── downloads │ │ ├── files │ │ │ ├── CCTV大赛上海分赛区.txt │ │ │ └── amazing.txt │ │ └── index.js │ ├── ejs │ │ ├── index.js │ │ ├── public │ │ │ └── stylesheets │ │ │ │ └── style.css │ │ └── views │ │ │ ├── footer.html │ │ │ ├── header.html │ │ │ └── users.html │ ├── error-pages │ │ ├── index.js │ │ └── views │ │ │ ├── 404.ejs │ │ │ ├── 500.ejs │ │ │ ├── error_header.ejs │ │ │ ├── footer.ejs │ │ │ └── index.ejs │ ├── error │ │ └── index.js │ ├── hello-world │ │ └── index.js │ ├── markdown │ │ └── index.js │ ├── multi-router │ │ ├── controllers │ │ │ ├── api_v1.js │ │ │ └── api_v2.js │ │ └── index.js │ ├── multipart │ │ └── index.js │ ├── mvc │ │ ├── controllers │ │ │ ├── main │ │ │ │ └── index.js │ │ │ ├── pet │ │ │ │ ├── index.js │ │ │ │ └── views │ │ │ │ │ ├── edit.ejs │ │ │ │ │ └── show.ejs │ │ │ ├── user-pet │ │ │ │ └── index.js │ │ │ └── user │ │ │ │ ├── index.js │ │ │ │ └── views │ │ │ │ ├── edit.hbs │ │ │ │ ├── list.hbs │ │ │ │ └── show.hbs │ │ ├── db.js │ │ ├── index.js │ │ ├── lib │ │ │ └── boot.js │ │ ├── public │ │ │ └── style.css │ │ └── views │ │ │ ├── 404.ejs │ │ │ └── 5xx.ejs │ ├── online │ │ └── index.js │ ├── params │ │ └── index.js │ ├── resource │ │ └── index.js │ ├── route-map │ │ └── index.js │ ├── route-middleware │ │ └── index.js │ ├── route-separation │ │ ├── index.js │ │ ├── post.js │ │ ├── public │ │ │ └── style.css │ │ ├── site.js │ │ ├── user.js │ │ └── views │ │ │ ├── footer.ejs │ │ │ ├── header.ejs │ │ │ ├── index.ejs │ │ │ ├── posts │ │ │ └── index.ejs │ │ │ └── users │ │ │ ├── edit.ejs │ │ │ ├── index.ejs │ │ │ └── view.ejs │ ├── search │ │ ├── index.js │ │ └── public │ │ │ ├── client.js │ │ │ └── index.html │ ├── session │ │ ├── index.js │ │ └── redis.js │ ├── static-files │ │ ├── index.js │ │ └── public │ │ │ ├── css │ │ │ └── style.css │ │ │ ├── hello.txt │ │ │ └── js │ │ │ └── app.js │ ├── vhost │ │ └── index.js │ ├── view-constructor │ │ ├── github-view.js │ │ └── index.js │ ├── view-locals │ │ ├── index.js │ │ ├── user.js │ │ └── views │ │ │ └── index.ejs │ └── web-service │ │ └── index.js ├── index.js ├── lib │ ├── application.js │ ├── express.js │ ├── middleware │ │ ├── init.js │ │ └── query.js │ ├── observer.js │ ├── request.js │ ├── response.js │ ├── router │ │ ├── index.js │ │ ├── layer.js │ │ └── route.js │ ├── utils.js │ └── view.js ├── package.json └── test │ ├── Route.js │ ├── Router.js │ ├── acceptance │ ├── auth.js │ ├── content-negotiation.js │ ├── cookie-sessions.js │ ├── cookies.js │ ├── downloads.js │ ├── ejs.js │ ├── error-pages.js │ ├── error.js │ ├── markdown.js │ ├── multi-router.js │ ├── mvc.js │ ├── params.js │ ├── resource.js │ ├── route-map.js │ ├── route-separation.js │ ├── vhost.js │ └── web-service.js │ ├── app.all.js │ ├── app.del.js │ ├── app.engine.js │ ├── app.head.js │ ├── app.js │ ├── app.listen.js │ ├── app.locals.js │ ├── app.options.js │ ├── app.param.js │ ├── app.render.js │ ├── app.request.js │ ├── app.response.js │ ├── app.route.js │ ├── app.router.js │ ├── app.routes.error.js │ ├── app.use.js │ ├── config.js │ ├── exports.js │ ├── express.json.js │ ├── express.raw.js │ ├── express.static.js │ ├── express.text.js │ ├── express.urlencoded.js │ ├── fixtures │ ├── % of dogs.txt │ ├── .name │ ├── blog │ │ ├── index.html │ │ └── post │ │ │ └── index.tmpl │ ├── broken.send │ ├── default_layout │ │ ├── name.tmpl │ │ └── user.tmpl │ ├── email.tmpl │ ├── empty.txt │ ├── local_layout │ │ └── user.tmpl │ ├── name.tmpl │ ├── name.txt │ ├── nums.txt │ ├── pets │ │ └── names.txt │ ├── snow ☃ │ │ └── .gitkeep │ ├── todo.html │ ├── todo.txt │ ├── user.html │ ├── user.tmpl │ └── users │ │ ├── index.html │ │ └── tobi.txt │ ├── middleware.basic.js │ ├── mocha.opts │ ├── regression.js │ ├── req.accepts.js │ ├── req.acceptsCharset.js │ ├── req.acceptsCharsets.js │ ├── req.acceptsEncoding.js │ ├── req.acceptsEncodings.js │ ├── req.acceptsLanguage.js │ ├── req.acceptsLanguages.js │ ├── req.baseUrl.js │ ├── req.fresh.js │ ├── req.get.js │ ├── req.host.js │ ├── req.hostname.js │ ├── req.ip.js │ ├── req.ips.js │ ├── req.is.js │ ├── req.param.js │ ├── req.path.js │ ├── req.protocol.js │ ├── req.query.js │ ├── req.range.js │ ├── req.route.js │ ├── req.secure.js │ ├── req.signedCookies.js │ ├── req.stale.js │ ├── req.subdomains.js │ ├── req.xhr.js │ ├── res.append.js │ ├── res.attachment.js │ ├── res.clearCookie.js │ ├── res.cookie.js │ ├── res.download.js │ ├── res.format.js │ ├── res.get.js │ ├── res.json.js │ ├── res.jsonp.js │ ├── res.links.js │ ├── res.locals.js │ ├── res.location.js │ ├── res.redirect.js │ ├── res.render.js │ ├── res.send.js │ ├── res.sendFile.js │ ├── res.sendStatus.js │ ├── res.set.js │ ├── res.status.js │ ├── res.type.js │ ├── res.vary.js │ ├── support │ ├── env.js │ ├── tmpl.js │ └── utils.js │ └── utils.js └── site ├── .eslintrc ├── .gitignore ├── README.md ├── components ├── Closing.js ├── Contact.js ├── Description.js ├── Feature.js ├── Header.js ├── Intro.js ├── Layout.js ├── LinkTo.js └── Team.js ├── next.config.js ├── package-lock.json ├── package.json ├── pages ├── _app.js ├── api │ └── hello.js ├── home │ ├── FeaturePage.js │ └── TeamPage.js └── index.js ├── public ├── app-tree.png ├── ashley.png ├── code-block.png ├── comp.png ├── dashboard1.png ├── eric.png ├── favicon.ico ├── grey-wave.png ├── josh.png ├── julia.png ├── landing.png ├── logo-eye.png ├── logo-text.png ├── logo.png ├── logoText.png ├── macbook-main.png ├── os-labs.png ├── tech-wave-BackGround.png └── vercel.svg ├── routes.js ├── styles ├── Home.module.css └── globals.css └── yarn.lock /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/.DS_Store -------------------------------------------------------------------------------- /app/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | }, 6 | extends: ['eslint:recommended', 'plugin:react/recommended', 'airbnb'], 7 | parserOptions: { 8 | ecmaFeatures: { 9 | jsx: true, 10 | }, 11 | ecmaVersion: 12, 12 | sourceType: 'module', 13 | }, 14 | plugins: ['react'], 15 | rules: { 16 | 'react/prop-types': 'off', 17 | 'linebreak-style': 0, 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | yarn.lock 3 | .DS_Store 4 | .env 5 | node_modules 6 | -------------------------------------------------------------------------------- /app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "observerjs-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@electron/remote": "^1.1.0", 7 | "@material-ui/core": "^4.11.4", 8 | "@material-ui/icons": "^4.11.2", 9 | "@testing-library/jest-dom": "^5.11.4", 10 | "@testing-library/user-event": "^12.1.10", 11 | "@visx/gradient": "^1.7.0", 12 | "@visx/group": "^1.7.0", 13 | "@visx/hierarchy": "^1.7.0", 14 | "@visx/responsive": "^1.10.1", 15 | "@visx/shape": "^1.8.0", 16 | "@visx/tooltip": "^1.7.2", 17 | "@visx/zoom": "^1.11.0", 18 | "concurrently": "^6.0.2", 19 | "cross-env": "^7.0.3", 20 | "d3-shape": "^2.1.0", 21 | "electron": "^12.0.6", 22 | "electron-is-dev": "^2.0.0", 23 | "lodash": "^4.17.21", 24 | "prettier": "^2.3.2", 25 | "prettier-eslint": "^12.0.0", 26 | "pretty-format": "^27.1.0", 27 | "prop-types": "^15.7.2", 28 | "react": "^17.0.2", 29 | "react-dom": "^17.0.2", 30 | "react-scripts": "4.0.3", 31 | "react-syntax-highlighter": "^15.4.3", 32 | "uuid": "^8.3.2", 33 | "wait-on": "^5.3.0", 34 | "web-vitals": "^1.0.1" 35 | }, 36 | "main": "public/main.js", 37 | "homepage": "./", 38 | "scripts": { 39 | "start": "react-scripts start", 40 | "build": "react-scripts build", 41 | "test": "react-scripts test", 42 | "eject": "react-scripts eject", 43 | "electron:serve": "concurrently -k \"cross-env BROWSER=none npm start\" \"npm run electron:start\"", 44 | "electron:build": "npm build && electron-builder -c.extraMetadata.main=build/main.js", 45 | "electron:start": "wait-on tcp:3000 && electron ." 46 | }, 47 | "eslintConfig": { 48 | "extends": [ 49 | "react-app", 50 | "react-app/jest" 51 | ] 52 | }, 53 | "browserslist": { 54 | "production": [ 55 | ">0.2%", 56 | "not dead", 57 | "not op_mini all" 58 | ], 59 | "development": [ 60 | "last 1 chrome version", 61 | "last 1 firefox version", 62 | "last 1 safari version" 63 | ] 64 | }, 65 | "devDependencies": { 66 | "@testing-library/react": "^11.2.7", 67 | "electron-devtools-installer": "^3.2.0", 68 | "eslint": "^7.30.0", 69 | "eslint-config-airbnb": "^18.2.1", 70 | "eslint-plugin-import": "^2.23.4", 71 | "eslint-plugin-jsx-a11y": "^6.4.1", 72 | "eslint-plugin-react": "^7.24.0" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | obServerJS 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /app/public/main.js: -------------------------------------------------------------------------------- 1 | const { app, BrowserWindow } = require('electron'); 2 | const path = require('path'); 3 | const isDev = require('electron-is-dev'); 4 | 5 | require('@electron/remote/main').initialize(); 6 | 7 | function createWindow() { 8 | // Create the browser window. 9 | const win = new BrowserWindow({ 10 | width: 800, 11 | height: 600, 12 | webPreferences: { 13 | nodeIntegration: true, 14 | enableRemoteModule: true, 15 | }, 16 | title: 'obServerJS', 17 | }); 18 | 19 | win.loadURL( 20 | isDev 21 | ? 'http://localhost:3000' 22 | : `file://${path.join(__dirname, '../build/index.html')}`, 23 | ); 24 | } 25 | 26 | app.on('ready', createWindow); 27 | 28 | // Quit when all windows are closed. 29 | app.on('window-all-closed', () => { 30 | // On OS X it is common for applications and their menu bar 31 | // to stay active until the user quits explicitly with Cmd + Q 32 | if (process.platform !== 'darwin') { 33 | app.quit(); 34 | } 35 | }); 36 | 37 | app.on('activate', () => { 38 | // On OS X it's common to re-create a window in the app when the 39 | // dock icon is clicked and there are no other windows open. 40 | if (BrowserWindow.getAllWindows().length === 0) createWindow(); 41 | }); 42 | -------------------------------------------------------------------------------- /app/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | :root { 6 | --Nav-bar: #333333; 7 | --Darkest-black: #181818; 8 | --Nav-Button: #383838; 9 | --Send-Button-Blue: #097bed; 10 | --Nav-Text-Grey: #aaaaaa; 11 | --Tab-Line-Green: #3ecc96; 12 | } 13 | -------------------------------------------------------------------------------- /app/src/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // import App from './App.css'; 3 | import MainContainer from './components/MainContainer'; 4 | import MainContainerProvider from './Global/context/MainContainerContext'; 5 | 6 | function App() { 7 | return ( 8 |
9 | 10 | 11 | 12 |
13 | ); 14 | } 15 | 16 | export default App; 17 | -------------------------------------------------------------------------------- /app/src/Global/actionTypes.js: -------------------------------------------------------------------------------- 1 | // Request Tabs 2 | export const CLOSE_TAB = 'CLOSE_TAB'; 3 | export const NEW_TAB = 'NEW_TAB'; 4 | export const CHANGE_ACTIVE_TAB = 'CHANGE_ACTIVE_TAB'; 5 | 6 | // Application Window 7 | export const CHANGE_WINDOW = 'CHANGE_WINDOW'; 8 | 9 | // Request Window 10 | export const TOGGLE_MIDDLEWARE = 'TOGGLE_MIDDLEWARE'; 11 | export const STORE_RESPONSE = 'STORE_RESPONSE'; 12 | export const UPDATE_TAB_INFO = 'UPDATE_TAB_INFO'; 13 | 14 | // Testing 15 | export const ADD_TEST = 'ADD_TEST'; 16 | export const STORE_TEST_RESULT = 'STORE_TEST_RESULT'; 17 | -------------------------------------------------------------------------------- /app/src/Global/context/AppContext.jsx: -------------------------------------------------------------------------------- 1 | import React, { useReducer } from 'react'; 2 | import * as actions from '../actionTypes'; 3 | 4 | const initialState = { 5 | currentWindow: 'Dashboard', // Current window view i.e. Dashboard, Performance Metrics, etc. 6 | }; 7 | 8 | export const AppContext = React.createContext(); 9 | 10 | const AppReducer = (state = initialState, action) => { 11 | switch (action.type) { 12 | case actions.CHANGE_WINDOW: 13 | return { ...state, currentWindow: action.payload }; 14 | default: 15 | return state; 16 | } 17 | }; 18 | 19 | // Function that gets exposed when context is used inside of the application 20 | const AppProvider = ({ children }) => { 21 | // useReducer exposes the state and dispatch functions 22 | const [state, dispatch] = useReducer(AppReducer, initialState); 23 | return ( 24 | 25 | {children} 26 | 27 | ); 28 | }; 29 | 30 | export default AppProvider; 31 | -------------------------------------------------------------------------------- /app/src/__tests__/body.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { screen, render } from "@testing-library/react"; 3 | import Body from '../components/Nav/Body' 4 | 5 | test('expect body to render', () => { 6 | render(); 7 | const bodyInput = screen.getByRole('input') 8 | expect(bodyInput).toBeInTheDocument(); 9 | }); -------------------------------------------------------------------------------- /app/src/__tests__/button.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { screen, render } from "@testing-library/react"; 3 | import Button from '../components/Sidebar/Button' 4 | 5 | test('expect body to render', () => { 6 | render( 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/components/Nav/Method.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/destructuring-assignment */ 2 | import React from 'react'; 3 | import { makeStyles } from '@material-ui/core/styles'; 4 | import Select from '@material-ui/core/Select'; 5 | import FormControl from '@material-ui/core/FormControl'; 6 | import InputLabel from '@material-ui/core/InputLabel'; 7 | 8 | const useStyles = makeStyles((theme) => ({ 9 | formControl: { 10 | margin: theme.spacing(1), 11 | minWidth: 120, 12 | }, 13 | root: { 14 | background: '#383838', 15 | }, 16 | cssLabel: { 17 | color: '#aaaaaa', 18 | }, 19 | white: { 20 | color: '#000000', 21 | }, 22 | })); 23 | 24 | export default function Method(props) { 25 | const classes = useStyles(); 26 | 27 | const { setMethodType } = props.value; 28 | 29 | return ( 30 |
31 | 32 | Method 33 | 49 | 50 |
51 | ); 52 | } 53 | -------------------------------------------------------------------------------- /app/src/components/Nav/Signup.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Button from '@material-ui/core/Button'; 3 | 4 | const styles = { 5 | button: { 6 | color: '#aaaaaa', 7 | }, 8 | }; 9 | 10 | export default function Signup() { 11 | return ( 12 |
13 | 14 |
15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/components/Nav/Url.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/destructuring-assignment */ 2 | import React from 'react'; 3 | import Input from '@material-ui/core/Input'; 4 | import { makeStyles } from '@material-ui/core/styles'; 5 | 6 | const styles = { 7 | urlInput: { 8 | background: '#383838', 9 | color: '#ffffff', 10 | height: 55, 11 | width: 230, 12 | }, 13 | }; 14 | 15 | const useStyles = makeStyles(styles); 16 | 17 | export default function Url(props) { 18 | const { setUrl } = props.value; 19 | 20 | const classes = useStyles(); 21 | return ( 22 |
23 | setUrl(e.target.value)} id="outlined-basic" placeholder=" Request URL" variant="outlined" /> 24 |
25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /app/src/components/Performance/Performance.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import React, { useContext } from 'react'; 3 | import { 4 | Container, 5 | } from '@material-ui/core'; 6 | import { MainContainerContext } from '../../Global/context/MainContainerContext'; 7 | 8 | const styles = { 9 | mainContainer: { 10 | background: '#292c30', 11 | gridArea: 'windows', 12 | display: 'flex', 13 | flexDirection: 'row', 14 | justfyContent: 'center', 15 | alignItems: 'center', 16 | padding: '0 2rem 0 .5rem', 17 | margin: 0, 18 | maxWidth: '100%', 19 | border: '1px solid blue', 20 | }, 21 | infoContainer: { 22 | display: 'flex', 23 | width: '100%', 24 | flexDirection: 'column', 25 | padding: 0, 26 | margin: 0, 27 | }, 28 | }; 29 | 30 | const PerformanceContainer = () => { 31 | const { 32 | state: { 33 | allTabs, 34 | currentTabIdx, 35 | }, 36 | dispatch, 37 | } = useContext(MainContainerContext); 38 | 39 | const currentTab = allTabs[currentTabIdx]; 40 | 41 | const populated = !!allTabs[currentTabIdx].middleware?.length; 42 | 43 | return ( 44 | 45 | Performance 46 | 47 | ); 48 | }; 49 | 50 | export default PerformanceContainer; 51 | -------------------------------------------------------------------------------- /app/src/components/Response/Middleware/FunctionContainer.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/button-has-type */ 2 | import React from 'react'; 3 | import { 4 | Container, 5 | makeStyles, 6 | Paper, 7 | } from '@material-ui/core'; 8 | import CodeBlock from '../../common/CodeBlock'; 9 | 10 | const useStyles = makeStyles({ 11 | mainContainer: { 12 | width: '45%', 13 | padding: '0 20px', 14 | height: '100%', 15 | maxWidth: '100%', 16 | maxHeight: '100%', 17 | background: '#1e2125', 18 | boxSizing: 'border-box', 19 | display: 'flex', 20 | flexDirection: 'column', 21 | alignItems: 'start', 22 | }, 23 | title: { 24 | color: 'white', 25 | alignSelf: 'center', 26 | }, 27 | }); 28 | 29 | const FunctionContainer = ({ currentTab, populated }) => ( 30 | populated 31 | ? 32 | : 33 | ); 34 | 35 | const NullFunctionContainer = () => { 36 | const classes = useStyles(); 37 | return ( 38 | 39 | Code not avaialble 40 | 41 | ); 42 | }; 43 | 44 | const PopulatedFunctionContainer = ({ currentTab }) => { 45 | const classes = useStyles(); 46 | 47 | const { currentMiddlewareIdx, middleware } = currentTab; 48 | 49 | const activeMiddleware = middleware[currentMiddlewareIdx]; 50 | 51 | return ( 52 | 53 |

54 | Function 55 |

56 | 61 |
62 | ); 63 | }; 64 | 65 | export default FunctionContainer; 66 | -------------------------------------------------------------------------------- /app/src/components/Response/Middleware/MiddlewareContainer.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { Container } from '@material-ui/core'; 3 | import { MainContainerContext } from '../../../Global/context/MainContainerContext'; 4 | import MiddlewareChain from './MiddlewareChain'; 5 | import FunctionContainer from './FunctionContainer'; 6 | import ResponseObject from './ResponseObject'; 7 | 8 | const styles = { 9 | container: { 10 | display: 'flex', 11 | justfyContent: 'space-between', 12 | alignItems: 'center', 13 | gap: '0 1rem', 14 | margin: 0, 15 | padding: 0, 16 | height: '90%', 17 | borderRadius: 12, 18 | }, 19 | info: { 20 | width: '50%', 21 | height: '100%', 22 | display: 'flex', 23 | justifyContent: 'space-between', 24 | 25 | }, 26 | }; 27 | 28 | const MiddlewareFunc = ({ populated }) => { 29 | const { 30 | state: { 31 | allTabs, 32 | currentTabIdx, 33 | }, 34 | dispatch, 35 | } = useContext(MainContainerContext); 36 | 37 | const currentTab = allTabs[currentTabIdx]; 38 | 39 | const generateChain = () => { 40 | if (allTabs.length > 0) { 41 | return ( 42 | 48 | ); 49 | } 50 | return ( 51 | 54 | ); 55 | }; 56 | 57 | return ( 58 | 59 |
60 | { 61 | generateChain() 62 | } 63 | 64 |
65 | 66 |
67 | ); 68 | }; 69 | 70 | export default MiddlewareFunc; 71 | -------------------------------------------------------------------------------- /app/src/components/Response/ResponseContainer.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { Container } from '@material-ui/core'; 3 | import { MainContainerContext } from '../../Global/context/MainContainerContext'; 4 | import MiddlewareContainer from './Middleware/MiddlewareContainer'; 5 | // import ValuesContainer from './Values/ValuesContainer' 6 | 7 | const styles = { 8 | mainContainer: { 9 | background: '#292c30', 10 | gridArea: 'windows', 11 | display: 'flex', 12 | flexDirection: 'row', 13 | justfyContent: 'center', 14 | alignItems: 'center', 15 | padding: '0 2rem 0 .5rem', 16 | margin: 0, 17 | }, 18 | }; 19 | 20 | const ResponseContainer = () => { 21 | const { state: { allTabs, currentTabIdx } } = useContext(MainContainerContext); 22 | let populated; 23 | 24 | if (allTabs[currentTabIdx]) { 25 | populated = !!allTabs[currentTabIdx].middleware?.length; 26 | } else { 27 | populated = false; 28 | } 29 | 30 | return ( 31 | 32 | 33 | {/* */} 34 | 35 | ); 36 | }; 37 | 38 | export default ResponseContainer; 39 | -------------------------------------------------------------------------------- /app/src/components/Sidebar/Button.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { 3 | Box, 4 | } from '@material-ui/core'; 5 | import { MainContainerContext } from '../../Global/context/MainContainerContext'; 6 | import * as actions from '../../Global/actionTypes'; 7 | 8 | const makeStyles = (selected) => ({ 9 | box: { 10 | background: (selected ? '#3f4245' : '#292c30'), 11 | color: 'white', 12 | height: '60px', 13 | width: '100%', 14 | margin: '0 0 5px 0', 15 | display: 'flex', 16 | justifyContent: 'center', 17 | alignItems: 'center', 18 | fontSize: '.6rem', 19 | borderLeft: (selected ? '4px solid #50b26c' : 'none'), 20 | boxSizing: 'border-box', 21 | }, 22 | }); 23 | 24 | const Button = ({ text }) => { 25 | const { state: { sidebarSelection }, dispatch } = useContext(MainContainerContext); 26 | 27 | const changeWindow = () => { 28 | dispatch({ 29 | type: actions.CHANGE_WINDOW, 30 | payload: text, 31 | }); 32 | }; 33 | 34 | const styles = makeStyles(sidebarSelection === text); 35 | return ( 36 | 37 | {text} 38 | 39 | ); 40 | }; 41 | 42 | export default Button; 43 | -------------------------------------------------------------------------------- /app/src/components/Sidebar/Buttons.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Box, 4 | } from '@material-ui/core'; 5 | 6 | const makeStyles = (selected) => ({ 7 | box: { 8 | background: (selected ? '#3f4245' : '#292c30'), 9 | color: 'white', 10 | height: '60px', 11 | width: '100%', 12 | margin: '0 0 5px 0', 13 | display: 'flex', 14 | justifyContent: 'center', 15 | alignItems: 'center', 16 | fontSize: '.6rem', 17 | borderLeft: (selected ? '4px solid #50b26c' : 'none'), 18 | boxSizing: 'border-box', 19 | }, 20 | }); 21 | 22 | const Buttons = ({ text }) => { 23 | // const [state: { }, dispatch] = useContext(); 24 | const styles = makeStyles(true); 25 | return ( 26 | 27 | {text} 28 | 29 | ); 30 | }; 31 | 32 | export default Buttons; 33 | -------------------------------------------------------------------------------- /app/src/components/Sidebar/Help.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Box, 4 | } from '@material-ui/core'; 5 | import HelpOutlineOutlinedIcon from '@material-ui/icons/HelpOutlineOutlined'; 6 | 7 | const styles = { 8 | box: { 9 | background: '#292c30', 10 | color: 'white', 11 | height: '60px', 12 | width: '100%', 13 | margin: '0 0 5px 0', 14 | display: 'flex', 15 | justifyContent: 'center', 16 | alignItems: 'center', 17 | fontSize: '.6rem', 18 | boxSizing: 'border-box', 19 | }, 20 | 21 | }; 22 | 23 | const Help = () => ( 24 | 25 | 26 | 27 | ); 28 | 29 | export default Help; 30 | -------------------------------------------------------------------------------- /app/src/components/Sidebar/Settings.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Box, 4 | } from '@material-ui/core'; 5 | import TuneIcon from '@material-ui/icons/Tune'; 6 | 7 | const styles = { 8 | box: { 9 | background: '#292c30', 10 | color: 'white', 11 | height: '60px', 12 | width: '100%', 13 | margin: '0 0 5px 0', 14 | display: 'flex', 15 | justifyContent: 'center', 16 | alignItems: 'center', 17 | fontSize: '.6rem', 18 | boxSizing: 'border-box', 19 | }, 20 | 21 | }; 22 | 23 | const Settings = () => ( 24 | 25 | 26 | 27 | ); 28 | 29 | export default Settings; 30 | -------------------------------------------------------------------------------- /app/src/components/Sidebar/SidebarContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Container, 4 | } from '@material-ui/core'; 5 | import PropTypes from 'prop-types'; 6 | import Button from './Button'; 7 | import Help from './Help'; 8 | import Settings from './Settings'; 9 | 10 | const styles = { 11 | container: { 12 | minHeight: '500px', 13 | width: '100px', 14 | background: '#1e2125', 15 | display: 'flex', 16 | flexDirection: 'column', 17 | justifyContent: 'space-between', 18 | padding: '45px 0', 19 | margin: 0, 20 | gridArea: 'sidebar', 21 | }, 22 | }; 23 | 24 | const SidebarContainer = () => { 25 | const primaryButtons = ['Tree', 'Response', 'Testing']; 26 | return ( 27 | 28 |
29 | {primaryButtons.map((option) =>
31 |
32 | 33 | 34 |
35 | 36 |
37 | ); 38 | }; 39 | // PropTypes added to catch errors with typechecking 40 | Button.propTypes = { 41 | text: PropTypes.string.isRequired, 42 | }; 43 | Help.propTypes = { 44 | text: PropTypes.node, 45 | }; 46 | Settings.propTypes = { 47 | text: PropTypes.node, 48 | }; 49 | 50 | export default SidebarContainer; 51 | -------------------------------------------------------------------------------- /app/src/components/Tab/Tab.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { 3 | Container, 4 | } from '@material-ui/core'; 5 | import CloseIcon from '@material-ui/icons/Close'; 6 | import IconButton from '@material-ui/core/IconButton'; 7 | import PropTypes from 'prop-types'; 8 | import { MainContainerContext } from '../../Global/context/MainContainerContext'; 9 | import * as actions from '../../Global/actionTypes'; 10 | 11 | const makeStyles = (active) => ({ 12 | container: { 13 | background: '#1e2125', 14 | width: '250px', 15 | borderBottom: active ? '3px solid #8bd8bd' : 'none', 16 | borderRight: '1px solid gray', 17 | borderRadius: 0, 18 | color: '#aaaaaa', 19 | display: 'flex', 20 | justifyContent: 'space-around', 21 | alignItems: 'center', 22 | margin: 0, 23 | padding: 0, 24 | }, 25 | method: { 26 | color: 'darkgray', 27 | fontSize: '.8rem', 28 | paddingLeft: '5px', 29 | }, 30 | link: { 31 | width: '60%', 32 | overflowX: 'hidden', 33 | }, 34 | closeIcon: { 35 | background: '#1e2125', 36 | color: '#aaaaaa', 37 | }, 38 | }); 39 | 40 | const Tab = ({ tabData }) => { 41 | const { state: { currentTabIdx }, dispatch } = useContext(MainContainerContext); 42 | const active = tabData.tabOrder === currentTabIdx; 43 | const styles = makeStyles(active); 44 | 45 | const makeActiveTab = () => { 46 | dispatch({ 47 | type: actions.CHANGE_ACTIVE_TAB, 48 | payload: tabData.tabOrder, 49 | }); 50 | }; 51 | 52 | const closeTab = () => { 53 | dispatch({ 54 | type: actions.CLOSE_TAB, 55 | payload: currentTabIdx, 56 | }); 57 | }; 58 | 59 | return ( 60 | 61 | {tabData.method} 62 | {tabData.link} 63 | closeTab()} fontSize="small"> 64 | 65 | ); 66 | }; 67 | 68 | // PropTypes added to catch errors with typechecking 69 | Tab.propTypes = { 70 | // validates the tabData prop and corresponding values 71 | // if the tabData prop is not present or invalid data type, it will throw an error in the console 72 | tabData: PropTypes.shape({ 73 | method: PropTypes.string.isRequired, 74 | link: PropTypes.string.isRequired, 75 | tabOrder: PropTypes.number.isRequired, 76 | }).isRequired, 77 | }; 78 | 79 | export default Tab; 80 | -------------------------------------------------------------------------------- /app/src/components/Tab/TabContainer.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { Container } from '@material-ui/core'; 3 | import { v4 as uuidv4 } from 'uuid'; 4 | import AddIcon from '@material-ui/icons/Add'; 5 | import IconButton from '@material-ui/core/IconButton'; 6 | import { MainContainerContext } from '../../Global/context/MainContainerContext'; 7 | import Tab from './Tab'; 8 | import * as actions from '../../Global/actionTypes'; 9 | 10 | const styles = { 11 | container: { 12 | gridArea: 'tabs', 13 | display: 'flex', 14 | justifyContent: 'flex-start', 15 | padding: 0, 16 | margin: 0, 17 | background: '#1e2125', 18 | }, 19 | addTab: { 20 | width: '5%', 21 | display: 'flex', 22 | justifyContent: 'space-around', 23 | alignItems: 'center', 24 | color: 'white', 25 | border: '1px solid grey', 26 | borderRadius: 0, 27 | background: '#1e2125', 28 | margin: 0, 29 | padding: 0, 30 | }, 31 | button: { 32 | color: '#aaaaaa', 33 | }, 34 | }; 35 | 36 | const TabContainer = () => { 37 | const { state: { allTabs }, dispatch } = useContext(MainContainerContext); 38 | 39 | const addNewTab = () => { 40 | dispatch({ 41 | type: actions.NEW_TAB, 42 | payload: { 43 | link: 'New Tab', 44 | route: '', 45 | method: 'METHOD', 46 | active: true, 47 | body: '', 48 | currentMiddlewareIdx: 0, 49 | tabOrder: allTabs.length, 50 | middleware: [], 51 | }, 52 | }); 53 | }; 54 | 55 | return ( 56 | 57 | {allTabs.map((tab) => )} 58 | 59 | 60 | 61 | 62 | 63 | 64 | ); 65 | }; 66 | 67 | export default TabContainer; 68 | -------------------------------------------------------------------------------- /app/src/components/Testing/IndividualTestView.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Container, Paper } from '@material-ui/core'; 3 | 4 | const styles = { 5 | container: { 6 | display: 'flex', 7 | justifyContent: 'space-around', 8 | alignItems: 'center', 9 | }, 10 | paper: { 11 | background: '#292c30', 12 | height: '90%', 13 | width: '40%', 14 | color: 'white', 15 | }, 16 | }; 17 | 18 | const IndividualTestView = ({ testCase }) => ( 19 | 20 | 21 |

Expected

22 | {testCase.expectedResponse} 23 |
24 | 25 | 26 |

Received

27 | {testCase.receivedResponse} 28 |
29 |
30 | ); 31 | 32 | export default IndividualTestView; 33 | -------------------------------------------------------------------------------- /app/src/components/Testing/TestComponent.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Paper } from '@material-ui/core'; 3 | 4 | const styles = { 5 | containerFail: { 6 | backgroundColor: 'darkred', 7 | color: 'white', 8 | margin: '.5rem', 9 | padding: '.6rem', 10 | display: 'flex', 11 | flexDirection: 'column', 12 | }, 13 | containerPass: { 14 | backgroundColor: 'darkgreen', 15 | color: 'white', 16 | margin: '.5rem', 17 | padding: '.6rem', 18 | display: 'flex', 19 | flexDirection: 'column', 20 | }, 21 | containerOther: { 22 | backgroundColor: 'gray', 23 | color: 'white', 24 | margin: '.5rem', 25 | padding: '.6rem', 26 | display: 'flex', 27 | flexDirection: 'column', 28 | }, 29 | }; 30 | 31 | const TestComponent = ({ test, setCurrentTest }) => { 32 | const generateTestColor = () => { 33 | if (test?.status === 1) return styles.containerPass; 34 | if (test?.status === 0) return styles.containerFail; 35 | // eslint-disable-next-line no-prototype-builtins 36 | if (!test.hasOwnProperty('status')) return styles.containerOther; 37 | return styles.containerOther; 38 | }; 39 | 40 | const generateTesStatus = () => { 41 | if (test?.status === 1) return 'PASSED'; 42 | if (test?.status === 0) return 'FAILED'; 43 | // eslint-disable-next-line no-prototype-builtins 44 | if (!test.hasOwnProperty('status')) return 'NOT RUN'; 45 | return 'NOT RUN'; 46 | }; 47 | 48 | const style = generateTestColor(); 49 | const status = generateTesStatus(); 50 | return ( 51 | setCurrentTest(test)}> 52 | {test.url} 53 | {test.method} 54 | {status} 55 | 56 | ); 57 | }; 58 | 59 | export default TestComponent; 60 | -------------------------------------------------------------------------------- /app/src/components/Testing/TestContainer.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Container } from '@material-ui/core'; 3 | import IndividualTestView from './IndividualTestView'; 4 | import TestMenuBar from './TestMenuBar'; 5 | 6 | const styles = { 7 | container: { 8 | gridArea: 'windows', 9 | display: 'flex', 10 | justifyContent: 'flex-start', 11 | padding: 0, 12 | margin: 0, 13 | background: '#1e2125', 14 | }, 15 | addTab: { 16 | width: '5%', 17 | display: 'flex', 18 | justifyContent: 'space-around', 19 | alignItems: 'center', 20 | color: 'white', 21 | border: '1px solid grey', 22 | borderRadius: 0, 23 | background: '#1e2125', 24 | margin: 0, 25 | padding: 0, 26 | }, 27 | button: { 28 | color: '#aaaaaa', 29 | }, 30 | }; 31 | 32 | const TestContainer = () => { 33 | const [showModal, setShowModal] = useState(false); 34 | const [currentTest, setCurrentTest] = useState(null); 35 | const handleClose = () => setShowModal(false); 36 | const handleOpen = () => setShowModal(true); 37 | 38 | return ( 39 | 40 | 46 | 47 | {currentTest && ( 48 | 49 | )} 50 | 51 | 52 | ); 53 | }; 54 | 55 | export default TestContainer; 56 | -------------------------------------------------------------------------------- /app/src/components/Testing/TestControls.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import AddIcon from '@material-ui/icons/Add'; 3 | import { Container } from '@material-ui/core'; 4 | import RunTestsComponent from './RunTestsComponent'; 5 | 6 | const styles = { 7 | container: { 8 | display: 'flex', 9 | justifyContent: 'space-between', 10 | alignItems: 'center', 11 | color: 'white', 12 | fontSize: '30', 13 | }, 14 | playButton: { 15 | color: 'green', 16 | fontSize: '30', 17 | }, 18 | addButton: { 19 | color: 'red', 20 | fontSize: '30', 21 | }, 22 | }; 23 | 24 | const TestControls = ({ openModal, allTests }) => { 25 | let passing = 0; 26 | allTests.forEach((test) => { 27 | if (test?.status) passing += 1; 28 | }); 29 | 30 | return ( 31 | 32 | 33 |

34 | {passing} 35 | {' '} 36 | / 37 | {' '} 38 | {allTests.length} 39 | {' '} 40 | Passing 41 |

42 | openModal()} /> 43 |
44 | ); 45 | }; 46 | 47 | export default TestControls; 48 | -------------------------------------------------------------------------------- /app/src/components/Testing/TestMenuBar.jsx: -------------------------------------------------------------------------------- 1 | import { React, useContext } from 'react'; 2 | import { Container } from '@material-ui/core'; 3 | import { MainContainerContext } from '../../Global/context/MainContainerContext'; 4 | import TestControls from './TestControls'; 5 | import TestComponent from './TestComponent'; 6 | import AddTestModal from './AddTestModal'; 7 | 8 | const styles = { 9 | container: { 10 | gridArea: 'tabs', 11 | display: 'flex', 12 | flexDirection: 'column', 13 | justifyContent: 'flex-start', 14 | padding: 0, 15 | margin: 0, 16 | width: '20%', 17 | background: '#1e2125', 18 | }, 19 | addTab: { 20 | width: '5%', 21 | display: 'flex', 22 | justifyContent: 'space-around', 23 | alignItems: 'center', 24 | color: 'white', 25 | border: '1px solid grey', 26 | borderRadius: 0, 27 | background: '#1e2125', 28 | margin: 0, 29 | padding: 0, 30 | }, 31 | button: { 32 | color: '#aaaaaa', 33 | }, 34 | }; 35 | 36 | const TestMenuBar = ({ 37 | openModal, closeModal, showModal, setCurrentTest, 38 | }) => { 39 | const { state: { allTests } } = useContext(MainContainerContext); 40 | 41 | return ( 42 | 43 | 44 | {allTests.map((test) => )} 45 | {showModal ? : null} 46 | 47 | ); 48 | }; 49 | 50 | export default TestMenuBar; 51 | -------------------------------------------------------------------------------- /app/src/components/Tree/Graph/AppNode.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-param-reassign */ 2 | import React from 'react'; 3 | 4 | const AppNode = ({ forceUpdate, node }) => ( 5 | { 9 | node.data.isExpanded = !node.data.isExpanded; 10 | forceUpdate(); 11 | }} 12 | /> 13 | ); 14 | 15 | export default AppNode; 16 | -------------------------------------------------------------------------------- /app/src/components/Tree/Graph/MiddlewareNode.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable indent */ 2 | /* eslint-disable no-param-reassign */ 3 | /* eslint-disable react/jsx-indent */ 4 | import React from 'react'; 5 | 6 | const MiddlewareNode = ({ 7 | height, width, node, forceUpdate, 8 | }) => ( 9 | { 21 | node.data.isExpanded = !node.data.isExpanded; 22 | forceUpdate(); 23 | }} 24 | /> 25 | ); 26 | 27 | export default MiddlewareNode; 28 | -------------------------------------------------------------------------------- /app/src/components/Tree/Graph/NodeText.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-nested-ternary */ 2 | import React from 'react'; 3 | 4 | const NodeText = ({ node }) => ( 5 | 13 | {node.data.name} 14 | 15 | ); 16 | 17 | export default NodeText; 18 | -------------------------------------------------------------------------------- /app/src/components/Tree/Graph/RouteNode.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-param-reassign */ 2 | /* eslint-disable react/jsx-indent */ 3 | import React from 'react'; 4 | 5 | const RouteNode = ({ 6 | node, forceUpdate, width, height, 7 | }) => ( 8 | { 16 | node.data.isExpanded = !node.data.isExpanded; 17 | forceUpdate(); 18 | }} 19 | /> 20 | ); 21 | 22 | export default RouteNode; 23 | -------------------------------------------------------------------------------- /app/src/components/Tree/Graph/useForceUpdate.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | 3 | const useForceUpdate = () => { 4 | const [, setValue] = useState(0); 5 | return () => setValue((value) => value + 1); // update state to force render 6 | }; 7 | 8 | export default useForceUpdate; 9 | -------------------------------------------------------------------------------- /app/src/components/Tree/Tree.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Zoom } from '@visx/zoom'; 3 | import { LinearGradient } from '@visx/gradient'; 4 | import ParentSize from '@visx/responsive/lib/components/ParentSize'; 5 | import Graph from './Graph/Graph'; 6 | import TreeRect from './TreeRect'; 7 | 8 | const styles = { 9 | parent: { 10 | gridArea: 'windows', 11 | margin: 0, 12 | padding: 0, 13 | }, 14 | }; 15 | 16 | const Tree = () => ( 17 | 18 | {({ width, height }) => { 19 | const initialTransform = { 20 | scaleX: 1, 21 | scaleY: 1, 22 | translateX: -211.62, 23 | translateY: 162.59, 24 | skewX: 0, 25 | skewY: 0, 26 | }; 27 | 28 | return ( 29 | 38 | {(zoom) => ( 39 | 40 | )} 41 | 42 | 43 | ); 44 | }} 45 | 46 | ); 47 | 48 | const TreeStructure = ({ totalWidth, totalHeight, zoom }) => { 49 | const margin = { 50 | top: 30, left: 30, right: 30, bottom: 70, 51 | }; 52 | 53 | const innerWidth = totalWidth - margin.left - margin.right; 54 | const innerHeight = totalHeight - margin.top - margin.bottom; 55 | 56 | const origin = { 57 | x: 0, 58 | y: 0, 59 | }; 60 | 61 | const sizeWidth = innerHeight; 62 | const sizeHeight = innerWidth; 63 | 64 | return ( 65 |
66 | 67 | 68 | 69 | 76 | 77 |
78 | ); 79 | }; 80 | 81 | export default Tree; 82 | -------------------------------------------------------------------------------- /app/src/components/Tree/TreeRect.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const TreeRect = ({ width, height, zoom }) => ( 4 | { 16 | if (zoom.isDragging) zoom.dragEnd(); 17 | }} 18 | /> 19 | ); 20 | 21 | export default TreeRect; 22 | -------------------------------------------------------------------------------- /app/src/components/common/CodeBlock.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { 3 | Container, 4 | makeStyles, 5 | } from '@material-ui/core'; 6 | import SyntaxHighlighter from 'react-syntax-highlighter'; 7 | import { atelierCaveDark } from 'react-syntax-highlighter/dist/esm/styles/hljs'; 8 | 9 | const useStyles = makeStyles({ 10 | codeContainer: { 11 | display: 'flex', 12 | flexDirection: 'column', 13 | justifyContent: 'center', 14 | alignItems: 'center', 15 | minWidth: 300, 16 | minHeight: 300, 17 | maxWidth: '100%', 18 | maxHeight: '97%', 19 | }, 20 | button: { 21 | background: 'darkgrey', 22 | border: 'none', 23 | color: 'white', 24 | height: 20, 25 | width: 20, 26 | margin: '0 5px', 27 | outline: 'none', 28 | }, 29 | code: { 30 | alignContent: 'start', 31 | height: 'inherit', 32 | width: 'inherit', 33 | minHeight: 'inherit', 34 | maxHeight: 'inherit', 35 | minWidth: 'inherit', 36 | maxWidth: 'inherit', 37 | overflow: 'auto', 38 | resize: 'both', 39 | borderRadius: '8px', 40 | fontSize: (props) => props?.fontSize || 10, 41 | textAlign: 'left', 42 | '&::-webkit-scrollbar': { 43 | width: '10px', 44 | height: '10px', 45 | }, 46 | '&::-webkit-scrollbar-thumb': { 47 | backgroundColor: 'gray', 48 | borderRadius: '10px', 49 | }, 50 | '&::-webkit-resizer': { 51 | background: 'gray', 52 | }, 53 | }, 54 | }); 55 | 56 | const CodeBlock = ({ functionDefinition }) => { 57 | const [fontSize, setFontSize] = useState(10); 58 | const classes = useStyles({ fontSize }); 59 | return ( 60 | 61 | 62 | 69 | 76 | 77 | 85 | { 86 | functionDefinition 87 | } 88 | 89 | 90 | ); 91 | }; 92 | 93 | export default CodeBlock; 94 | -------------------------------------------------------------------------------- /app/src/img/dashboard1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/app/src/img/dashboard1.png -------------------------------------------------------------------------------- /app/src/img/dashboard3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/app/src/img/dashboard3.png -------------------------------------------------------------------------------- /app/src/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/app/src/img/logo.png -------------------------------------------------------------------------------- /app/src/img/require.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/app/src/img/require.png -------------------------------------------------------------------------------- /app/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /app/src/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import AppProvider from './Global/context/AppContext'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | 11 | 12 | , 13 | document.getElementById('root'), 14 | ); 15 | -------------------------------------------------------------------------------- /npm/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | 9 | [{*.js,*.json,*.yml}] 10 | indent_size = 2 11 | indent_style = space 12 | -------------------------------------------------------------------------------- /npm/.eslintignore: -------------------------------------------------------------------------------- 1 | coverage 2 | node_modules 3 | -------------------------------------------------------------------------------- /npm/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | root: true 2 | 3 | rules: 4 | eol-last: error 5 | eqeqeq: [error, allow-null] 6 | indent: [error, 2, { SwitchCase: 1 }] 7 | no-trailing-spaces: error 8 | no-unused-vars: [error, { vars: all, args: none, ignoreRestSiblings: true }] 9 | -------------------------------------------------------------------------------- /npm/.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store* 3 | Icon? 4 | ._* 5 | 6 | # Windows 7 | Thumbs.db 8 | ehthumbs.db 9 | Desktop.ini 10 | 11 | # Linux 12 | .directory 13 | *~ 14 | 15 | 16 | # npm 17 | node_modules 18 | package-lock.json 19 | *.log 20 | *.gz 21 | 22 | 23 | # Coveralls 24 | coverage 25 | 26 | # Benchmarking 27 | benchmarks/graphs 28 | 29 | 30 | *.lock 31 | *.md -------------------------------------------------------------------------------- /npm/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | - "0.12" 5 | - "1.8" 6 | - "2.5" 7 | - "3.3" 8 | - "4.9" 9 | - "5.12" 10 | - "6.17" 11 | - "7.10" 12 | - "8.17" 13 | - "9.11" 14 | - "10.23" 15 | - "11.15" 16 | - "12.18" 17 | matrix: 18 | include: 19 | - node_js: "13" 20 | env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" 21 | allow_failures: 22 | # Allow the nightly installs to fail 23 | - env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" 24 | cache: 25 | directories: 26 | - node_modules 27 | before_install: 28 | # Configure npm 29 | - | 30 | # Skip updating shrinkwrap / lock 31 | npm config set shrinkwrap false 32 | # Remove all non-test dependencies 33 | - | 34 | # Remove example dependencies 35 | npm rm --silent --save-dev connect-redis 36 | # Setup Node.js version-specific dependencies 37 | - | 38 | # mocha for testing 39 | # - use 3.x for Node.js < 4 40 | # - use 5.x for Node.js < 6 41 | # - use 6.x for Node.js < 8 42 | if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then 43 | npm install --silent --save-dev mocha@3.5.3 44 | elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then 45 | npm install --silent --save-dev mocha@5.2.0 46 | elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 8 ]]; then 47 | npm install --silent --save-dev mocha@6.2.2 48 | fi 49 | - | 50 | # supertest for http calls 51 | # - use 2.0.0 for Node.js < 4 52 | # - use 3.4.2 for Node.js < 6 53 | if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then 54 | npm install --silent --save-dev supertest@2.0.0 55 | elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then 56 | npm install --silent --save-dev supertest@3.4.2 57 | fi 58 | # Update Node.js modules 59 | - | 60 | # Prune and rebuild node_modules 61 | if [[ -d node_modules ]]; then 62 | npm prune 63 | npm rebuild 64 | fi 65 | script: 66 | # Run test script 67 | - npm run test-ci 68 | # Run linting 69 | - npm run lint 70 | after_script: 71 | - | 72 | # Upload coverage to coveralls 73 | npm install --save-dev coveralls@2.12.0 74 | coveralls < ./coverage/lcov.info 75 | -------------------------------------------------------------------------------- /npm/LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2009-2014 TJ Holowaychuk 4 | Copyright (c) 2013-2014 Roman Shtylman 5 | Copyright (c) 2014-2015 Douglas Christopher Wilson 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the 9 | 'Software'), to deal in the Software without restriction, including 10 | without limitation the rights to use, copy, modify, merge, publish, 11 | distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to 13 | the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /npm/appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - nodejs_version: "0.10" 4 | - nodejs_version: "0.12" 5 | - nodejs_version: "1.8" 6 | - nodejs_version: "2.5" 7 | - nodejs_version: "3.3" 8 | - nodejs_version: "4.9" 9 | - nodejs_version: "5.12" 10 | - nodejs_version: "6.17" 11 | - nodejs_version: "7.10" 12 | - nodejs_version: "8.16" 13 | - nodejs_version: "9.11" 14 | - nodejs_version: "10.23" 15 | - nodejs_version: "11.15" 16 | - nodejs_version: "12.18" 17 | cache: 18 | - node_modules 19 | install: 20 | # Install Node.js 21 | - ps: >- 22 | try { Install-Product node $env:nodejs_version -ErrorAction Stop } 23 | catch { Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) } 24 | # Configure npm 25 | - ps: | 26 | # Skip updating shrinkwrap / lock 27 | npm config set shrinkwrap false 28 | # Remove all non-test dependencies 29 | - ps: | 30 | # Remove example dependencies 31 | npm rm --silent --save-dev connect-redis 32 | # Setup Node.js version-specific dependencies 33 | - ps: | 34 | # mocha for testing 35 | # - use 3.x for Node.js < 4 36 | # - use 5.x for Node.js < 6 37 | # - use 6.x for Node.js < 8 38 | if ($env:nodejs_version.split(".")[0] -lt 4) { 39 | npm install --silent --save-dev mocha@3.5.3 40 | } elseif ($env:nodejs_version.split(".")[0] -lt 6) { 41 | npm install --silent --save-dev mocha@5.2.0 42 | } elseif ($env:nodejs_version.split(".")[0] -lt 8) { 43 | npm install --silent --save-dev mocha@6.2.2 44 | } 45 | - ps: | 46 | # supertest for http calls 47 | # - use 2.0.0 for Node.js < 4 48 | # - use 3.4.2 for Node.js < 6 49 | if ($env:nodejs_version.split(".")[0] -lt 4) { 50 | npm install --silent --save-dev supertest@2.0.0 51 | } elseif ($env:nodejs_version.split(".")[0] -lt 6) { 52 | npm install --silent --save-dev supertest@3.4.2 53 | } 54 | # Update Node.js modules 55 | - ps: | 56 | # Prune & rebuild node_modules 57 | if (Test-Path -Path node_modules) { 58 | npm prune 59 | npm rebuild 60 | } 61 | # Install Node.js modules 62 | - npm install 63 | build: off 64 | test_script: 65 | # Output version data 66 | - ps: | 67 | node --version 68 | npm --version 69 | # Run test script 70 | - npm run test-ci 71 | # Run linting 72 | - npm run lint 73 | version: "{build}" 74 | -------------------------------------------------------------------------------- /npm/benchmarks/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | @./run 1 middleware 4 | @./run 5 middleware 5 | @./run 10 middleware 6 | @./run 15 middleware 7 | @./run 20 middleware 8 | @./run 30 middleware 9 | @./run 50 middleware 10 | @./run 100 middleware 11 | @echo 12 | 13 | .PHONY: all 14 | -------------------------------------------------------------------------------- /npm/benchmarks/middleware.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('..'); 3 | var app = express(); 4 | 5 | // number of middleware 6 | 7 | var n = parseInt(process.env.MW || '1', 10); 8 | console.log(' %s middleware', n); 9 | 10 | while (n--) { 11 | app.use(function(req, res, next){ 12 | next(); 13 | }); 14 | } 15 | 16 | app.use(function(req, res, next){ 17 | res.send('Hello World') 18 | }); 19 | 20 | app.listen(3333); 21 | -------------------------------------------------------------------------------- /npm/benchmarks/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo 4 | MW=$1 node $2 & 5 | pid=$! 6 | 7 | sleep 2 8 | 9 | wrk 'http://localhost:3333/?foo[bar]=baz' \ 10 | -d 3 \ 11 | -c 50 \ 12 | -t 8 \ 13 | | grep 'Requests/sec' \ 14 | | awk '{ print " " $2 }' 15 | 16 | kill $pid 17 | -------------------------------------------------------------------------------- /npm/examples/auth/views/foot.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /npm/examples/auth/views/head.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%= title %> 7 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /npm/examples/auth/views/login.ejs: -------------------------------------------------------------------------------- 1 | 2 | <% var title = 'Authentication Example' %> 3 | <% include head %> 4 | 5 |

Login

6 | <%- message %> 7 | Try accessing /restricted, then authenticate with "tj" and "foobar". 8 |
9 |

10 | 11 | 12 |

13 |

14 | 15 | 16 |

17 |

18 | 19 |

20 |
21 | 22 | <% include foot %> 23 | -------------------------------------------------------------------------------- /npm/examples/content-negotiation/db.js: -------------------------------------------------------------------------------- 1 | var users = []; 2 | 3 | users.push({ name: 'Tobi' }); 4 | users.push({ name: 'Loki' }); 5 | users.push({ name: 'Jane' }); 6 | 7 | module.exports = users; 8 | -------------------------------------------------------------------------------- /npm/examples/content-negotiation/index.js: -------------------------------------------------------------------------------- 1 | var express = require('../../'); 2 | var app = module.exports = express(); 3 | var users = require('./db'); 4 | 5 | // so either you can deal with different types of formatting 6 | // for expected response in index.js 7 | app.get('/', function(req, res){ 8 | res.format({ 9 | html: function(){ 10 | res.send('
    ' + users.map(function(user){ 11 | return '
  • ' + user.name + '
  • '; 12 | }).join('') + '
'); 13 | }, 14 | 15 | text: function(){ 16 | res.send(users.map(function(user){ 17 | return ' - ' + user.name + '\n'; 18 | }).join('')); 19 | }, 20 | 21 | json: function(){ 22 | res.json(users); 23 | } 24 | }); 25 | }); 26 | 27 | // or you could write a tiny middleware like 28 | // this to add a layer of abstraction 29 | // and make things a bit more declarative: 30 | 31 | function format(path) { 32 | var obj = require(path); 33 | return function(req, res){ 34 | res.format(obj); 35 | }; 36 | } 37 | 38 | app.get('/users', format('./users')); 39 | 40 | /* istanbul ignore next */ 41 | if (!module.parent) { 42 | app.listen(3000); 43 | console.log('Express started on port 3000'); 44 | } 45 | -------------------------------------------------------------------------------- /npm/examples/content-negotiation/users.js: -------------------------------------------------------------------------------- 1 | 2 | var users = require('./db'); 3 | 4 | exports.html = function(req, res){ 5 | res.send('
    ' + users.map(function(user){ 6 | return '
  • ' + user.name + '
  • '; 7 | }).join('') + '
'); 8 | }; 9 | 10 | exports.text = function(req, res){ 11 | res.send(users.map(function(user){ 12 | return ' - ' + user.name + '\n'; 13 | }).join('')); 14 | }; 15 | 16 | exports.json = function(req, res){ 17 | res.json(users); 18 | }; 19 | -------------------------------------------------------------------------------- /npm/examples/cookie-sessions/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var cookieSession = require('cookie-session'); 6 | var express = require('../../'); 7 | 8 | var app = module.exports = express(); 9 | 10 | // add req.session cookie support 11 | app.use(cookieSession({ secret: 'manny is cool' })); 12 | 13 | // do something with the session 14 | app.use(count); 15 | 16 | // custom middleware 17 | function count(req, res) { 18 | req.session.count = (req.session.count || 0) + 1 19 | res.send('viewed ' + req.session.count + ' times\n') 20 | } 21 | 22 | /* istanbul ignore next */ 23 | if (!module.parent) { 24 | app.listen(3000); 25 | console.log('Express started on port 3000'); 26 | } 27 | -------------------------------------------------------------------------------- /npm/examples/cookies/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../../'); 6 | var app = module.exports = express(); 7 | var logger = require('morgan'); 8 | var cookieParser = require('cookie-parser'); 9 | 10 | // custom log format 11 | if (process.env.NODE_ENV !== 'test') app.use(logger(':method :url')) 12 | 13 | // parses request cookies, populating 14 | // req.cookies and req.signedCookies 15 | // when the secret is passed, used 16 | // for signing the cookies. 17 | app.use(cookieParser('my secret here')); 18 | 19 | // parses x-www-form-urlencoded 20 | app.use(express.urlencoded({ extended: false })) 21 | 22 | app.get('/', function(req, res){ 23 | if (req.cookies.remember) { 24 | res.send('Remembered :). Click to forget!.'); 25 | } else { 26 | res.send('

Check to ' 28 | + '.

'); 29 | } 30 | }); 31 | 32 | app.get('/forget', function(req, res){ 33 | res.clearCookie('remember'); 34 | res.redirect('back'); 35 | }); 36 | 37 | app.post('/', function(req, res){ 38 | var minute = 60000; 39 | if (req.body.remember) res.cookie('remember', 1, { maxAge: minute }); 40 | res.redirect('back'); 41 | }); 42 | 43 | /* istanbul ignore next */ 44 | if (!module.parent) { 45 | app.listen(3000); 46 | console.log('Express started on port 3000'); 47 | } 48 | -------------------------------------------------------------------------------- /npm/examples/downloads/files/CCTV大赛上海分赛区.txt: -------------------------------------------------------------------------------- 1 | Only for test. 2 | The file name is faked. -------------------------------------------------------------------------------- /npm/examples/downloads/files/amazing.txt: -------------------------------------------------------------------------------- 1 | what an amazing download -------------------------------------------------------------------------------- /npm/examples/downloads/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../../'); 6 | var path = require('path'); 7 | var app = module.exports = express(); 8 | 9 | app.get('/', function(req, res){ 10 | res.send(''); 15 | }); 16 | 17 | // /files/* is accessed via req.params[0] 18 | // but here we name it :file 19 | app.get('/files/:file(*)', function(req, res, next){ 20 | var filePath = path.join(__dirname, 'files', req.params.file); 21 | 22 | res.download(filePath, function (err) { 23 | if (!err) return; // file sent 24 | if (err.status !== 404) return next(err); // non-404 error 25 | // file for download not found 26 | res.statusCode = 404; 27 | res.send('Cant find that file, sorry!'); 28 | }); 29 | }); 30 | 31 | /* istanbul ignore next */ 32 | if (!module.parent) { 33 | app.listen(3000); 34 | console.log('Express started on port 3000'); 35 | } 36 | -------------------------------------------------------------------------------- /npm/examples/ejs/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../../'); 6 | var path = require('path'); 7 | 8 | var app = module.exports = express(); 9 | 10 | // Register ejs as .html. If we did 11 | // not call this, we would need to 12 | // name our views foo.ejs instead 13 | // of foo.html. The __express method 14 | // is simply a function that engines 15 | // use to hook into the Express view 16 | // system by default, so if we want 17 | // to change "foo.ejs" to "foo.html" 18 | // we simply pass _any_ function, in this 19 | // case `ejs.__express`. 20 | 21 | app.engine('.html', require('ejs').__express); 22 | 23 | // Optional since express defaults to CWD/views 24 | 25 | app.set('views', path.join(__dirname, 'views')); 26 | 27 | // Path to our public directory 28 | 29 | app.use(express.static(path.join(__dirname, 'public'))); 30 | 31 | // Without this you would need to 32 | // supply the extension to res.render() 33 | // ex: res.render('users.html'). 34 | app.set('view engine', 'html'); 35 | 36 | // Dummy users 37 | var users = [ 38 | { name: 'tobi', email: 'tobi@learnboost.com' }, 39 | { name: 'loki', email: 'loki@learnboost.com' }, 40 | { name: 'jane', email: 'jane@learnboost.com' } 41 | ]; 42 | 43 | app.get('/', function(req, res){ 44 | res.render('users', { 45 | users: users, 46 | title: "EJS example", 47 | header: "Some users" 48 | }); 49 | }); 50 | 51 | /* istanbul ignore next */ 52 | if (!module.parent) { 53 | app.listen(3000); 54 | console.log('Express started on port 3000'); 55 | } 56 | -------------------------------------------------------------------------------- /npm/examples/ejs/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px 80px; 3 | font: 14px "Helvetica Nueue", "Lucida Grande", Arial, sans-serif; 4 | } 5 | -------------------------------------------------------------------------------- /npm/examples/ejs/views/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /npm/examples/ejs/views/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%= title %> 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /npm/examples/ejs/views/users.html: -------------------------------------------------------------------------------- 1 | <% include header.html %> 2 | 3 |

Users

4 |
    5 | <% users.forEach(function(user){ %> 6 |
  • <%= user.name %> <<%= user.email %>>
  • 7 | <% }) %> 8 |
9 | 10 | <% include footer.html %> 11 | -------------------------------------------------------------------------------- /npm/examples/error-pages/views/404.ejs: -------------------------------------------------------------------------------- 1 | <% include error_header %> 2 |

Cannot find <%= url %>

3 | <% include footer %> 4 | -------------------------------------------------------------------------------- /npm/examples/error-pages/views/500.ejs: -------------------------------------------------------------------------------- 1 | <% include error_header %> 2 |

Error: <%= error.message %>

3 | <% if (settings['verbose errors']) { %> 4 |
<%= error.stack %>
5 | <% } else { %> 6 |

An error occurred!

7 | <% } %> 8 | <% include footer %> 9 | -------------------------------------------------------------------------------- /npm/examples/error-pages/views/error_header.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Error 7 | 8 | 9 | 10 |

An error occurred!

11 | -------------------------------------------------------------------------------- /npm/examples/error-pages/views/footer.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /npm/examples/error-pages/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Custom Pages Example 7 | 8 | 9 | 10 |

My Site

11 |

Pages Example

12 | 13 |
    14 |
  • visit 500
  • 15 |
  • visit 404
  • 16 |
  • visit 403
  • 17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /npm/examples/error/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../../'); 6 | var logger = require('morgan'); 7 | var app = module.exports = express(); 8 | var test = app.get('env') === 'test' 9 | 10 | if (!test) app.use(logger('dev')); 11 | 12 | // error handling middleware have an arity of 4 13 | // instead of the typical (req, res, next), 14 | // otherwise they behave exactly like regular 15 | // middleware, you may have several of them, 16 | // in different orders etc. 17 | 18 | function error(err, req, res, next) { 19 | // log it 20 | if (!test) console.error(err.stack); 21 | 22 | // respond with 500 "Internal Server Error". 23 | res.status(500); 24 | res.send('Internal Server Error'); 25 | } 26 | 27 | app.get('/', function(req, res){ 28 | // Caught and passed down to the errorHandler middleware 29 | throw new Error('something broke!'); 30 | }); 31 | 32 | app.get('/next', function(req, res, next){ 33 | // We can also pass exceptions to next() 34 | // The reason for process.nextTick() is to show that 35 | // next() can be called inside an async operation, 36 | // in real life it can be a DB read or HTTP request. 37 | process.nextTick(function(){ 38 | next(new Error('oh no!')); 39 | }); 40 | }); 41 | 42 | // the error handler is placed after routes 43 | // if it were above it would not receive errors 44 | // from app.get() etc 45 | app.use(error); 46 | 47 | /* istanbul ignore next */ 48 | if (!module.parent) { 49 | app.listen(3000); 50 | console.log('Express started on port 3000'); 51 | } 52 | -------------------------------------------------------------------------------- /npm/examples/hello-world/index.js: -------------------------------------------------------------------------------- 1 | var express = require('../../'); 2 | 3 | var app = express(); 4 | 5 | app.get('/', function(req, res){ 6 | res.send('Hello World'); 7 | }); 8 | 9 | /* istanbul ignore next */ 10 | if (!module.parent) { 11 | app.listen(3000); 12 | console.log('Express started on port 3000'); 13 | } 14 | -------------------------------------------------------------------------------- /npm/examples/markdown/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var escapeHtml = require('escape-html'); 6 | var express = require('../..'); 7 | var fs = require('fs'); 8 | var marked = require('marked'); 9 | var path = require('path'); 10 | 11 | var app = module.exports = express(); 12 | 13 | // register .md as an engine in express view system 14 | 15 | app.engine('md', function(path, options, fn){ 16 | fs.readFile(path, 'utf8', function(err, str){ 17 | if (err) return fn(err); 18 | var html = marked.parse(str).replace(/\{([^}]+)\}/g, function(_, name){ 19 | return escapeHtml(options[name] || ''); 20 | }); 21 | fn(null, html); 22 | }); 23 | }); 24 | 25 | app.set('views', path.join(__dirname, 'views')); 26 | 27 | // make it the default so we dont need .md 28 | app.set('view engine', 'md'); 29 | 30 | app.get('/', function(req, res){ 31 | res.render('index', { title: 'Markdown Example' }); 32 | }); 33 | 34 | app.get('/fail', function(req, res){ 35 | res.render('missing', { title: 'Markdown Example' }); 36 | }); 37 | 38 | /* istanbul ignore next */ 39 | if (!module.parent) { 40 | app.listen(3000); 41 | console.log('Express started on port 3000'); 42 | } 43 | -------------------------------------------------------------------------------- /npm/examples/multi-router/controllers/api_v1.js: -------------------------------------------------------------------------------- 1 | var express = require('../../..'); 2 | 3 | var apiv1 = express.Router(); 4 | 5 | apiv1.get('/', function(req, res) { 6 | res.send('Hello from APIv1 root route.'); 7 | }); 8 | 9 | apiv1.get('/users', function(req, res) { 10 | res.send('List of APIv1 users.'); 11 | }); 12 | 13 | module.exports = apiv1; 14 | -------------------------------------------------------------------------------- /npm/examples/multi-router/controllers/api_v2.js: -------------------------------------------------------------------------------- 1 | var express = require('../../..'); 2 | 3 | var apiv2 = express.Router(); 4 | 5 | apiv2.get('/', function(req, res) { 6 | res.send('Hello from APIv2 root route.'); 7 | }); 8 | 9 | apiv2.get('/users', function(req, res) { 10 | res.send('List of APIv2 users.'); 11 | }); 12 | 13 | module.exports = apiv2; 14 | -------------------------------------------------------------------------------- /npm/examples/multi-router/index.js: -------------------------------------------------------------------------------- 1 | var express = require('../..'); 2 | 3 | var app = module.exports = express(); 4 | 5 | app.use('/api/v1', require('./controllers/api_v1')); 6 | app.use('/api/v2', require('./controllers/api_v2')); 7 | 8 | app.get('/', function(req, res) { 9 | res.send('Hello from root route.') 10 | }); 11 | 12 | /* istanbul ignore next */ 13 | if (!module.parent) { 14 | app.listen(3000); 15 | console.log('Express started on port 3000'); 16 | } 17 | -------------------------------------------------------------------------------- /npm/examples/multipart/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../..'); 6 | var multiparty = require('multiparty'); 7 | var format = require('util').format; 8 | 9 | var app = module.exports = express(); 10 | 11 | app.get('/', function(req, res){ 12 | res.send('
' 13 | + '

Title:

' 14 | + '

Image:

' 15 | + '

' 16 | + '
'); 17 | }); 18 | 19 | app.post('/', function(req, res, next){ 20 | // create a form to begin parsing 21 | var form = new multiparty.Form(); 22 | var image; 23 | var title; 24 | 25 | form.on('error', next); 26 | form.on('close', function(){ 27 | res.send(format('\nuploaded %s (%d Kb) as %s' 28 | , image.filename 29 | , image.size / 1024 | 0 30 | , title)); 31 | }); 32 | 33 | // listen on field event for title 34 | form.on('field', function(name, val){ 35 | if (name !== 'title') return; 36 | title = val; 37 | }); 38 | 39 | // listen on part event for image file 40 | form.on('part', function(part){ 41 | if (!part.filename) return; 42 | if (part.name !== 'image') return part.resume(); 43 | image = {}; 44 | image.filename = part.filename; 45 | image.size = 0; 46 | part.on('data', function(buf){ 47 | image.size += buf.length; 48 | }); 49 | }); 50 | 51 | 52 | // parse the form 53 | form.parse(req); 54 | }); 55 | 56 | /* istanbul ignore next */ 57 | if (!module.parent) { 58 | app.listen(4000); 59 | console.log('Express started on port 4000'); 60 | } 61 | -------------------------------------------------------------------------------- /npm/examples/mvc/controllers/main/index.js: -------------------------------------------------------------------------------- 1 | exports.index = function(req, res){ 2 | res.redirect('/users'); 3 | }; 4 | -------------------------------------------------------------------------------- /npm/examples/mvc/controllers/pet/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var db = require('../../db'); 6 | 7 | exports.engine = 'ejs'; 8 | 9 | exports.before = function(req, res, next){ 10 | var pet = db.pets[req.params.pet_id]; 11 | if (!pet) return next('route'); 12 | req.pet = pet; 13 | next(); 14 | }; 15 | 16 | exports.show = function(req, res, next){ 17 | res.render('show', { pet: req.pet }); 18 | }; 19 | 20 | exports.edit = function(req, res, next){ 21 | res.render('edit', { pet: req.pet }); 22 | }; 23 | 24 | exports.update = function(req, res, next){ 25 | var body = req.body; 26 | req.pet.name = body.pet.name; 27 | res.message('Information updated!'); 28 | res.redirect('/pet/' + req.pet.id); 29 | }; 30 | -------------------------------------------------------------------------------- /npm/examples/mvc/controllers/pet/views/edit.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Edit <%= pet.name %> 8 | 9 | 10 | 11 |

<%= pet.name %>

12 |
13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /npm/examples/mvc/controllers/pet/views/show.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= pet.name %> 8 | 9 | 10 | 11 |

<%= pet.name %> edit

12 | 13 |

You are viewing <%= pet.name %>

14 | 15 | 16 | -------------------------------------------------------------------------------- /npm/examples/mvc/controllers/user-pet/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var db = require('../../db'); 6 | 7 | exports.name = 'pet'; 8 | exports.prefix = '/user/:user_id'; 9 | 10 | exports.create = function(req, res, next){ 11 | var id = req.params.user_id; 12 | var user = db.users[id]; 13 | var body = req.body; 14 | if (!user) return next('route'); 15 | var pet = { name: body.pet.name }; 16 | pet.id = db.pets.push(pet) - 1; 17 | user.pets.push(pet); 18 | res.message('Added pet ' + body.pet.name); 19 | res.redirect('/user/' + id); 20 | }; 21 | -------------------------------------------------------------------------------- /npm/examples/mvc/controllers/user/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var db = require('../../db'); 6 | 7 | exports.engine = 'hbs'; 8 | 9 | exports.before = function(req, res, next){ 10 | var id = req.params.user_id; 11 | if (!id) return next(); 12 | // pretend to query a database... 13 | process.nextTick(function(){ 14 | req.user = db.users[id]; 15 | // cant find that user 16 | if (!req.user) return next('route'); 17 | // found it, move on to the routes 18 | next(); 19 | }); 20 | }; 21 | 22 | exports.list = function(req, res, next){ 23 | res.render('list', { users: db.users }); 24 | }; 25 | 26 | exports.edit = function(req, res, next){ 27 | res.render('edit', { user: req.user }); 28 | }; 29 | 30 | exports.show = function(req, res, next){ 31 | res.render('show', { user: req.user }); 32 | }; 33 | 34 | exports.update = function(req, res, next){ 35 | var body = req.body; 36 | req.user.name = body.user.name; 37 | res.message('Information updated!'); 38 | res.redirect('/user/' + req.user.id); 39 | }; 40 | -------------------------------------------------------------------------------- /npm/examples/mvc/controllers/user/views/edit.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Edit {{user.name}} 8 | 9 | 10 |

{{user.name}}

11 |
12 | 15 | 16 | 17 |
18 | 19 |
20 | 23 | 24 | 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /npm/examples/mvc/controllers/user/views/list.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Users 8 | 9 | 10 |

Users

11 |

Click a user below to view their pets.

12 |
    13 | {{#each users}} 14 |
  • {{name}}
  • 15 | {{/each}} 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /npm/examples/mvc/controllers/user/views/show.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{user.name}} 8 | 9 | 10 |

{{user.name}} edit

11 | 12 | {{#if hasMessages}} 13 |
    14 | {{#each messages}} 15 |
  • {{this}}
  • 16 | {{/each}} 17 |
18 | {{/if}} 19 | 20 | {{#if user.pets.length}} 21 |

View {{user.name}}'s pets:

22 |
    23 | {{#each user.pets}} 24 |
  • {{name}}
  • 25 | {{/each}} 26 |
27 | {{else}} 28 |

No pets!

29 | {{/if}} 30 | 31 | 32 | -------------------------------------------------------------------------------- /npm/examples/mvc/db.js: -------------------------------------------------------------------------------- 1 | // faux database 2 | 3 | var pets = exports.pets = []; 4 | 5 | pets.push({ name: 'Tobi', id: 0 }); 6 | pets.push({ name: 'Loki', id: 1 }); 7 | pets.push({ name: 'Jane', id: 2 }); 8 | pets.push({ name: 'Raul', id: 3 }); 9 | 10 | var users = exports.users = []; 11 | 12 | users.push({ name: 'TJ', pets: [pets[0], pets[1], pets[2]], id: 0 }); 13 | users.push({ name: 'Guillermo', pets: [pets[3]], id: 1 }); 14 | users.push({ name: 'Nathan', pets: [], id: 2 }); 15 | -------------------------------------------------------------------------------- /npm/examples/mvc/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../..'); 6 | var logger = require('morgan'); 7 | var path = require('path'); 8 | var session = require('express-session'); 9 | var methodOverride = require('method-override'); 10 | 11 | var app = module.exports = express(); 12 | 13 | // set our default template engine to "ejs" 14 | // which prevents the need for using file extensions 15 | app.set('view engine', 'ejs'); 16 | 17 | // set views for error and 404 pages 18 | app.set('views', path.join(__dirname, 'views')); 19 | 20 | // define a custom res.message() method 21 | // which stores messages in the session 22 | app.response.message = function(msg){ 23 | // reference `req.session` via the `this.req` reference 24 | var sess = this.req.session; 25 | // simply add the msg to an array for later 26 | sess.messages = sess.messages || []; 27 | sess.messages.push(msg); 28 | return this; 29 | }; 30 | 31 | // log 32 | if (!module.parent) app.use(logger('dev')); 33 | 34 | // serve static files 35 | app.use(express.static(path.join(__dirname, 'public'))); 36 | 37 | // session support 38 | app.use(session({ 39 | resave: false, // don't save session if unmodified 40 | saveUninitialized: false, // don't create session until something stored 41 | secret: 'some secret here' 42 | })); 43 | 44 | // parse request bodies (req.body) 45 | app.use(express.urlencoded({ extended: true })) 46 | 47 | // allow overriding methods in query (?_method=put) 48 | app.use(methodOverride('_method')); 49 | 50 | // expose the "messages" local variable when views are rendered 51 | app.use(function(req, res, next){ 52 | var msgs = req.session.messages || []; 53 | 54 | // expose "messages" local variable 55 | res.locals.messages = msgs; 56 | 57 | // expose "hasMessages" 58 | res.locals.hasMessages = !! msgs.length; 59 | 60 | /* This is equivalent: 61 | res.locals({ 62 | messages: msgs, 63 | hasMessages: !! msgs.length 64 | }); 65 | */ 66 | 67 | next(); 68 | // empty or "flush" the messages so they 69 | // don't build up 70 | req.session.messages = []; 71 | }); 72 | 73 | // load controllers 74 | require('./lib/boot')(app, { verbose: !module.parent }); 75 | 76 | app.use(function(err, req, res, next){ 77 | // log it 78 | if (!module.parent) console.error(err.stack); 79 | 80 | // error page 81 | res.status(500).render('5xx'); 82 | }); 83 | 84 | // assume 404 since no middleware responded 85 | app.use(function(req, res, next){ 86 | res.status(404).render('404', { url: req.originalUrl }); 87 | }); 88 | 89 | /* istanbul ignore next */ 90 | if (!module.parent) { 91 | app.listen(3000); 92 | console.log('Express started on port 3000'); 93 | } 94 | -------------------------------------------------------------------------------- /npm/examples/mvc/lib/boot.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../../..'); 6 | var fs = require('fs'); 7 | var path = require('path'); 8 | 9 | module.exports = function(parent, options){ 10 | var dir = path.join(__dirname, '..', 'controllers'); 11 | var verbose = options.verbose; 12 | fs.readdirSync(dir).forEach(function(name){ 13 | var file = path.join(dir, name) 14 | if (!fs.statSync(file).isDirectory()) return; 15 | verbose && console.log('\n %s:', name); 16 | var obj = require(file); 17 | var name = obj.name || name; 18 | var prefix = obj.prefix || ''; 19 | var app = express(); 20 | var handler; 21 | var method; 22 | var url; 23 | 24 | // allow specifying the view engine 25 | if (obj.engine) app.set('view engine', obj.engine); 26 | app.set('views', path.join(__dirname, '..', 'controllers', name, 'views')); 27 | 28 | // generate routes based 29 | // on the exported methods 30 | for (var key in obj) { 31 | // "reserved" exports 32 | if (~['name', 'prefix', 'engine', 'before'].indexOf(key)) continue; 33 | // route exports 34 | switch (key) { 35 | case 'show': 36 | method = 'get'; 37 | url = '/' + name + '/:' + name + '_id'; 38 | break; 39 | case 'list': 40 | method = 'get'; 41 | url = '/' + name + 's'; 42 | break; 43 | case 'edit': 44 | method = 'get'; 45 | url = '/' + name + '/:' + name + '_id/edit'; 46 | break; 47 | case 'update': 48 | method = 'put'; 49 | url = '/' + name + '/:' + name + '_id'; 50 | break; 51 | case 'create': 52 | method = 'post'; 53 | url = '/' + name; 54 | break; 55 | case 'index': 56 | method = 'get'; 57 | url = '/'; 58 | break; 59 | default: 60 | /* istanbul ignore next */ 61 | throw new Error('unrecognized route: ' + name + '.' + key); 62 | } 63 | 64 | // setup 65 | handler = obj[key]; 66 | url = prefix + url; 67 | 68 | // before middleware support 69 | if (obj.before) { 70 | app[method](url, obj.before, handler); 71 | verbose && console.log(' %s %s -> before -> %s', method.toUpperCase(), url, key); 72 | } else { 73 | app[method](url, handler); 74 | verbose && console.log(' %s %s -> %s', method.toUpperCase(), url, key); 75 | } 76 | } 77 | 78 | // mount the app 79 | parent.use(app); 80 | }); 81 | }; 82 | -------------------------------------------------------------------------------- /npm/examples/mvc/public/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 16px "Helvetica Neue", Helvetica, Arial, sans-serif; 4 | } 5 | a { 6 | color: #107aff; 7 | text-decoration: none; 8 | } 9 | a:hover { 10 | text-decoration: underline; 11 | } 12 | h1 a { 13 | font-size: 16px; 14 | } 15 | -------------------------------------------------------------------------------- /npm/examples/mvc/views/404.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Not Found 7 | 8 | 9 | 10 |

404: Not Found

11 |

Sorry we can't find <%= url %>

12 | 13 | 14 | -------------------------------------------------------------------------------- /npm/examples/mvc/views/5xx.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Internal Server Error 7 | 8 | 9 | 10 |

500: Internal Server Error

11 |

Looks like something blew up!

12 | 13 | 14 | -------------------------------------------------------------------------------- /npm/examples/online/index.js: -------------------------------------------------------------------------------- 1 | 2 | // install redis first: 3 | // https://redis.io/ 4 | 5 | // then: 6 | // $ npm install redis online 7 | // $ redis-server 8 | 9 | /** 10 | * Module dependencies. 11 | */ 12 | 13 | var express = require('../..'); 14 | var online = require('online'); 15 | var redis = require('redis'); 16 | var db = redis.createClient(); 17 | 18 | // online 19 | 20 | online = online(db); 21 | 22 | // app 23 | 24 | var app = express(); 25 | 26 | // activity tracking, in this case using 27 | // the UA string, you would use req.user.id etc 28 | 29 | app.use(function(req, res, next){ 30 | // fire-and-forget 31 | online.add(req.headers['user-agent']); 32 | next(); 33 | }); 34 | 35 | /** 36 | * List helper. 37 | */ 38 | 39 | function list(ids) { 40 | return '
    ' + ids.map(function(id){ 41 | return '
  • ' + id + '
  • '; 42 | }).join('') + '
'; 43 | } 44 | 45 | /** 46 | * GET users online. 47 | */ 48 | 49 | app.get('/', function(req, res, next){ 50 | online.last(5, function(err, ids){ 51 | if (err) return next(err); 52 | res.send('

Users online: ' + ids.length + '

' + list(ids)); 53 | }); 54 | }); 55 | 56 | /* istanbul ignore next */ 57 | if (!module.parent) { 58 | app.listen(3000); 59 | console.log('Express started on port 3000'); 60 | } 61 | -------------------------------------------------------------------------------- /npm/examples/params/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../../'); 6 | var app = module.exports = express(); 7 | 8 | // Faux database 9 | 10 | var users = [ 11 | { name: 'tj' } 12 | , { name: 'tobi' } 13 | , { name: 'loki' } 14 | , { name: 'jane' } 15 | , { name: 'bandit' } 16 | ]; 17 | 18 | // Create HTTP error 19 | 20 | function createError(status, message) { 21 | var err = new Error(message); 22 | err.status = status; 23 | return err; 24 | } 25 | 26 | // Convert :to and :from to integers 27 | 28 | app.param(['to', 'from'], function(req, res, next, num, name){ 29 | req.params[name] = parseInt(num, 10); 30 | if( isNaN(req.params[name]) ){ 31 | next(createError(400, 'failed to parseInt '+num)); 32 | } else { 33 | next(); 34 | } 35 | }); 36 | 37 | // Load user by id 38 | 39 | app.param('user', function(req, res, next, id){ 40 | if (req.user = users[id]) { 41 | next(); 42 | } else { 43 | next(createError(404, 'failed to find user')); 44 | } 45 | }); 46 | 47 | /** 48 | * GET index. 49 | */ 50 | 51 | app.get('/', function(req, res){ 52 | res.send('Visit /user/0 or /users/0-2'); 53 | }); 54 | 55 | /** 56 | * GET :user. 57 | */ 58 | 59 | app.get('/user/:user', function(req, res, next){ 60 | res.send('user ' + req.user.name); 61 | }); 62 | 63 | /** 64 | * GET users :from - :to. 65 | */ 66 | 67 | app.get('/users/:from-:to', function(req, res, next){ 68 | var from = req.params.from; 69 | var to = req.params.to; 70 | var names = users.map(function(user){ return user.name; }); 71 | res.send('users ' + names.slice(from, to + 1).join(', ')); 72 | }); 73 | 74 | /* istanbul ignore next */ 75 | if (!module.parent) { 76 | app.listen(3000); 77 | console.log('Express started on port 3000'); 78 | } 79 | -------------------------------------------------------------------------------- /npm/examples/resource/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../../'); 6 | 7 | var app = module.exports = express(); 8 | 9 | // Ad-hoc example resource method 10 | 11 | app.resource = function(path, obj) { 12 | this.get(path, obj.index); 13 | this.get(path + '/:a..:b.:format?', function(req, res){ 14 | var a = parseInt(req.params.a, 10); 15 | var b = parseInt(req.params.b, 10); 16 | var format = req.params.format; 17 | obj.range(req, res, a, b, format); 18 | }); 19 | this.get(path + '/:id', obj.show); 20 | this.delete(path + '/:id', function(req, res){ 21 | var id = parseInt(req.params.id, 10); 22 | obj.destroy(req, res, id); 23 | }); 24 | }; 25 | 26 | // Fake records 27 | 28 | var users = [ 29 | { name: 'tj' } 30 | , { name: 'ciaran' } 31 | , { name: 'aaron' } 32 | , { name: 'guillermo' } 33 | , { name: 'simon' } 34 | , { name: 'tobi' } 35 | ]; 36 | 37 | // Fake controller. 38 | 39 | var User = { 40 | index: function(req, res){ 41 | res.send(users); 42 | }, 43 | show: function(req, res){ 44 | res.send(users[req.params.id] || { error: 'Cannot find user' }); 45 | }, 46 | destroy: function(req, res, id){ 47 | var destroyed = id in users; 48 | delete users[id]; 49 | res.send(destroyed ? 'destroyed' : 'Cannot find user'); 50 | }, 51 | range: function(req, res, a, b, format){ 52 | var range = users.slice(a, b + 1); 53 | switch (format) { 54 | case 'json': 55 | res.send(range); 56 | break; 57 | case 'html': 58 | default: 59 | var html = '
    ' + range.map(function(user){ 60 | return '
  • ' + user.name + '
  • '; 61 | }).join('\n') + '
'; 62 | res.send(html); 63 | break; 64 | } 65 | } 66 | }; 67 | 68 | // curl http://localhost:3000/users -- responds with all users 69 | // curl http://localhost:3000/users/1 -- responds with user 1 70 | // curl http://localhost:3000/users/4 -- responds with error 71 | // curl http://localhost:3000/users/1..3 -- responds with several users 72 | // curl -X DELETE http://localhost:3000/users/1 -- deletes the user 73 | 74 | app.resource('/users', User); 75 | 76 | app.get('/', function(req, res){ 77 | res.send([ 78 | '

Examples:

    ' 79 | , '
  • GET /users
  • ' 80 | , '
  • GET /users/1
  • ' 81 | , '
  • GET /users/3
  • ' 82 | , '
  • GET /users/1..3
  • ' 83 | , '
  • GET /users/1..3.json
  • ' 84 | , '
  • DELETE /users/4
  • ' 85 | , '
' 86 | ].join('\n')); 87 | }); 88 | 89 | /* istanbul ignore next */ 90 | if (!module.parent) { 91 | app.listen(3000); 92 | console.log('Express started on port 3000'); 93 | } 94 | -------------------------------------------------------------------------------- /npm/examples/route-map/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var escapeHtml = require('escape-html') 6 | var express = require('../../lib/express'); 7 | 8 | var verbose = process.env.NODE_ENV !== 'test' 9 | 10 | var app = module.exports = express(); 11 | 12 | app.map = function(a, route){ 13 | route = route || ''; 14 | for (var key in a) { 15 | switch (typeof a[key]) { 16 | // { '/path': { ... }} 17 | case 'object': 18 | app.map(a[key], route + key); 19 | break; 20 | // get: function(){ ... } 21 | case 'function': 22 | if (verbose) console.log('%s %s', key, route); 23 | app[key](route, a[key]); 24 | break; 25 | } 26 | } 27 | }; 28 | 29 | var users = { 30 | list: function(req, res){ 31 | res.send('user list'); 32 | }, 33 | 34 | get: function(req, res){ 35 | res.send('user ' + escapeHtml(req.params.uid)) 36 | }, 37 | 38 | delete: function(req, res){ 39 | res.send('delete users'); 40 | } 41 | }; 42 | 43 | var pets = { 44 | list: function(req, res){ 45 | res.send('user ' + escapeHtml(req.params.uid) + '\'s pets') 46 | }, 47 | 48 | delete: function(req, res){ 49 | res.send('delete ' + escapeHtml(req.params.uid) + '\'s pet ' + escapeHtml(req.params.pid)) 50 | } 51 | }; 52 | 53 | app.map({ 54 | '/users': { 55 | get: users.list, 56 | delete: users.delete, 57 | '/:uid': { 58 | get: users.get, 59 | '/pets': { 60 | get: pets.list, 61 | '/:pid': { 62 | delete: pets.delete 63 | } 64 | } 65 | } 66 | } 67 | }); 68 | 69 | /* istanbul ignore next */ 70 | if (!module.parent) { 71 | app.listen(3000); 72 | console.log('Express started on port 3000'); 73 | } 74 | -------------------------------------------------------------------------------- /npm/examples/route-separation/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../..'); 6 | var path = require('path'); 7 | var app = express(); 8 | var logger = require('morgan'); 9 | var cookieParser = require('cookie-parser'); 10 | var methodOverride = require('method-override'); 11 | var site = require('./site'); 12 | var post = require('./post'); 13 | var user = require('./user'); 14 | 15 | module.exports = app; 16 | 17 | // Config 18 | 19 | app.set('view engine', 'ejs'); 20 | app.set('views', path.join(__dirname, 'views')); 21 | 22 | /* istanbul ignore next */ 23 | if (!module.parent) { 24 | app.use(logger('dev')); 25 | } 26 | 27 | app.use(methodOverride('_method')); 28 | app.use(cookieParser()); 29 | app.use(express.urlencoded({ extended: true })) 30 | app.use(express.static(path.join(__dirname, 'public'))); 31 | 32 | // General 33 | 34 | app.get('/', site.index); 35 | 36 | // User 37 | 38 | app.get('/users', user.list); 39 | app.all('/user/:id/:op?', user.load); 40 | app.get('/user/:id', user.view); 41 | app.get('/user/:id/view', user.view); 42 | app.get('/user/:id/edit', user.edit); 43 | app.put('/user/:id/edit', user.update); 44 | 45 | // Posts 46 | 47 | app.get('/posts', post.list); 48 | 49 | /* istanbul ignore next */ 50 | if (!module.parent) { 51 | app.listen(3000); 52 | console.log('Express started on port 3000'); 53 | } 54 | -------------------------------------------------------------------------------- /npm/examples/route-separation/post.js: -------------------------------------------------------------------------------- 1 | // Fake posts database 2 | 3 | var posts = [ 4 | { title: 'Foo', body: 'some foo bar' }, 5 | { title: 'Foo bar', body: 'more foo bar' }, 6 | { title: 'Foo bar baz', body: 'more foo bar baz' } 7 | ]; 8 | 9 | exports.list = function(req, res){ 10 | res.render('posts', { title: 'Posts', posts: posts }); 11 | }; 12 | -------------------------------------------------------------------------------- /npm/examples/route-separation/public/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Helvetica Neue", Arial, sans-serif; 4 | } 5 | a { 6 | color: #00AEFF; 7 | text-decoration: none; 8 | } 9 | a.edit { 10 | color: #000; 11 | opacity: .3; 12 | } 13 | a.edit::before { 14 | content: ' ['; 15 | } 16 | a.edit::after { 17 | content: ']'; 18 | } 19 | dt { 20 | font-weight: bold; 21 | } 22 | dd { 23 | margin: 15px; 24 | } -------------------------------------------------------------------------------- /npm/examples/route-separation/site.js: -------------------------------------------------------------------------------- 1 | exports.index = function(req, res){ 2 | res.render('index', { title: 'Route Separation Example' }); 3 | }; 4 | -------------------------------------------------------------------------------- /npm/examples/route-separation/user.js: -------------------------------------------------------------------------------- 1 | // Fake user database 2 | 3 | var users = [ 4 | { name: 'TJ', email: 'tj@vision-media.ca' }, 5 | { name: 'Tobi', email: 'tobi@vision-media.ca' } 6 | ]; 7 | 8 | exports.list = function(req, res){ 9 | res.render('users', { title: 'Users', users: users }); 10 | }; 11 | 12 | exports.load = function(req, res, next){ 13 | var id = req.params.id; 14 | req.user = users[id]; 15 | if (req.user) { 16 | next(); 17 | } else { 18 | var err = new Error('cannot find user ' + id); 19 | err.status = 404; 20 | next(err); 21 | } 22 | }; 23 | 24 | exports.view = function(req, res){ 25 | res.render('users/view', { 26 | title: 'Viewing user ' + req.user.name, 27 | user: req.user 28 | }); 29 | }; 30 | 31 | exports.edit = function(req, res){ 32 | res.render('users/edit', { 33 | title: 'Editing user ' + req.user.name, 34 | user: req.user 35 | }); 36 | }; 37 | 38 | exports.update = function(req, res){ 39 | // Normally you would handle all kinds of 40 | // validation and save back to the db 41 | var user = req.body.user; 42 | req.user.name = user.name; 43 | req.user.email = user.email; 44 | res.redirect('back'); 45 | }; 46 | -------------------------------------------------------------------------------- /npm/examples/route-separation/views/footer.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /npm/examples/route-separation/views/header.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%= title %> 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /npm/examples/route-separation/views/index.ejs: -------------------------------------------------------------------------------- 1 | <% include header %> 2 | 3 |

<%= title %>

4 | 5 |
    6 |
  • Visit the users page.
  • 7 |
  • Visit the posts page.
  • 8 |
9 | 10 | <% include footer %> 11 | -------------------------------------------------------------------------------- /npm/examples/route-separation/views/posts/index.ejs: -------------------------------------------------------------------------------- 1 | <% include ../header %> 2 | 3 |

Posts

4 | 5 |
6 | <% posts.forEach(function(post) { %> 7 |
<%= post.title %>
8 |
<%= post.body %>
9 | <% }) %> 10 |
11 | 12 | <% include ../footer %> 13 | -------------------------------------------------------------------------------- /npm/examples/route-separation/views/users/edit.ejs: -------------------------------------------------------------------------------- 1 | <% include ../header %> 2 | 3 |

Editing <%= user.name %>

4 | 5 |
6 |
7 |

8 | Name: 9 | 10 |

11 | 12 |

13 | Email: 14 | 15 |

16 | 17 |

18 | 19 |

20 |
21 |
22 | 23 | <% include ../footer %> 24 | -------------------------------------------------------------------------------- /npm/examples/route-separation/views/users/index.ejs: -------------------------------------------------------------------------------- 1 | <% include ../header %> 2 | 3 |

<%= title %>

4 | 5 |
6 | <% users.forEach(function(user, index) { %> 7 |
  • 8 | <%= user.name %> 9 | edit 10 |
  • 11 | <% }) %> 12 |
    13 | 14 | <% include ../footer %> 15 | -------------------------------------------------------------------------------- /npm/examples/route-separation/views/users/view.ejs: -------------------------------------------------------------------------------- 1 | <% include ../header %> 2 | 3 |

    <%= user.name %>

    4 | 5 |
    6 |

    Email: <%= user.email %>

    7 |
    8 | 9 | <% include ../footer %> 10 | -------------------------------------------------------------------------------- /npm/examples/search/index.js: -------------------------------------------------------------------------------- 1 | 2 | // install redis first: 3 | // https://redis.io/ 4 | 5 | // then: 6 | // $ npm install redis 7 | // $ redis-server 8 | 9 | /** 10 | * Module dependencies. 11 | */ 12 | 13 | var express = require('../..'); 14 | var path = require('path'); 15 | var redis = require('redis'); 16 | 17 | var db = redis.createClient(); 18 | 19 | // npm install redis 20 | 21 | var app = express(); 22 | 23 | app.use(express.static(path.join(__dirname, 'public'))); 24 | 25 | // populate search 26 | 27 | db.sadd('ferret', 'tobi'); 28 | db.sadd('ferret', 'loki'); 29 | db.sadd('ferret', 'jane'); 30 | db.sadd('cat', 'manny'); 31 | db.sadd('cat', 'luna'); 32 | 33 | /** 34 | * GET search for :query. 35 | */ 36 | 37 | app.get('/search/:query?', function(req, res){ 38 | var query = req.params.query; 39 | db.smembers(query, function(err, vals){ 40 | if (err) return res.send(500); 41 | res.send(vals); 42 | }); 43 | }); 44 | 45 | /** 46 | * GET client javascript. Here we use sendFile() 47 | * because serving __dirname with the static() middleware 48 | * would also mean serving our server "index.js" and the "search.jade" 49 | * template. 50 | */ 51 | 52 | app.get('/client.js', function(req, res){ 53 | res.sendFile(path.join(__dirname, 'client.js')); 54 | }); 55 | 56 | /* istanbul ignore next */ 57 | if (!module.parent) { 58 | app.listen(3000); 59 | console.log('Express started on port 3000'); 60 | } 61 | -------------------------------------------------------------------------------- /npm/examples/search/public/client.js: -------------------------------------------------------------------------------- 1 | var search = document.querySelector('[type=search]'); 2 | var code = document.querySelector('pre'); 3 | 4 | search.addEventListener('keyup', function(){ 5 | var xhr = new XMLHttpRequest; 6 | xhr.open('GET', '/search/' + search.value, true); 7 | xhr.onreadystatechange = function(){ 8 | if (xhr.readyState === 4) { 9 | code.textContent = xhr.responseText; 10 | } 11 | }; 12 | xhr.send(); 13 | }, false); 14 | -------------------------------------------------------------------------------- /npm/examples/search/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Search example 7 | 13 | 14 | 15 |

    Search

    16 |

    Try searching for "ferret" or "cat".

    17 | 18 |
    19 |   
    20 | 
    21 | 
    22 | 
    
    
    --------------------------------------------------------------------------------
    /npm/examples/session/index.js:
    --------------------------------------------------------------------------------
     1 | 
     2 | // install redis first:
     3 | // https://redis.io/
     4 | 
     5 | // then:
     6 | // $ npm install redis
     7 | // $ redis-server
     8 | 
     9 | var express = require('../..');
    10 | var session = require('express-session');
    11 | 
    12 | var app = express();
    13 | 
    14 | // Populates req.session
    15 | app.use(session({
    16 |   resave: false, // don't save session if unmodified
    17 |   saveUninitialized: false, // don't create session until something stored
    18 |   secret: 'keyboard cat'
    19 | }));
    20 | 
    21 | app.get('/', function(req, res){
    22 |   var body = '';
    23 |   if (req.session.views) {
    24 |     ++req.session.views;
    25 |   } else {
    26 |     req.session.views = 1;
    27 |     body += '

    First time visiting? view this page in several browsers :)

    '; 28 | } 29 | res.send(body + '

    viewed ' + req.session.views + ' times.

    '); 30 | }); 31 | 32 | /* istanbul ignore next */ 33 | if (!module.parent) { 34 | app.listen(3000); 35 | console.log('Express started on port 3000'); 36 | } 37 | -------------------------------------------------------------------------------- /npm/examples/session/redis.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../..'); 6 | var logger = require('morgan'); 7 | var session = require('express-session'); 8 | 9 | // pass the express to the connect redis module 10 | // allowing it to inherit from session.Store 11 | var RedisStore = require('connect-redis')(session); 12 | 13 | var app = express(); 14 | 15 | app.use(logger('dev')); 16 | 17 | // Populates req.session 18 | app.use(session({ 19 | resave: false, // don't save session if unmodified 20 | saveUninitialized: false, // don't create session until something stored 21 | secret: 'keyboard cat', 22 | store: new RedisStore 23 | })); 24 | 25 | app.get('/', function(req, res){ 26 | var body = ''; 27 | if (req.session.views) { 28 | ++req.session.views; 29 | } else { 30 | req.session.views = 1; 31 | body += '

    First time visiting? view this page in several browsers :)

    '; 32 | } 33 | res.send(body + '

    viewed ' + req.session.views + ' times.

    '); 34 | }); 35 | 36 | app.listen(3000); 37 | console.log('Express app started on port 3000'); 38 | -------------------------------------------------------------------------------- /npm/examples/static-files/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../..'); 6 | var logger = require('morgan'); 7 | var path = require('path'); 8 | var app = express(); 9 | 10 | // log requests 11 | app.use(logger('dev')); 12 | 13 | // express on its own has no notion 14 | // of a "file". The express.static() 15 | // middleware checks for a file matching 16 | // the `req.path` within the directory 17 | // that you pass it. In this case "GET /js/app.js" 18 | // will look for "./public/js/app.js". 19 | 20 | app.use(express.static(path.join(__dirname, 'public'))); 21 | 22 | // if you wanted to "prefix" you may use 23 | // the mounting feature of Connect, for example 24 | // "GET /static/js/app.js" instead of "GET /js/app.js". 25 | // The mount-path "/static" is simply removed before 26 | // passing control to the express.static() middleware, 27 | // thus it serves the file correctly by ignoring "/static" 28 | app.use('/static', express.static(path.join(__dirname, 'public'))); 29 | 30 | // if for some reason you want to serve files from 31 | // several directories, you can use express.static() 32 | // multiple times! Here we're passing "./public/css", 33 | // this will allow "GET /style.css" instead of "GET /css/style.css": 34 | app.use(express.static(path.join(__dirname, 'public', 'css'))); 35 | 36 | app.listen(3000); 37 | console.log('listening on port 3000'); 38 | console.log('try:'); 39 | console.log(' GET /hello.txt'); 40 | console.log(' GET /js/app.js'); 41 | console.log(' GET /css/style.css'); 42 | -------------------------------------------------------------------------------- /npm/examples/static-files/public/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | 3 | } -------------------------------------------------------------------------------- /npm/examples/static-files/public/hello.txt: -------------------------------------------------------------------------------- 1 | hey -------------------------------------------------------------------------------- /npm/examples/static-files/public/js/app.js: -------------------------------------------------------------------------------- 1 | // foo 2 | -------------------------------------------------------------------------------- /npm/examples/vhost/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../..'); 6 | var logger = require('morgan'); 7 | var vhost = require('vhost'); 8 | 9 | /* 10 | edit /etc/hosts: 11 | 12 | 127.0.0.1 foo.example.com 13 | 127.0.0.1 bar.example.com 14 | 127.0.0.1 example.com 15 | */ 16 | 17 | // Main server app 18 | 19 | var main = express(); 20 | 21 | if (!module.parent) main.use(logger('dev')); 22 | 23 | main.get('/', function(req, res){ 24 | res.send('Hello from main app!'); 25 | }); 26 | 27 | main.get('/:sub', function(req, res){ 28 | res.send('requested ' + req.params.sub); 29 | }); 30 | 31 | // Redirect app 32 | 33 | var redirect = express(); 34 | 35 | redirect.use(function(req, res){ 36 | if (!module.parent) console.log(req.vhost); 37 | res.redirect('http://example.com:3000/' + req.vhost[0]); 38 | }); 39 | 40 | // Vhost app 41 | 42 | var app = module.exports = express(); 43 | 44 | app.use(vhost('*.example.com', redirect)); // Serves all subdomains via Redirect app 45 | app.use(vhost('example.com', main)); // Serves top level domain via Main server app 46 | 47 | /* istanbul ignore next */ 48 | if (!module.parent) { 49 | app.listen(3000); 50 | console.log('Express started on port 3000'); 51 | } 52 | -------------------------------------------------------------------------------- /npm/examples/view-constructor/github-view.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var https = require('https'); 6 | var path = require('path'); 7 | var extname = path.extname; 8 | 9 | /** 10 | * Expose `GithubView`. 11 | */ 12 | 13 | module.exports = GithubView; 14 | 15 | /** 16 | * Custom view that fetches and renders 17 | * remove github templates. You could 18 | * render templates from a database etc. 19 | */ 20 | 21 | function GithubView(name, options){ 22 | this.name = name; 23 | options = options || {}; 24 | this.engine = options.engines[extname(name)]; 25 | // "root" is the app.set('views') setting, however 26 | // in your own implementation you could ignore this 27 | this.path = '/' + options.root + '/master/' + name; 28 | } 29 | 30 | /** 31 | * Render the view. 32 | */ 33 | 34 | GithubView.prototype.render = function(options, fn){ 35 | var self = this; 36 | var opts = { 37 | host: 'raw.githubusercontent.com', 38 | port: 443, 39 | path: this.path, 40 | method: 'GET' 41 | }; 42 | 43 | https.request(opts, function(res) { 44 | var buf = ''; 45 | res.setEncoding('utf8'); 46 | res.on('data', function(str){ buf += str }); 47 | res.on('end', function(){ 48 | self.engine(buf, options, fn); 49 | }); 50 | }).end(); 51 | }; 52 | -------------------------------------------------------------------------------- /npm/examples/view-constructor/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var express = require('../../'); 6 | var GithubView = require('./github-view'); 7 | var md = require('marked').parse; 8 | 9 | var app = module.exports = express(); 10 | 11 | // register .md as an engine in express view system 12 | app.engine('md', function(str, options, fn){ 13 | try { 14 | var html = md(str); 15 | html = html.replace(/\{([^}]+)\}/g, function(_, name){ 16 | return options[name] || ''; 17 | }); 18 | fn(null, html); 19 | } catch(err) { 20 | fn(err); 21 | } 22 | }); 23 | 24 | // pointing to a particular github repo to load files from it 25 | app.set('views', 'expressjs/express'); 26 | 27 | // register a new view constructor 28 | app.set('view', GithubView); 29 | 30 | app.get('/', function(req, res){ 31 | // rendering a view relative to the repo. 32 | // app.locals, res.locals, and locals passed 33 | // work like they normally would 34 | res.render('examples/markdown/views/index.md', { title: 'Example' }); 35 | }); 36 | 37 | app.get('/Readme.md', function(req, res){ 38 | // rendering a view from https://github.com/expressjs/express/blob/master/Readme.md 39 | res.render('Readme.md'); 40 | }); 41 | 42 | /* istanbul ignore next */ 43 | if (!module.parent) { 44 | app.listen(3000); 45 | console.log('Express started on port 3000'); 46 | } 47 | -------------------------------------------------------------------------------- /npm/examples/view-locals/user.js: -------------------------------------------------------------------------------- 1 | module.exports = User; 2 | 3 | // faux model 4 | 5 | function User(name, age, species) { 6 | this.name = name; 7 | this.age = age; 8 | this.species = species; 9 | } 10 | 11 | User.all = function(fn){ 12 | // process.nextTick makes sure this function API 13 | // behaves in an asynchronous manner, like if it 14 | // was a real DB query to read all users. 15 | process.nextTick(function(){ 16 | fn(null, users); 17 | }); 18 | }; 19 | 20 | User.count = function(fn){ 21 | process.nextTick(function(){ 22 | fn(null, users.length); 23 | }); 24 | }; 25 | 26 | // faux database 27 | 28 | var users = []; 29 | 30 | users.push(new User('Tobi', 2, 'ferret')); 31 | users.push(new User('Loki', 1, 'ferret')); 32 | users.push(new User('Jane', 6, 'ferret')); 33 | users.push(new User('Luna', 1, 'cat')); 34 | users.push(new User('Manny', 1, 'cat')); 35 | -------------------------------------------------------------------------------- /npm/examples/view-locals/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%= title %> 7 | 13 | 14 | 15 |

    <%= title %>

    16 | <% users.forEach(function(user) { %> 17 |
  • <%= user.name %> is a <% user.age %> year old <%= user.species %>
  • 18 | <% }); %> 19 | 20 | 21 | -------------------------------------------------------------------------------- /npm/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | module.exports = require('./lib/express'); 12 | -------------------------------------------------------------------------------- /npm/lib/middleware/init.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Module dependencies. 13 | * @private 14 | */ 15 | 16 | var setPrototypeOf = require('setprototypeof') 17 | 18 | /** 19 | * Initialization middleware, exposing the 20 | * request and response to each other, as well 21 | * as defaulting the X-Powered-By header field. 22 | * 23 | * @param {Function} app 24 | * @return {Function} 25 | * @api private 26 | */ 27 | 28 | exports.init = function (app) { 29 | return function expressInit(req, res, next) { 30 | if (app.enabled('x-powered-by')) res.setHeader('X-Powered-By', 'Express'); 31 | req.res = res; 32 | res.req = req; 33 | req.next = next; 34 | 35 | setPrototypeOf(req, app.request) 36 | setPrototypeOf(res, app.response) 37 | 38 | // console.log('new app', app._router.stack[6].handle.stack[1].route.stack) 39 | res.locals = res.locals || Object.create(null); 40 | 41 | next(); 42 | }; 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /npm/lib/middleware/query.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Module dependencies. 13 | */ 14 | 15 | var merge = require('utils-merge') 16 | var parseUrl = require('parseurl'); 17 | var qs = require('qs'); 18 | 19 | /** 20 | * @param {Object} options 21 | * @return {Function} 22 | * @api public 23 | */ 24 | 25 | module.exports = function query(options) { 26 | var opts = merge({}, options) 27 | var queryparse = qs.parse; 28 | 29 | if (typeof options === 'function') { 30 | queryparse = options; 31 | opts = undefined; 32 | } 33 | 34 | if (opts !== undefined && opts.allowPrototypes === undefined) { 35 | // back-compat for qs module 36 | opts.allowPrototypes = true; 37 | } 38 | 39 | return function query(req, res, next) { 40 | if (!req.query) { 41 | var val = parseUrl(req).query; 42 | req.query = queryparse(val, opts); 43 | } 44 | 45 | next(); 46 | }; 47 | }; 48 | -------------------------------------------------------------------------------- /npm/test/acceptance/content-negotiation.js: -------------------------------------------------------------------------------- 1 | 2 | var request = require('supertest') 3 | , app = require('../../examples/content-negotiation'); 4 | 5 | describe('content-negotiation', function(){ 6 | describe('GET /', function(){ 7 | it('should default to text/html', function(done){ 8 | request(app) 9 | .get('/') 10 | .expect(200, '
    • Tobi
    • Loki
    • Jane
    ', done) 11 | }) 12 | 13 | it('should accept to text/plain', function(done){ 14 | request(app) 15 | .get('/') 16 | .set('Accept', 'text/plain') 17 | .expect(200, ' - Tobi\n - Loki\n - Jane\n', done) 18 | }) 19 | 20 | it('should accept to application/json', function(done){ 21 | request(app) 22 | .get('/') 23 | .set('Accept', 'application/json') 24 | .expect(200, '[{"name":"Tobi"},{"name":"Loki"},{"name":"Jane"}]', done) 25 | }) 26 | }) 27 | 28 | describe('GET /users', function(){ 29 | it('should default to text/html', function(done){ 30 | request(app) 31 | .get('/users') 32 | .expect(200, '
    • Tobi
    • Loki
    • Jane
    ', done) 33 | }) 34 | 35 | it('should accept to text/plain', function(done){ 36 | request(app) 37 | .get('/users') 38 | .set('Accept', 'text/plain') 39 | .expect(200, ' - Tobi\n - Loki\n - Jane\n', done) 40 | }) 41 | 42 | it('should accept to application/json', function(done){ 43 | request(app) 44 | .get('/users') 45 | .set('Accept', 'application/json') 46 | .expect(200, '[{"name":"Tobi"},{"name":"Loki"},{"name":"Jane"}]', done) 47 | }) 48 | }) 49 | }) 50 | -------------------------------------------------------------------------------- /npm/test/acceptance/cookie-sessions.js: -------------------------------------------------------------------------------- 1 | 2 | var app = require('../../examples/cookie-sessions') 3 | var request = require('supertest') 4 | 5 | describe('cookie-sessions', function () { 6 | describe('GET /', function () { 7 | it('should display no views', function (done) { 8 | request(app) 9 | .get('/') 10 | .expect(200, 'viewed 1 times\n', done) 11 | }) 12 | 13 | it('should set a session cookie', function (done) { 14 | request(app) 15 | .get('/') 16 | .expect('Set-Cookie', /express:sess=/) 17 | .expect(200, done) 18 | }) 19 | 20 | it('should display 1 view on revisit', function (done) { 21 | request(app) 22 | .get('/') 23 | .expect(200, 'viewed 1 times\n', function (err, res) { 24 | if (err) return done(err) 25 | request(app) 26 | .get('/') 27 | .set('Cookie', getCookies(res)) 28 | .expect(200, 'viewed 2 times\n', done) 29 | }) 30 | }) 31 | }) 32 | }) 33 | 34 | function getCookies(res) { 35 | return res.headers['set-cookie'].map(function (val) { 36 | return val.split(';')[0] 37 | }).join('; '); 38 | } 39 | -------------------------------------------------------------------------------- /npm/test/acceptance/cookies.js: -------------------------------------------------------------------------------- 1 | 2 | var app = require('../../examples/cookies') 3 | , request = require('supertest'); 4 | var utils = require('../support/utils'); 5 | 6 | describe('cookies', function(){ 7 | describe('GET /', function(){ 8 | it('should have a form', function(done){ 9 | request(app) 10 | .get('/') 11 | .expect(/
    tobi <tobi@learnboost\.com><\/li>/) 12 | .expect(/
  • loki <loki@learnboost\.com><\/li>/) 13 | .expect(/
  • jane <jane@learnboost\.com><\/li>/) 14 | .expect(200, done) 15 | }) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /npm/test/acceptance/error.js: -------------------------------------------------------------------------------- 1 | 2 | var app = require('../../examples/error') 3 | , request = require('supertest'); 4 | 5 | describe('error', function(){ 6 | describe('GET /', function(){ 7 | it('should respond with 500', function(done){ 8 | request(app) 9 | .get('/') 10 | .expect(500,done) 11 | }) 12 | }) 13 | 14 | describe('GET /next', function(){ 15 | it('should respond with 500', function(done){ 16 | request(app) 17 | .get('/next') 18 | .expect(500,done) 19 | }) 20 | }) 21 | 22 | describe('GET /missing', function(){ 23 | it('should respond with 404', function(done){ 24 | request(app) 25 | .get('/missing') 26 | .expect(404,done) 27 | }) 28 | }) 29 | }) 30 | -------------------------------------------------------------------------------- /npm/test/acceptance/markdown.js: -------------------------------------------------------------------------------- 1 | 2 | var app = require('../../examples/markdown') 3 | var request = require('supertest') 4 | 5 | describe('markdown', function(){ 6 | describe('GET /', function(){ 7 | it('should respond with html', function(done){ 8 | request(app) 9 | .get('/') 10 | .expect(/]*>Markdown Example<\/h1>/,done) 11 | }) 12 | }) 13 | 14 | describe('GET /fail',function(){ 15 | it('should respond with an error', function(done){ 16 | request(app) 17 | .get('/fail') 18 | .expect(500,done) 19 | }) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /npm/test/acceptance/multi-router.js: -------------------------------------------------------------------------------- 1 | var app = require('../../examples/multi-router') 2 | var request = require('supertest') 3 | 4 | describe('multi-router', function(){ 5 | describe('GET /',function(){ 6 | it('should respond with root handler', function(done){ 7 | request(app) 8 | .get('/') 9 | .expect(200, 'Hello from root route.', done) 10 | }) 11 | }) 12 | 13 | describe('GET /api/v1/',function(){ 14 | it('should respond with APIv1 root handler', function(done){ 15 | request(app) 16 | .get('/api/v1/') 17 | .expect(200, 'Hello from APIv1 root route.', done) 18 | }) 19 | }) 20 | 21 | describe('GET /api/v1/users',function(){ 22 | it('should respond with users from APIv1', function(done){ 23 | request(app) 24 | .get('/api/v1/users') 25 | .expect(200, 'List of APIv1 users.', done) 26 | }) 27 | }) 28 | 29 | describe('GET /api/v2/',function(){ 30 | it('should respond with APIv2 root handler', function(done){ 31 | request(app) 32 | .get('/api/v2/') 33 | .expect(200, 'Hello from APIv2 root route.', done) 34 | }) 35 | }) 36 | 37 | describe('GET /api/v2/users',function(){ 38 | it('should respond with users from APIv2', function(done){ 39 | request(app) 40 | .get('/api/v2/users') 41 | .expect(200, 'List of APIv2 users.', done) 42 | }) 43 | }) 44 | }) 45 | -------------------------------------------------------------------------------- /npm/test/acceptance/params.js: -------------------------------------------------------------------------------- 1 | var app = require('../../examples/params') 2 | var request = require('supertest') 3 | 4 | describe('params', function(){ 5 | describe('GET /', function(){ 6 | it('should respond with instructions', function(done){ 7 | request(app) 8 | .get('/') 9 | .expect(/Visit/,done) 10 | }) 11 | }) 12 | 13 | describe('GET /user/0', function(){ 14 | it('should respond with a user', function(done){ 15 | request(app) 16 | .get('/user/0') 17 | .expect(/user tj/,done) 18 | }) 19 | }) 20 | 21 | describe('GET /user/9', function(){ 22 | it('should fail to find user', function(done){ 23 | request(app) 24 | .get('/user/9') 25 | .expect(404, /failed to find user/, done) 26 | }) 27 | }) 28 | 29 | describe('GET /users/0-2', function(){ 30 | it('should respond with three users', function(done){ 31 | request(app) 32 | .get('/users/0-2') 33 | .expect(/users tj, tobi, loki/, done) 34 | }) 35 | }) 36 | 37 | describe('GET /users/foo-bar', function(){ 38 | it('should fail integer parsing', function(done){ 39 | request(app) 40 | .get('/users/foo-bar') 41 | .expect(400, /failed to parseInt foo/, done) 42 | }) 43 | }) 44 | }) 45 | -------------------------------------------------------------------------------- /npm/test/acceptance/resource.js: -------------------------------------------------------------------------------- 1 | var app = require('../../examples/resource') 2 | var request = require('supertest') 3 | 4 | describe('resource', function(){ 5 | describe('GET /', function(){ 6 | it('should respond with instructions', function(done){ 7 | request(app) 8 | .get('/') 9 | .expect(/^

    Examples:<\/h1>/,done) 10 | }) 11 | }) 12 | 13 | describe('GET /users', function(){ 14 | it('should respond with all users', function(done){ 15 | request(app) 16 | .get('/users') 17 | .expect(/^\[{"name":"tj"},{"name":"ciaran"},{"name":"aaron"},{"name":"guillermo"},{"name":"simon"},{"name":"tobi"}\]/,done) 18 | }) 19 | }) 20 | 21 | describe('GET /users/1', function(){ 22 | it('should respond with user 1', function(done){ 23 | request(app) 24 | .get('/users/1') 25 | .expect(/^{"name":"ciaran"}/,done) 26 | }) 27 | }) 28 | 29 | describe('GET /users/9', function(){ 30 | it('should respond with error', function(done){ 31 | request(app) 32 | .get('/users/9') 33 | .expect('{"error":"Cannot find user"}', done) 34 | }) 35 | }) 36 | 37 | describe('GET /users/1..3', function(){ 38 | it('should respond with users 1 through 3', function(done){ 39 | request(app) 40 | .get('/users/1..3') 41 | .expect(/^
    • ciaran<\/li>\n
    • aaron<\/li>\n
    • guillermo<\/li><\/ul>/,done) 42 | }) 43 | }) 44 | 45 | describe('DELETE /users/1', function(){ 46 | it('should delete user 1', function(done){ 47 | request(app) 48 | .del('/users/1') 49 | .expect(/^destroyed/,done) 50 | }) 51 | }) 52 | 53 | describe('DELETE /users/9', function(){ 54 | it('should fail', function(done){ 55 | request(app) 56 | .del('/users/9') 57 | .expect('Cannot find user', done) 58 | }) 59 | }) 60 | 61 | describe('GET /users/1..3.json', function(){ 62 | it('should respond with users 2 and 3 as json', function(done){ 63 | request(app) 64 | .get('/users/1..3.json') 65 | .expect(/^\[null,{"name":"aaron"},{"name":"guillermo"}\]/,done) 66 | }) 67 | }) 68 | }) 69 | -------------------------------------------------------------------------------- /npm/test/acceptance/route-map.js: -------------------------------------------------------------------------------- 1 | 2 | var request = require('supertest') 3 | , app = require('../../examples/route-map'); 4 | 5 | describe('route-map', function(){ 6 | describe('GET /users', function(){ 7 | it('should respond with users', function(done){ 8 | request(app) 9 | .get('/users') 10 | .expect('user list', done); 11 | }) 12 | }) 13 | 14 | describe('DELETE /users', function(){ 15 | it('should delete users', function(done){ 16 | request(app) 17 | .del('/users') 18 | .expect('delete users', done); 19 | }) 20 | }) 21 | 22 | describe('GET /users/:id', function(){ 23 | it('should get a user', function(done){ 24 | request(app) 25 | .get('/users/12') 26 | .expect('user 12', done); 27 | }) 28 | }) 29 | 30 | describe('GET /users/:id/pets', function(){ 31 | it('should get a users pets', function(done){ 32 | request(app) 33 | .get('/users/12/pets') 34 | .expect('user 12\'s pets', done); 35 | }) 36 | }) 37 | 38 | describe('GET /users/:id/pets/:pid', function(){ 39 | it('should get a users pet', function(done){ 40 | request(app) 41 | .del('/users/12/pets/2') 42 | .expect('delete 12\'s pet 2', done); 43 | }) 44 | }) 45 | }) 46 | -------------------------------------------------------------------------------- /npm/test/acceptance/vhost.js: -------------------------------------------------------------------------------- 1 | var app = require('../../examples/vhost') 2 | var request = require('supertest') 3 | 4 | describe('vhost', function(){ 5 | describe('example.com', function(){ 6 | describe('GET /', function(){ 7 | it('should say hello', function(done){ 8 | request(app) 9 | .get('/') 10 | .set('Host', 'example.com') 11 | .expect(200, /hello/i, done) 12 | }) 13 | }) 14 | 15 | describe('GET /foo', function(){ 16 | it('should say foo', function(done){ 17 | request(app) 18 | .get('/foo') 19 | .set('Host', 'example.com') 20 | .expect(200, 'requested foo', done) 21 | }) 22 | }) 23 | }) 24 | 25 | describe('foo.example.com', function(){ 26 | describe('GET /', function(){ 27 | it('should redirect to /foo', function(done){ 28 | request(app) 29 | .get('/') 30 | .set('Host', 'foo.example.com') 31 | .expect(302, /Redirecting to http:\/\/example.com:3000\/foo/, done) 32 | }) 33 | }) 34 | }) 35 | 36 | describe('bar.example.com', function(){ 37 | describe('GET /', function(){ 38 | it('should redirect to /bar', function(done){ 39 | request(app) 40 | .get('/') 41 | .set('Host', 'bar.example.com') 42 | .expect(302, /Redirecting to http:\/\/example.com:3000\/bar/, done) 43 | }) 44 | }) 45 | }) 46 | }) 47 | -------------------------------------------------------------------------------- /npm/test/app.all.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('app.all()', function(){ 6 | it('should add a router per method', function(done){ 7 | var app = express(); 8 | 9 | app.all('/tobi', function(req, res){ 10 | res.end(req.method); 11 | }); 12 | 13 | request(app) 14 | .put('/tobi') 15 | .expect('PUT', function(){ 16 | request(app) 17 | .get('/tobi') 18 | .expect('GET', done); 19 | }); 20 | }) 21 | 22 | it('should run the callback for a method just once', function(done){ 23 | var app = express() 24 | , n = 0; 25 | 26 | app.all('/*', function(req, res, next){ 27 | if (n++) return done(new Error('DELETE called several times')); 28 | next(); 29 | }); 30 | 31 | request(app) 32 | .del('/tobi') 33 | .expect(404, done); 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /npm/test/app.del.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('app.del()', function(){ 6 | it('should alias app.delete()', function(done){ 7 | var app = express(); 8 | 9 | app.del('/tobi', function(req, res){ 10 | res.end('deleted tobi!'); 11 | }); 12 | 13 | request(app) 14 | .del('/tobi') 15 | .expect('deleted tobi!', done); 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /npm/test/app.engine.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , fs = require('fs'); 4 | var path = require('path') 5 | 6 | function render(path, options, fn) { 7 | fs.readFile(path, 'utf8', function(err, str){ 8 | if (err) return fn(err); 9 | str = str.replace('{{user.name}}', options.user.name); 10 | fn(null, str); 11 | }); 12 | } 13 | 14 | describe('app', function(){ 15 | describe('.engine(ext, fn)', function(){ 16 | it('should map a template engine', function(done){ 17 | var app = express(); 18 | 19 | app.set('views', path.join(__dirname, 'fixtures')) 20 | app.engine('.html', render); 21 | app.locals.user = { name: 'tobi' }; 22 | 23 | app.render('user.html', function(err, str){ 24 | if (err) return done(err); 25 | str.should.equal('

      tobi

      '); 26 | done(); 27 | }) 28 | }) 29 | 30 | it('should throw when the callback is missing', function(){ 31 | var app = express(); 32 | (function(){ 33 | app.engine('.html', null); 34 | }).should.throw('callback function required'); 35 | }) 36 | 37 | it('should work without leading "."', function(done){ 38 | var app = express(); 39 | 40 | app.set('views', path.join(__dirname, 'fixtures')) 41 | app.engine('html', render); 42 | app.locals.user = { name: 'tobi' }; 43 | 44 | app.render('user.html', function(err, str){ 45 | if (err) return done(err); 46 | str.should.equal('

      tobi

      '); 47 | done(); 48 | }) 49 | }) 50 | 51 | it('should work "view engine" setting', function(done){ 52 | var app = express(); 53 | 54 | app.set('views', path.join(__dirname, 'fixtures')) 55 | app.engine('html', render); 56 | app.set('view engine', 'html'); 57 | app.locals.user = { name: 'tobi' }; 58 | 59 | app.render('user', function(err, str){ 60 | if (err) return done(err); 61 | str.should.equal('

      tobi

      '); 62 | done(); 63 | }) 64 | }) 65 | 66 | it('should work "view engine" with leading "."', function(done){ 67 | var app = express(); 68 | 69 | app.set('views', path.join(__dirname, 'fixtures')) 70 | app.engine('.html', render); 71 | app.set('view engine', '.html'); 72 | app.locals.user = { name: 'tobi' }; 73 | 74 | app.render('user', function(err, str){ 75 | if (err) return done(err); 76 | str.should.equal('

      tobi

      '); 77 | done(); 78 | }) 79 | }) 80 | }) 81 | }) 82 | -------------------------------------------------------------------------------- /npm/test/app.head.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../'); 3 | var request = require('supertest'); 4 | var assert = require('assert'); 5 | 6 | describe('HEAD', function(){ 7 | it('should default to GET', function(done){ 8 | var app = express(); 9 | 10 | app.get('/tobi', function(req, res){ 11 | // send() detects HEAD 12 | res.send('tobi'); 13 | }); 14 | 15 | request(app) 16 | .head('/tobi') 17 | .expect(200, done); 18 | }) 19 | 20 | it('should output the same headers as GET requests', function(done){ 21 | var app = express(); 22 | 23 | app.get('/tobi', function(req, res){ 24 | // send() detects HEAD 25 | res.send('tobi'); 26 | }); 27 | 28 | request(app) 29 | .get('/tobi') 30 | .expect(200, function(err, res){ 31 | if (err) return done(err); 32 | var headers = res.headers; 33 | request(app) 34 | .get('/tobi') 35 | .expect(200, function(err, res){ 36 | if (err) return done(err); 37 | delete headers.date; 38 | delete res.headers.date; 39 | assert.deepEqual(res.headers, headers); 40 | done(); 41 | }); 42 | }); 43 | }) 44 | }) 45 | 46 | describe('app.head()', function(){ 47 | it('should override', function(done){ 48 | var app = express() 49 | , called; 50 | 51 | app.head('/tobi', function(req, res){ 52 | called = true; 53 | res.end(''); 54 | }); 55 | 56 | app.get('/tobi', function(req, res){ 57 | assert(0, 'should not call GET'); 58 | res.send('tobi'); 59 | }); 60 | 61 | request(app) 62 | .head('/tobi') 63 | .expect(200, function(){ 64 | assert(called); 65 | done(); 66 | }); 67 | }) 68 | }) 69 | -------------------------------------------------------------------------------- /npm/test/app.listen.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | 4 | describe('app.listen()', function(){ 5 | it('should wrap with an HTTP server', function(done){ 6 | var app = express(); 7 | 8 | app.del('/tobi', function(req, res){ 9 | res.end('deleted tobi!'); 10 | }); 11 | 12 | var server = app.listen(9999, function(){ 13 | server.close(); 14 | done(); 15 | }); 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /npm/test/app.locals.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | 4 | describe('app', function(){ 5 | describe('.locals(obj)', function(){ 6 | it('should merge locals', function(){ 7 | var app = express(); 8 | Object.keys(app.locals).should.eql(['settings']); 9 | app.locals.user = 'tobi'; 10 | app.locals.age = 2; 11 | Object.keys(app.locals).should.eql(['settings', 'user', 'age']); 12 | app.locals.user.should.equal('tobi'); 13 | app.locals.age.should.equal(2); 14 | }) 15 | }) 16 | 17 | describe('.locals.settings', function(){ 18 | it('should expose app settings', function(){ 19 | var app = express(); 20 | app.set('title', 'House of Manny'); 21 | var obj = app.locals.settings; 22 | obj.should.have.property('env', 'test'); 23 | obj.should.have.property('title', 'House of Manny'); 24 | }) 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /npm/test/app.request.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('app', function(){ 6 | describe('.request', function(){ 7 | it('should extend the request prototype', function(done){ 8 | var app = express(); 9 | 10 | app.request.querystring = function(){ 11 | return require('url').parse(this.url).query; 12 | }; 13 | 14 | app.use(function(req, res){ 15 | res.end(req.querystring()); 16 | }); 17 | 18 | request(app) 19 | .get('/foo?name=tobi') 20 | .expect('name=tobi', done); 21 | }) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /npm/test/app.response.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('app', function(){ 6 | describe('.response', function(){ 7 | it('should extend the response prototype', function(done){ 8 | var app = express(); 9 | 10 | app.response.shout = function(str){ 11 | this.send(str.toUpperCase()); 12 | }; 13 | 14 | app.use(function(req, res){ 15 | res.shout('hey'); 16 | }); 17 | 18 | request(app) 19 | .get('/') 20 | .expect('HEY', done); 21 | }) 22 | 23 | it('should not be influenced by other app protos', function(done){ 24 | var app = express() 25 | , app2 = express(); 26 | 27 | app.response.shout = function(str){ 28 | this.send(str.toUpperCase()); 29 | }; 30 | 31 | app2.response.shout = function(str){ 32 | this.send(str); 33 | }; 34 | 35 | app.use(function(req, res){ 36 | res.shout('hey'); 37 | }); 38 | 39 | request(app) 40 | .get('/') 41 | .expect('HEY', done); 42 | }) 43 | }) 44 | }) 45 | -------------------------------------------------------------------------------- /npm/test/app.route.js: -------------------------------------------------------------------------------- 1 | var express = require('../'); 2 | var request = require('supertest'); 3 | 4 | describe('app.route', function(){ 5 | it('should return a new route', function(done){ 6 | var app = express(); 7 | 8 | app.route('/foo') 9 | .get(function(req, res) { 10 | res.send('get'); 11 | }) 12 | .post(function(req, res) { 13 | res.send('post'); 14 | }); 15 | 16 | request(app) 17 | .post('/foo') 18 | .expect('post', done); 19 | }); 20 | 21 | it('should all .VERB after .all', function(done){ 22 | var app = express(); 23 | 24 | app.route('/foo') 25 | .all(function(req, res, next) { 26 | next(); 27 | }) 28 | .get(function(req, res) { 29 | res.send('get'); 30 | }) 31 | .post(function(req, res) { 32 | res.send('post'); 33 | }); 34 | 35 | request(app) 36 | .post('/foo') 37 | .expect('post', done); 38 | }); 39 | 40 | it('should support dynamic routes', function(done){ 41 | var app = express(); 42 | 43 | app.route('/:foo') 44 | .get(function(req, res) { 45 | res.send(req.params.foo); 46 | }); 47 | 48 | request(app) 49 | .get('/test') 50 | .expect('test', done); 51 | }); 52 | 53 | it('should not error on empty routes', function(done){ 54 | var app = express(); 55 | 56 | app.route('/:foo'); 57 | 58 | request(app) 59 | .get('/test') 60 | .expect(404, done); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /npm/test/app.routes.error.js: -------------------------------------------------------------------------------- 1 | var express = require('../') 2 | , request = require('supertest'); 3 | 4 | describe('app', function(){ 5 | describe('.VERB()', function(){ 6 | it('should not get invoked without error handler on error', function(done) { 7 | var app = express(); 8 | 9 | app.use(function(req, res, next){ 10 | next(new Error('boom!')) 11 | }); 12 | 13 | app.get('/bar', function(req, res){ 14 | res.send('hello, world!'); 15 | }); 16 | 17 | request(app) 18 | .post('/bar') 19 | .expect(500, /Error: boom!/, done); 20 | }); 21 | 22 | it('should only call an error handling routing callback when an error is propagated', function(done){ 23 | var app = express(); 24 | 25 | var a = false; 26 | var b = false; 27 | var c = false; 28 | var d = false; 29 | 30 | app.get('/', function(req, res, next){ 31 | next(new Error('fabricated error')); 32 | }, function(req, res, next) { 33 | a = true; 34 | next(); 35 | }, function(err, req, res, next){ 36 | b = true; 37 | err.message.should.equal('fabricated error'); 38 | next(err); 39 | }, function(err, req, res, next){ 40 | c = true; 41 | err.message.should.equal('fabricated error'); 42 | next(); 43 | }, function(err, req, res, next){ 44 | d = true; 45 | next(); 46 | }, function(req, res){ 47 | a.should.be.false() 48 | b.should.be.true() 49 | c.should.be.true() 50 | d.should.be.false() 51 | res.send(204); 52 | }); 53 | 54 | request(app) 55 | .get('/') 56 | .expect(204, done); 57 | }) 58 | }) 59 | }) 60 | -------------------------------------------------------------------------------- /npm/test/exports.js: -------------------------------------------------------------------------------- 1 | 2 | var assert = require('assert') 3 | var express = require('../'); 4 | var request = require('supertest'); 5 | var should = require('should'); 6 | 7 | describe('exports', function(){ 8 | it('should expose Router', function(){ 9 | express.Router.should.be.a.Function() 10 | }) 11 | 12 | it('should expose json middleware', function () { 13 | assert.equal(typeof express.json, 'function') 14 | assert.equal(express.json.length, 1) 15 | }) 16 | 17 | it('should expose raw middleware', function () { 18 | assert.equal(typeof express.raw, 'function') 19 | assert.equal(express.raw.length, 1) 20 | }) 21 | 22 | it('should expose static middleware', function () { 23 | assert.equal(typeof express.static, 'function') 24 | assert.equal(express.static.length, 2) 25 | }) 26 | 27 | it('should expose text middleware', function () { 28 | assert.equal(typeof express.text, 'function') 29 | assert.equal(express.text.length, 1) 30 | }) 31 | 32 | it('should expose urlencoded middleware', function () { 33 | assert.equal(typeof express.urlencoded, 'function') 34 | assert.equal(express.urlencoded.length, 1) 35 | }) 36 | 37 | it('should expose the application prototype', function(){ 38 | express.application.set.should.be.a.Function() 39 | }) 40 | 41 | it('should expose the request prototype', function(){ 42 | express.request.accepts.should.be.a.Function() 43 | }) 44 | 45 | it('should expose the response prototype', function(){ 46 | express.response.send.should.be.a.Function() 47 | }) 48 | 49 | it('should permit modifying the .application prototype', function(){ 50 | express.application.foo = function(){ return 'bar'; }; 51 | express().foo().should.equal('bar'); 52 | }) 53 | 54 | it('should permit modifying the .request prototype', function(done){ 55 | express.request.foo = function(){ return 'bar'; }; 56 | var app = express(); 57 | 58 | app.use(function(req, res, next){ 59 | res.end(req.foo()); 60 | }); 61 | 62 | request(app) 63 | .get('/') 64 | .expect('bar', done); 65 | }) 66 | 67 | it('should permit modifying the .response prototype', function(done){ 68 | express.response.foo = function(){ this.send('bar'); }; 69 | var app = express(); 70 | 71 | app.use(function(req, res, next){ 72 | res.foo(); 73 | }); 74 | 75 | request(app) 76 | .get('/') 77 | .expect('bar', done); 78 | }) 79 | 80 | it('should throw on old middlewares', function(){ 81 | var error; 82 | try { express.bodyParser; } catch (e) { error = e; } 83 | should(error).have.property('message'); 84 | error.message.should.containEql('middleware'); 85 | error.message.should.containEql('bodyParser'); 86 | }) 87 | }) 88 | -------------------------------------------------------------------------------- /npm/test/fixtures/% of dogs.txt: -------------------------------------------------------------------------------- 1 | 20% -------------------------------------------------------------------------------- /npm/test/fixtures/.name: -------------------------------------------------------------------------------- 1 | tobi -------------------------------------------------------------------------------- /npm/test/fixtures/blog/index.html: -------------------------------------------------------------------------------- 1 | index -------------------------------------------------------------------------------- /npm/test/fixtures/blog/post/index.tmpl: -------------------------------------------------------------------------------- 1 |

      blog post

      -------------------------------------------------------------------------------- /npm/test/fixtures/broken.send: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/npm/test/fixtures/broken.send -------------------------------------------------------------------------------- /npm/test/fixtures/default_layout/name.tmpl: -------------------------------------------------------------------------------- 1 |

      $name

      -------------------------------------------------------------------------------- /npm/test/fixtures/default_layout/user.tmpl: -------------------------------------------------------------------------------- 1 |

      $user.name

      -------------------------------------------------------------------------------- /npm/test/fixtures/email.tmpl: -------------------------------------------------------------------------------- 1 |

      This is an email

      -------------------------------------------------------------------------------- /npm/test/fixtures/empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/npm/test/fixtures/empty.txt -------------------------------------------------------------------------------- /npm/test/fixtures/local_layout/user.tmpl: -------------------------------------------------------------------------------- 1 | $user.name -------------------------------------------------------------------------------- /npm/test/fixtures/name.tmpl: -------------------------------------------------------------------------------- 1 |

      $name

      -------------------------------------------------------------------------------- /npm/test/fixtures/name.txt: -------------------------------------------------------------------------------- 1 | tobi -------------------------------------------------------------------------------- /npm/test/fixtures/nums.txt: -------------------------------------------------------------------------------- 1 | 123456789 -------------------------------------------------------------------------------- /npm/test/fixtures/pets/names.txt: -------------------------------------------------------------------------------- 1 | tobi,loki -------------------------------------------------------------------------------- /npm/test/fixtures/snow ☃/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/npm/test/fixtures/snow ☃/.gitkeep -------------------------------------------------------------------------------- /npm/test/fixtures/todo.html: -------------------------------------------------------------------------------- 1 |
    • groceries
    • -------------------------------------------------------------------------------- /npm/test/fixtures/todo.txt: -------------------------------------------------------------------------------- 1 | - groceries -------------------------------------------------------------------------------- /npm/test/fixtures/user.html: -------------------------------------------------------------------------------- 1 |

      {{user.name}}

      -------------------------------------------------------------------------------- /npm/test/fixtures/user.tmpl: -------------------------------------------------------------------------------- 1 |

      $user.name

      -------------------------------------------------------------------------------- /npm/test/fixtures/users/index.html: -------------------------------------------------------------------------------- 1 |

      tobi, loki, jane

      -------------------------------------------------------------------------------- /npm/test/fixtures/users/tobi.txt: -------------------------------------------------------------------------------- 1 | ferret -------------------------------------------------------------------------------- /npm/test/middleware.basic.js: -------------------------------------------------------------------------------- 1 | 2 | var assert = require('assert') 3 | var express = require('../'); 4 | var request = require('supertest'); 5 | 6 | describe('middleware', function(){ 7 | describe('.next()', function(){ 8 | it('should behave like connect', function(done){ 9 | var app = express() 10 | , calls = []; 11 | 12 | app.use(function(req, res, next){ 13 | calls.push('one'); 14 | next(); 15 | }); 16 | 17 | app.use(function(req, res, next){ 18 | calls.push('two'); 19 | next(); 20 | }); 21 | 22 | app.use(function(req, res){ 23 | var buf = ''; 24 | res.setHeader('Content-Type', 'application/json'); 25 | req.setEncoding('utf8'); 26 | req.on('data', function(chunk){ buf += chunk }); 27 | req.on('end', function(){ 28 | res.end(buf); 29 | }); 30 | }); 31 | 32 | request(app) 33 | .get('/') 34 | .set('Content-Type', 'application/json') 35 | .send('{"foo":"bar"}') 36 | .expect('Content-Type', 'application/json') 37 | .expect(function () { assert.deepEqual(calls, ['one', 'two']) }) 38 | .expect(200, '{"foo":"bar"}', done) 39 | }) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /npm/test/mocha.opts: -------------------------------------------------------------------------------- 1 | --require should 2 | --slow 20 3 | -------------------------------------------------------------------------------- /npm/test/regression.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('throw after .end()', function(){ 6 | it('should fail gracefully', function(done){ 7 | var app = express(); 8 | 9 | app.get('/', function(req, res){ 10 | res.end('yay'); 11 | throw new Error('boom'); 12 | }); 13 | 14 | request(app) 15 | .get('/') 16 | .expect('yay') 17 | .expect(200, done); 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /npm/test/req.acceptsCharset.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.acceptsCharset(type)', function(){ 7 | describe('when Accept-Charset is not present', function(){ 8 | it('should return true', function(done){ 9 | var app = express(); 10 | 11 | app.use(function(req, res, next){ 12 | res.end(req.acceptsCharset('utf-8') ? 'yes' : 'no'); 13 | }); 14 | 15 | request(app) 16 | .get('/') 17 | .expect('yes', done); 18 | }) 19 | }) 20 | 21 | describe('when Accept-Charset is present', function () { 22 | it('should return true', function (done) { 23 | var app = express(); 24 | 25 | app.use(function(req, res, next){ 26 | res.end(req.acceptsCharset('utf-8') ? 'yes' : 'no'); 27 | }); 28 | 29 | request(app) 30 | .get('/') 31 | .set('Accept-Charset', 'foo, bar, utf-8') 32 | .expect('yes', done); 33 | }) 34 | 35 | it('should return false otherwise', function(done){ 36 | var app = express(); 37 | 38 | app.use(function(req, res, next){ 39 | res.end(req.acceptsCharset('utf-8') ? 'yes' : 'no'); 40 | }); 41 | 42 | request(app) 43 | .get('/') 44 | .set('Accept-Charset', 'foo, bar') 45 | .expect('no', done); 46 | }) 47 | }) 48 | }) 49 | }) 50 | -------------------------------------------------------------------------------- /npm/test/req.acceptsCharsets.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.acceptsCharsets(type)', function(){ 7 | describe('when Accept-Charset is not present', function(){ 8 | it('should return true', function(done){ 9 | var app = express(); 10 | 11 | app.use(function(req, res, next){ 12 | res.end(req.acceptsCharsets('utf-8') ? 'yes' : 'no'); 13 | }); 14 | 15 | request(app) 16 | .get('/') 17 | .expect('yes', done); 18 | }) 19 | }) 20 | 21 | describe('when Accept-Charset is present', function () { 22 | it('should return true', function (done) { 23 | var app = express(); 24 | 25 | app.use(function(req, res, next){ 26 | res.end(req.acceptsCharsets('utf-8') ? 'yes' : 'no'); 27 | }); 28 | 29 | request(app) 30 | .get('/') 31 | .set('Accept-Charset', 'foo, bar, utf-8') 32 | .expect('yes', done); 33 | }) 34 | 35 | it('should return false otherwise', function(done){ 36 | var app = express(); 37 | 38 | app.use(function(req, res, next){ 39 | res.end(req.acceptsCharsets('utf-8') ? 'yes' : 'no'); 40 | }); 41 | 42 | request(app) 43 | .get('/') 44 | .set('Accept-Charset', 'foo, bar') 45 | .expect('no', done); 46 | }) 47 | }) 48 | }) 49 | }) 50 | -------------------------------------------------------------------------------- /npm/test/req.acceptsEncoding.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.acceptsEncoding', function(){ 7 | it('should be true if encoding accepted', function(done){ 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | req.acceptsEncoding('gzip').should.be.ok() 12 | req.acceptsEncoding('deflate').should.be.ok() 13 | res.end(); 14 | }); 15 | 16 | request(app) 17 | .get('/') 18 | .set('Accept-Encoding', ' gzip, deflate') 19 | .expect(200, done); 20 | }) 21 | 22 | it('should be false if encoding not accepted', function(done){ 23 | var app = express(); 24 | 25 | app.use(function(req, res){ 26 | req.acceptsEncoding('bogus').should.not.be.ok() 27 | res.end(); 28 | }); 29 | 30 | request(app) 31 | .get('/') 32 | .set('Accept-Encoding', ' gzip, deflate') 33 | .expect(200, done); 34 | }) 35 | }) 36 | }) 37 | -------------------------------------------------------------------------------- /npm/test/req.acceptsEncodings.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.acceptsEncodings', function () { 7 | it('should be true if encoding accepted', function(done){ 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | req.acceptsEncodings('gzip').should.be.ok() 12 | req.acceptsEncodings('deflate').should.be.ok() 13 | res.end(); 14 | }); 15 | 16 | request(app) 17 | .get('/') 18 | .set('Accept-Encoding', ' gzip, deflate') 19 | .expect(200, done); 20 | }) 21 | 22 | it('should be false if encoding not accepted', function(done){ 23 | var app = express(); 24 | 25 | app.use(function(req, res){ 26 | req.acceptsEncodings('bogus').should.not.be.ok() 27 | res.end(); 28 | }); 29 | 30 | request(app) 31 | .get('/') 32 | .set('Accept-Encoding', ' gzip, deflate') 33 | .expect(200, done); 34 | }) 35 | }) 36 | }) 37 | -------------------------------------------------------------------------------- /npm/test/req.acceptsLanguage.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.acceptsLanguage', function(){ 7 | it('should be true if language accepted', function(done){ 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | req.acceptsLanguage('en-us').should.be.ok() 12 | req.acceptsLanguage('en').should.be.ok() 13 | res.end(); 14 | }); 15 | 16 | request(app) 17 | .get('/') 18 | .set('Accept-Language', 'en;q=.5, en-us') 19 | .expect(200, done); 20 | }) 21 | 22 | it('should be false if language not accepted', function(done){ 23 | var app = express(); 24 | 25 | app.use(function(req, res){ 26 | req.acceptsLanguage('es').should.not.be.ok() 27 | res.end(); 28 | }); 29 | 30 | request(app) 31 | .get('/') 32 | .set('Accept-Language', 'en;q=.5, en-us') 33 | .expect(200, done); 34 | }) 35 | 36 | describe('when Accept-Language is not present', function(){ 37 | it('should always return true', function(done){ 38 | var app = express(); 39 | 40 | app.use(function(req, res){ 41 | req.acceptsLanguage('en').should.be.ok() 42 | req.acceptsLanguage('es').should.be.ok() 43 | req.acceptsLanguage('jp').should.be.ok() 44 | res.end(); 45 | }); 46 | 47 | request(app) 48 | .get('/') 49 | .expect(200, done); 50 | }) 51 | }) 52 | }) 53 | }) 54 | -------------------------------------------------------------------------------- /npm/test/req.acceptsLanguages.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.acceptsLanguages', function(){ 7 | it('should be true if language accepted', function(done){ 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | req.acceptsLanguages('en-us').should.be.ok() 12 | req.acceptsLanguages('en').should.be.ok() 13 | res.end(); 14 | }); 15 | 16 | request(app) 17 | .get('/') 18 | .set('Accept-Language', 'en;q=.5, en-us') 19 | .expect(200, done); 20 | }) 21 | 22 | it('should be false if language not accepted', function(done){ 23 | var app = express(); 24 | 25 | app.use(function(req, res){ 26 | req.acceptsLanguages('es').should.not.be.ok() 27 | res.end(); 28 | }); 29 | 30 | request(app) 31 | .get('/') 32 | .set('Accept-Language', 'en;q=.5, en-us') 33 | .expect(200, done); 34 | }) 35 | 36 | describe('when Accept-Language is not present', function(){ 37 | it('should always return true', function(done){ 38 | var app = express(); 39 | 40 | app.use(function(req, res){ 41 | req.acceptsLanguages('en').should.be.ok() 42 | req.acceptsLanguages('es').should.be.ok() 43 | req.acceptsLanguages('jp').should.be.ok() 44 | res.end(); 45 | }); 46 | 47 | request(app) 48 | .get('/') 49 | .expect(200, done); 50 | }) 51 | }) 52 | }) 53 | }) 54 | -------------------------------------------------------------------------------- /npm/test/req.baseUrl.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('..') 3 | var request = require('supertest') 4 | 5 | describe('req', function(){ 6 | describe('.baseUrl', function(){ 7 | it('should be empty for top-level route', function(done){ 8 | var app = express() 9 | 10 | app.get('/:a', function(req, res){ 11 | res.end(req.baseUrl) 12 | }) 13 | 14 | request(app) 15 | .get('/foo') 16 | .expect(200, '', done) 17 | }) 18 | 19 | it('should contain lower path', function(done){ 20 | var app = express() 21 | var sub = express.Router() 22 | 23 | sub.get('/:b', function(req, res){ 24 | res.end(req.baseUrl) 25 | }) 26 | app.use('/:a', sub) 27 | 28 | request(app) 29 | .get('/foo/bar') 30 | .expect(200, '/foo', done); 31 | }) 32 | 33 | it('should contain full lower path', function(done){ 34 | var app = express() 35 | var sub1 = express.Router() 36 | var sub2 = express.Router() 37 | var sub3 = express.Router() 38 | 39 | sub3.get('/:d', function(req, res){ 40 | res.end(req.baseUrl) 41 | }) 42 | sub2.use('/:c', sub3) 43 | sub1.use('/:b', sub2) 44 | app.use('/:a', sub1) 45 | 46 | request(app) 47 | .get('/foo/bar/baz/zed') 48 | .expect(200, '/foo/bar/baz', done); 49 | }) 50 | 51 | it('should travel through routers correctly', function(done){ 52 | var urls = [] 53 | var app = express() 54 | var sub1 = express.Router() 55 | var sub2 = express.Router() 56 | var sub3 = express.Router() 57 | 58 | sub3.get('/:d', function(req, res, next){ 59 | urls.push('0@' + req.baseUrl) 60 | next() 61 | }) 62 | sub2.use('/:c', sub3) 63 | sub1.use('/', function(req, res, next){ 64 | urls.push('1@' + req.baseUrl) 65 | next() 66 | }) 67 | sub1.use('/bar', sub2) 68 | sub1.use('/bar', function(req, res, next){ 69 | urls.push('2@' + req.baseUrl) 70 | next() 71 | }) 72 | app.use(function(req, res, next){ 73 | urls.push('3@' + req.baseUrl) 74 | next() 75 | }) 76 | app.use('/:a', sub1) 77 | app.use(function(req, res, next){ 78 | urls.push('4@' + req.baseUrl) 79 | res.end(urls.join(',')) 80 | }) 81 | 82 | request(app) 83 | .get('/foo/bar/baz/zed') 84 | .expect(200, '3@,1@/foo,0@/foo/bar/baz,2@/foo/bar,4@', done); 85 | }) 86 | }) 87 | }) 88 | -------------------------------------------------------------------------------- /npm/test/req.fresh.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.fresh', function(){ 7 | it('should return true when the resource is not modified', function(done){ 8 | var app = express(); 9 | var etag = '"12345"'; 10 | 11 | app.use(function(req, res){ 12 | res.set('ETag', etag); 13 | res.send(req.fresh); 14 | }); 15 | 16 | request(app) 17 | .get('/') 18 | .set('If-None-Match', etag) 19 | .expect(304, done); 20 | }) 21 | 22 | it('should return false when the resource is modified', function(done){ 23 | var app = express(); 24 | 25 | app.use(function(req, res){ 26 | res.set('ETag', '"123"'); 27 | res.send(req.fresh); 28 | }); 29 | 30 | request(app) 31 | .get('/') 32 | .set('If-None-Match', '"12345"') 33 | .expect(200, 'false', done); 34 | }) 35 | 36 | it('should return false without response headers', function(done){ 37 | var app = express(); 38 | 39 | app.disable('x-powered-by') 40 | app.use(function(req, res){ 41 | res.send(req.fresh); 42 | }); 43 | 44 | request(app) 45 | .get('/') 46 | .expect(200, 'false', done); 47 | }) 48 | }) 49 | }) 50 | -------------------------------------------------------------------------------- /npm/test/req.get.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest') 4 | , assert = require('assert'); 5 | 6 | describe('req', function(){ 7 | describe('.get(field)', function(){ 8 | it('should return the header field value', function(done){ 9 | var app = express(); 10 | 11 | app.use(function(req, res){ 12 | assert(req.get('Something-Else') === undefined); 13 | res.end(req.get('Content-Type')); 14 | }); 15 | 16 | request(app) 17 | .post('/') 18 | .set('Content-Type', 'application/json') 19 | .expect('application/json', done); 20 | }) 21 | 22 | it('should special-case Referer', function(done){ 23 | var app = express(); 24 | 25 | app.use(function(req, res){ 26 | res.end(req.get('Referer')); 27 | }); 28 | 29 | request(app) 30 | .post('/') 31 | .set('Referrer', 'http://foobar.com') 32 | .expect('http://foobar.com', done); 33 | }) 34 | 35 | it('should throw missing header name', function (done) { 36 | var app = express() 37 | 38 | app.use(function (req, res) { 39 | res.end(req.get()) 40 | }) 41 | 42 | request(app) 43 | .get('/') 44 | .expect(500, /TypeError: name argument is required to req.get/, done) 45 | }) 46 | 47 | it('should throw for non-string header name', function (done) { 48 | var app = express() 49 | 50 | app.use(function (req, res) { 51 | res.end(req.get(42)) 52 | }) 53 | 54 | request(app) 55 | .get('/') 56 | .expect(500, /TypeError: name must be a string to req.get/, done) 57 | }) 58 | }) 59 | }) 60 | -------------------------------------------------------------------------------- /npm/test/req.ips.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.ips', function(){ 7 | describe('when X-Forwarded-For is present', function(){ 8 | describe('when "trust proxy" is enabled', function(){ 9 | it('should return an array of the specified addresses', function(done){ 10 | var app = express(); 11 | 12 | app.enable('trust proxy'); 13 | 14 | app.use(function(req, res, next){ 15 | res.send(req.ips); 16 | }); 17 | 18 | request(app) 19 | .get('/') 20 | .set('X-Forwarded-For', 'client, p1, p2') 21 | .expect('["client","p1","p2"]', done); 22 | }) 23 | 24 | it('should stop at first untrusted', function(done){ 25 | var app = express(); 26 | 27 | app.set('trust proxy', 2); 28 | 29 | app.use(function(req, res, next){ 30 | res.send(req.ips); 31 | }); 32 | 33 | request(app) 34 | .get('/') 35 | .set('X-Forwarded-For', 'client, p1, p2') 36 | .expect('["p1","p2"]', done); 37 | }) 38 | }) 39 | 40 | describe('when "trust proxy" is disabled', function(){ 41 | it('should return an empty array', function(done){ 42 | var app = express(); 43 | 44 | app.use(function(req, res, next){ 45 | res.send(req.ips); 46 | }); 47 | 48 | request(app) 49 | .get('/') 50 | .set('X-Forwarded-For', 'client, p1, p2') 51 | .expect('[]', done); 52 | }) 53 | }) 54 | }) 55 | 56 | describe('when X-Forwarded-For is not present', function(){ 57 | it('should return []', function(done){ 58 | var app = express(); 59 | 60 | app.use(function(req, res, next){ 61 | res.send(req.ips); 62 | }); 63 | 64 | request(app) 65 | .get('/') 66 | .expect('[]', done); 67 | }) 68 | }) 69 | }) 70 | }) 71 | -------------------------------------------------------------------------------- /npm/test/req.param.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest') 4 | 5 | describe('req', function(){ 6 | describe('.param(name, default)', function(){ 7 | it('should use the default value unless defined', function(done){ 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | res.end(req.param('name', 'tj')); 12 | }); 13 | 14 | request(app) 15 | .get('/') 16 | .expect('tj', done); 17 | }) 18 | }) 19 | 20 | describe('.param(name)', function(){ 21 | it('should check req.query', function(done){ 22 | var app = express(); 23 | 24 | app.use(function(req, res){ 25 | res.end(req.param('name')); 26 | }); 27 | 28 | request(app) 29 | .get('/?name=tj') 30 | .expect('tj', done); 31 | }) 32 | 33 | it('should check req.body', function(done){ 34 | var app = express(); 35 | 36 | app.use(express.json()) 37 | 38 | app.use(function(req, res){ 39 | res.end(req.param('name')); 40 | }); 41 | 42 | request(app) 43 | .post('/') 44 | .send({ name: 'tj' }) 45 | .expect('tj', done); 46 | }) 47 | 48 | it('should check req.params', function(done){ 49 | var app = express(); 50 | 51 | app.get('/user/:name', function(req, res){ 52 | res.end(req.param('filter') + req.param('name')); 53 | }); 54 | 55 | request(app) 56 | .get('/user/tj') 57 | .expect('undefinedtj', done); 58 | }) 59 | }) 60 | }) 61 | -------------------------------------------------------------------------------- /npm/test/req.path.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.path', function(){ 7 | it('should return the parsed pathname', function(done){ 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | res.end(req.path); 12 | }); 13 | 14 | request(app) 15 | .get('/login?redirect=/post/1/comments') 16 | .expect('/login', done); 17 | }) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /npm/test/req.route.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.route', function(){ 7 | it('should be the executed Route', function(done){ 8 | var app = express(); 9 | 10 | app.get('/user/:id/:op?', function(req, res, next){ 11 | req.route.path.should.equal('/user/:id/:op?'); 12 | next(); 13 | }); 14 | 15 | app.get('/user/:id/edit', function(req, res){ 16 | req.route.path.should.equal('/user/:id/edit'); 17 | res.end(); 18 | }); 19 | 20 | request(app) 21 | .get('/user/12/edit') 22 | .expect(200, done); 23 | }) 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /npm/test/req.signedCookies.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest') 4 | , cookieParser = require('cookie-parser') 5 | 6 | describe('req', function(){ 7 | describe('.signedCookies', function(){ 8 | it('should return a signed JSON cookie', function(done){ 9 | var app = express(); 10 | 11 | app.use(cookieParser('secret')); 12 | 13 | app.use(function(req, res){ 14 | if (req.path === '/set') { 15 | res.cookie('obj', { foo: 'bar' }, { signed: true }); 16 | res.end(); 17 | } else { 18 | res.send(req.signedCookies); 19 | } 20 | }); 21 | 22 | request(app) 23 | .get('/set') 24 | .end(function(err, res){ 25 | if (err) return done(err); 26 | var cookie = res.header['set-cookie']; 27 | 28 | request(app) 29 | .get('/') 30 | .set('Cookie', cookie) 31 | .expect(200, { obj: { foo: 'bar' } }, done) 32 | }); 33 | }) 34 | }) 35 | }) 36 | 37 | -------------------------------------------------------------------------------- /npm/test/req.stale.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.stale', function(){ 7 | it('should return false when the resource is not modified', function(done){ 8 | var app = express(); 9 | var etag = '"12345"'; 10 | 11 | app.use(function(req, res){ 12 | res.set('ETag', etag); 13 | res.send(req.stale); 14 | }); 15 | 16 | request(app) 17 | .get('/') 18 | .set('If-None-Match', etag) 19 | .expect(304, done); 20 | }) 21 | 22 | it('should return true when the resource is modified', function(done){ 23 | var app = express(); 24 | 25 | app.use(function(req, res){ 26 | res.set('ETag', '"123"'); 27 | res.send(req.stale); 28 | }); 29 | 30 | request(app) 31 | .get('/') 32 | .set('If-None-Match', '"12345"') 33 | .expect(200, 'true', done); 34 | }) 35 | 36 | it('should return true without response headers', function(done){ 37 | var app = express(); 38 | 39 | app.disable('x-powered-by') 40 | app.use(function(req, res){ 41 | res.send(req.stale); 42 | }); 43 | 44 | request(app) 45 | .get('/') 46 | .expect(200, 'true', done); 47 | }) 48 | }) 49 | }) 50 | -------------------------------------------------------------------------------- /npm/test/req.xhr.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('req', function(){ 6 | describe('.xhr', function(){ 7 | it('should return true when X-Requested-With is xmlhttprequest', function(done){ 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | req.xhr.should.be.true() 12 | res.end(); 13 | }); 14 | 15 | request(app) 16 | .get('/') 17 | .set('X-Requested-With', 'xmlhttprequest') 18 | .expect(200, done) 19 | }) 20 | 21 | it('should case-insensitive', function(done){ 22 | var app = express(); 23 | 24 | app.use(function(req, res){ 25 | req.xhr.should.be.true() 26 | res.end(); 27 | }); 28 | 29 | request(app) 30 | .get('/') 31 | .set('X-Requested-With', 'XMLHttpRequest') 32 | .expect(200, done) 33 | }) 34 | 35 | it('should return false otherwise', function(done){ 36 | var app = express(); 37 | 38 | app.use(function(req, res){ 39 | req.xhr.should.be.false() 40 | res.end(); 41 | }); 42 | 43 | request(app) 44 | .get('/') 45 | .set('X-Requested-With', 'blahblah') 46 | .expect(200, done) 47 | }) 48 | 49 | it('should return false when not present', function(done){ 50 | var app = express(); 51 | 52 | app.use(function(req, res){ 53 | req.xhr.should.be.false() 54 | res.end(); 55 | }); 56 | 57 | request(app) 58 | .get('/') 59 | .expect(200, done) 60 | }) 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /npm/test/res.attachment.js: -------------------------------------------------------------------------------- 1 | 2 | var Buffer = require('safe-buffer').Buffer 3 | var express = require('../') 4 | , request = require('supertest'); 5 | 6 | describe('res', function(){ 7 | describe('.attachment()', function(){ 8 | it('should Content-Disposition to attachment', function(done){ 9 | var app = express(); 10 | 11 | app.use(function(req, res){ 12 | res.attachment().send('foo'); 13 | }); 14 | 15 | request(app) 16 | .get('/') 17 | .expect('Content-Disposition', 'attachment', done); 18 | }) 19 | }) 20 | 21 | describe('.attachment(filename)', function(){ 22 | it('should add the filename param', function(done){ 23 | var app = express(); 24 | 25 | app.use(function(req, res){ 26 | res.attachment('/path/to/image.png'); 27 | res.send('foo'); 28 | }); 29 | 30 | request(app) 31 | .get('/') 32 | .expect('Content-Disposition', 'attachment; filename="image.png"', done); 33 | }) 34 | 35 | it('should set the Content-Type', function(done){ 36 | var app = express(); 37 | 38 | app.use(function(req, res){ 39 | res.attachment('/path/to/image.png'); 40 | res.send(Buffer.alloc(4, '.')) 41 | }); 42 | 43 | request(app) 44 | .get('/') 45 | .expect('Content-Type', 'image/png', done); 46 | }) 47 | }) 48 | 49 | describe('.attachment(utf8filename)', function(){ 50 | it('should add the filename and filename* params', function(done){ 51 | var app = express(); 52 | 53 | app.use(function(req, res){ 54 | res.attachment('/locales/日本語.txt'); 55 | res.send('japanese'); 56 | }); 57 | 58 | request(app) 59 | .get('/') 60 | .expect('Content-Disposition', 'attachment; filename="???.txt"; filename*=UTF-8\'\'%E6%97%A5%E6%9C%AC%E8%AA%9E.txt') 61 | .expect(200, done); 62 | }) 63 | 64 | it('should set the Content-Type', function(done){ 65 | var app = express(); 66 | 67 | app.use(function(req, res){ 68 | res.attachment('/locales/日本語.txt'); 69 | res.send('japanese'); 70 | }); 71 | 72 | request(app) 73 | .get('/') 74 | .expect('Content-Type', 'text/plain; charset=utf-8', done); 75 | }) 76 | }) 77 | }) 78 | -------------------------------------------------------------------------------- /npm/test/res.clearCookie.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('res', function(){ 6 | describe('.clearCookie(name)', function(){ 7 | it('should set a cookie passed expiry', function(done){ 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | res.clearCookie('sid').end(); 12 | }); 13 | 14 | request(app) 15 | .get('/') 16 | .expect('Set-Cookie', 'sid=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT') 17 | .expect(200, done) 18 | }) 19 | }) 20 | 21 | describe('.clearCookie(name, options)', function(){ 22 | it('should set the given params', function(done){ 23 | var app = express(); 24 | 25 | app.use(function(req, res){ 26 | res.clearCookie('sid', { path: '/admin' }).end(); 27 | }); 28 | 29 | request(app) 30 | .get('/') 31 | .expect('Set-Cookie', 'sid=; Path=/admin; Expires=Thu, 01 Jan 1970 00:00:00 GMT') 32 | .expect(200, done) 33 | }) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /npm/test/res.get.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('..'); 3 | var request = require('supertest'); 4 | 5 | describe('res', function(){ 6 | describe('.get(field)', function(){ 7 | it('should get the response header field', function (done) { 8 | var app = express(); 9 | 10 | app.use(function (req, res) { 11 | res.setHeader('Content-Type', 'text/x-foo'); 12 | res.send(res.get('Content-Type')); 13 | }); 14 | 15 | request(app) 16 | .get('/') 17 | .expect(200, 'text/x-foo', done); 18 | }) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /npm/test/res.links.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('..'); 3 | var request = require('supertest'); 4 | 5 | describe('res', function(){ 6 | describe('.links(obj)', function(){ 7 | it('should set Link header field', function (done) { 8 | var app = express(); 9 | 10 | app.use(function (req, res) { 11 | res.links({ 12 | next: 'http://api.example.com/users?page=2', 13 | last: 'http://api.example.com/users?page=5' 14 | }); 15 | res.end(); 16 | }); 17 | 18 | request(app) 19 | .get('/') 20 | .expect('Link', '; rel="next", ; rel="last"') 21 | .expect(200, done); 22 | }) 23 | 24 | it('should set Link header field for multiple calls', function (done) { 25 | var app = express(); 26 | 27 | app.use(function (req, res) { 28 | res.links({ 29 | next: 'http://api.example.com/users?page=2', 30 | last: 'http://api.example.com/users?page=5' 31 | }); 32 | 33 | res.links({ 34 | prev: 'http://api.example.com/users?page=1' 35 | }); 36 | 37 | res.end(); 38 | }); 39 | 40 | request(app) 41 | .get('/') 42 | .expect('Link', '; rel="next", ; rel="last", ; rel="prev"') 43 | .expect(200, done); 44 | }) 45 | }) 46 | }) 47 | -------------------------------------------------------------------------------- /npm/test/res.locals.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('res', function(){ 6 | describe('.locals', function(){ 7 | it('should be empty by default', function(done){ 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | res.json(res.locals) 12 | }); 13 | 14 | request(app) 15 | .get('/') 16 | .expect(200, {}, done) 17 | }) 18 | }) 19 | 20 | it('should work when mounted', function(done){ 21 | var app = express(); 22 | var blog = express(); 23 | 24 | app.use(blog); 25 | 26 | blog.use(function(req, res, next){ 27 | res.locals.foo = 'bar'; 28 | next(); 29 | }); 30 | 31 | app.use(function(req, res){ 32 | res.json(res.locals) 33 | }); 34 | 35 | request(app) 36 | .get('/') 37 | .expect(200, { foo: 'bar' }, done) 38 | }) 39 | }) 40 | -------------------------------------------------------------------------------- /npm/test/res.sendStatus.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('..') 3 | var request = require('supertest') 4 | 5 | describe('res', function () { 6 | describe('.sendStatus(statusCode)', function () { 7 | it('should send the status code and message as body', function (done) { 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | res.sendStatus(201); 12 | }); 13 | 14 | request(app) 15 | .get('/') 16 | .expect(201, 'Created', done); 17 | }) 18 | 19 | it('should work with unknown code', function (done) { 20 | var app = express(); 21 | 22 | app.use(function(req, res){ 23 | res.sendStatus(599); 24 | }); 25 | 26 | request(app) 27 | .get('/') 28 | .expect(599, '599', done); 29 | }) 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /npm/test/res.status.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('res', function(){ 6 | describe('.status(code)', function(){ 7 | it('should set the response .statusCode', function(done){ 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | res.status(201).end('Created'); 12 | }); 13 | 14 | request(app) 15 | .get('/') 16 | .expect('Created') 17 | .expect(201, done); 18 | }) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /npm/test/res.type.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('../') 3 | , request = require('supertest'); 4 | 5 | describe('res', function(){ 6 | describe('.type(str)', function(){ 7 | it('should set the Content-Type based on a filename', function(done){ 8 | var app = express(); 9 | 10 | app.use(function(req, res){ 11 | res.type('foo.js').end('var name = "tj";'); 12 | }); 13 | 14 | request(app) 15 | .get('/') 16 | .expect('Content-Type', 'application/javascript; charset=utf-8') 17 | .end(done) 18 | }) 19 | 20 | it('should default to application/octet-stream', function(done){ 21 | var app = express(); 22 | 23 | app.use(function(req, res){ 24 | res.type('rawr').end('var name = "tj";'); 25 | }); 26 | 27 | request(app) 28 | .get('/') 29 | .expect('Content-Type', 'application/octet-stream', done); 30 | }) 31 | 32 | it('should set the Content-Type with type/subtype', function(done){ 33 | var app = express(); 34 | 35 | app.use(function(req, res){ 36 | res.type('application/vnd.amazon.ebook') 37 | .end('var name = "tj";'); 38 | }); 39 | 40 | request(app) 41 | .get('/') 42 | .expect('Content-Type', 'application/vnd.amazon.ebook', done); 43 | }) 44 | }) 45 | }) 46 | -------------------------------------------------------------------------------- /npm/test/res.vary.js: -------------------------------------------------------------------------------- 1 | 2 | var express = require('..'); 3 | var request = require('supertest'); 4 | var utils = require('./support/utils'); 5 | 6 | describe('res.vary()', function(){ 7 | describe('with no arguments', function(){ 8 | it('should not set Vary', function (done) { 9 | var app = express(); 10 | 11 | app.use(function (req, res) { 12 | res.vary(); 13 | res.end(); 14 | }); 15 | 16 | request(app) 17 | .get('/') 18 | .expect(utils.shouldNotHaveHeader('Vary')) 19 | .expect(200, done); 20 | }) 21 | }) 22 | 23 | describe('with an empty array', function(){ 24 | it('should not set Vary', function (done) { 25 | var app = express(); 26 | 27 | app.use(function (req, res) { 28 | res.vary([]); 29 | res.end(); 30 | }); 31 | 32 | request(app) 33 | .get('/') 34 | .expect(utils.shouldNotHaveHeader('Vary')) 35 | .expect(200, done); 36 | }) 37 | }) 38 | 39 | describe('with an array', function(){ 40 | it('should set the values', function (done) { 41 | var app = express(); 42 | 43 | app.use(function (req, res) { 44 | res.vary(['Accept', 'Accept-Language', 'Accept-Encoding']); 45 | res.end(); 46 | }); 47 | 48 | request(app) 49 | .get('/') 50 | .expect('Vary', 'Accept, Accept-Language, Accept-Encoding') 51 | .expect(200, done); 52 | }) 53 | }) 54 | 55 | describe('with a string', function(){ 56 | it('should set the value', function (done) { 57 | var app = express(); 58 | 59 | app.use(function (req, res) { 60 | res.vary('Accept'); 61 | res.end(); 62 | }); 63 | 64 | request(app) 65 | .get('/') 66 | .expect('Vary', 'Accept') 67 | .expect(200, done); 68 | }) 69 | }) 70 | 71 | describe('when the value is present', function(){ 72 | it('should not add it again', function (done) { 73 | var app = express(); 74 | 75 | app.use(function (req, res) { 76 | res.vary('Accept'); 77 | res.vary('Accept-Encoding'); 78 | res.vary('Accept-Encoding'); 79 | res.vary('Accept-Encoding'); 80 | res.vary('Accept'); 81 | res.end(); 82 | }); 83 | 84 | request(app) 85 | .get('/') 86 | .expect('Vary', 'Accept, Accept-Encoding') 87 | .expect(200, done); 88 | }) 89 | }) 90 | }) 91 | -------------------------------------------------------------------------------- /npm/test/support/env.js: -------------------------------------------------------------------------------- 1 | 2 | process.env.NODE_ENV = 'test'; 3 | process.env.NO_DEPRECATION = 'body-parser,express'; 4 | -------------------------------------------------------------------------------- /npm/test/support/tmpl.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | 3 | var variableRegExp = /\$([0-9a-zA-Z\.]+)/g; 4 | 5 | module.exports = function renderFile(fileName, options, callback) { 6 | function onReadFile(err, str) { 7 | if (err) { 8 | callback(err); 9 | return; 10 | } 11 | 12 | try { 13 | str = str.replace(variableRegExp, generateVariableLookup(options)); 14 | } catch (e) { 15 | err = e; 16 | err.name = 'RenderError' 17 | } 18 | 19 | callback(err, str); 20 | } 21 | 22 | fs.readFile(fileName, 'utf8', onReadFile); 23 | }; 24 | 25 | function generateVariableLookup(data) { 26 | return function variableLookup(str, path) { 27 | var parts = path.split('.'); 28 | var value = data; 29 | 30 | for (var i = 0; i < parts.length; i++) { 31 | value = value[parts[i]]; 32 | } 33 | 34 | return value; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /npm/test/support/utils.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | * @private 5 | */ 6 | 7 | var assert = require('assert'); 8 | var Buffer = require('safe-buffer').Buffer 9 | 10 | /** 11 | * Module exports. 12 | * @public 13 | */ 14 | 15 | exports.shouldHaveBody = shouldHaveBody 16 | exports.shouldNotHaveBody = shouldNotHaveBody 17 | exports.shouldNotHaveHeader = shouldNotHaveHeader; 18 | 19 | /** 20 | * Assert that a supertest response has a specific body. 21 | * 22 | * @param {Buffer} buf 23 | * @returns {function} 24 | */ 25 | 26 | function shouldHaveBody (buf) { 27 | return function (res) { 28 | var body = !Buffer.isBuffer(res.body) 29 | ? Buffer.from(res.text) 30 | : res.body 31 | assert.ok(body, 'response has body') 32 | assert.strictEqual(body.toString('hex'), buf.toString('hex')) 33 | } 34 | } 35 | 36 | /** 37 | * Assert that a supertest response does not have a body. 38 | * 39 | * @returns {function} 40 | */ 41 | 42 | function shouldNotHaveBody () { 43 | return function (res) { 44 | assert.ok(res.text === '' || res.text === undefined) 45 | } 46 | } 47 | 48 | /** 49 | * Assert that a supertest response does not have a header. 50 | * 51 | * @param {string} header Header name to check 52 | * @returns {function} 53 | */ 54 | function shouldNotHaveHeader(header) { 55 | return function (res) { 56 | assert.ok(!(header.toLowerCase() in res.headers), 'should not have header ' + header); 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /site/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["next", "next/core-web-vitals"] 3 | } 4 | -------------------------------------------------------------------------------- /site/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /site/README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | 15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. 16 | 17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`. 18 | 19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. 20 | 21 | ## Learn More 22 | 23 | To learn more about Next.js, take a look at the following resources: 24 | 25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 27 | 28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 29 | 30 | ## Deploy on Vercel 31 | 32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 33 | 34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 35 | -------------------------------------------------------------------------------- /site/components/Closing.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Image from 'next/image'; 3 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' 4 | import { faLinkedin, faGithub, faMedium } from '@fortawesome/free-brands-svg-icons' 5 | 6 | const Closing = () => { 7 | return ( 8 |
      9 |

      Featured In Tech Accelerator

      10 | 11 |
      12 | 13 | 14 | 15 |
      16 |
      17 | ) 18 | } 19 | 20 | export default Closing 21 | -------------------------------------------------------------------------------- /site/components/Description.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { motion } from 'framer-motion'; 3 | import Image from 'next/image'; 4 | import { Button } from 'react-bootstrap'; 5 | 6 | const Description = () => { 7 | return ( 8 |
      9 |
      10 | 11 |
      12 |
      13 |

      This is obServerJS

      14 |

      15 | obServerJS is the first backend debugging tool that allows developers to view the entire request and response lifecycle, along every routing and middleware function. 16 | Download our intuitively designed desktop application to have access to the expected response, a visual represention of the entire application stack (every possible route the response object can take in the server), 17 | and a testing suite to run multiple endpoints to check for errors. 18 |

      19 | 20 |
      21 |
      22 | ) 23 | } 24 | 25 | export default Description 26 | 27 | -------------------------------------------------------------------------------- /site/components/Header.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Nav, Navbar, NavbarBrand } from 'react-bootstrap'; 3 | import Image from 'next/image'; 4 | import { motion } from 'framer-motion'; 5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' 6 | import { faLinkedin, faGithub } from '@fortawesome/free-brands-svg-icons' 7 | import LinkTo from '../components/LinkTo'; 8 | import { Link } from '../routes'; 9 | 10 | const Header = () => { 11 | return ( 12 |
      13 | 14 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | 34 |
      35 | ) 36 | } 37 | 38 | export default Header 39 | -------------------------------------------------------------------------------- /site/components/Intro.js: -------------------------------------------------------------------------------- 1 | import React, { Component, useState, useEffect, useCallback } from 'react' 2 | import { motion } from 'framer-motion'; 3 | import Image from 'next/image'; 4 | import { Button } from 'react-bootstrap'; 5 | 6 | const Intro = () => { 7 | 8 | const names = ['Tweeting', 'Studying', 'Napping', 'Slacking', 'Tindering', 'Chatting', 'Coding', 'Snacking'] 9 | 10 | const [newName, setnewName] = useState(""); 11 | 12 | const shuffle = useCallback(() => { 13 | const index = Math.floor(Math.random() * names.length); 14 | setnewName(names[index]); 15 | }, []); 16 | useEffect(() => { 17 | const intervalID = setInterval(shuffle, 2000); 18 | return () => clearInterval(intervalID); 19 | }, [shuffle]) 20 | 21 | return ( 22 |
      23 |
      24 | Less Time Debugging 30 | More Time{` ${newName}`} 36 | 37 | 38 |

      obServerJS saves developers time and headaches by providing transparent express routing.

      39 |
      40 | 41 |
      42 | 55 | 56 |
      57 |
      58 | computer image 59 |
      60 |
      61 | ) 62 | } 63 | 64 | export default Intro 65 | -------------------------------------------------------------------------------- /site/components/Layout.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Head from 'next/head' 3 | import { Container } from 'semantic-ui-react'; 4 | import Header from './Header'; 5 | const Layout = (props) => { 6 | return ( 7 | 8 | 9 | ObServerJS 10 | 11 | 12 | 13 | 14 | 15 |
      16 | {props.children} 17 |

      © 2021 obServerJS. All Rights Reserved.

      18 | 19 | ) 20 | } 21 | 22 | export default Layout 23 | -------------------------------------------------------------------------------- /site/components/LinkTo.js: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | 3 | function LinkTo({ href, children, ...props }) { 4 | return ( 5 | 6 | {children} 7 | 8 | ); 9 | } 10 | 11 | export default LinkTo; -------------------------------------------------------------------------------- /site/next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | reactStrictMode: true, 3 | } 4 | -------------------------------------------------------------------------------- /site/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "observer-site", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@fortawesome/fontawesome-svg-core": "^1.2.35", 13 | "@fortawesome/free-brands-svg-icons": "^5.15.3", 14 | "@fortawesome/free-solid-svg-icons": "^5.15.3", 15 | "@fortawesome/react-fontawesome": "^0.1.14", 16 | "bootstrap": "^4.6.0", 17 | "bootstrap-react": "^0.5.0-alpha.14", 18 | "framer-motion": "^4.1.17", 19 | "history": "^5.0.0", 20 | "next": "11.0.1", 21 | "next-routes": "^1.4.2", 22 | "react": "17.0.2", 23 | "react-bootstrap": "^1.6.1", 24 | "react-dom": "17.0.2", 25 | "react-hook-form": "^7.11.0", 26 | "semantic-ui-react": "^2.0.3" 27 | }, 28 | "devDependencies": { 29 | "eslint": "7.30.0", 30 | "eslint-config-next": "11.0.1" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /site/pages/_app.js: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css' 2 | 3 | function MyApp({ Component, pageProps }) { 4 | return 5 | } 6 | 7 | export default MyApp 8 | -------------------------------------------------------------------------------- /site/pages/api/hello.js: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | 3 | export default function handler(req, res) { 4 | res.status(200).json({ name: 'John Doe' }) 5 | } 6 | -------------------------------------------------------------------------------- /site/pages/home/FeaturePage.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Feature from '../../components/Feature'; 3 | import Layout from '../../components/Layout'; 4 | const FeaturePage = () => { 5 | return ( 6 | 7 | 8 | 9 | ) 10 | } 11 | 12 | export default FeaturePage 13 | -------------------------------------------------------------------------------- /site/pages/home/TeamPage.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Layout from '../../components/Layout'; 3 | import Team from '../../components/Team'; 4 | import Contact from '../../components/Contact'; 5 | const TeamPage = () => { 6 | return ( 7 | 8 |
      9 | 10 |
      11 | 12 |
      13 | ) 14 | } 15 | 16 | export default TeamPage 17 | -------------------------------------------------------------------------------- /site/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Layout from '../components/Layout' 3 | import Intro from '../components/Intro'; 4 | import Description from '../components/Description'; 5 | import Feature from '../components/Feature'; 6 | import Team from '../components/Team'; 7 | import Closing from '../components/Closing'; 8 | import 'bootstrap/dist/css/bootstrap.min.css'; 9 | 10 | 11 | export default function Home() { 12 | 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /site/public/app-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/app-tree.png -------------------------------------------------------------------------------- /site/public/ashley.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/ashley.png -------------------------------------------------------------------------------- /site/public/code-block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/code-block.png -------------------------------------------------------------------------------- /site/public/comp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/comp.png -------------------------------------------------------------------------------- /site/public/dashboard1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/dashboard1.png -------------------------------------------------------------------------------- /site/public/eric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/eric.png -------------------------------------------------------------------------------- /site/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/favicon.ico -------------------------------------------------------------------------------- /site/public/grey-wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/grey-wave.png -------------------------------------------------------------------------------- /site/public/josh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/josh.png -------------------------------------------------------------------------------- /site/public/julia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/julia.png -------------------------------------------------------------------------------- /site/public/landing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/landing.png -------------------------------------------------------------------------------- /site/public/logo-eye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/logo-eye.png -------------------------------------------------------------------------------- /site/public/logo-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/logo-text.png -------------------------------------------------------------------------------- /site/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/logo.png -------------------------------------------------------------------------------- /site/public/logoText.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/logoText.png -------------------------------------------------------------------------------- /site/public/macbook-main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/macbook-main.png -------------------------------------------------------------------------------- /site/public/os-labs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/os-labs.png -------------------------------------------------------------------------------- /site/public/tech-wave-BackGround.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/obServerJS/7a7c72d594746a35d1c5c27973fd444cf086b94c/site/public/tech-wave-BackGround.png -------------------------------------------------------------------------------- /site/public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /site/routes.js: -------------------------------------------------------------------------------- 1 | const { route } = require('next/dist/next-server/server/router'); 2 | 3 | const routes = require('next-routes')(); 4 | 5 | //arg 1: pattern we want to look for 6 | //arg 2 what component do we want to show 7 | //add on another route mapping BEFORE for other edge cases like campaign/new (overrides) 8 | 9 | routes.add('/feature', '/home/FeaturePage'); 10 | routes.add('/team', '/home/TeamPage'); 11 | 12 | 13 | 14 | module.exports = routes; -------------------------------------------------------------------------------- /site/styles/Home.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | min-height: 100vh; 3 | padding: 0 0.5rem; 4 | display: flex; 5 | flex-direction: column; 6 | justify-content: center; 7 | align-items: center; 8 | height: 100vh; 9 | } 10 | 11 | .main { 12 | padding: 5rem 0; 13 | flex: 1; 14 | display: flex; 15 | flex-direction: column; 16 | justify-content: center; 17 | align-items: center; 18 | } 19 | 20 | .footer { 21 | width: 100%; 22 | height: 100px; 23 | border-top: 1px solid #eaeaea; 24 | display: flex; 25 | justify-content: center; 26 | align-items: center; 27 | } 28 | 29 | .footer a { 30 | display: flex; 31 | justify-content: center; 32 | align-items: center; 33 | flex-grow: 1; 34 | } 35 | 36 | .title a { 37 | color: #0070f3; 38 | text-decoration: none; 39 | } 40 | 41 | .title a:hover, 42 | .title a:focus, 43 | .title a:active { 44 | text-decoration: underline; 45 | } 46 | 47 | .title { 48 | margin: 0; 49 | line-height: 1.15; 50 | font-size: 4rem; 51 | } 52 | 53 | .title, 54 | .description { 55 | text-align: center; 56 | } 57 | 58 | .description { 59 | line-height: 1.5; 60 | font-size: 1.5rem; 61 | } 62 | 63 | .code { 64 | background: #fafafa; 65 | border-radius: 5px; 66 | padding: 0.75rem; 67 | font-size: 1.1rem; 68 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, 69 | Bitstream Vera Sans Mono, Courier New, monospace; 70 | } 71 | 72 | .grid { 73 | display: flex; 74 | align-items: center; 75 | justify-content: center; 76 | flex-wrap: wrap; 77 | max-width: 800px; 78 | margin-top: 3rem; 79 | } 80 | 81 | .card { 82 | margin: 1rem; 83 | padding: 1.5rem; 84 | text-align: left; 85 | color: inherit; 86 | text-decoration: none; 87 | border: 1px solid #eaeaea; 88 | border-radius: 10px; 89 | transition: color 0.15s ease, border-color 0.15s ease; 90 | width: 45%; 91 | } 92 | 93 | .card:hover, 94 | .card:focus, 95 | .card:active { 96 | color: #0070f3; 97 | border-color: #0070f3; 98 | } 99 | 100 | .card h2 { 101 | margin: 0 0 1rem 0; 102 | font-size: 1.5rem; 103 | } 104 | 105 | .card p { 106 | margin: 0; 107 | font-size: 1.25rem; 108 | line-height: 1.5; 109 | } 110 | 111 | .logo { 112 | height: 1em; 113 | margin-left: 0.5rem; 114 | } 115 | 116 | @media (max-width: 600px) { 117 | .grid { 118 | width: 100%; 119 | flex-direction: column; 120 | } 121 | } 122 | --------------------------------------------------------------------------------