Skip to content

Commit 202b203

Browse files
authored
Merge pull request #854 from marle3003/develop
Develop
2 parents ae2c610 + 7e19bd9 commit 202b203

88 files changed

Lines changed: 2281 additions & 701 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ jobs:
138138
node-version: 23
139139
registry-url: 'https://registry.npmjs.org'
140140
- run: npm install
141+
working-directory: ./webui
141142
- name: Install taskfile
142143
run: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin
143144
- name: Publish

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
data/*
1818
dist/
1919
bin/*
20+
obj/
21+
Debug/
2022

2123
node_modules
2224

acceptance/petstore_test.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,16 @@ func (suite *PetStoreSuite) TestEvents() {
293293
try.AssertBody(func(t *testing.T, body string) {
294294
var data map[string]any
295295
err := json.Unmarshal([]byte(body), &data)
296-
require.NoError(t, err)
296+
assert.NoError(t, err)
297297
results := data["results"].([]any)
298-
evt := results[0].(map[string]any)
299-
require.Equal(t, "Event", evt["type"])
300-
require.Equal(t, "GET http://127.0.0.1:18080/user/bob", evt["title"])
301-
require.Equal(t, "Swagger Petstore", evt["domain"])
298+
assert.NotNil(t, results, "search result should contain results")
299+
assert.Greater(t, len(results), 0)
300+
evt, ok := results[0].(map[string]any)
301+
assert.True(t, ok, "event should be a map[string]any")
302+
assert.NotNil(t, evt)
303+
assert.Equal(t, "Event", evt["type"])
304+
assert.Equal(t, "GET http://127.0.0.1:18080/user/bob", evt["title"])
305+
assert.Equal(t, "Swagger Petstore", evt["domain"])
302306
}),
303307
)
304308
}

api/handler_search_test.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package api
22

33
import (
4+
"context"
45
"encoding/json"
56
"mokapi/config/dynamic"
67
"mokapi/config/dynamic/asyncApi/asyncapitest"
@@ -10,6 +11,7 @@ import (
1011
"mokapi/providers/openapi/openapitest"
1112
"mokapi/runtime"
1213
"mokapi/runtime/search"
14+
"mokapi/safe"
1315
"mokapi/try"
1416
"net/http"
1517
"testing"
@@ -43,7 +45,8 @@ func TestHandler_SearchQuery(t *testing.T) {
4345
},
4446
app: func() *runtime.App {
4547
app := runtime.New(&static.Config{Api: static.Api{Search: static.Search{
46-
Enabled: true,
48+
Enabled: true,
49+
InMemory: true,
4750
}}})
4851

4952
cfg := openapitest.NewConfig("3.0", openapitest.WithInfo("foo", "", ""))
@@ -62,7 +65,8 @@ func TestHandler_SearchQuery(t *testing.T) {
6265
},
6366
app: func() *runtime.App {
6467
app := runtime.New(&static.Config{Api: static.Api{Search: static.Search{
65-
Enabled: true,
68+
Enabled: true,
69+
InMemory: true,
6670
}}})
6771

6872
cfg := openapitest.NewConfig("3.0", openapitest.WithInfo("foo", "", ""))
@@ -81,7 +85,8 @@ func TestHandler_SearchQuery(t *testing.T) {
8185
},
8286
app: func() *runtime.App {
8387
app := runtime.New(&static.Config{Api: static.Api{Search: static.Search{
84-
Enabled: true,
88+
Enabled: true,
89+
InMemory: true,
8590
}}})
8691

8792
cfg := openapitest.NewConfig("3.0", openapitest.WithInfo("foo", "", ""))
@@ -102,7 +107,8 @@ func TestHandler_SearchQuery(t *testing.T) {
102107
},
103108
app: func() *runtime.App {
104109
app := runtime.New(&static.Config{Api: static.Api{Search: static.Search{
105-
Enabled: true,
110+
Enabled: true,
111+
InMemory: true,
106112
}}})
107113

108114
cfg := openapitest.NewConfig("3.0", openapitest.WithInfo("foo", "", ""))
@@ -131,7 +137,8 @@ func TestHandler_SearchQuery(t *testing.T) {
131137
},
132138
app: func() *runtime.App {
133139
app := runtime.New(&static.Config{Api: static.Api{Search: static.Search{
134-
Enabled: true,
140+
Enabled: true,
141+
InMemory: true,
135142
}}})
136143

137144
h := openapitest.NewConfig("3.0", openapitest.WithInfo("foo", "", ""))
@@ -160,7 +167,8 @@ func TestHandler_SearchQuery(t *testing.T) {
160167
},
161168
app: func() *runtime.App {
162169
app := runtime.New(&static.Config{Api: static.Api{Search: static.Search{
163-
Enabled: true,
170+
Enabled: true,
171+
InMemory: true,
164172
}}})
165173

166174
h := openapitest.NewConfig("3.0", openapitest.WithInfo("foo", "", ""))
@@ -180,7 +188,12 @@ func TestHandler_SearchQuery(t *testing.T) {
180188
t.Run(tc.name, func(t *testing.T) {
181189
t.Parallel()
182190

183-
h := New(tc.app(), static.Api{})
191+
app := tc.app()
192+
pool := safe.NewPool(context.Background())
193+
app.Start(pool)
194+
defer pool.Stop()
195+
196+
h := New(app, static.Api{})
184197

185198
try.Handler(t,
186199
http.MethodGet,

api/handler_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ func TestHandler_NoDashboard(t *testing.T) {
196196
}
197197

198198
func TestHandler_SearchEnabled(t *testing.T) {
199-
h := api.New(runtime.New(&static.Config{}), static.Api{Dashboard: true, Search: static.Search{Enabled: true}})
199+
h := api.New(runtime.New(&static.Config{}), static.Api{Dashboard: true, Search: static.Search{Enabled: true, InMemory: true}})
200200
try.Handler(t,
201201
http.MethodGet,
202202
"http://foo.api/api/info",

cmd/mokapi/main_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ api:
8282
dashboard: true
8383
search:
8484
enabled: true
85+
indexPath: ""
86+
inMemory: false
8587
rootCaCert: ""
8688
rootCaKey: ""
8789
configs: []

config/static/static_config.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ type Api struct {
6666
}
6767

6868
type Search struct {
69-
Enabled bool
69+
Enabled bool
70+
IndexPath string `yaml:"indexPath" json:"indexPath" flag:"index-path"`
71+
InMemory bool `yaml:"inMemory" json:"inMemory" flag:"in-memory"`
7072
}
7173

7274
type FileProvider struct {

docs/config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,9 +588,9 @@
588588
},
589589
"items": [
590590
{
591-
"label": "Ensuring API Contract Compliance with Mokapi",
591+
"label": "Guard Your API Contracts: Catch Breaking Changes Before Production",
592592
"source": "resources/blogs/ensuring-api-contract-compliance-with-mokapi.md",
593-
"path": "/resources/blogs/ensuring-api-contract-compliance-with-mokapi",
593+
"path": "/resources/blogs/guard-your-api-contracts",
594594
"hideNavigation": true
595595
},
596596
{

docs/javascript-api/mokapi/eventhandler/eventargs.md

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,34 @@ description: EventArgs is an object used to configure event handlers registered
88
[`on`](/docs/javascript-api/mokapi/on.md) function when registering an event handler.
99
It allows controlling how and when an event handler is executed.
1010

11-
| Name | Type | Description |
12-
|----------|---------|--------------------------------------------------------------------------------------------------------|
13-
| tags | object | Adds or overrides existing tags that are used in dashboard |
14-
| priority | integer | Defines the execution priority of the event handler. Handlers with a higher value are executed first. |
15-
16-
If no priority is specified, the default priority is `0`.
11+
<div class="table-responsive-sm">
12+
<table>
13+
<thead>
14+
<tr>
15+
<th scope="col" class="col-2">Name</th>
16+
<th scope="col" class="col-2">Type</th>
17+
<th scope="col" class="col">Description</th>
18+
</tr>
19+
</thead>
20+
<tbody>
21+
<tr>
22+
<td>tags</td>
23+
<td><code>object</code></td>
24+
<td>Adds or overrides existing tags that are used in dashboard.</td>
25+
</tr>
26+
<tr>
27+
<td>track</td>
28+
<td><code>boolean | <br />(params) => boolean</code></td>
29+
<td>Controls whether this event handler is tracked in the dashboard.</td>
30+
</tr>
31+
<tr>
32+
<td>priority</td>
33+
<td><code>integer</code></td>
34+
<td>Defines the execution priority of the event handler. Handlers with a higher value are executed first. If no priority is specified, the default priority is <code>0</code>.</td>
35+
</tr>
36+
</tbody>
37+
</table>
38+
</div>
1739

1840
## Example: Adding custom tags
1941

@@ -29,6 +51,62 @@ export default function() {
2951
}
3052
```
3153

54+
## Example: Controlling whether an event handler is tracked in the dashboard
55+
56+
The track field controls whether executions of an event handler appear in the dashboard.
57+
58+
It supports two modes:
59+
- true / false — always track or never track
60+
- a function — decide dynamically per request
61+
62+
### Static tracking
63+
64+
```javascript
65+
on('http', handler, { track: true })
66+
```
67+
68+
### Dynamic tracking (function)
69+
70+
```javascript
71+
on('http', handler, {
72+
track: (request, response) => request.key !== '/health'
73+
})
74+
```
75+
76+
### Full example: Delay simulation with tracking
77+
78+
```javascript
79+
import { on, sleep } from 'mokapi'
80+
81+
export default () => {
82+
let delay = undefined
83+
84+
on('http', (request, response) => {
85+
if (request.key === '/simulations/delay') {
86+
switch (request.method) {
87+
case 'PUT':
88+
delay = request.query.duration;
89+
break;
90+
case 'DELETE':
91+
delay = undefined;
92+
break;
93+
}
94+
}
95+
}, { track: true })
96+
on('http', (request, response) => {
97+
if (!delay) {
98+
sleep(delay);
99+
}
100+
}, { track: () => delay !== undefined } )
101+
}
102+
```
103+
104+
#### Explanation
105+
- The first handler exposes a control endpoint to configure the delay.
106+
- track: true ensures all configuration changes are visible in the dashboard.
107+
- The second handler applies the delay to incoming requests.
108+
- Tracking is enabled only while a delay is active, keeping the dashboard clean when no simulation is running.
109+
32110
## Example: Controlling execution order with priority
33111

34112
When multiple handlers are registered for the same event, the priority

0 commit comments

Comments
 (0)