github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/js/jobs.go (about)

     1  package js
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/angenalZZZ/gofunc/f"
    11  	"github.com/dop251/goja"
    12  )
    13  
    14  // NewJobs create javascript jobs.
    15  func NewJobs(r *GoRuntime, script string, parentName string, name string) ([]*JobJs, error) {
    16  	var (
    17  		filename    string
    18  		fileModTime time.Time
    19  		prev        = fmt.Sprintf("init %q jobs, ", parentName)
    20  	)
    21  	if r == nil {
    22  		return nil, errors.New(prev + "js runtime object is not initialized")
    23  	}
    24  	if script == "" {
    25  		return nil, errors.New(prev + "js script content can't be empty")
    26  	}
    27  	if strings.HasSuffix(script, ".js") {
    28  		filename = script
    29  		info, err := os.Stat(filename)
    30  		if os.IsNotExist(err) || info.IsDir() {
    31  			return nil, errors.New(prev + "js script file does not exist")
    32  		}
    33  		buf, err1 := f.ReadFile(filename)
    34  		if err1 != nil {
    35  			return nil, errors.New(prev + err1.Error())
    36  		}
    37  		script, fileModTime = strings.TrimSpace(string(buf)), info.ModTime()
    38  	}
    39  	if script == "" {
    40  		return nil, errors.New(prev + "js script content can't be empty")
    41  	}
    42  	if parentName == "" {
    43  		return nil, errors.New(prev + "js script var name can't be empty")
    44  	}
    45  	if _, err := r.RunString(script); err != nil {
    46  		return nil, err
    47  	}
    48  
    49  	var newErr = func(errs ...string) error {
    50  		err := prev + "load script error:"
    51  		for _, s := range errs {
    52  			err += fmt.Sprintf(" %+v", s)
    53  		}
    54  		return errors.New(err)
    55  	}
    56  
    57  	self := r.Runtime.Get(parentName)
    58  	if self == nil {
    59  		return nil, errors.New(prev + "js script var name can't be empty")
    60  	}
    61  	objs, ok := self.Export().([]interface{})
    62  	if !ok {
    63  		return nil, newErr(parentName, "must be an array")
    64  	}
    65  
    66  	jobs, find := make([]*JobJs, 0, len(objs)), name != ""
    67  	for i, obj := range objs {
    68  		objMap, ok := obj.(map[string]interface{})
    69  		if !ok {
    70  			return nil, newErr(parentName, "array item be an object")
    71  		}
    72  
    73  		item := new(JobJs)
    74  		if item.Name, ok = objMap["name"].(string); !ok {
    75  			return nil, newErr(parentName, fmt.Sprintf("array item[%d]'s name not found", i))
    76  		} else if item.Name == "" {
    77  			return nil, newErr(parentName, fmt.Sprintf("array item[%d]'s name can't be empty", i))
    78  		}
    79  		if item.Spec, ok = objMap["spec"].(string); !ok {
    80  			return nil, newErr(parentName, fmt.Sprintf("array item[%d]'s spec not found", i))
    81  		} else if item.Spec == "" {
    82  			return nil, newErr(parentName, fmt.Sprintf("array item[%d]'s spec can't be empty", i))
    83  		}
    84  		if item.Func, ok = objMap["func"].(func(goja.FunctionCall) goja.Value); !ok {
    85  			return nil, newErr(parentName, fmt.Sprintf("array item[%d]'s func not found", i))
    86  		}
    87  
    88  		item.Script, item.File, item.FileModTime = script, filename, fileModTime
    89  		item.Self, item.ParentName = r.ToValue(obj), parentName
    90  
    91  		if find {
    92  			if name != item.Name {
    93  				continue
    94  			}
    95  			jobs = append(jobs, item)
    96  			break
    97  		}
    98  
    99  		jobs = append(jobs, item)
   100  	}
   101  
   102  	for _, item := range jobs {
   103  		item.Parent = jobs
   104  	}
   105  
   106  	return jobs, nil
   107  }