Browse Source

move docs to wiki and examples to separate project

master
Lloyd Brookes 8 years ago
parent
commit
b888315783
  1. 1
      .travis.yml
  2. 72
      doc/api.md
  3. 9
      doc/blacklist.md
  4. 32
      doc/distribute.md
  5. 59
      doc/https.md
  6. BIN
      doc/img/logstagia.gif
  7. 69
      doc/logging.md
  8. 12
      doc/mime-types.md
  9. 241
      doc/mock-response.md
  10. 37
      doc/rewrite.md
  11. 12
      doc/spa.md
  12. 28
      doc/stored-config.md
  13. 56
      doc/visualisation.md
  14. 5
      example/built-in/forbid/.local-web-server.json
  15. 1
      example/built-in/forbid/admin/blocked.html
  16. 1
      example/built-in/forbid/allowed.html
  17. 5
      example/built-in/forbid/index.html
  18. 1
      example/built-in/forbid/something.php
  19. 5
      example/built-in/mime-override/.local-web-server.json
  20. 1
      example/built-in/mime-override/something.php
  21. 8
      example/built-in/mock-async/.local-web-server.json
  22. 11
      example/built-in/mock-async/mocks/delayed.js
  23. 58
      example/built-in/mock/.local-web-server.json
  24. 6
      example/built-in/mock/mocks/five.js
  25. 8
      example/built-in/mock/mocks/stream-self.js
  26. 41
      example/built-in/mock/mocks/user.js
  27. 32
      example/built-in/mock/mocks/users.js
  28. 5
      example/built-in/mock/mocks/users.json
  29. 37
      example/built-in/mock/mocks/users2.js
  30. 8
      example/built-in/rewrite/.local-web-server.json
  31. 4
      example/built-in/rewrite/build/styles/style.css
  32. 24
      example/built-in/rewrite/index.html
  33. 8
      example/built-in/rewrite/lws.config.js
  34. 7
      example/built-in/simple/css/style.css
  35. 10
      example/built-in/simple/index.html
  36. 7
      example/built-in/simple/package.json
  37. 4
      example/built-in/spa/.local-web-server.json
  38. 5
      example/built-in/spa/css/style.css
  39. BIN
      example/built-in/spa/image.jpg
  40. 14
      example/built-in/spa/index.html

1
.travis.yml

@ -1,3 +1,4 @@
language: node_js language: node_js
node_js: node_js:
- 7 - 7
- 8

72
doc/api.md

@ -1,72 +0,0 @@
## API Reference
* [local-web-server](#module_local-web-server)
* [LocalWebServer](#exp_module_local-web-server--LocalWebServer) ⇐ <code>module:middleware-stack</code>
* [new LocalWebServer([options])](#new_module_local-web-server--LocalWebServer_new)
* _instance_
* [.features](#module_local-web-server--LocalWebServer.LocalWebServer+features) : <code>Array.&lt;Feature&gt;</code>
* [.options](#module_local-web-server--LocalWebServer.LocalWebServer+options) : <code>object</code>
* [.view](#module_local-web-server--LocalWebServer.LocalWebServer+view) : <code>View</code>
* [.server](#module_local-web-server--LocalWebServer.LocalWebServer+server) : <code>Server</code>
* [.getApplication()](#module_local-web-server--LocalWebServer+getApplication) ⇒ <code>function</code>
* [.getServer()](#module_local-web-server--LocalWebServer+getServer) ⇒ <code>Server</code>
* _inner_
* [~loadStack()](#module_local-web-server--LocalWebServer..loadStack) ⇒ <code>object</code>
<a name="exp_module_local-web-server--LocalWebServer"></a>
### LocalWebServer ⇐ <code>module:middleware-stack</code>
**Kind**: Exported class
**Extends:** <code>module:middleware-stack</code>
<a name="new_module_local-web-server--LocalWebServer_new"></a>
#### new LocalWebServer([options])
**Params**
- [options] <code>object</code> - Server options
- .port} <code>number</code> - Port
- .stack} <code>Array.&lt;string&gt;</code> | <code>Array.&lt;Features&gt;</code> - Port
<a name="module_local-web-server--LocalWebServer.LocalWebServer+features"></a>
#### localWebServer.features : <code>Array.&lt;Feature&gt;</code>
Loaded feature modules
**Kind**: instance property of <code>[LocalWebServer](#exp_module_local-web-server--LocalWebServer)</code>
<a name="module_local-web-server--LocalWebServer.LocalWebServer+options"></a>
#### localWebServer.options : <code>object</code>
Config
**Kind**: instance property of <code>[LocalWebServer](#exp_module_local-web-server--LocalWebServer)</code>
<a name="module_local-web-server--LocalWebServer.LocalWebServer+view"></a>
#### localWebServer.view : <code>View</code>
Current view.
**Kind**: instance property of <code>[LocalWebServer](#exp_module_local-web-server--LocalWebServer)</code>
<a name="module_local-web-server--LocalWebServer.LocalWebServer+server"></a>
#### localWebServer.server : <code>Server</code>
Node.js server
**Kind**: instance property of <code>[LocalWebServer](#exp_module_local-web-server--LocalWebServer)</code>
<a name="module_local-web-server--LocalWebServer+getApplication"></a>
#### localWebServer.getApplication() ⇒ <code>function</code>
Returns a middleware application suitable for passing to `http.createServer`. The application is a function with three args (req, res and next) which can be created by express, Koa or hand-rolled.
**Kind**: instance method of <code>[LocalWebServer](#exp_module_local-web-server--LocalWebServer)</code>
<a name="module_local-web-server--LocalWebServer+getServer"></a>
#### localWebServer.getServer() ⇒ <code>Server</code>
Returns a listening server which processes requests using the middleware supplied.
**Kind**: instance method of <code>[LocalWebServer](#exp_module_local-web-server--LocalWebServer)</code>
<a name="module_local-web-server--LocalWebServer..loadStack"></a>
#### LocalWebServer~loadStack() ⇒ <code>object</code>
Loads a module by either path or name.
**Kind**: inner method of <code>[LocalWebServer](#exp_module_local-web-server--LocalWebServer)</code>

9
doc/blacklist.md

@ -1,9 +0,0 @@
## Access Control
By default, access to all files is allowed (including dot files). Use `--forbid` to establish a blacklist:
```sh
$ ws --forbid '*.json' '*.yml'
serving at http://localhost:8000
```
[Example](https://github.com/lwsjs/local-web-server/tree/master/example/forbid).

32
doc/distribute.md

@ -1,32 +0,0 @@
## Distribute with your project
The standard convention with client-server applications is to add an `npm start` command to launch the server component.
1\. Install the server as a dev dependency
```sh
$ npm install local-web-server --save-dev
```
2\. Add a `start` command to your `package.json`:
```json
{
"name": "example",
"version": "1.0.0",
"local-web-server": {
"port": 8100,
"forbid": "*.json"
},
"scripts": {
"start": "ws"
}
}
```
3\. Document how to build and launch your site
```sh
$ npm install
$ npm start
serving at http://localhost:8100
```

59
doc/https.md

@ -1,59 +0,0 @@
## HTTPS Server
Some modern techs (ServiceWorker, any `MediaDevices.getUserMedia()` request etc.) *must* be served from a secure origin (HTTPS). To launch an HTTPS server, supply a `--key` and `--cert` to local-web-server, for example:
```
$ ws --key localhost.key --cert localhost.crt
```
If you don't have a key and certificate it's trivial to create them. You do not need third-party verification (Verisign etc.) for development purposes. To get the green padlock in the browser, the certificate..
* must have a `Common Name` value matching the FQDN of the server
* must be verified by a Certificate Authority (but we can overrule this - see below)
First create a certificate:
1. Install openssl.
`$ brew install openssl`
2. Generate a RSA private key.
`$ openssl genrsa -des3 -passout pass:x -out ws.pass.key 2048`
3. Create RSA key.
```
$ openssl rsa -passin pass:x -in ws.pass.key -out ws.key
```
4. Create certificate request. The command below will ask a series of questions about the certificate owner. The most imporant answer to give is for `Common Name`, you can accept the default values for the others. **Important**: you **must** input your server's correct FQDN (`dev-server.local`, `laptop.home` etc.) into the `Common Name` field. The cert is only valid for the domain specified here. You can find out your computers host name by running the command `hostname`. For example, mine is `mba3.home`.
`$ openssl req -new -key ws.key -out ws.csr`
5. Generate self-signed certificate.
`$ openssl x509 -req -days 365 -in ws.csr -signkey ws.key -out ws.crt`
6. Clean up files we're finished with
`$ rm ws.pass.key ws.csr`
7. Launch HTTPS server. In iTerm, control-click the first URL (with the hostname matching `Common Name`) to launch your browser.
```
$ ws --key ws.key --cert ws.crt
serving at https://mba3.home:8010, https://127.0.0.1:8010, https://192.168.1.203:8010
```
Chrome and Firefox will still complain your certificate has not been verified by a Certificate Authority. Firefox will offer you an `Add an exception` option, allowing you to ignore the warning and manually mark the certificate as trusted. In Chrome on Mac, you can manually trust the certificate another way:
1. Open Keychain
2. Click File -> Import. Select the `.crt` file you created.
3. In the `Certificates` category, double-click the cert you imported.
4. In the `trust` section, underneath `when using this certificate`, select `Always Trust`.
Now you have a valid, trusted certificate for development.
### Built-in certificate
As a quick win, you can run `ws` with the `https` flag. This will launch an HTTPS server using a [built-in certificate](https://github.com/lwsjs/local-web-server/tree/master/ssl) registered to the domain 127.0.0.1.

BIN
doc/img/logstagia.gif

Before

Width: 700  |  Height: 360  |  Size: 570 KiB

69
doc/logging.md

@ -1,69 +0,0 @@
# Logging
By default, local-web-server outputs a simple, dynamic statistics view. To see traditional web server logs, use `--log.format`:
```sh
$ ws --log.format combined
serving at http://localhost:8000
::1 - - [16/Nov/2015:11:16:52 +0000] "GET / HTTP/1.1" 200 12290 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2562.0 Safari/537.36"
```
The format value supplied is passed directly to [morgan](https://github.com/expressjs/morgan). The exception is `--log.format none` which disables all output.
# Visualisation
## Goaccess
To get live statistics in [goaccess](http://goaccess.io/), first create this config file at `~/.goaccessrc`:
```
time-format %T
date-format %d/%b/%Y
log.format %h %^[%d:%t %^] "%r" %s %b "%R" "%u"
```
Then, start the server, outputting `combined` format logs to disk:
```sh
$ ws -f combined > web.log
```
In a separate tab, point goaccess at `web.log` and it will display statistics in real time:
```
$ goaccess -p ~/.goaccessrc -f web.log
```
## Logstalgia
local-web-server is compatible with [logstalgia](http://code.google.com/p/logstalgia/).
### Install Logstalgia
On MacOSX, install with [homebrew](http://brew.sh):
```sh
$ brew install logstalgia
```
Alternatively, [download a release for your system from github](https://github.com/acaudwell/Logstalgia/releases/latest).
Then pipe the `logstalgia` output format directly into logstalgia for real-time visualisation:
```sh
$ ws -f logstalgia | logstalgia -
```
![local-web-server with logstalgia](https://raw.githubusercontent.com/lwsjs/local-web-server/master/doc/img/logstagia.gif)
## glTail
To use with [glTail](http://www.fudgie.org), write your log to disk using the "default" format:
```sh
$ ws -f default > web.log
```
Then specify this file in your glTail config:
```yaml
servers:
dev:
host: localhost
source: local
files: /Users/Lloyd/Documents/MySite/web.log
parser: apache
color: 0.2, 0.2, 1.0, 1.0
```

12
doc/mime-types.md

@ -1,12 +0,0 @@
## mime-types
You can set additional mime-type/extension mappings, or override the defaults by setting a `mime` value in the stored config. This value is passed directly to [mime.define()](https://github.com/broofa/node-mime#mimedefine). Example:
```json
{
"mime": {
"text/plain": [ "php", "pl" ]
}
}
```
[Example](https://github.com/lwsjs/local-web-server/tree/master/example/mime-override).

241
doc/mock-response.md

@ -1,241 +0,0 @@
## Mock Responses
Mocks give you full control over the response headers and body returned to the client. They can be used to return anything from a simple html string to a resourceful REST API. Typically, they're used to mock services but can be used for anything.
In the config, define an array called `mocks`. Each mock definition maps a <code>[route](http://expressjs.com/guide/routing.html#route-paths)</code> to a `response`. A simple home page:
```json
{
"mocks": [
{
"route": "/",
"response": {
"body": "<h1>Welcome to the Mock Responses example</h1>"
}
}
]
}
```
Under the hood, the property values from the `response` object are written onto the underlying [koa response object](https://github.com/koajs/koa/blob/master/docs/api/response.md). You can set any valid koa response properies, for example [type](https://github.com/koajs/koa/blob/master/docs/api/response.md#responsetype-1):
```json
{
"mocks": [
{
"route": "/",
"response": {
"type": "text/plain",
"body": "<h1>Welcome to the Mock Responses example</h1>"
}
}
]
}
```
### Conditional Response
To define a conditional response, set a `request` object on the mock definition. The `request` value acts as a query - the response defined will only be returned if each property of the `request` query matches. For example, return an XML response *only* if the request headers include `accept: application/xml`, else return 404 Not Found.
```json
{
"mocks": [
{
"route": "/two",
"request": { "accepts": "xml" },
"response": {
"body": "<result id='2' name='whatever' />"
}
}
]
}
```
### Multiple Potential Responses
To specify multiple potential responses, set an array of mock definitions to the `responses` property. The first response with a matching request query will be sent. In this example, the client will get one of two responses depending on the request method:
```json
{
"mocks": [
{
"route": "/three",
"responses": [
{
"request": { "method": "GET" },
"response": {
"body": "<h1>Mock response for 'GET' request on /three</h1>"
}
},
{
"request": { "method": "POST" },
"response": {
"status": 400,
"body": { "message": "That method is not allowed." }
}
}
]
}
]
}
```
### Dynamic Response
The examples above all returned static data. To define a dynamic response, create a mock module. Specify its path in the `module` property:
```json
{
"mocks": [
{
"route": "/four",
"module": "/mocks/stream-self.js"
}
]
}
```
Here's what the `stream-self` module looks like. The module should export a mock definition (an object, or array of objects, each with a `response` and optional `request`). In this example, the module simply streams itself to the response but you could set `body` to *any* [valid value](https://github.com/koajs/koa/blob/master/docs/api/response.md#responsebody-1).
```js
const fs = require('fs')
module.exports = {
response: {
body: fs.createReadStream(__filename)
}
}
```
### Response function
For more power, define the response as a function. It will receive the [koa context](https://github.com/koajs/koa/blob/master/docs/api/context.md) as its first argument. Now you have full programmatic control over the response returned.
```js
module.exports = {
response: function (ctx) {
ctx.body = '<h1>I can do anything i want.</h1>'
}
}
```
If the route contains tokens, their values are passed to the response. For example, with this mock...
```json
{
"mocks": [
{
"route": "/players/:id",
"module": "/mocks/players.js"
}
]
}
```
...the `id` value is passed to the `response` function. For example, a path of `/players/10?name=Lionel` would pass `10` to the response function. Additional, the value `Lionel` would be available on `ctx.query.name`:
```js
module.exports = {
response: function (ctx, id) {
ctx.body = `<h1>id: ${id}, name: ${ctx.query.name}</h1>`
}
}
```
### RESTful Resource example
Here's an example of a REST collection (users). We'll create two routes, one for actions on the resource collection, one for individual resource actions.
```json
{
"mocks": [
{ "route": "/users", "module": "/mocks/users.js" },
{ "route": "/users/:id", "module": "/mocks/user.js" }
]
}
```
Define a module (`users.json`) defining seed data:
```json
[
{ "id": 1, "name": "Lloyd", "age": 40, "nationality": "English" },
{ "id": 2, "name": "Mona", "age": 34, "nationality": "Palestinian" },
{ "id": 3, "name": "Francesco", "age": 24, "nationality": "Italian" }
]
```
The collection module:
```js
const users = require('./users.json')
/* responses for /users */
const mockResponses = [
/* Respond with 400 Bad Request for PUT and DELETE - inappropriate on a collection */
{ request: { method: 'PUT' }, response: { status: 400 } },
{ request: { method: 'DELETE' }, response: { status: 400 } },
{
/* for GET requests return a subset of data, optionally filtered on 'minAge' and 'nationality' */
request: { method: 'GET' },
response: function (ctx) {
ctx.body = users.filter(user => {
const meetsMinAge = (user.age || 1000) >= (Number(ctx.query.minAge) || 0)
const requiredNationality = user.nationality === (ctx.query.nationality || user.nationality)
return meetsMinAge && requiredNationality
})
}
},
{
/* for POST requests, create a new user and return the path to the new resource */
request: { method: 'POST' },
response: function (ctx) {
const newUser = ctx.request.body
users.push(newUser)
newUser.id = users.length
ctx.status = 201
ctx.response.set('Location', `/users/${newUser.id}`)
}
}
]
module.exports = mockResponses
```
The individual resource module:
```js
const users = require('./users.json')
/* responses for /users/:id */
const mockResponses = [
/* don't support POST here */
{ request: { method: 'POST' }, response: { status: 400 } },
/* for GET requests, return a particular user */
{
request: { method: 'GET' },
response: function (ctx, id) {
ctx.body = users.find(user => user.id === Number(id))
}
},
/* for PUT requests, update the record */
{
request: { method: 'PUT' },
response: function (ctx, id) {
const updatedUser = ctx.request.body
const existingUserIndex = users.findIndex(user => user.id === Number(id))
users.splice(existingUserIndex, 1, updatedUser)
ctx.status = 200
}
},
/* DELETE request: remove the record */
{
request: { method: 'DELETE' },
response: function (ctx, id) {
const existingUserIndex = users.findIndex(user => user.id === Number(id))
users.splice(existingUserIndex, 1)
ctx.status = 200
}
}
]
module.exports = mockResponses
```
[Example](https://github.com/lwsjs/local-web-server/tree/master/example/mock).

37
doc/rewrite.md

@ -1,37 +0,0 @@
## URL rewriting
Your application requested `/css/style.css` but it's stored at `/build/css/style.css`. To avoid a 404 you need a rewrite rule:
```sh
$ ws --rewrite '/css/style.css -> /build/css/style.css'
```
Or, more generally (matching any stylesheet under `/css`):
```sh
$ ws --rewrite '/css/:stylesheet -> /build/css/:stylesheet'
```
With a deep CSS directory structure it may be easier to mount the entire contents of `/build/css` to the `/css` path:
```sh
$ ws --rewrite '/css/* -> /build/css/$1'
```
this rewrites `/css/a` as `/build/css/a`, `/css/a/b/c` as `/build/css/a/b/c` etc.
### Proxied requests
If the `to` URL contains a remote host, local-web-server will act as a proxy - fetching and responding with the remote resource.
Mount the npm registry locally:
```sh
$ ws --rewrite '/npm/* -> http://registry.npmjs.org/$1'
```
Map local requests for repo data to the Github API:
```sh
$ ws --rewrite '/:user/repos/:name -> https://api.github.com/repos/:user/:name'
```
[Example](https://github.com/lwsjs/local-web-server/tree/master/example/rewrite).

12
doc/spa.md

@ -1,12 +0,0 @@
## Single Page Application
You're building a web app with client-side routing, so mark `index.html` as the SPA.
```sh
$ ws --spa index.html
```
By default, typical SPA paths (e.g. `/user/1`, `/login`) would return `404 Not Found` as a file does not exist with that path. By marking `index.html` as the SPA you create this rule:
*If a static file at the requested path exists (e.g. `/css/style.css`) then serve it, if it does not (e.g. `/login`) then serve the specified SPA and handle the route client-side.*
[Example](https://github.com/lwsjs/local-web-server/tree/master/example/spa).

28
doc/stored-config.md

@ -1,28 +0,0 @@
## Stored config
Use the same options every time? Persist then to `package.json`:
```json
{
"name": "example",
"version": "1.0.0",
"local-web-server": {
"port": 8100,
"forbid": "*.json"
}
}
```
or `.local-web-server.json`
```json
{
"port": 8100,
"forbid": "*.json"
}
```
local-web-server will merge and use all config found, searching from the current directory upward. In the case both `package.json` and `.local-web-server.json` config is found in the same directory, `.local-web-server.json` will take precedence. Options set on the command line take precedence over all.
To inspect stored config, run:
```sh
$ ws --config
```

56
doc/visualisation.md

@ -1,56 +0,0 @@
## Goaccess
To get live statistics in [goaccess](http://goaccess.io/), first create this config file at `~/.goaccessrc`:
```
time-format %T
date-format %d/%b/%Y
log.format %h %^[%d:%t %^] "%r" %s %b "%R" "%u"
```
Then, start the server, outputting `combined` format logs to disk:
```sh
$ ws -f combined > web.log
```
In a separate terminal, point goaccess at `web.log` and it will display statistics in real time:
```
$ goaccess -p ~/.goaccessrc -f web.log
```
## Logstalgia
local-web-server is compatible with [logstalgia](http://code.google.com/p/logstalgia/).
### Install Logstalgia
On MacOSX, install with [homebrew](http://brew.sh):
```sh
$ brew install logstalgia
```
Alternatively, [download a release for your system from github](https://github.com/acaudwell/Logstalgia/releases/latest).
Then pipe the `logstalgia` output format directly into logstalgia for real-time visualisation:
```sh
$ ws -f logstalgia | logstalgia -
```
![local-web-server with logstalgia](https://raw.githubusercontent.com/lwsjs/local-web-server/master/doc/img/logstagia.gif)
## glTail
To use with [glTail](http://www.fudgie.org), write your log to disk using the "default" format:
```sh
$ ws -f default > web.log
```
Then specify this file in your glTail config:
```yaml
servers:
dev:
host: localhost
source: local
files: /Users/Lloyd/Documents/MySite/web.log
parser: apache
color: 0.2, 0.2, 1.0, 1.0
```

5
example/built-in/forbid/.local-web-server.json

@ -1,5 +0,0 @@
{
"forbid": [
"/admin/*", "*.php"
]
}

1
example/built-in/forbid/admin/blocked.html

@ -1 +0,0 @@
<h1>Forbidden page</h1>

1
example/built-in/forbid/allowed.html

@ -1 +0,0 @@
<h1>A permitted page</h1>

5
example/built-in/forbid/index.html

@ -1,5 +0,0 @@
<h1>Forbidden routes</h1>
<p>
Notice you can access <a href="allowed.html">this page</a>, but not <a href="admin/blocked.html">this admin page</a> or <a href="something.php">php file</a>.
</p>

1
example/built-in/forbid/something.php

@ -1 +0,0 @@
<?php echo "i'm coding PHP templatez!\n" ?>

5
example/built-in/mime-override/.local-web-server.json

@ -1,5 +0,0 @@
{
"mime": {
"text/plain": [ "php" ]
}
}

1
example/built-in/mime-override/something.php

@ -1 +0,0 @@
<?php echo "i'm coding PHP templatez!\n" ?>

8
example/built-in/mock-async/.local-web-server.json

@ -1,8 +0,0 @@
{
"mocks": [
{
"route": "/",
"module": "/mocks/delayed.js"
}
]
}

11
example/built-in/mock-async/mocks/delayed.js

@ -1,11 +0,0 @@
module.exports = {
name: 'delayed response',
response: function (ctx) {
return new Promise((resolve, reject) => {
setTimeout(() => {
ctx.body = '<h1>You waited 2s for this</h1>'
resolve()
}, 2000)
})
}
}

58
example/built-in/mock/.local-web-server.json

@ -1,58 +0,0 @@
{
"mocks": [
{
"route": "/",
"response": {
"body": "<h1>Welcome to the Mock Responses example</h1>"
}
},
{
"route": "/one",
"response": {
"type": "text/plain",
"body": "<h1>Welcome to the Mock Responses example</h1>"
}
},
{
"route": "/two",
"request": { "accepts": "xml" },
"response": {
"body": "<result id='2' name='whatever' />"
}
},
{
"route": "/three",
"responses": [
{
"request": { "method": "GET" },
"response": {
"body": "<h1>Mock response for 'GET' request on /three</h1>"
}
},
{
"request": { "method": "POST" },
"response": {
"status": 400,
"body": { "message": "That method is not allowed." }
}
}
]
},
{
"route": "/stream",
"module": "/mocks/stream-self.js"
},
{
"route": "/five/:id",
"module": "/mocks/five.js"
},
{
"route": "/users",
"module": "/mocks/users.js"
},
{
"route": "/users/:id",
"module": "/mocks/user.js"
}
]
}

6
example/built-in/mock/mocks/five.js

@ -1,6 +0,0 @@
module.exports = {
name: '/five/:id?name=:name',
response: function (ctx, id) {
ctx.body = `<h1>id: ${id}, name: ${ctx.query.name}</h1>`
}
}

8
example/built-in/mock/mocks/stream-self.js

@ -1,8 +0,0 @@
const fs = require('fs')
module.exports = {
name: 'stream response',
response: {
body: fs.createReadStream(__filename)
}
}

41
example/built-in/mock/mocks/user.js

@ -1,41 +0,0 @@
const users = require('./users.json')
/* responses for /users/:id */
const mockResponses = [
/* don't support POST here */
{ request: { method: 'POST' }, response: { status: 400 } },
/* for GET requests, return a particular user */
{
name: 'GET user',
request: { method: 'GET' },
response: function (ctx, id) {
ctx.body = users.find(user => user.id === Number(id))
}
},
/* for PUT requests, update the record */
{
name: 'PUT user',
request: { method: 'PUT' },
response: function (ctx, id) {
const updatedUser = ctx.request.body
const existingUserIndex = users.findIndex(user => user.id === Number(id))
users.splice(existingUserIndex, 1, updatedUser)
ctx.status = 200
}
},
/* DELETE request: remove the record */
{
name: 'DELETE user',
request: { method: 'DELETE' },
response: function (ctx, id) {
const existingUserIndex = users.findIndex(user => user.id === Number(id))
users.splice(existingUserIndex, 1)
ctx.status = 200
}
}
]
module.exports = mockResponses

32
example/built-in/mock/mocks/users.js

@ -1,32 +0,0 @@
const users = require('./users.json')
/* responses for /users */
const mockResponses = [
/* Respond with 400 Bad Request for PUT and DELETE - inappropriate on a collection */
{ request: { method: 'PUT' }, response: { status: 400 } },
{ request: { method: 'DELETE' }, response: { status: 400 } },
{
/* for GET requests return a subset of data, optionally filtered on 'minAge' and 'nationality' */
request: { method: 'GET' },
response: function (ctx) {
ctx.body = users.filter(user => {
const meetsMinAge = (user.age || 1000) >= (Number(ctx.query.minAge) || 0)
const requiredNationality = user.nationality === (ctx.query.nationality || user.nationality)
return meetsMinAge && requiredNationality
})
}
},
{
/* for POST requests, create a new user and return the path to the new resource */
request: { method: 'POST' },
response: function (ctx) {
const newUser = ctx.request.body
users.push(newUser)
newUser.id = users.length
ctx.status = 201
ctx.response.set('Location', `/users/${newUser.id}`)
}
}
]
module.exports = mockResponses

5
example/built-in/mock/mocks/users.json

@ -1,5 +0,0 @@
[
{ "id": 1, "name": "Lloyd", "age": 40, "nationality": "English" },
{ "id": 2, "name": "Mona", "age": 34, "nationality": "Palestinian" },
{ "id": 3, "name": "Francesco", "age": 24, "nationality": "Italian" }
]

37
example/built-in/mock/mocks/users2.js

@ -1,37 +0,0 @@
const users = require('./users.json')
/* responses for /users */
const userResponses = [
{
route: '/users',
responses: [
/* Respond with 400 Bad Request for PUT and DELETE - inappropriate on a collection */
{ request: { method: 'PUT' }, response: { status: 400 } },
{ request: { method: 'DELETE' }, response: { status: 400 } },
{
/* for GET requests return a subset of data, optionally filtered on 'minAge' and 'nationality' */
request: { method: 'GET' },
response: function (ctx) {
ctx.body = users.filter(user => {
const meetsMinAge = (user.age || 1000) >= (Number(ctx.query.minAge) || 0)
const requiredNationality = user.nationality === (ctx.query.nationality || user.nationality)
return meetsMinAge && requiredNationality
})
}
},
{
/* for POST requests, create a new user and return the path to the new resource */
request: { method: 'POST' },
response: function (ctx) {
const newUser = ctx.request.body
users.push(newUser)
newUser.id = users.length
ctx.status = 201
ctx.response.set('Location', `/users/${newUser.id}`)
}
}
]
}
]
module.exports = userResponses

8
example/built-in/rewrite/.local-web-server.json

@ -1,8 +0,0 @@
{
"rewrite": [
{ "from": "/css/*", "to": "/build/styles/$1" },
{ "from": "/npm/*", "to": "http://registry.npmjs.org/$1" },
{ "from": "/broken/*", "to": "http://localhost:9999" },
{ "from": "/:user/repos/:name", "to": "https://api.github.com/repos/:user/:name" }
]
}

4
example/built-in/rewrite/build/styles/style.css

@ -1,4 +0,0 @@
body {
font-family: monospace;
font-size: 1.3em;
}

24
example/built-in/rewrite/index.html

@ -1,24 +0,0 @@
<head>
<link rel="stylesheet" href="css/style.css">
</head>
<h1>Rewriting paths</h1>
<h2>Config</h2>
<pre><code>
{
"rewrite": [
{ "from": "/css/*", "to": "/build/styles/$1" },
{ "from": "/npm/*", "to": "http://registry.npmjs.org/$1" },
{ "from": "/broken/*", "to": "http://localhost:9999" },
{ "from": "/:user/repos/:name", "to": "https://api.github.com/repos/:user/:name" }
]
}
</code></pre>
<h2>Links</h2>
<ul>
<li><a href="/css/style.css">/css/style.css</li>
<li><a href="/npm/local-web-server">/npm/local-web-server</a></li>
<li><a href="/broken/">/broken/</a></li>
<li><a href="/75lb/repos/work">/75lb/repos/work</a></li>
</ul>

8
example/built-in/rewrite/lws.config.js

@ -1,8 +0,0 @@
module.exports = {
rewrite: [
{ from: '/css/*', 'to': '/build/styles/$1' },
{ from: '/npm/*', 'to': 'http://registry.npmjs.org/$1' },
{ from: '/broken/*', 'to': 'http://localhost:9999' },
{ from: '/:user/repos/:name', 'to': 'https://api.github.com/repos/:user/:name' }
]
}

7
example/built-in/simple/css/style.css

@ -1,7 +0,0 @@
body {
background-color: #AA3939;
color: #FFE2E2
}
svg {
fill: #000
}

10
example/built-in/simple/index.html

@ -1,10 +0,0 @@
<head>
<link rel="stylesheet" href="css/style.css">
</head>
<h1>Amazing Page</h1>
<p>
With a freaky triangle..
</p>
<svg width="500" height="500">
<polygon points="250,0 0,500 500,500"></polygon>
</svg>

7
example/built-in/simple/package.json

@ -1,7 +0,0 @@
{
"name": "example",
"version": "1.0.0",
"local-web-server": {
"port": 8100
}
}

4
example/built-in/spa/.local-web-server.json

@ -1,4 +0,0 @@
{
"spa": "index.html",
"no-cache": true
}

5
example/built-in/spa/css/style.css

@ -1,5 +0,0 @@
body {
background-color: IndianRed;
}
a { color: black }

BIN
example/built-in/spa/image.jpg

Before

Width: 91  |  Height: 71  |  Size: 2.3 KiB

14
example/built-in/spa/index.html

@ -1,14 +0,0 @@
<head>
<link rel="stylesheet" href="/css/style.css">
</head>
<h1>Single Page App</h1>
<h2>Location: <span></span></h2>
<ul>
<li><a href="/login">/login</a></li>
<li><a href="/search">/search</a></li>
</ul>
<p>Found asset: <img src="image.jpg" /></p>
<p>Missing asset (should 404): <img src="sdafsadf.jpg" /></p>
<script>
document.querySelector('h2 span').textContent = window.location.pathname
</script>
Loading…
Cancel
Save