mockaton 13.14.0 → 13.15.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 +13 -8
- package/index.d.ts +1 -2
- package/package.json +1 -1
- package/src/server/Mockaton.js +3 -6
- package/src/server/Mockaton.test.js +1 -4
- package/src/server/stores/config.js +0 -1
- package/src/server/utils/resolveBypassImportCache.js +21 -0
- package/src/server/resolveBypassImportCache.js +0 -19
- /package/src/server/{resolveExtensionless.js → utils/resolveExtensionless.js} +0 -0
package/README.md
CHANGED
|
@@ -8,20 +8,22 @@
|
|
|
8
8
|
|
|
9
9
|
*No API state should be too difficult to test*
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### [Docs](https://mockaton.com) | [Changelog](https://mockaton.com/changelog) | [Skills](skills/mockaton/SKILL.md) | [Use Cases](https://mockaton.com/use-cases)
|
|
12
12
|
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
Mockaton is a local HTTP mock server. With it, you can test API states
|
|
16
|
+
that are difficult to reproduce from an actual backend.
|
|
17
|
+
|
|
18
|
+
For example, to quickly trigger an error on an endpoint, click the 500 button.
|
|
19
|
+
Then, unclick it to test your retry logic.
|
|
13
20
|
|
|
14
|
-
Simulate API states that are normally ignored. For example, quickly trigger an error on
|
|
15
|
-
an endpoint by clicking the 500 button. Then, unclick it to test your retry logic.
|
|
16
21
|
Similarly, pick a mock variant from the dropdown, say to respond with a 423 (locked account).
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
their animation midway.
|
|
22
|
+
|
|
23
|
+
Or click the clock button 🕓 to delay a response so you can test spinners.
|
|
20
24
|
|
|
21
25
|
|
|
22
26
|
## Dashboard
|
|
23
|
-
Besides the dashboard UI, there’s a [programmatic API](https://mockaton.com/api),
|
|
24
|
-
which is handy for setting up tests.
|
|
25
27
|
|
|
26
28
|
<picture>
|
|
27
29
|
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/ericfortis/mockaton/refs/heads/main/pixaton-tests/tests/macos/pic-for-readme.vp762x762.light.gold.png">
|
|
@@ -29,6 +31,9 @@ which is handy for setting up tests.
|
|
|
29
31
|
<img alt="Mockaton Dashboard" src="https://raw.githubusercontent.com/ericfortis/mockaton/refs/heads/main/pixaton-tests/tests/macos/pic-for-readme.vp762x762.dark.gold.png">
|
|
30
32
|
</picture>
|
|
31
33
|
|
|
34
|
+
Besides the dashboard, there’s a [programmatic API](https://mockaton.com/api),
|
|
35
|
+
which is handy for setting up tests.
|
|
36
|
+
|
|
32
37
|
|
|
33
38
|
## Demo (Docker)
|
|
34
39
|
This will spin up Mockaton with the [sample directory](./mockaton-mocks)
|
package/index.d.ts
CHANGED
|
@@ -46,7 +46,6 @@ export declare interface Config {
|
|
|
46
46
|
onReady?: (address: string) => void
|
|
47
47
|
|
|
48
48
|
hotReload?: boolean // For UI dev purposes only
|
|
49
|
-
bypassImportCache?: boolean
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
|
|
@@ -102,4 +101,4 @@ declare global {
|
|
|
102
101
|
}
|
|
103
102
|
}
|
|
104
103
|
|
|
105
|
-
export type { JsonPromise, ClientMockBroker, ClientBrokersByMethod, State }
|
|
104
|
+
export type { JsonPromise, ClientMockBroker, ClientBrokersByMethod, State }
|
package/package.json
CHANGED
package/src/server/Mockaton.js
CHANGED
|
@@ -8,6 +8,8 @@ import { ServerResponse } from './utils/HttpServerResponse.js'
|
|
|
8
8
|
import { setCorsHeaders, isPreflight } from './utils/http-cors.js'
|
|
9
9
|
import { IncomingMessage } from './utils/HttpIncomingMessage.js'
|
|
10
10
|
import { watchDevSPA } from './utils/WatcherDevClient.js'
|
|
11
|
+
import { resolveExtensionless } from './utils/resolveExtensionless.js'
|
|
12
|
+
import { bypassImportCache } from './utils/resolveBypassImportCache.js'
|
|
11
13
|
|
|
12
14
|
import { API } from '../client/ApiConstants.js'
|
|
13
15
|
import { dispatchMock } from './MockDispatcher.js'
|
|
@@ -18,9 +20,6 @@ import { cookie } from './stores/cookies.js'
|
|
|
18
20
|
import { config, initConfig } from './stores/config.js'
|
|
19
21
|
import { watchMocksDir } from './stores/Watcher.js'
|
|
20
22
|
|
|
21
|
-
import { resolveExtensionless } from './resolveExtensionless.js'
|
|
22
|
-
import { resolveBypassImportCache } from './resolveBypassImportCache.js'
|
|
23
|
-
|
|
24
23
|
|
|
25
24
|
export function Mockaton(options) {
|
|
26
25
|
return new Promise((resolve, reject) => {
|
|
@@ -29,9 +28,7 @@ export function Mockaton(options) {
|
|
|
29
28
|
brokers.init()
|
|
30
29
|
|
|
31
30
|
registerHooks({ resolve: resolveExtensionless })
|
|
32
|
-
|
|
33
|
-
if (config.bypassImportCache)
|
|
34
|
-
registerHooks({ resolve: resolveBypassImportCache })
|
|
31
|
+
registerHooks({ resolve: bypassImportCache(config.mocksDir) })
|
|
35
32
|
|
|
36
33
|
if (config.watcherEnabled)
|
|
37
34
|
watchMocksDir()
|
|
@@ -1218,10 +1218,7 @@ describe('Registering Mocks', () => {
|
|
|
1218
1218
|
})
|
|
1219
1219
|
|
|
1220
1220
|
|
|
1221
|
-
/**
|
|
1222
|
-
* It resolves when a new version is pushed that differs from `currSyncVer`;
|
|
1223
|
-
* when `currSyncVer` is omitted, the first push after the initial connection is
|
|
1224
|
-
* used. */
|
|
1221
|
+
/** Resolves when a new mock is added, deleted, or renamed. */
|
|
1225
1222
|
function resolveOnNextSyncVersion(currSyncVer = undefined) {
|
|
1226
1223
|
let skipFirst = currSyncVer === undefined
|
|
1227
1224
|
return new Promise((resolve, reject) => {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { realpathSync } from 'node:fs'
|
|
2
|
+
import { pathToFileURL } from 'node:url'
|
|
3
|
+
|
|
4
|
+
export function bypassImportCache(srcPath) {
|
|
5
|
+
const resolvedSrcPath = pathToFileURL(realpathSync(srcPath)).href
|
|
6
|
+
|
|
7
|
+
// We register this `resolve` hook at runtime so it doesn't interfere with non-dynamic imports.
|
|
8
|
+
return function resolve(specifier, context, nextResolve) {
|
|
9
|
+
const result = nextResolve(specifier, context)
|
|
10
|
+
if (result.url.startsWith(resolvedSrcPath)) {
|
|
11
|
+
const url = new URL(result.url)
|
|
12
|
+
url.searchParams.set('t', performance.now())
|
|
13
|
+
return {
|
|
14
|
+
...result,
|
|
15
|
+
url: url.href,
|
|
16
|
+
shortCircuit: true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return result
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { resolve as _resolve } from 'node:path'
|
|
2
|
-
|
|
3
|
-
const mockatonSrcRoot = `file://${_resolve(import.meta.dirname, '..')}`
|
|
4
|
-
|
|
5
|
-
// We register this hook at runtime so it doesn’t interfere with non-dynamic imports.
|
|
6
|
-
// It cache-busts by appending timestamp query param
|
|
7
|
-
export function resolveBypassImportCache(specifier, context, nextResolve) {
|
|
8
|
-
const result = nextResolve(specifier, context)
|
|
9
|
-
if (result.url?.startsWith('file://') && !result.url.startsWith(mockatonSrcRoot)) {
|
|
10
|
-
const url = new URL(result.url)
|
|
11
|
-
url.searchParams.set('t', performance.now())
|
|
12
|
-
return {
|
|
13
|
-
...result,
|
|
14
|
-
url: url.href,
|
|
15
|
-
shortCircuit: true
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return result
|
|
19
|
-
}
|
|
File without changes
|