1.0.0-alpha.26 • Published 1 year ago

ezrun v1.0.0-alpha.26

Weekly downloads
-
License
ISC
Repository
github
Last release
1 year ago

ezrun

A platform helps to run everythings base on a yaml script file

Installation

Install via npm

  npm install -g ezrun

Install via yarn

  yarn global add ezrun

Run a scene

Run a scene file

  r $PATH_TO_SCENE_FILE

Run a encrypted scene file with a password

  r $PATH_TO_SCENE_FILE $PASSWORD

Override env variables then run

  r -e "port=80" -e "log=error" -- $PATH_TO_SCENE_FILE

CLI

Show helps

  r -h

Upgrade external tags which are auto installed when lacks in the scene

  r up ezrun-telegram@latest

Customize source paths which are registed tags in application

  r --tagDirs /myapp1 --tagDirs /myapp2 -- myapp.yaml     # "/myapp1", "/myapp2" are includes source code

Example

  1. Create a scene file at test.yaml
title: Test scene
runs:
  - Hello world
  1. Run
  r test.yaml

Common tags which is used in the program

TagsDescription
md'docGenerate comment in a file to document
echoPrint to console screen
clearClear console screen
execExecute a program
exec'jsExecute a nodejs code
exec'shExecute a shell script
exitStop then quit the program
file'readRead a file then load data into a variable
file'storeStore data to file
file'writeWrite data to file
groupGroup elements
http'delSend a http request with DELETE method
http'getSend a http request with GET method
http'headSend a http request with HEAD method
http'patchSend a http request with PATCH method
http'postSend a http request with POST method
http'putSend a http request with PUT method
http/jobsCreate a jobs queue to do something step by step
http/jobs'addAdd a job to the queue
http/jobs'stopStop the jobs queue
input'confirmGet user confirm (yes/no)
input'multiselectSuggest a list of choices for user then allow pick multiple choices
input'numberGet user input from keyboard then convert to number
input'passwordGet user input from keyboard but hide them then convert to text
input'selectSuggest a list of choices for user then allow pick a choice
input'suggestSuggest a list of choices for user then allow pick a choice or create a new one
input'textGet user input from keyboard then convert to text
npm'installInstall librarries to use in the scene.
npm'uninstallUninstall librarries to use in the scene.
pausePause the program then wait to user enter to continue
sceneLoad another scene into the running program
sleepSleep the program then wait to user enter to continue
tag'registerRegister custom tags from code or npm module, github....
testCheck conditions in the program
varsDeclare and set value to variables to reused in the scene/global scope
  • If the first character is uppercase, it's auto assigned to global which is used in the program (all of scenes)
  • If the first character is NOT uppercase, it will be assigned to scene scope which is only used in the scene | | view | View data in a pretty format | | view'json | View data in a json format | | view'table | View data in a table format | | view'yaml | View data in a yaml format |

Root scene

It's a scene file
Root scene file includes all of steps to run

Example:

  title: Scene name                 # Scene name
  description: Scene description    # Scene description
  log: info                         # Show log when run. Default is info. [silent, error, warn, info, debug, trace, all]
  password:                         # Encrypted this file with the password. To run this file, need to provides a password in the command line
  vars:                             # Declare global variables which are used in the program.
    env: production                 # |- Only the variables which are declared at here just can be overrided by environment variables
  runs:                             # Defined all of steps which will be run in the scene
    - echo: Hello world
    - test: test props

->

It's a property in a tag
Expose item properties for others extends

Example:

  - echo:                     # Not run
      ->: helloTemplate
      skip: true
      content: Hello

  - echo:                     # => Hi
      <-: helloTemplate
      content: Hi

<-

It's a property in a tag
Copy properties from others (a item, or list items)

Example:

  - http'get:
      skip: true
      ->: baseRequest
      baseURL: http://localhost
  - http'get:
      skip: true
      <-: baseRequest
      ->: user1Request
      headers:
        authorization: Bearer user1_token
  - http'get:
      skip: true
      ->: user2RequestWithoutBaseURL
      headers:
        authorization: Bearer user2_token

  - http'get:                      # Send a get request with baseURL is "http://localhost" and headers.authorization is "Bearer user1_token"
      <-: user1Request
      url: /posts
      vars: user1Posts

  - http'get:                      # Send a get request with baseURL is "http://localhost" and headers.authorization is "Bearer user2_token"
      <-:
        - baseRequest
        - user2RequestWithoutBaseURL
      url: /posts
      vars: user2Posts

async

It's a property in a tag
Execute parallel tasks

Example:

  - http'get:
      async: true
      url: /categories
      vars: categories
  - http'get:
      async: true
      url: /product/1
      vars: product

  - echo: The product ${product.name} is in the categories ${categories.map(c => c.name)}

force

It's a property in a tag
Try to execute and ignore error in the running

Example:

  - echo:                     # Not run
      force: true
      content: Got error "abc is not defined" but it should not stop here ${abc}

  - echo: Keep playing

if

It's a property in a tag
Check condition before run the item

Example:

  - vars:
      number: 11
  - echo:                               # => Value is greater than 10
      if: ${vars.number > 10}
      content: Value is greater than 10
  - echo:                               # No print
      if: ${vars.number < 10}
      content: Value is lessthan than 10

log

It's a property in a tag
How to print log details for each of item. Default is info Value must be:

  • all: Print all of log message
  • trace: Print all of log message
  • debug: Print short of log
  • info: Print title, not show log details
  • warn: Only show warning log
  • error: Only show error log

Example:

  - http'get:
      title: Get data from a API
      log: debug
      url: http://...../data.json

loop

It's a property in a tag
Loop to run items with a condition

Example:

Loop in array

  - vars:
      arrs: [1,2,3,4]
  - echo:
      loop: ${vars.arrs}
      content: Index is ${this.loopKey}, value is ${this.loopValue}
  # =>
  # Index is 0, value is 1
  # Index is 1, value is 2
  # Index is 2, value is 3
  # Index is 3, value is 4

Loop in object

  - vars:
      obj: {
        "name": "thanh",
        "sex": "male"
      }
  - echo:
      loop: ${vars.obj}
      content: Key is ${this.loopKey}, value is ${this.loopValue}
  # =>
  # Key is name, value is thanh
  # Key is sex, value is male

Dynamic loop in a condition

  - vars:
      i: 0
  - echo:
      loop: ${vars.i < 3}
      content: value is ${vars.i++}
  # =>
  # value is 0
  # value is 1
  # value is 2

Loop in nested items

  - vars:
      arrs: [1,2,3]
  - group:
      loop: ${vars.arrs}
      title: group ${this.loopValue}
      items:
        - echo: item value is ${this.parent.loopValue}
  # =>
  # group 1
  # item value is 1

skip

It's a property in a tag
Only init but not execute

Example:

  - echo:                     # Not run
      ->: helloTemplate
      skip: true
      content: Hello

  - echo:                      # => Hi
      <-: helloTemplate
      content: Hi

title

It's a property in a tag
Title

Example:

  - sleep:
      title: Sleep in 1s
      duration: 1000

vars

It's a property in a tag
Set value in the item to global vars to reused later

Example:

  - echo:
      content: Hello world
      vars: helloText
  - echo: ${vars.helloTexxt}
  # =>
  # Hello world

md'doc

doc
Generate comment in a file to document

Example:

  - doc'md:
      includeDirs:
        - /workspaces/ezrun/src/components/doc/md.ts
      includePattern: "^(?!.*\\.spec\\.ts$)"
      excludeDirs:
        - node_modules
      prependMDs:                                     # Prepend content in the document (Optional)
        - path: ${utils.curDir}/../INSTALLATION.md    # |- {path}: Read file content then copy it into document
        - ---                                         # |- string: Markdown content
      appendMDs:                                      # Append content in the document
        - ---
        - "### Have fun :)"
      saveTo: /workspaces/ezrun/test/thanh.doc.md

Declare doc in file Example

echo

Print to console screen

Example:

Print a message

  - echo: Hello world

  - echo:
      if: ${true}
      content: Hello

Print a variable

  - vars:
      name: thanh
  - echo: ${vars.name}

Quick print

  - Hello world

  - vars:
      name: thanh
  - ${vars.name}

Print text with custom type. (Follow "chalk")

  - echo'red: Color is red
  - echo'yellow: Color is yellow
  - echo'gray: Color is gray
  - echo'blue: Color is blue
  - echo'cyan: Color is cyan
  - echo'green: Color is green
  - echo'magenta: Color is magenta
  - echo: Color is white

  - echo:
      style: red
      content: Color is red
  - echo:
      style: red.bold
      content: Content is red and bold

clear

Clear console screen

Example:

  - clear:

exec

Execute a program

Example:

Execute a bash script

  - exec:
      title: Run a bash script
      commands:
        - /bin/sh
        - /startup.sh

Execute a python app

  - exec:
      title: Run a python app
      commands:
        - python
        - app.py

exec'js

Execute a nodejs code

Example:

Set value to a variable

  - exec'js:
      title: Set value to a variable
      script: |
        vars.name = 'thanh'
        logger.info(vars.name)

Write a file

  - exec'js:
      title: Write a file
      path: /sayHello.sh              # Path of js file (Use only "path" OR "script")
      script: |                       # NodeJS content
        const { writeFileSync } = require('fs')
        writeFileSync('/tmp/hello.txt', 'Hello world')
        return "OK"
      vars: result    # !optional

exec'sh

Execute a shell script

Example:

  - exec'sh:
      title: Write a hello file
      path: /sayHello.sh              # Path of sh file (Use only "path" OR "script")
      script: |                       # Shell script content
        touch hello.txt
        echo "Hello world" > /tmp/hello.txt
      bin: /bin/sh    # !optional. Default use /bin/sh to run sh script
      vars: log       # !optional

exit

Stop then quit the program

Example:

  - exit:

file'read

Read a file then load data into a variable

Example:

Read a json file

  - file'read:
      path: /tmp/data.json
      vars: fileData
      format: json  # !optional

Read a yaml file

  - file'read:
      path: /tmp/data.yaml
      vars: fileData
      format: yaml  # !optional

Read a text file

  - file'read:
      path: /tmp/data.txt
      vars: fileContent

file'store

Store data to file

Example:

  - file'store:
      path: /tmp/data.json      # Path to store data
      password:                 # Password to encrypt/decrypt data content
      initData: []              # Default data will be stored when file not found

Use in global by reference

  - file'store:
      path: /tmp/data.yaml
      initData: []
      vars:
        fileDB: ${this}         # Store this element to "fileDB" in vars

  - exec'js: |
      const { fileDB } = vars
      fileDB.data.push('item 1')
      fileDB.data.push('item 2')
      // Save data to file
      fileDB.save()

  - echo: ${vars.fileDB.data}   # => ['item 1', 'item 2']

file'write

Write data to file

Example:

Write a json file

  - file'write:
      path: /tmp/data.json
      content: {
        "say": "hello"
      }
      format: json  # !optional
      pretty: true  # !optional

Write a yaml file

  - file'write:
      path: /tmp/data.yaml
      content: ${vars.fileData}
      format: yaml  # !optional

Write a text file

  - file'write:
      path: /tmp/data.txt
      content: Hello world

group

Group elements

Example:

  - group:
      title: Print all of message
      runs:
        - echo: hello
        - echo: world
        - group:
            title: Stop
            runs:
              - exit:

http'del

Send a http request with DELETE method

Example:

  # DELETE http://localhost:3000/posts/1?method=check_existed
  - http'del:
      title: Delete a post
      url: /posts/1
      baseURL: http://localhost:3000  # !optional - Request base url
      query:                          # !optional - Request query string
        method: check_existed
      headers:                        # !optional - Request headers
        authorization: Bearer TOKEN
      timeout: 5000                   # !optional - Request timeout. Default is no timeout
      vars:                           # !optional - Global variable which store value after executed
        status: ${this.response.status}

http'get

Send a http request with GET method

Example:

Get data from API then store value in vars.posts

  # GET http://localhost:3000/posts?category=users
  - http'get:
      title: Get list posts
      url: /posts
      timeout: 5000                   # !optional - Request timeout. Default is no timeout
      baseURL: http://localhost:3000  # !optional - Request base url
      query:                          # !optional - Request query string
        category: users
      headers:                        # !optional - Request headers
        authorization: Bearer TOKEN
      responseType: json              # !optional - Default is json ['json' | 'blob' | 'text' | 'buffer' | 'none']
      vars: posts                     # !optional - Global variable which store value after executed

Download file from a API

  # GET http://localhost:3000/posts?category=users
  - http'get:
      title: Download a file
      baseURL: http://localhost:3000
      url: /posts
      query:
        category: users
      headers:
        authorization: Bearer TOKEN
      saveTo: /tmp/post.json

http'head

Send a http request with HEAD method

Example:

  # HEAD http://localhost:3000/posts/1?method=check_existed
  - http'head:
      title: Check post is existed or not
      baseURL: http://localhost:
      timeout: 5000                   # !optional - Request timeout. Default is no timeout
      url: /posts/1
      query:
        method: check_existed
      headers:
        authorization: Bearer TOKEN
      vars:
        status: ${this.response?.status}

http'patch

Send a http request with PATCH method

Example:

Update apart of data to API then store value in vars.posts

  # PATCH http://localhost:3000/posts/ID?category=users
  - http'patch:
      title: Update a post
      baseURL: http://localhost:3000
      url: /posts/ID
      query:
        category: users
      headers:
        authorization: Bearer TOKEN
      type: json                      # 'json' | 'form' | 'raw' | 'multipart' | 'text'
      timeout: 5000                   # !optional - Request timeout. Default is no timeout
      body: {
        "title": "My title",
        "description": "My description"
      }
      responseType: json              # 'json' | 'blob' | 'text' | 'buffer' | 'none'
      vars: newPost

Upload file to server

  # PATCH http://localhost:3000/upload/ID_UPLOADER_TO_REPLACE
  - http'patch:
      title: Upload and update data
      baseURL: http://localhost:3000
      url: /upload/ID_UPLOADER_TO_REPLACE
      headers:
        authorization: Bearer TOKEN
      type: multipart
      body: {
        "file": { # File upload must includes path of file, name is optional
          "path": "/tmp/new_my_avatar.jpg",
          "name": "thanh_avatar"
        }
      }
      vars:
        status: ${this.response.status}

http'post

Send a http request with POST method

Example:

Post data to API then store value in vars.posts

  # POST http://localhost:3000/posts?category=users
  - http'post:
      title: Create a new post
      baseURL: http://localhost:3000
      url: /posts
      query:
        category: users
      headers:
        authorization: Bearer TOKEN
      type: json                      # 'json' | 'form' | 'raw' | 'multipart' | 'text'
      timeout: 5000                   # !optional - Request timeout. Default is no timeout
      body: {
        "title": "My title",
        "description": "My description"
      }
      responseType: json              # 'json' | 'blob' | 'text' | 'buffer' | 'none'
      vars: newPost

Upload file to server

  # POST http://localhost:3000/upload
  - http'post:
      title: Upload a new avatar
      baseURL: http://localhost:3000
      url: /upload
      headers:
        authorization: Bearer TOKEN
      type: multipart
      body: {
        "category": "avatar",
        "file": { # File upload must includes path of file, name is optional
          "path": "/tmp/my_avatar.jpg",
          "name": "thanh_avatar"
        }
      }
      vars:
        status: ${this.response.status}

http'put

Send a http request with PUT method

Example:

Update data to API then store value in vars.posts

  # PUT http://localhost:3000/posts/ID?category=users
  - http'put:
      title: Update a post
      baseURL: http://localhost:3000
      url: /posts/ID
      query:
        category: users
      headers:
        authorization: Bearer TOKEN
      type: json                      # 'json' | 'form' | 'raw' | 'multipart' | 'text'
      timeout: 5000                   # !optional - Request timeout. Default is no timeout
      body: {
        "title": "My title",
        "description": "My description"
      }
      responseType: json              # 'json' | 'blob' | 'text' | 'buffer' | 'none'
      vars: newPost

Upload file to server

  # PUT http://localhost:3000/upload/ID_UPLOADER_TO_REPLACE
  - http'put:
      title: Upload and update data
      baseURL: http://localhost:3000
      url: /upload/ID_UPLOADER_TO_REPLACE
      headers:
        authorization: Bearer TOKEN
      type: multipart
      body: {
        "category": "avatar updated",
        "file": { # File upload must includes path of file, name is optional
          "path": "/tmp/new_my_avatar.jpg",
          "name": "thanh_avatar"
        }
      }
      vars:
        status: ${this.response.status}

http/jobs

Create a jobs queue to do something step by step

Example:

  - file'store:                       # Defined a file store to save data to file
      path: /tmp/test.queue,
      initData: [],
      vars:
        fileStorage: '${this}'

  - http/jobs:
      address: 0.0.0.0:8811           # Address to listen to add a new job to
      queue:                          # Wait to finish a job before keep doing the next
        concurrent: 1                 # Num of jobs can be run parallel
        storage: ${vars.fileStorage}  # Set a storage to queue
      runs:                           # Steps to do a job
        - ${parentState.jobData}      # {parentState.jobData} is job data in the queue which is included both querystring and request body
        - ${parentState.jobInfo}      # {parentState.jobInfo} is job information
                                      # {parentState.jobInfo.path} request path
                                      # {parentState.jobInfo.method} request method
                                      # {parentState.jobInfo.query} request query string
                                      # {parentState.jobInfo.headers} request headers

http/jobs'add

Add a job to the queue

Example:

Add a job by default

  - http/jobs'add:
      address: 0.0.0.0:3007         # Address to listen to add a new job to queue
      data:                         # Steps to do a job
        name: name1
        age: 2

Use a "GET" http request to add a job

  - http'get:
      url: http://0.0.0.0:3007?name=name1&age=2

Use a "POST" http request to add a job

  - http'post:
      url: http://0.0.0.0:3007?name=name1
      body:
        age: 2

http/jobs'stop

Stop the jobs queue

Example:

  - http/jobs:
      address: 0.0.0.0:3007         # Address to listen to add a new job to
      runs:                         # Steps to do a job
        - echo: Display then stop
        - http/jobs'stop:           # Stop job here

input'confirm

Get user confirm (yes/no)

Example:

# - input'conf:
  - input'confirm:
      title: Are you sure to delete it ?
      vars: userWantToDelete
      default: false  # !optional
      required: true  # !optional

input'multiselect

Suggest a list of choices for user then allow pick multiple choices

Example:

# - input'msel:
  - input'multiselect:
      title: Please select your hobbies ?
      vars: hobbies
      choices:
        - title: Tennis
          value: tn
        - title: Football
          value: fb
        - title: Basket ball
          value: bb
      default: [tn, fb]   # !optional
      required: true      # !optional

input'number

Get user input from keyboard then convert to number

Example:

# - input'num:
  - input'number:
      title: Enter your age ?
      vars: age
      default: 18     # !optional
      required: true  # !optional

input'password

Get user input from keyboard but hide them then convert to text

Example:

# - input'pwd:
  - input'password:
      title: Enter your password ?
      vars: password
      required: true  # !optional

input'select

Suggest a list of choices for user then allow pick a choice

Example:

# - input'sel:
  - input'select:
      title: Your sex ?
      vars: sex
      choices:
        - title: male
          value: m
        - title: female
          value: f
      default: m      # !optional
      required: true  # !optional

input'suggest

Suggest a list of choices for user then allow pick a choice or create a new one

Example:

# - input'sug:
  - input'suggest:
      title: Your hobby
      vars: hobby
      choices:
        - title: Football
          value: football
        - title: Basket Ball
          value: backetball
      default: football                         # !optional
      required: true                            # !optional
      suggestType: INCLUDE_AND_ALLOW_NEW        # Must be in [STARTSWITH_AND_ALLOW_NEW, INCLUDE_AND_ALLOW_NEW, STARTSWITH, INCLUDE]
                                                # - "INCLUDE": Only find in the text in the list suggestions
                                                # - "INCLUDE_AND_ALLOW_NEW": Same "INCLUDE" and allow to create a new one if not in the list suggestions
                                                # - "STARTSWITH": Only find in the start of text
                                                # - "STARTSWITH_AND_ALLOW_NEW": Same "STARTSWITH" and allow to create a new one if not in the list suggestions

input'text

Get user input from keyboard then convert to text

Example:

# - input:
  - input'text:
      title: Enter your name
      vars: name
      default: Noname # !optional
      required: true  # !optional

npm'install

Install librarries to use in the scene.

Example:

  - npm'install: module1, module2

  - npm'install:
      - module1
      - myapp: git+ssh:git@github.com:...

  - npm'install:
      packages:
        - lodash
        - ezrun-telegram@latest     // Always get latest ezrun-telegram librarry

  # How to used
  - exec'js: |
      vars.newObject = require('lodash').merge({a: 2, b: 2}, {a: 1})
      require('myapp')

  - echo'pretty: ${vars.newObject}

Install from github

  - npm'install:
      title: Install from github
      if: ${vars.useExternalPackage}
      packages:
        - myapp: git+ssh:git@github.com:...
        - ezrun...

  # How to used
  - myapp:
      title: This is my first application

npm'uninstall

Uninstall librarries to use in the scene.

Example:

  - npm'uninstall: module1, module2

  - npm'uninstall:
      - module1
      - myapp

  - npm'uninstall:
      title: Uninstall librarry
      packages:
        - ezrun-telegram
        - ezrun...

pause

Pause the program then wait to user enter to continue

Example:

  - pause:

  - pause:
      title: Pause here

scene

Load another scene into the running program

Example:

  - scene:
      title: A scene from remote server
      path: https://.../another.yaml    # path can be URL or local path
      password:                         # password to decode when the file is encrypted
      vars:                             # Set value to global environment
        foo: bar

sleep

Sleep the program then wait to user enter to continue

Example:

Sleep for a time

  - sleep: 10000              # Sleep 10s then keep continue

Full props

  - sleep:
      title: Sleep 10s
      duration 10000          # Sleep 10s then keep continue

tag'register

Register custom tags from code or npm module, github....

Example:

Register custom tags from a file

  - tag'register:
      test1: /workspaces/ezrun/test/resources/test.js       # { tagName: pathOfModule }

  - test1:
      foo: bar

Register custom tags from an object

  - tag'register:
      newOne: |
        {
          constructor(props) {
            Object.assign(this, props)
          },
          async asyncConstructor(props) {
            // Do async job to init data
          },
          exec() {
            this.logger.info('ok ' + this.name, this.tag)
          },
          dispose() {
            // Dispose after finished this
          },
          disposeApp() {
            // Dispose when exit app
          }
        }

  - newOne:
      name: foo

Register custom tags from a class

  - tag'register:
      newOne: |
        class {
          constructor(props) {
            Object.assign(this, props)
          }
          async asyncConstructor(props) {
            // Do async job to init data
          }
          exec() {
            this.logger.info('ok ' + this.name, this.tag)
          }
          dispose() {
            // Dispose after finished this
          }
          disposeApp() {
            // Dispose when exit app
          }
        }

  - newOne:
      name: foo

test

Check conditions in the program

Example:

Quick test

  - test:
      title: Number must be greater than 10
      check: ${vars.age > 10}

  - test: ${vars.age < 10}

Test with nodejs script

  - test:
      title: Number must be greater than 10
      script: |
        if (vars.age > 10) this.failed('Age is not valid')

vars

Declare and set value to variables to reused in the scene/global scope

  • If the first character is uppercase, it's auto assigned to global which is used in the program (all of scenes)
  • If the first character is NOT uppercase, it will be assigned to scene scope which is only used in the scene

Example:

A main scene file

  - vars:
      MainName: global var      # Is used in all of scenes
      mainName: local var       # Only used in this scene

  - scene:
      path: ./child.scene.yaml

  - echo: ${vars.MainName}      # => global var
  - echo: ${vars.mainName}      # => local var
  - echo: ${vars.name}          # => undefined
  - echo: ${vars.Name}          # => global name here

A scene file child.scene.yaml is:

  - vars:
      Name: global name here
      name: scene name here     # Only used in this scene

  - echo: ${vars.MainName}      # => global var
  - echo: ${vars.mainName}      # => undefined
  - echo: ${vars.name}          # => scene name here
  - echo: ${vars.Name}          # => global name here

view

View data in a pretty format

Example:

  - view:
      title: Pretty Viewer
      data: [{ name: "name 2", age: 2 }, { name: "name 2", age: 3 }]

  - view: ${vars.TEST_DATA}

view'json

View data in a json format

Example:

  - view'json:
      title: JSON Viewer
      data: [{ name: "name 2", age: 2 }, { name: "name 2", age: 3 }]

  - view'json: ${vars.TEST_DATA}

view'table

View data in a table format

Example:

  - view'table:
      title: Table viewer
      headers:            # Pick some headers to show. Default is all
        - name
        - age
      data: [{ name: "name 2", age: 2 }, { name: "name 2", age: 3 }]

  - view'table: ${vars.TEST_DATA}

view'yaml

View data in a yaml format

Example:

  - view'yaml:
      title: Yaml Viewer
      data: [{ name: "name 2", age: 2 }, { name: "name 2", age: 3 }]

  - view'yaml: ${vars.TEST_DATA}

Have fun :)

1.0.0-alpha.19

1 year ago

1.0.0-alpha.16

1 year ago

1.0.0-alpha.18

1 year ago

1.0.0-alpha.17

1 year ago

1.0.0-alpha.21

1 year ago

1.0.0-alpha.20

1 year ago

1.0.0-alpha.27

1 year ago

1.0.0-alpha.26

1 year ago

1.0.0-alpha.29

1 year ago

1.0.0-alpha.28

1 year ago

1.0.0-alpha.23

1 year ago

1.0.0-alpha.22

1 year ago

1.0.0-alpha.25

1 year ago

1.0.0-alpha.24

1 year ago

1.0.0-alpha.30

1 year ago

1.0.0-alpha.31

1 year ago

1.0.0-alpha.15

1 year ago

1.0.0-alpha.14

1 year ago

1.0.0-alpha.13

1 year ago

1.0.0-alpha.12

1 year ago

1.0.0-alpha.11

1 year ago

1.0.0-alpha.10

1 year ago

1.0.0-alpha.9

1 year ago

1.0.0-alpha.8

1 year ago

1.0.0-alpha.7

1 year ago

1.0.0-alpha.6

1 year ago

1.0.0-alpha.5

1 year ago

1.0.0-alpha.4

1 year ago

1.0.0-alpha.3

1 year ago

1.0.0-alpha.2

1 year ago

1.0.0-alpha.1

1 year ago

1.0.0-alpha.0

1 year ago

0.0.0-alpha.66

1 year ago

0.0.0-alpha.65

1 year ago

0.0.0-alpha.64

1 year ago

0.0.0-alpha.63

1 year ago

0.0.0-alpha.62

1 year ago

0.0.0-alpha.61

1 year ago

0.0.0-alpha.59

1 year ago

0.0.0-alpha.58

1 year ago

0.0.0-alpha.57

1 year ago

0.0.0-alpha.56

1 year ago

0.0.0-alpha.55

1 year ago

0.0.0-alpha.54

1 year ago

0.0.0-alpha.53

1 year ago

0.0.0-alpha.52

1 year ago

0.0.0-alpha.51

1 year ago

0.0.0-alpha.50

1 year ago

0.0.0-alpha.49

1 year ago

0.0.0-alpha.48

1 year ago

0.0.0-alpha.47

1 year ago

0.0.0-alpha.46

1 year ago

0.0.0-alpha.45

1 year ago

0.0.0-alpha.44

1 year ago

0.0.0-alpha.42

1 year ago

0.0.0-alpha.41

1 year ago

0.0.0-alpha.40

1 year ago

0.0.0-alpha.39

1 year ago

0.0.0-alpha.38

1 year ago

0.0.0-alpha.37

1 year ago

0.0.0-alpha.35

1 year ago

0.0.0-alpha.33

1 year ago

0.0.0-alpha.32

1 year ago

0.0.0-alpha.31

1 year ago

0.0.0-alpha.30

1 year ago

0.0.0-alpha.29

1 year ago

0.0.0-alpha.28

1 year ago

0.0.0-alpha.27

1 year ago

0.0.0-alpha.26

1 year ago

0.0.0-alpha.25

1 year ago

0.0.0-alpha.24

1 year ago

0.0.0-alpha.23

1 year ago

0.0.0-alpha.22

1 year ago

0.0.0-alpha.21

1 year ago

0.0.0-alpha.20

1 year ago

0.0.0-alpha.19

1 year ago

0.0.0-alpha.18

1 year ago

0.0.0-alpha.17

1 year ago

0.0.0-alpha.16

1 year ago

0.0.0-alpha.15

1 year ago

0.0.0-alpha.14

1 year ago

0.0.0-alpha.13

1 year ago

0.0.0-alpha.12

1 year ago

0.0.0-alpha.11

1 year ago

0.0.0-alpha.10

1 year ago

0.0.0-alpha.9

1 year ago

0.0.0-alpha.8

1 year ago

0.0.0-alpha.7

1 year ago

0.0.0-alpha.6

1 year ago

0.0.0-alpha.5

1 year ago

0.0.0-alpha.4

1 year ago

0.0.0-alpha.3

1 year ago

0.0.0-alpha.2

1 year ago

0.0.0-alpha.1

1 year ago