mockaton 0.9.9 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,9 +5,7 @@ It scans `Config.mocksDir` for files following a specific directory
5
5
  and file name convention, which is similar to the URL paths. For
6
6
  example, the following file will be served for `/api/user/1234`
7
7
  ```
8
- -- api/
9
- |-- user/
10
- |-- [user-id].GET.200.json
8
+ my-mocks-dir/api/user/[user-id].GET.200.json
11
9
  ```
12
10
 
13
11
  By the way, [this browser
@@ -63,7 +61,7 @@ npm install mockaton
63
61
  Create a `my-mockaton.js` file
64
62
  ```js
65
63
  import { resolve } from 'node:path'
66
- import { Mockaton } from 'mockaton'
64
+ import { Mockaton } from 'src/Mockaton'
67
65
 
68
66
  Mockaton({ // Config options
69
67
  port: 2345,
@@ -86,16 +84,17 @@ interface Config {
86
84
  cookies?(): object
87
85
  database?: object // for "Transforms"
88
86
  skipOpen?: boolean // Prevents opening the dashboard in a browser
87
+ proxyFallback?: string // e.g. http://localhost:9999 For relaying routes without mocks
89
88
  allowedExt?: RegExp // /\.(json|txt|md|mjs)$/ Just for excluding temporary editor files (e.g. JetBrains appends a ~)
90
89
  }
91
90
  ```
92
91
 
93
92
  ## Cookies
94
93
  ```js
95
- import { jwtCookie } from 'mockaton'
94
+ import { jwtCookie } from 'src/Mockaton'
96
95
 
97
96
  Config.cookies = {
98
- 'My Admin User': 'my-cookie=1;Path=/;SameSite=strict',
97
+ 'My Admin User': 'my-cookie=1;Path=/;SameSite=strict',
99
98
  'My Normal User': 'my-cookie=0;Path=/;SameSite=strict',
100
99
  'My JWT': jwtCookie('my-cookie', {
101
100
  email: 'john.doe@example.com',
@@ -177,9 +176,9 @@ with `.mjs` will process the mock before serving it.
177
176
 
178
177
  For example, this handler will capitalize the mock body and increment a counter.
179
178
  ```js
180
- export default function capitalizeAllText(mockAsText, requestBody, Config) {
181
- Config.database.myCount ??= 0
182
- Config.database.myCount++
179
+ export default function capitalizeAllText(mockAsText, requestBody, config) {
180
+ config.database.myCount ??= 0
181
+ config.database.myCount++
183
182
  return mockAsText.toUpperCase()
184
183
  }
185
184
  ```
package/Tests.js CHANGED
@@ -3,13 +3,14 @@
3
3
  import { tmpdir } from 'node:os'
4
4
  import { dirname } from 'node:path'
5
5
  import { describe, it } from 'node:test'
6
+ import { createServer } from 'node:http'
6
7
  import { equal, deepEqual, match } from 'node:assert/strict'
7
8
  import { writeFileSync, mkdtempSync, mkdirSync } from 'node:fs'
8
9
 
9
- import { Route } from './Route.js'
10
- import { mimeFor } from './utils/mime.js'
11
- import { DP, DF } from './ApiConstants.js'
12
- import { Mockaton } from './Mockaton.js'
10
+ import { Route } from './src/Route.js'
11
+ import { mimeFor } from './src/utils/mime.js'
12
+ import { Mockaton } from './src/Mockaton.js'
13
+ import { DP, DF } from './src/ApiConstants.js'
13
14
 
14
15
 
15
16
  const tmpDir = mkdtempSync(tmpdir()) + '/'
@@ -98,17 +99,22 @@ writeStatic('index.html', '<h1>Static</h1>')
98
99
  writeStatic('assets/app.js', 'const app = 1')
99
100
  writeStatic('another-entry/index.html', '<h1>Another</h1>')
100
101
 
101
-
102
- const server = Mockaton({
103
- mocksDir: tmpDir,
104
- staticDir: staticTmpDir,
105
- skipOpen: true,
106
- cookies: {
107
- userA: 'CookieA',
108
- userB: 'CookieB'
109
- }
102
+ let server
103
+ const fallbackServer = createServer((_, response) => {
104
+ response.end('From_Fallback_Server')
105
+ }).listen(0, 'localhost', function () {
106
+ server = Mockaton({
107
+ mocksDir: tmpDir,
108
+ staticDir: staticTmpDir,
109
+ skipOpen: true,
110
+ cookies: {
111
+ userA: 'CookieA',
112
+ userB: 'CookieB'
113
+ },
114
+ proxyFallback: `http://localhost:${fallbackServer.address().port}`
115
+ })
116
+ server.on('listening', runTests)
110
117
  })
111
- server.on('listening', runTests)
112
118
 
113
119
  async function runTests() {
114
120
  await testItRendersDashboard()
@@ -157,7 +163,9 @@ async function runTests() {
157
163
  await testTransforms()
158
164
  await testStaticFileServing()
159
165
  await testInvalidFilenamesAreIgnored()
166
+ await testRouteWithoutMocksRelaysGetsProxied()
160
167
  server.close()
168
+ fallbackServer.close()
161
169
  }
162
170
 
163
171
  async function reset() {
@@ -350,6 +358,12 @@ async function testInvalidFilenamesAreIgnored() {
350
358
  })
351
359
  }
352
360
 
361
+ async function testRouteWithoutMocksRelaysGetsProxied() {
362
+ await it('Fallback relay', async () => {
363
+ const res = await request('/non-existing-mock')
364
+ equal(await res.text(), 'From_Fallback_Server')
365
+ })
366
+ }
353
367
 
354
368
  // Utils
355
369
 
package/index.d.ts CHANGED
@@ -11,6 +11,7 @@ interface Config {
11
11
 
12
12
  database?: object
13
13
  skipOpen?: boolean
14
+ proxyFallback?: string
14
15
  allowedExt?: RegExp
15
16
  }
16
17
 
package/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { Mockaton } from './Mockaton.js'
2
- export { jwtCookie } from './utils/jwt.js'
1
+ export { Mockaton } from './src/Mockaton.js'
2
+ export { jwtCookie } from './src/utils/jwt.js'
package/package.json CHANGED
@@ -2,13 +2,13 @@
2
2
  "name": "mockaton",
3
3
  "description": "A deterministic server-side for developing and testing frontend clients",
4
4
  "type": "module",
5
- "version": "0.9.9",
5
+ "version": "0.10.0",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "license": "MIT",
9
9
  "repository": "https://github.com/ericfortis/mockaton",
10
10
  "scripts": {
11
11
  "test": "./Tests.js",
12
- "demo": "_usage_example.js"
12
+ "demo": "./_usage_example.js"
13
13
  }
14
14
  }
@@ -11,6 +11,7 @@ export const Config = {
11
11
  cookies: {}, // defaults to the first kv
12
12
  database: {},
13
13
  skipOpen: false,
14
+ proxyFallback: '', // e.g. http://localhost:9999
14
15
  allowedExt: /\.(json|txt|md|mjs)$/ // Just for excluding temporary editor files (e.g. JetBrains appends a ~)
15
16
  }
16
17
 
@@ -25,6 +26,7 @@ export function setup(options) {
25
26
  cookies: is(Object),
26
27
  database: is(Object),
27
28
  skipOpen: is(Boolean),
29
+ proxyFallback: is(String),
28
30
  allowedExt: is(RegExp)
29
31
  })
30
32
  }
@@ -2,6 +2,7 @@ import { join } from 'node:path'
2
2
  import { readFileSync } from 'node:fs'
3
3
 
4
4
  import { DF } from './ApiConstants.js'
5
+ import { proxy } from './ProxyRelay.js'
5
6
  import { cookie } from './cookie.js'
6
7
  import { Config } from './Config.js'
7
8
  import { mimeFor } from './utils/mime.js'
@@ -19,10 +20,13 @@ export async function dispatchMock(req, response) {
19
20
 
20
21
  const broker = mockBrokerCollection.getBrokerForUrl(req.method, req.url)
21
22
  if (!broker) {
22
- sendNotFound(response)
23
+ if (Config.proxyFallback)
24
+ await proxy(req, response)
25
+ else
26
+ sendNotFound(response) // TESTME
23
27
  return
24
28
  }
25
-
29
+
26
30
  try {
27
31
  const { file, status, delay, currentTransform } = broker
28
32
  console.log('\n', req.url, '→\n ', file)
@@ -0,0 +1,11 @@
1
+ import { Config } from './Config.js'
2
+
3
+
4
+ export async function proxy(req, response) {
5
+ const proxyResponse = await fetch(Config.proxyFallback + req.url, {
6
+ method: req.method,
7
+ headers: req.headers
8
+ })
9
+ response.writeHead(proxyResponse.status, proxyResponse.headers)
10
+ response.end(await proxyResponse.text())
11
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes