Skip to content

Commit 2885628

Browse files
committed
Merge remote-tracking branch 'origin/develop' into develop
2 parents ee80396 + 5ab392f commit 2885628

9 files changed

Lines changed: 116 additions & 52 deletions

File tree

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ go 1.25.1
44

55
require (
66
github.com/Masterminds/sprig v2.22.0+incompatible
7-
github.com/blevesearch/bleve/v2 v2.5.5
7+
github.com/blevesearch/bleve/v2 v2.5.6
88
github.com/blevesearch/bleve_index_api v1.2.11
99
github.com/bradleyfalzon/ghinstallation/v2 v2.17.0
1010
github.com/brianvoe/gofakeit/v6 v6.28.0
1111
github.com/dop251/goja v0.0.0-20250309171923-bcd7cc6bf64c
12-
github.com/evanw/esbuild v0.27.0
12+
github.com/evanw/esbuild v0.27.1
1313
github.com/fsnotify/fsnotify v1.9.0
1414
github.com/go-co-op/gocron v1.37.0
1515
github.com/go-git/go-git/v5 v5.16.4

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
2222
github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
2323
github.com/bits-and-blooms/bitset v1.22.0 h1:Tquv9S8+SGaS3EhyA+up3FXzmkhxPGjQQCkcs2uw7w4=
2424
github.com/bits-and-blooms/bitset v1.22.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
25-
github.com/blevesearch/bleve/v2 v2.5.5 h1:lzC89QUCco+y1qBnJxGqm4AbtsdsnlUvq0kXok8n3C8=
26-
github.com/blevesearch/bleve/v2 v2.5.5/go.mod h1:t5WoESS5TDteTdnjhhvpA1BpLYErOBX2IQViTMLK7wo=
25+
github.com/blevesearch/bleve/v2 v2.5.6 h1:YdixQmOUuZHojQRe8Te7BY2cRirbzpbcpybAFs0m2DI=
26+
github.com/blevesearch/bleve/v2 v2.5.6/go.mod h1:t5WoESS5TDteTdnjhhvpA1BpLYErOBX2IQViTMLK7wo=
2727
github.com/blevesearch/bleve_index_api v1.2.11 h1:bXQ54kVuwP8hdrXUSOnvTQfgK0KI1+f9A0ITJT8tX1s=
2828
github.com/blevesearch/bleve_index_api v1.2.11/go.mod h1:rKQDl4u51uwafZxFrPD1R7xFOwKnzZW7s/LSeK4lgo0=
2929
github.com/blevesearch/geo v0.2.4 h1:ECIGQhw+QALCZaDcogRTNSJYQXRtC8/m8IKiA706cqk=
@@ -81,8 +81,8 @@ github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o
8181
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
8282
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
8383
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
84-
github.com/evanw/esbuild v0.27.0 h1:1fbrgepqU1rZeu4VPcQRZJpvIfQpbrYqRr1wJdeMkfM=
85-
github.com/evanw/esbuild v0.27.0/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
84+
github.com/evanw/esbuild v0.27.1 h1:SkYgb1wrwJkJYwBp5hjmQGm3riUHbCdfViyEvjAA/KA=
85+
github.com/evanw/esbuild v0.27.1/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
8686
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
8787
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
8888
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=

js/mokapi/shared.go

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@ func (m *SharedMemory) Clear() {
5050
func (m *SharedMemory) Update(key string, fn goja.Value) any {
5151
p := m.store.Update(key, func(v any) any {
5252
var arg goja.Value
53+
var sv *SharedValue
5354
if v != nil {
54-
arg = v.(*SharedValue).Use(m.vm).ToValue()
55+
sv = v.(*SharedValue)
56+
arg = sv.ToValue()
5557
}
5658
call, ok := goja.AssertFunction(fn)
5759
if !ok {
@@ -61,6 +63,9 @@ func (m *SharedMemory) Update(key string, fn goja.Value) any {
6163
if err != nil {
6264
panic(m.vm.ToValue(err))
6365
}
66+
if sv != nil && r == arg {
67+
return sv.Use(m.vm)
68+
}
6469

6570
return NewSharedValue(r, m.vm)
6671
})
@@ -110,9 +115,6 @@ func Export(v any) any {
110115
// SharedValue represents a Go-managed value that can be shared across
111116
// multiple Goja runtimes, while maintaining reference identity.
112117
type SharedValue struct {
113-
KeyNormalizer func(string) string
114-
ToJSValue func(vm *goja.Runtime, k string, v goja.Value) goja.Value
115-
116118
vm *goja.Runtime
117119
source goja.Value
118120
}
@@ -125,23 +127,16 @@ func NewSharedValue(v goja.Value, vm *goja.Runtime) *SharedValue {
125127
}
126128

127129
func (p *SharedValue) Use(vm *goja.Runtime) *SharedValue {
128-
return &SharedValue{source: p.source, vm: vm}
130+
return NewSharedValue(p.source, vm)
129131
}
130132

131133
func (p *SharedValue) Get(key string) goja.Value {
132-
if p.KeyNormalizer != nil {
133-
key = p.KeyNormalizer(key)
134-
}
135-
136134
switch v := p.source.(type) {
137135
case *goja.Object:
138136
f := v.Get(key)
139137
if _, ok := goja.AssertFunction(f); ok {
140138
return f
141139
} else if _, isObject := f.(*goja.Object); isObject {
142-
if p.ToJSValue != nil {
143-
return p.ToJSValue(p.vm, key, f)
144-
}
145140
return p.vm.NewDynamicObject(NewSharedValue(f, p.vm))
146141
}
147142
return f
@@ -151,10 +146,6 @@ func (p *SharedValue) Get(key string) goja.Value {
151146
}
152147

153148
func (p *SharedValue) Has(key string) bool {
154-
if p.KeyNormalizer != nil {
155-
key = p.KeyNormalizer(key)
156-
}
157-
158149
switch v := p.source.(type) {
159150
case *goja.Object:
160151
return slices.Contains(v.Keys(), key)
@@ -164,10 +155,6 @@ func (p *SharedValue) Has(key string) bool {
164155
}
165156

166157
func (p *SharedValue) Set(key string, value goja.Value) bool {
167-
if p.KeyNormalizer != nil {
168-
key = p.KeyNormalizer(key)
169-
}
170-
171158
switch v := p.source.(type) {
172159
case *goja.Object:
173160
err := v.Set(key, value)
@@ -180,10 +167,6 @@ func (p *SharedValue) Set(key string, value goja.Value) bool {
180167
}
181168

182169
func (p *SharedValue) Delete(key string) bool {
183-
if p.KeyNormalizer != nil {
184-
key = p.KeyNormalizer(key)
185-
}
186-
187170
switch v := p.source.(type) {
188171
case *goja.Object:
189172
err := v.Delete(key)
@@ -209,6 +192,7 @@ func (p *SharedValue) ToValue() goja.Value {
209192
if p.source == nil {
210193
return goja.Undefined()
211194
}
195+
212196
switch p.source.ExportType().Kind() {
213197
case reflect.Map, reflect.Slice:
214198
return p.vm.NewDynamicObject(p)

js/mokapi/shared_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"mokapi/js/eventloop"
1010
"mokapi/js/mokapi"
1111
"mokapi/js/require"
12+
"mokapi/try"
1213
"testing"
1314

1415
"github.com/dop251/goja"
@@ -307,6 +308,37 @@ func TestModule_Shared(t *testing.T) {
307308
r.Equal(t, []any{int64(1), int64(2), int64(3)}, mokapi.Export(v))
308309
},
309310
},
311+
{
312+
name: "set array using index operator",
313+
test: func(t *testing.T, newVm func() *goja.Runtime) {
314+
vm1 := newVm()
315+
316+
v, err := vm1.RunString(`
317+
const m = require('mokapi');
318+
m.shared.set('foo', [1,2])
319+
const shared = m.shared.get('foo');
320+
shared[1] = 10
321+
m.shared.get('foo')
322+
`)
323+
r.NoError(t, err)
324+
r.Equal(t, []any{int64(1), int64(10)}, mokapi.Export(v))
325+
},
326+
},
327+
{
328+
name: "get index from array",
329+
test: func(t *testing.T, newVm func() *goja.Runtime) {
330+
vm1 := newVm()
331+
332+
v, err := vm1.RunString(`
333+
const m = require('mokapi');
334+
m.shared.set('foo', [1,2])
335+
const shared = m.shared.get('foo');
336+
shared[1];
337+
`)
338+
r.NoError(t, err)
339+
r.Equal(t, int64(2), mokapi.Export(v))
340+
},
341+
},
310342
{
311343
name: "splice array",
312344
test: func(t *testing.T, newVm func() *goja.Runtime) {
@@ -375,3 +407,51 @@ func TestModule_Shared(t *testing.T) {
375407
})
376408
}
377409
}
410+
411+
func TestSharedFromModule(t *testing.T) {
412+
// import shared multiple times should not result to illegal runtime error
413+
414+
host := &enginetest.Host{}
415+
host.OpenFunc = func(file, hint string) (*dynamic.Config, error) {
416+
return &dynamic.Config{
417+
Info: dynamictest.NewConfigInfo(),
418+
Raw: []byte(`import { shared } from "mokapi"
419+
export const store = shared.update('stored', (v) => v ?? [{ foo: 'bar' }]);
420+
`),
421+
}, nil
422+
}
423+
424+
s1, err := js.New(&dynamic.Config{
425+
Info: dynamictest.NewConfigInfo(),
426+
Raw: []byte(`import { store } from "store.js"
427+
428+
`),
429+
}, host)
430+
r.NoError(t, err)
431+
defer s1.Close()
432+
433+
err = s1.Run()
434+
r.NoError(t, err)
435+
436+
s2, err := js.New(&dynamic.Config{
437+
Info: dynamic.ConfigInfo{Url: try.MustUrl("script1.js")},
438+
Raw: []byte(`import { store } from "store.js"
439+
`),
440+
}, host)
441+
r.NoError(t, err)
442+
defer s2.Close()
443+
444+
err = s2.Run()
445+
r.NoError(t, err)
446+
447+
s3, err := js.New(&dynamic.Config{
448+
Info: dynamic.ConfigInfo{Url: try.MustUrl("script1.js")},
449+
Raw: []byte(`import { store } from "store.js"
450+
`),
451+
}, host)
452+
r.NoError(t, err)
453+
defer s3.Close()
454+
455+
err = s3.Run()
456+
r.NoError(t, err)
457+
}

webui/e2e/home.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ import { test, expect } from './models/fixture-website'
33
test('home overview', async ({ home }) => {
44
await home.open()
55

6-
await expect(home.heroTitle).toHaveText('Mock and Take Control of APIs You Don’t Own')
7-
await expect(home.heroDescription).toHaveText(`Build better software by mocking external APIs and testing without dependencies.Free, open-source, and under your control — your data is yours.`)
6+
await expect(home.heroTitle).toHaveText('Mock APIs. Test Faster. Ship Better.')
7+
await expect(home.heroDescription).toHaveText(`Test without external dependencies and build more reliable software.Free, open-source, and fully under your control.`)
88
})

webui/package-lock.json

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webui/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"@ssthouse/vue3-tree-chart": "^0.3.0",
2121
"@types/bootstrap": "^5.2.10",
2222
"@types/whatwg-mimetype": "^3.0.2",
23-
"ace-builds": "^1.43.4",
23+
"ace-builds": "^1.43.5",
2424
"bootstrap": "^5.3.8",
2525
"bootstrap-icons": "^1.13.1",
2626
"dayjs": "^1.11.19",
@@ -49,9 +49,9 @@
4949
"eslint": "^9.39.1",
5050
"eslint-plugin-vue": "^10.6.2",
5151
"npm-run-all": "^4.1.5",
52-
"prettier": "^3.6.2",
52+
"prettier": "^3.7.4",
5353
"typescript": "~5.9.3",
54-
"vite": "^7.2.4",
54+
"vite": "^7.2.6",
5555
"vue-tsc": "^3.1.5",
5656
"xml2js": "^0.6.2"
5757
}

webui/src/components/dashboard/http/RequestInfoCard.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ const apiRoute = computed(() => {
7575
<p class="label">Duration</p>
7676
<p>{{ duration(eventData.duration) }}</p>
7777
</div>
78-
<div class="col-1">
78+
<div class="col-2">
7979
<p class="label">Client IP</p>
8080
<p>{{ eventData.clientIP }}</p>
8181
</div>

webui/src/views/Home.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import Footer from '@/components/Footer.vue'
44
import { ref, onMounted } from 'vue'
55
import { Modal } from 'bootstrap'
66
7-
const title = 'Mock APIs with Realistic Data | Mokapi Open Source Tool'
8-
const description = `Mokapi is a developer-friendly open-source API mocking tool that allows you to prototype, test, and demonstrate APIs using realistic data scenarios.`
7+
const title = 'Mock APIs with Realistic Test Data | Mokapi – Open-Source API Mocking Tool'
8+
const description = `Mock any external API and test without real dependencies. Mokapi is free, open-source, and build for realistic, spec-driven test data.`
99
1010
useMeta(title, description, 'https://mokapi.io')
1111
@@ -38,14 +38,14 @@ function hasTouchSupport() {
3838
<div class="row hero-title justify-content-center">
3939
<div class="col-12 col-lg-6 px-0">
4040

41-
<h1>Mock and Take Control of APIs You Don’t Own</h1>
41+
<h1>Mock APIs. Test Faster. Ship Better.</h1>
4242
<div class="badge-list mb-3" role="navigation" aria-label="API type navigation">
4343
<a href="http"><span class="badge" aria-label="HTTP API Support">HTTP</span></a>
4444
<a href="kafka"><span class="badge" aria-label="Kafka Support">Kafka</span></a>
4545
<a href="ldap"><span class="badge" aria-label="LDAP Support">LDAP</span></a>
4646
<a href="mail"><span class="badge" aria-label="Email Support">Email</span></a>
4747
</div>
48-
<p class="lead description">Build better software by mocking external APIs and testing without dependencies.<br/><b>Free</b>, <b>open-source</b>, and under your control — your data is yours.</p>
48+
<p class="lead description">Test without external dependencies and build more reliable software.<br/><b>Free</b>, <b>open-source</b>, and fully under your control.</p>
4949
<p class="d-none d-md-block">
5050
<router-link :to="{ path: '/docs/guides' }">
5151
<button type="button" class="btn btn-outline-primary">Get Started</button>

0 commit comments

Comments
 (0)