Skip to content

Commit 179b450

Browse files
authored
Merge pull request #178 from SenseUnit/js_env
Export env to JS scripts
2 parents 501051c + aeb498e commit 179b450

File tree

5 files changed

+97
-6
lines changed

5 files changed

+97
-6
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,10 @@ Following builtin functions are addionally available within JS scripts:
385385
* `print(val)` - print arbitrary values *val* into dumbproxy log for debugging purposes.
386386
* `readFile(path: string): string` - read file from *path* and return its content as a string.
387387

388+
Following objects are additionally available in global scope of JS scripts:
389+
390+
* `env` - readonly object containing all environment variables.
391+
388392
## Supported upstream proxy schemes
389393

390394
Supported proxy schemes are:

access/jsfilter.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ func NewJSFilter(filename string, instances int, logger *clog.CondLogger, next F
3737
vm := goja.New()
3838
err = jsext.AddPrinter(vm, logger)
3939
if err != nil {
40-
return nil, errors.New("can't add print function to runtime")
40+
return nil, fmt.Errorf("can't add print function to runtime: %w", err)
4141
}
42-
err = jsext.AddFileReader(vm)
42+
err = jsext.ConfigureRuntime(vm)
4343
if err != nil {
44-
return nil, errors.New("can't add file reader function to runtime")
44+
return nil, fmt.Errorf("can't configure runtime: %w", err)
4545
}
4646
vm.SetFieldNameMapper(goja.TagFieldNameMapper("json", true))
4747
_, err = vm.RunString(string(script))

dialer/jsrouter.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ func NewJSRouter(filename string, instances int, factory func(string) (Dialer, e
3535
vm := goja.New()
3636
err := jsext.AddPrinter(vm, logger)
3737
if err != nil {
38-
return nil, errors.New("can't add print function to runtime")
38+
return nil, fmt.Errorf("can't add print function to runtime: %w", err)
3939
}
40-
err = jsext.AddFileReader(vm)
40+
err = jsext.ConfigureRuntime(vm)
4141
if err != nil {
42-
return nil, errors.New("can't add file reader function to runtime")
42+
return nil, fmt.Errorf("can't configure runtime runtime: %w", err)
4343
}
4444
vm.SetFieldNameMapper(goja.TagFieldNameMapper("json", true))
4545
_, err = vm.RunString(string(script))

jsext/env.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package jsext
2+
3+
import (
4+
"os"
5+
"slices"
6+
"strings"
7+
"sync"
8+
9+
"github.com/dop251/goja"
10+
)
11+
12+
var (
13+
createEnvObjectOnce sync.Once
14+
envObject *goja.Object
15+
)
16+
17+
type readonlyEnvObject struct {
18+
m map[string]goja.String
19+
k []string
20+
}
21+
22+
func (o *readonlyEnvObject) Get(key string) goja.Value {
23+
v, ok := o.m[key]
24+
if ok {
25+
return v
26+
}
27+
return goja.Undefined()
28+
}
29+
30+
func (o *readonlyEnvObject) Set(_ string, _ goja.Value) bool {
31+
return false
32+
}
33+
34+
func (o *readonlyEnvObject) Has(key string) bool {
35+
_, ok := o.m[key]
36+
return ok
37+
}
38+
39+
func (o *readonlyEnvObject) Delete(key string) bool {
40+
return false
41+
}
42+
43+
func (o *readonlyEnvObject) Keys() []string {
44+
return o.k
45+
}
46+
47+
func createEnvObject() *goja.Object {
48+
env := os.Environ()
49+
m := make(map[string]goja.String, len(env))
50+
k := make([]string, 0, len(env))
51+
for _, pair := range env {
52+
key, value, _ := strings.Cut(pair, "=")
53+
sb := new(goja.StringBuilder)
54+
sb.WriteUTF8String(value)
55+
m[key] = sb.String()
56+
k = append(k, key)
57+
}
58+
slices.Sort(k)
59+
return goja.NewSharedDynamicObject(&readonlyEnvObject{
60+
m: m,
61+
k: k,
62+
})
63+
}
64+
65+
func GetEnvSharedDynamicObject() *goja.Object {
66+
createEnvObjectOnce.Do(func() {
67+
envObject = createEnvObject()
68+
})
69+
return envObject
70+
}
71+
72+
func ExportEnv(vm *goja.Runtime) error {
73+
return vm.Set("env", GetEnvSharedDynamicObject())
74+
}

jsext/jsext.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package jsext
2+
3+
import "github.com/dop251/goja"
4+
5+
func ConfigureRuntime(vm *goja.Runtime) error {
6+
if err := AddFileReader(vm); err != nil {
7+
return err
8+
}
9+
if err := ExportEnv(vm); err != nil {
10+
return err
11+
}
12+
return nil
13+
}

0 commit comments

Comments
 (0)