Skip to content

Commit 7526d89

Browse files
authored
Merge pull request #586 from marle3003/develop
Develop
2 parents 20e5002 + eaf40d6 commit 7526d89

File tree

14 files changed

+255
-74
lines changed

14 files changed

+255
-74
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/evanw/esbuild v0.25.5
1313
github.com/fsnotify/fsnotify v1.9.0
1414
github.com/go-co-op/gocron v1.37.0
15-
github.com/go-git/go-git/v5 v5.16.1
15+
github.com/go-git/go-git/v5 v5.16.2
1616
github.com/google/uuid v1.6.0
1717
github.com/jinzhu/inflection v1.0.0
1818
github.com/pkg/errors v0.9.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN
5454
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
5555
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
5656
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
57-
github.com/go-git/go-git/v5 v5.16.1 h1:TuxMBWNL7R05tXsUGi0kh1vi4tq0WfXNLlIrAkXG1k8=
58-
github.com/go-git/go-git/v5 v5.16.1/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
57+
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
58+
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
5959
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
6060
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
6161
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=

js/mokapi/cron.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,27 @@ import (
88
"reflect"
99
)
1010

11-
func (m *Module) Cron(expr string, do func(), args goja.Value) (int, error) {
11+
func (m *Module) Cron(expr string, do goja.Value, args goja.Value) (int, error) {
1212
options, err := getJobOptions(m.vm, args)
1313
if err != nil {
1414
panic(m.vm.ToValue(err.Error()))
1515
}
1616

17-
return m.host.Cron(expr, do, options)
17+
f := func() {
18+
_, err := m.loop.RunAsync(func(vm *goja.Runtime) (goja.Value, error) {
19+
call, _ := goja.AssertFunction(do)
20+
v, err := call(goja.Undefined())
21+
if err != nil {
22+
return nil, err
23+
}
24+
return v, nil
25+
})
26+
if err != nil {
27+
panic(m.vm.ToValue(err.Error()))
28+
}
29+
}
30+
31+
return m.host.Cron(expr, f, options)
1832
}
1933

2034
func getJobOptions(vm *goja.Runtime, opt goja.Value) (common.JobOptions, error) {

js/mokapi/cron_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,37 @@ func TestModule_Cron(t *testing.T) {
146146
r.EqualError(t, err, "unexpected type for skipImmediateFirstRun: String at mokapi/js/mokapi.(*Module).Cron-fm (native)")
147147
},
148148
},
149+
{
150+
name: "async handler",
151+
test: func(t *testing.T, vm *goja.Runtime, host *enginetest.Host) {
152+
var f func()
153+
host.CronFunc = func(cron string, do func(), opt common.JobOptions) {
154+
f = do
155+
}
156+
157+
_, err := vm.RunString(`
158+
const m = require('mokapi')
159+
let result;
160+
m.cron('', async () => {
161+
result = await getMessage();
162+
})
163+
164+
let getMessage = async () => {
165+
return new Promise(async (resolve, reject) => {
166+
setTimeout(() => {
167+
resolve('foo');
168+
}, 200);
169+
});
170+
}
171+
`)
172+
r.NoError(t, err)
173+
f()
174+
r.NoError(t, err)
175+
v, err := vm.RunString("result")
176+
r.NoError(t, err)
177+
r.Equal(t, "foo", v.Export())
178+
},
179+
},
149180
}
150181

151182
t.Parallel()

js/mokapi/every.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,25 @@ import (
44
"github.com/dop251/goja"
55
)
66

7-
func (m *Module) Every(every string, do func(), args goja.Value) (int, error) {
7+
func (m *Module) Every(every string, do goja.Value, args goja.Value) (int, error) {
88
options, err := getJobOptions(m.vm, args)
99
if err != nil {
1010
panic(m.vm.ToValue(err.Error()))
1111
}
1212

13-
return m.host.Every(every, do, options)
13+
f := func() {
14+
_, err := m.loop.RunAsync(func(vm *goja.Runtime) (goja.Value, error) {
15+
call, _ := goja.AssertFunction(do)
16+
v, err := call(goja.Undefined())
17+
if err != nil {
18+
return nil, err
19+
}
20+
return v, nil
21+
})
22+
if err != nil {
23+
panic(m.vm.ToValue(err.Error()))
24+
}
25+
}
26+
27+
return m.host.Every(every, f, options)
1428
}

js/mokapi/every_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,37 @@ func TestModule_Every(t *testing.T) {
146146
r.EqualError(t, err, "unexpected type for skipImmediateFirstRun: String at mokapi/js/mokapi.(*Module).Every-fm (native)")
147147
},
148148
},
149+
{
150+
name: "async handler",
151+
test: func(t *testing.T, vm *goja.Runtime, host *enginetest.Host) {
152+
var f func()
153+
host.EveryFunc = func(every string, do func(), opt common.JobOptions) {
154+
f = do
155+
}
156+
157+
_, err := vm.RunString(`
158+
const m = require('mokapi')
159+
let result;
160+
m.every('1m', async () => {
161+
result = await getMessage();
162+
})
163+
164+
let getMessage = async () => {
165+
return new Promise(async (resolve, reject) => {
166+
setTimeout(() => {
167+
resolve('foo');
168+
}, 200);
169+
});
170+
}
171+
`)
172+
r.NoError(t, err)
173+
f()
174+
r.NoError(t, err)
175+
v, err := vm.RunString("result")
176+
r.NoError(t, err)
177+
r.Equal(t, "foo", v.Export())
178+
},
179+
},
149180
}
150181

151182
t.Parallel()

js/mokapi/on_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ func TestModule_On(t *testing.T) {
146146
const m = require('mokapi')
147147
m.on('http', async (p) => {
148148
p.msg = await getMessage();
149-
return true;
150149
})
151150
152151
let getMessage = async () => {

js/script_mokapi_test.go

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -178,26 +178,6 @@ func TestScript_Mokapi_Every(t *testing.T) {
178178
r.NoError(t, err)
179179
},
180180
},
181-
{
182-
name: "run function",
183-
test: func(t *testing.T, host *enginetest.Host) {
184-
host.EveryFunc = func(every string, do func(), opt common.JobOptions) {
185-
do()
186-
}
187-
s, err := jstest.New(jstest.WithSource(
188-
`import { every } from 'mokapi'
189-
export default function() {
190-
let counter = 1
191-
every('1s', function() {counter++}, {tags: {foo: 'bar'}})
192-
return counter
193-
}`),
194-
js.WithHost(host))
195-
r.NoError(t, err)
196-
v, err := s.RunDefault()
197-
r.NoError(t, err)
198-
r.Equal(t, int64(2), v.ToInteger())
199-
},
200-
},
201181
}
202182

203183
t.Parallel()
@@ -297,26 +277,6 @@ func TestScript_Mokapi_Cron(t *testing.T) {
297277
r.NoError(t, err)
298278
},
299279
},
300-
{
301-
name: "run function",
302-
test: func(t *testing.T, host *enginetest.Host) {
303-
host.CronFunc = func(every string, do func(), opt common.JobOptions) {
304-
do()
305-
}
306-
s, err := jstest.New(jstest.WithSource(
307-
`import { cron } from 'mokapi'
308-
export default function() {
309-
let counter = 1
310-
cron('0/1 0 0 ? * * *', function() {counter++}, {tags: {foo: 'bar'}})
311-
return counter
312-
}`),
313-
js.WithHost(host))
314-
r.NoError(t, err)
315-
v, err := s.RunDefault()
316-
r.NoError(t, err)
317-
r.Equal(t, int64(2), v.ToInteger())
318-
},
319-
},
320280
}
321281

322282
t.Parallel()

npm/types/faker.d.ts

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function findByName(name: string): Node;
3636
/**
3737
* The name of the root node in the faker tree.
3838
*/
39-
export const Root_Name = "root";
39+
export const ROOT_NAME = "root";
4040

4141
/**
4242
* Represents a node in the faker tree.
@@ -63,7 +63,54 @@ export interface Node {
6363
/**
6464
* The child nodes of this node.
6565
*/
66-
children: Node[];
66+
children: Array<Node | AddNode>;
67+
68+
/**
69+
* Generates a fake value based on the given request.
70+
*
71+
* @param r r - The request describing the value to generate.
72+
* @returns A generated fake value.
73+
*
74+
* @example
75+
* export default function() {
76+
* const frequencyItems = ['never', 'daily', 'weekly', 'monthly', 'yearly']
77+
* const node = findByName(ROOT_NAME)
78+
* node.children.unshift({
79+
* name: 'Frequency',
80+
* attributes: [ 'frequency' ]
81+
* fake: (r) => {
82+
* return frequencyItems[Math.floor(Math.random()*frequencyItems.length)]
83+
* }
84+
* })
85+
* console.log(fake({ properties: { frequency } }))
86+
* // Expected output: an object with a frequency attribute containing a random value of frequency
87+
* }
88+
*/
89+
fake: (r: Request) => any;
90+
}
91+
92+
export interface AddNode {
93+
/**
94+
* The unique name of the node.
95+
*/
96+
name: string;
97+
98+
/**
99+
* Attributes associated with this node.
100+
* These will be used for matching path or schema properties.
101+
*/
102+
attributes?: string[];
103+
104+
/**
105+
* A weight that determines how likely this node is to be selected,
106+
* if multiple nodes match.
107+
*/
108+
weight?: number;
109+
110+
/**
111+
* The child nodes of this node.
112+
*/
113+
children?: Array<Node | AddNode>;
67114

68115
/**
69116
* Generates a fake value based on the given request.

npm/types/index.d.ts

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,6 @@ export interface EventHandler {
108108
smtp: SmtpEventHandler;
109109
}
110110

111-
export type ChangeResult = boolean | undefined;
112-
113-
export type EventHandlerResult = ChangeResult | Promise<ChangeResult>;
114-
115111
/**
116112
* HttpEventHandler is a function that is executed when an HTTP event is triggered.
117113
* https://mokapi.io/docs/javascript-api/mokapi/eventhandler/httpeventhandler
@@ -126,7 +122,7 @@ export type EventHandlerResult = ChangeResult | Promise<ChangeResult>;
126122
* })
127123
* }
128124
*/
129-
export type HttpEventHandler = (request: HttpRequest, response: HttpResponse) => EventHandlerResult;
125+
export type HttpEventHandler = (request: HttpRequest, response: HttpResponse) => void;
130126

131127
/**
132128
* HttpRequest is an object used by HttpEventHandler that contains request-specific
@@ -208,7 +204,7 @@ export interface Url {
208204
* })
209205
* }
210206
*/
211-
export type KafkaEventHandler = (message: KafkaEventMessage) => EventHandlerResult;
207+
export type KafkaEventHandler = (message: KafkaEventMessage) => void;
212208

213209
/**
214210
* KafkaEventMessage is an object used by KafkaEventHandler that contains Kafka-specific message data.
@@ -247,7 +243,7 @@ export interface KafkaEventMessage {
247243
* })
248244
* }
249245
*/
250-
export type LdapEventHandler = (request: LdapSearchRequest, response: LdapSearchResponse) => EventHandlerResult;
246+
export type LdapEventHandler = (request: LdapSearchRequest, response: LdapSearchResponse) => void;
251247

252248
/**
253249
* LdapSearchRequest is an object used by LdapEventHandler that contains request-specific data.
@@ -347,7 +343,7 @@ export enum LdapResultStatus {
347343
SizeLimitExceeded = 4,
348344
}
349345

350-
export type SmtpEventHandler = (record: SmtpEventMessage) => EventHandlerResult;
346+
export type SmtpEventHandler = (record: SmtpEventMessage) => void;
351347

352348
export interface SmtpEventMessage {
353349
server: string;
@@ -460,4 +456,57 @@ export interface JSONObject {
460456
[key: string]: JSONValue;
461457
}
462458

463-
export const RFC3339 = "RFC3339";
459+
/**
460+
* Specifies the date-time format defined in [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339).
461+
* This constant can be used when defining or validating datetime strings.
462+
*
463+
* @example
464+
* const date = new Date().toISOString()
465+
* if (isValidDate(date, RFC3339)) {
466+
* // do something
467+
* }
468+
*/
469+
export const RFC3339 = "RFC3339";
470+
471+
/**
472+
* Applies a patch object to a target object. Only properties that are explicitly defined in the patch
473+
* are applied. This includes nested objects. Properties marked with `Delete` will be removed.
474+
*
475+
* This function is especially useful when working with generated mock data in Mokapi that you want to override
476+
* or refine with specific values.
477+
*
478+
* https://mokapi.io/docs/javascript-api/mokapi/patch
479+
*
480+
* @param target The original object or value to be patched.
481+
* @param patch The patch object or value. Only defined values are applied; undefined values are ignored. Use `Delete` to remove fields.
482+
* @returns A new object or value with the patch applied.
483+
*
484+
* @example
485+
* const result = patch({ name: "foo", age: 42 }, { name: "bar" })
486+
* // result: { name: "bar", age: 42 }
487+
*
488+
* @example
489+
* const result = patch({ name: "foo", meta: { version: 1 } }, { meta: { version: 2 } })
490+
* // result: { name: "foo", meta: { version: 2 } }
491+
*
492+
* @example
493+
* const result = patch({ name: "foo", age: 42 }, { age: Delete })
494+
* // result: { name: "foo" }
495+
*/
496+
export function patch(target: any, patch: any): any;
497+
498+
/**
499+
* Special marker used with the `patch` function to indicate a property should be removed.
500+
*
501+
* When used as a value inside a patch object, the corresponding property will be deleted
502+
* from the result.
503+
*
504+
* This is useful when refining or overriding mock data in a script while keeping validation logic intact.
505+
*
506+
* https://mokapi.io/docs/javascript-api/mokapi/patch#delete
507+
*
508+
* @example
509+
* const result = patch({ name: "foo", age: 42 }, { age: Delete })
510+
* // result: { name: "foo" }
511+
*/
512+
export const Delete: unique symbol;

0 commit comments

Comments
 (0)