Skip to content

Commit

Permalink
Merge branch 'main' of github.com:HexmosTech/Lama2
Browse files Browse the repository at this point in the history
  • Loading branch information
lovestaco committed Aug 12, 2023
2 parents d94e88b + 1efcf44 commit 768eb9f
Show file tree
Hide file tree
Showing 41 changed files with 483 additions and 240 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: Lama2 Release
on:
release:
types: [created]
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'

jobs:
releases-matrix:
Expand All @@ -27,4 +28,4 @@ jobs:
goversion: "https://dl.google.com/go/go1.19.3.linux-amd64.tar.gz"
binary_name: "l2"
extra_files: LICENSE README.md
ldflags: -X main.version=${{ github.event.release.tag_name }}
ldflags: -X main.version=${{ github.ref_name }}
138 changes: 74 additions & 64 deletions codegen/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strings"
"text/template"

"github.com/dop251/goja"
"github.com/rs/zerolog/log"

"github.com/HexmosTech/gabs/v2"
Expand All @@ -25,6 +26,12 @@ type SnippetArgs struct {
SnippetCore string
}

var globalVM *goja.Runtime

func initialize() {
globalVM = cmdexec.GetJSVm()
}

func PrepareHTTPSnippetGenerator(snippetArgs SnippetArgs) string {
var templOutput bytes.Buffer
templStr := `{{.SnippetCore}}
Expand Down Expand Up @@ -89,79 +96,82 @@ func GetHARHeadersCookies(headers *gabs.Container) (*gabs.Container, *gabs.Conta
return headersData, cookiesData
}

func GetRequestHARString(parsedAPI *gabs.Container) string {
func GetRequestHARString(block *gabs.Container) string {
preprocess.ProcessVarsInBlock(block, globalVM)
httpv := block.S("verb", "value")
url := block.S("url", "value")
jsonObj := block.S("details", "ip_data")
headers := block.S("details", "headers")
/*
TODO: Handle multipart case
multipart := block.S("multipart", "value")
multipartBool := false
if multipart != nil {
multipartBool = true
}
*/
harObj := gabs.New()

if jsonObj != nil {
postData := gabs.New()
postData.Set("application/json", "mimeType")
postData.Set(jsonObj.String(), "text")
harObj.Set(postData, "postData")
}

if headers != nil {
headersData, cookiesData := GetHARHeadersCookies(headers)
if cookiesData.String() != "[]" {
harObj.Set(cookiesData, "cookies")
}
harObj.Set(headersData, "headers")
}

harObj.Set(httpv, "method")
harObj.Set(url, "url")

res := harObj.String()
return res
}

func GenerateTargetCode(targetLangLib string, parsedAPI *gabs.Container) {
initialize()
parsedAPIblocks := parsedAPI.S("value").Data().(*gabs.Container).Children()
vm := cmdexec.GetJSVm()
convertedSnippetList := make([]string, 0)

for i, block := range parsedAPIblocks {
log.Debug().Int("Block num", i).Msg("")
log.Debug().Str("Block getting processed", block.String()).Msg("")
blockType := block.S("type").Data().(string)
if blockType == "processor" {
fmt.Println("Skipping processor block")
snippet := block.S("value").Data().(*gabs.Container).Data().(string)
convertedSnippetList = append(convertedSnippetList, snippet)
} else if blockType == "Lama2File" {
preprocess.ProcessVarsInBlock(block, vm)
httpv := block.S("verb", "value")
url := block.S("url", "value")
jsonObj := block.S("details", "ip_data")
headers := block.S("details", "headers")
/*
TODO: Handle multipart case
multipart := block.S("multipart", "value")
multipartBool := false
if multipart != nil {
multipartBool = true
}
*/
harObj := gabs.New()

if jsonObj != nil {
postData := gabs.New()
postData.Set("application/json", "mimeType")
postData.Set(jsonObj.String(), "text")
harObj.Set(postData, "postData")
harRequest := GetRequestHARString(block)
snippetArgs := SnippetArgs{}
lang, lib := SplitLangLib(targetLangLib)
snippetArgs.Language = lang
snippetArgs.Library = lib
snippetArgs.HARRequest = harRequest
snippetArgs.SnippetCore = snippetcore
httpsnippetCode := PrepareHTTPSnippetGenerator(snippetArgs)

vm := cmdexec.GetJSVm()
_, e := vm.RunString(httpsnippetCode)
if e != nil {
log.Fatal().
Str("Type", "CodeGen").
Str("Error", e.Error()).
Msg("Code generator error")
}

if headers != nil {
headersData, cookiesData := GetHARHeadersCookies(headers)
if cookiesData.String() != "[]" {
harObj.Set(cookiesData, "cookies")
}
harObj.Set(headersData, "headers")
}

harObj.Set(httpv, "method")
harObj.Set(url, "url")

res := harObj.String()
return res
// Init returns an error if the package is not ready for use.
convertedSnippet := vm.Get("convertedSnippet").String()
convertedSnippetList = append(convertedSnippetList, convertedSnippet)
}
}
// TODO: Handle multi-stage files properly
// Better exception handling
return ""
}

func GenerateTargetCode(targetLangLib string, parsedAPI *gabs.Container) {
harRequest := GetRequestHARString(parsedAPI)
snippetArgs := SnippetArgs{}
lang, lib := SplitLangLib(targetLangLib)
snippetArgs.Language = lang
snippetArgs.Library = lib
snippetArgs.HARRequest = harRequest
snippetArgs.SnippetCore = snippetcore
httpsnippetCode := PrepareHTTPSnippetGenerator(snippetArgs)
vm := cmdexec.GetJSVm()
_, e := vm.RunString(httpsnippetCode)
if e != nil {
log.Fatal().
Str("Type", "CodeGen").
Str("Error", e.Error()).
Msg(fmt.Sprint("Code generator error"))
}
// Init returns an error if the package is not ready for use.
convertedSnippet := vm.Get("convertedSnippet").String()
fmt.Println(convertedSnippet)
clipboard.WriteAll(convertedSnippet)
convertedSnippetFinal := strings.Join(convertedSnippetList, "\n")
fmt.Println(convertedSnippetFinal)
clipboard.WriteAll(convertedSnippetFinal)
fmt.Println("Code copied to clipboard")
}
2 changes: 1 addition & 1 deletion controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func Process(version string) {
Str("Type", "Controller").
Str("LamaFile", o.Positional.LamaAPIFile).
Str("Error", e.Error()).
Msg(fmt.Sprint("Parse Error"))
Msg("Parse Error")
}
log.Debug().Str("Parsed API", parsedAPI.String()).Msg("")
HandleParsedFile(parsedAPI, o, dir)
Expand Down
Binary file removed docs/Lama2/docs/explanation/l2envOverideL2config.png
Binary file not shown.
56 changes: 32 additions & 24 deletions docs/Lama2/docs/explanation/l2format.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,12 @@ Cookies are specified in a `Cookie` header as follows:
Cookie:'sessionid=foo;another-cookie=bar'
```

### API variables can be defined in `apirequest.l2`

L2 uses the variables declared inside the `.l2` file and makes the request
### Environment Variables

#### API variables can be defined in `apirequest.l2`
Variables are declared within the JS processor block and serve as dynamic placeholders for data used in API requests.
By utilizing these variables, L2 enables flexibility and reusability in defining API endpoints and data payloads.

Example `login.l2`:

Expand All @@ -103,41 +106,45 @@ ${REMOTE}/login
Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0021_varjson_variable/0021_varjson_variable.l2)


### API environment variables can be defined locally in `l2.env`
#### API environment variables can be defined locally in `l2.env`
L2 provides a convenient way to define environment variables through the l2.env file.
This file is automatically searched for in the present directory,
and its contents are loaded to create a set of variables (local).

`l2.env` is searched for, from the present directory and variables(local) are loaded from this file.
In the `l2.env` file, you can specify environment-specific values for variables used in your L2 scripts, such as URLs, authentication tokens, or any other data that may vary depending on the environment in which the API requests are executed.

Example `l2.env`:
![l2.env at API level](../tutorials/l2env.png)

```
export PHOTO=`base64 aadhaarlarge.jpg`
export AHOST="http://localhost:8000"
```
Go to [Example](../tutorials/examples.md#case-1-l2env-adjacent-to-an-api-file)

Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0004_env_switch_root)
Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0023_l2env_declare)

### API environment variables can be defined at root using `l2config.env`
`l2config.env` is searched for, from the present directory to all its ancestors (upto `/`) and
variables(root) are loaded from this file.
Example `l2config.env`:

```
export PHOTO=`base64 aadhaarsmall.jpg`
export AHOST="http://localhost:8001"
```
#### API environment variables can be defined at project root using `l2config.env`
The `l2config.env` file serves as a centralized storage for environment variables located at the project root, streamlining the management of configuration settings across all L2 scripts. With this file present, every L2 script within the project automatically inherits the defined variables, effectively eliminating the necessity to duplicate configurations in individual subdirectories using `l2.env`.

The search for `l2config.env` extends from the present directory up to the root directory (`/`). During this process, the variables defined in the root file are loaded and made available for use in all relevant scripts. This approach significantly enhances efficiency and maintainability, as it ensures consistent settings throughout the project while reducing redundancy in configuration data.

Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0019_env_switch_global_root)
![l2config.env at Project root level](../tutorials/l2configAtRoot.png)

### If `l2config.env`(root) variables are redeclared in `l2.env`(local)
Go to [Example](../tutorials/examples.md#case-2-root-variables)

The local variable's value is taken into consideration regardless of both files residing in same directory
Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0022_l2config_declare)

Get [Source Files](https://github.com/HexmosTech/Lama2/tree/main/examples/0020_override_project_root_local)

![Override of l2config.env with l2.env variable](l2envOverideL2config.png)
#### If `l2config.env`(root) variables are redeclared in `l2.env`(local)
In situations where both root and local variables share the same variable name, the local variable takes precedence over the root variable. This behavior remains consistent, even if both `l2config.env` (root) and `l2.env` (local) files reside in the same directory.

The local variable's value will always be considered over the root variable, ensuring that specific configurations defined at the local level effectively override any corresponding settings present in the root file. This approach provides developers with granular control and flexibility in tailoring environment variables to suit specific needs within different parts of the project while maintaining the overall structure and organization of configuration settings.

#### The environment file can load results of commands
![l2config.env at Project root level](../tutorials/l2envOverideL2config.png)

Go to [Example](../tutorials/examples.md#case-3-override-root-variable-with-local-variable)

Get [Source File](https://github.com/HexmosTech/Lama2/tree/main/examples/0020_override_project_root_local)


### The environment file can load results of commands

Use the backtick notation `\`command\`` to place the results of
commands into environment variables:
Expand All @@ -148,6 +155,7 @@ export PHOTO=`base64 image.jpeg`

One can load the `PHOTO` variable in API files.


### Chain requests through Javascript blocks

*Lama2* supports plain Javascript (JS) blocks
Expand Down
14 changes: 7 additions & 7 deletions docs/Lama2/docs/reference/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ From a high level, how does it work now?
3. Initialize Javascript VM for executing JS blocks
4. For each block
1. If block is JS Processor block
1. Execute JS code in VM
1. Execute JS code in VM
2. Else if block is Requestor block
1. Replace variables with values in the following order
1. Try fetch variable from Javascript VM
2. If (1) fails, try fetch Local env variable from `l2.env`
3. Try fetch root env variable from `l2config.env`
2. Use the processed elements to create an httpie-go request
3. Fetch response
1. Replace variables with values in the following order
1. Try fetch variable from Javascript VM
2. If (1) fails, try fetch Local env variable from `l2.env`
3. Try fetch root env variable from `l2config.env`
2. Use the processed elements to create an httpie-go request
3. Fetch response
5. If necessary, write the last transaction to `.json` file
12 changes: 6 additions & 6 deletions docs/Lama2/docs/reference/parser.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ var DataInputType string
```

<a name="CustomPairMerge"></a>
## func [CustomPairMerge](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L29>)
## func [CustomPairMerge](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L30>)

```go
func CustomPairMerge(destination, source interface{}) interface{}
Expand Down Expand Up @@ -122,7 +122,7 @@ func (p *Lama2Parser) AnyType() (*gabs.Container, error)
AnyType is the top\-most element of a JSON structure It consists of Complex and Primitive Types

<a name="Lama2Parser.Boolean"></a>
### func \(\*Lama2Parser\) [Boolean](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L126>)
### func \(\*Lama2Parser\) [Boolean](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L127>)

```go
func (p *Lama2Parser) Boolean() (*gabs.Container, error)
Expand Down Expand Up @@ -320,7 +320,7 @@ func (p *Lama2Parser) Lama2File() (*gabs.Container, error)


<a name="Lama2Parser.List"></a>
### func \(\*Lama2Parser\) [List](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L69>)
### func \(\*Lama2Parser\) [List](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L70>)

```go
func (p *Lama2Parser) List() (*gabs.Container, error)
Expand All @@ -329,7 +329,7 @@ func (p *Lama2Parser) List() (*gabs.Container, error)
List is a slightly lenient version of standard JSON list. In Lama2 List, it is OK to have a trailing comma after the last element \(whereas in strict JSON, it is not OK to have trailing comma\)

<a name="Lama2Parser.Map"></a>
### func \(\*Lama2Parser\) [Map](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L37>)
### func \(\*Lama2Parser\) [Map](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L38>)

```go
func (p *Lama2Parser) Map() (*gabs.Container, error)
Expand All @@ -347,7 +347,7 @@ func (p *Lama2Parser) Multipart() (*gabs.Container, error)


<a name="Lama2Parser.Null"></a>
### func \(\*Lama2Parser\) [Null](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L142>)
### func \(\*Lama2Parser\) [Null](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L143>)

```go
func (p *Lama2Parser) Null() (*gabs.Container, error)
Expand All @@ -374,7 +374,7 @@ func (p *Lama2Parser) OneNine() (*gabs.Container, error)


<a name="Lama2Parser.Pair"></a>
### func \(\*Lama2Parser\) [Pair](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L105>)
### func \(\*Lama2Parser\) [Pair](<https://github.com/HexmosTech/Lama2/blob/main/parser/jsonparser.go#L106>)

```go
func (p *Lama2Parser) Pair() (*gabs.Container, error)
Expand Down
6 changes: 3 additions & 3 deletions docs/Lama2/docs/reference/preprocess.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func ExpandURL(block *gabs.Container, vm *goja.Runtime)


<a name="GetL2EnvVariables"></a>
## func [GetL2EnvVariables](<https://github.com/HexmosTech/Lama2/blob/main/preprocess/preprocess.go#L170>)
## func [GetL2EnvVariables](<https://github.com/HexmosTech/Lama2/blob/main/preprocess/preprocess.go#L169>)

```go
func GetL2EnvVariables(dir string) ([]byte, error)
Expand All @@ -79,7 +79,7 @@ func GetL2EnvVariables(dir string) ([]byte, error)


<a name="GetLamaFileAsString"></a>
## func [GetLamaFileAsString](<https://github.com/HexmosTech/Lama2/blob/main/preprocess/preprocess.go#L201>)
## func [GetLamaFileAsString](<https://github.com/HexmosTech/Lama2/blob/main/preprocess/preprocess.go#L200>)

```go
func GetLamaFileAsString(path string) string
Expand All @@ -88,7 +88,7 @@ func GetLamaFileAsString(path string) string


<a name="LamaFile"></a>
## func [LamaFile](<https://github.com/HexmosTech/Lama2/blob/main/preprocess/preprocess.go#L215>)
## func [LamaFile](<https://github.com/HexmosTech/Lama2/blob/main/preprocess/preprocess.go#L214>)

```go
func LamaFile(inputFile string) (string, string)
Expand Down
Loading

0 comments on commit 768eb9f

Please sign in to comment.