npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ymlr

v1.3.1-alpha.8

Published

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

Downloads

638

Readme

ymlr

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

Installation

Install via npm

  npm install -g ymlr

Install via yarn

  yarn global add ymlr

Supported tags

  1. ymlr-mqtt Pub/sub messages to channels in mqtt
  2. ymlr-redis Handle redis into ymlr platform
  3. ymlr-telegram Send telegram text, photo..., support "listen", "command", "hears"... in telegram bot
  4. ymlr-sql Execute query to mysql, postgresql, orable, sqlite...
  5. ymlr-cron Schedule jobs to do something base on cron pattern

Run a scene

Run a scene file

  ymlr $PATH_TO_SCENE_FILE

Run a encrypted scene file with a password

  ymlr $PATH_TO_SCENE_FILE $PASSWORD

Override env variables then run

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

CLI

Show helps

  ymlr -h

Show all tags version

  ymlr

Add new external tags, libraries which is used in the scene

  ymlr add ymlr-telegram@latest

Upgrade external tags, libraries which is used in the scene

  ymlr up ymlr-telegram@latest

Remove external tags, libraries which is used in the scene

  ymlr rm ymlr-telegram@latest

Customize source paths which are registed tags in your application

  ymlr --tag-dirs /myapp1 --tag-dirs /myapp2 -- myapp.yaml     # "/myapp1", "/myapp2" are includes source code

Override show debug log for all of tags

  ymlr --debug=all -- myapp.yaml

Docker

Docker image file: circle2jt/ymlr

Run a scene file.
Default is /script/index.yaml, you can override it in commands
$PASSWORD is optional when run a encrypted scene file

  docker run -v $PATH_TO_SCENE_FILE:/scripts/index.yaml --rm -it circle2jt/ymlr /scripts/index.yaml $PASSWORD

Run a specific file

  docker run -v $PATH_TO_SCENE_DIR:/scripts --rm -it circle2jt/ymlr /scripts/$PATH_TO_SCENE_FILE

Example

  1. Create a scene file at test.yaml
name: Test scene
runs:
  - echo: Hello world

  - name: Get post data
    http'get:
      url: http://localhost:3000/posts
    vars: postData

  - echo: ${ $vars.postData }
  1. Run
  ymlr test.yaml

Common tags which is used in the program

| Tags | Description | |---|---| | md'doc | Generate comment in a file to document | | echo | Print to console screen | | echo'debug | Add more information when print to console screen | | clear | Clear console screen | | event'emit | Send data via global event | | event'on | Handle global events in app | | fn-debounce | Debounce function (#Ref: lodash.debounce) | | fn-debounce'cancel | Cancel debounce function (#Ref: lodash.debounce) | | fn-debounce'del | Cancel & remove debounce function (#Ref: lodash.debounce) | | fn-debounce'flush | Force to call debounce function ASAP if it's called before that (#Ref: lodash.debounce) | | fn-debounce'touch | touch debounce function. Reused last agruments(#Ref: lodash.debounce) | | fn-queue | Register a queue job | | fn-queue'add | Add a job to an exsited queue | | fn-queue'del | Stop and remove a queue | | fn-singleton | This is locked before run and unlock after done. When it's called many time, this is only run after unlock | | fn-singleton'del | Remove singleton function | | fn-throttle | Throttle function (#Ref: lodash.throttle) | | fn-throttle'cancel | Cancel throttle function (#Ref: lodash.throttle) | | fn-throttle'del | Cancel & remove throttle function (#Ref: lodash.throttle) | | fn-throttle'flush | Force to call throttle function ASAP if it's called before that (#Ref: lodash.throttle) | | fn-throttle'touch | touch throttle function. Reused last agruments (#Ref: lodash.throttle) | | exec | Execute a program | | exec'js | Execute a nodejs code | | exec'sh | Execute a shell script | | exit | Stop then quit the program | | fetch'del | Send a http request with DELETE method | | fetch'get | Send a http request with GET method | | fetch'head | Send a http request with HEAD method | | fetch'patch | Send a http request with PATCH method | | fetch'post | Send a http request with POST method | | fetch'put | Send a http request with PUT method | | file'read | Read a file then load data into a variable | | file'store | Store data to file | | file'write | Write data to file | | http'del | Send a http request with DELETE method | | http'get | Send a http request with GET method | | http'head | Send a http request with HEAD method | | http'patch | Send a http request with PATCH method | | http'post | Send a http request with POST method | | http'put | Send a http request with PUT method | | http'server | Create a http server to serve content via http | | include | Include a scene file or list scene files in a folder | | input'confirm | Get user confirm (yes/no) | | input'multiselect | Suggest a list of choices for user then allow pick multiple choices | | input'number | Get user input from keyboard then convert to number | | input'password | Get user input from keyboard but hide them then convert to text | | input'select | Suggest a list of choices for user then allow pick a choice | | input'suggest | Suggest a list of choices for user then allow pick a choice or create a new one | | input'text | Get user input from keyboard then convert to text | | js | Execute a nodejs code | | npm'install | Install librarries to use in the scene. | | npm'uninstall | Uninstall librarries to use in the scene. | | pause | Pause the program then wait to user enter to continue | | runs | Group elements | | scene | Load another scene into the running program | | scene'returns | Return value to parent scene | | scene'thread | Same "scene" but it run in a new thread | | sh | Execute a shell script | | sleep | Sleep the program then wait to user enter to continue | | tag'register | Register custom tags from code or npm module, github.... | | test | Check conditions in the program | | view'flow | View flows in a scene |

Root scene

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

Example:

  name: Scene name                  # Scene name
  description: Scene description    # Scene description
  debug: 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 in the top of root scene just can be overrided by environment variables
  env:                              # Set value to environment variable (process.env)
    DEBUG: all
    NODE_ENV: production
    env: dev                        # It overrides to $vars.env
    # - NODE_ENV=production
  envFiles:                         # Load env variable from files (string | string[])
    - .env
    - .env.dev
  varsFiles:                        # Load vars from json or yaml files (string | string[])
    - ./var1.json
    - ./var2.yaml
  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:

Use skip

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

  - <-: helloTemplate         # => Hello

Use template

  - ->: hiTemplate
    template: Hi              # Not run

  - <-: hiTemplate            # => Hi
    echo:

# @include

It's a yaml comment type
Include the content file to current position. This is will be read a file then copy file content into current position If you want to use expresion ${}, you can use tag "include". Useful for import var file ....

Example:

  - vars:
      # @include ./.env

.env file is

ENV: production
APP: test

<-

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

Example:

  - ->: baseRequest
    template:
      baseURL: http://localhost
  - <-: baseRequest
    ->: user1Request
    template:
      headers:
        authorization: Bearer user1_token
  - ->: user2RequestWithoutBaseURL
    template:
      headers:
        authorization: Bearer user2_token

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

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

async

It's a property in a tag
Execute parallel tasks

Example:

  - async: true
    http'get:
      url: /categories
    vars: categories
  - ~http'get:            # Can use shortcut by add "~"" before tag name
      url: /product/1
    vars: product

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

context

It's a property in a tag
Context logger name which is allow filter log by cli "ymlr --debug-context context_name=level --"

Example:

  - name: Get list user
    context: userapi
    debug: warn
    http'get: ...

  - name: Get user details
    context: userapi
    debug: warn
    http'get: ...

  - name: Get product details
    context: productapi
    debug: warn
    http'get: ...

Now, we have 2 choices to debug all of user APIs and product APIs

  1. Replace all "debug: warn" to "debug: debug"
  2. Only run cli as below
  ymlr --debug-context userapi=debug --debug-context productapi=trace -- $SCENE_FILE.yaml

debug

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

  • true: is debug
  • all: Same trace
  • trace: Print all of messages
  • debug: Print of debug, info, warn, error, fatal messages
  • info: Print info, warn, error, fatal messages
  • warn: Print warn, error, fatal messages
  • error: Print error, fatal messages
  • fatal: Print fatal messages
  • secret: Only show secret log. Example config, password, keys...
  • silent: Not print anything

Example:

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

detach

It's a property in a tag
Push the tag execution to background jobs to run async, the next steps will be run ASAP. Before the program is exited, it will be released

Example:

  - name: job1
    detach: true
    loop: ${[1,2,3]}
    runs:
      - echo: Hello ${this.parentProxy.loopValue}
      - sleep: 1s
  - name: job2
    echo: first
  - name: job3
    echo: second

In above example, job2, job3 will run step by step, but job1 run in background, the program will wait job1 done then finish the program

else

It's a property in a tag
Check condition before run the item and skip the next cases when it passed

Example:

  - vars:
      number: 11

  - if: ${$vars.number === 11}
    echo: Value is 11                   # => Value is 11

  - elseif: ${$vars.number > 10}
    echo: Value is greater than 10      # =>

  - else:
    echo: Value is lessthan than 10     # =>

  - echo: Done                          # => Done

elseif

It's a property in a tag
Check condition before run the item and skip the next cases when it passed

Example:

  - vars:
      number: 11

  - if: ${$vars.number === 11}
    echo: Value is 11                   # => Value is 11

  - elseif: ${$vars.number > 10}
    echo: Value is greater than 10      # =>

  - elseif: ${$vars.number < 10}
    echo: Value is lessthan than 10     # =>

  - echo: Done                          # => Done

failure

It's a property in a tag
Handle error when do something wrong. Default it will exit app when something error.

  • ignore: Ignore error then keep playing the next
  • restart: max: 3 When got something error, it will be restarted automatically ASAP (-1/0 is same) sleep: 3000

Example:

  - failure:
      restart:                     # Try to restart 3 time before exit app. Each of retry, it will be sleep 3s before restart
        max: 3
        sleep: 3s
    js: |
      const a = 1/0
  - failure:
      ignore: true                 # Ignore error then play the next
    js: |
      const a = 1/0

id

It's a property in a tag
ID Reference to element object in the $vars

Example:

  - id: echo1
    echo: Hello

  - exec'js: |
      this.logger.debug($vars.echo1.content)

if

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

Example:

  - vars:
      number: 11

  - if: ${$vars.number === 11}
    echo: Value is 11                   # => Value is 11

  - if: ${$vars.number > 10}
    echo: Value is greater than 10      # => Value is greater than 10

  - if: ${$vars.number < 10}
    echo: Value is lessthan than 10     # =>

  - echo: Done                          # => Done

loop

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

  • $lv, $loopValue: Get loop value
  • $lk, $loopKey: Get loop key

Example:

Loop in array

  - vars:
      arrs: [1,2,3,4]
  - loop: ${$vars.arrs}
    echo: Index is ${$loopKey}, value is ${$loopValue}    # $loopKey ~ this.loopKey AND $loopValue ~ 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"
      }
  - loop: ${$vars.obj}
    echo: Key is ${$loopKey}, value is ${$loopValue}
  # =>
  # Key is name, value is thanh
  # Key is sex, value is male

Dynamic loop in a condition

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

Loop in nested items

  - vars:
      arrs: [1,2,3]
  - loop: ${$vars.arrs}
    name: group ${$loopValue}
    runs:
      - echo: value is ${$loopValue}                                  # => item value is "1" then "2" then "3"

      - loop: ${ [4,5,6] }
        runs:
          - echo: value is ${$loopValue}                              # => item value is "4" then "5" then "6"

          - echo: parent is ${this.parentProxy.parentProxy.loopValue} # => item value is "1" then "2" then "3"
  # =>
  # group 1
  # item value is 1

name

It's a property in a tag
Step name

Example:

  - name: Sleep in 1s
    sleep: 1000

only

It's a property in a tag
Only run this

Example:

  - echo: Hi                   # No print "hi"

  - only: true
    echo: Hello                # Only print "Hello"

  - echo: world                # No print "world"

  - only: true
    echo: Bye                  # Only print "Bye"

parentState

It's used in js code

  • Set/Get value to context variables. Used in tags support runs and support parentState Variables:
  • $ps, $parentState: Reference to context state

Example:

  - name: listen to handle an events
    event'on:
      name: test-event
    runs:
      - echo: ${ $parentState.eventData }   # => { name: Test event, data: Hello }
      - echo: ${ $ps.eventOpts }            # => [ params 1, params 2 ]

  - event'emit:
      name: test-event
      data:
        name: Test event
        data: Hello
      opts:
        - params 1
        - params 2

runs

It's a property in a tag
Steps will be run in the running element

Example:

  - http'server:
      address: 0.0.0.0:1234
    runs:
      - echo: Do something when a request comes
      - echo: Do something when a request comes...
      ...

skip

It's a property in a tag
No run this

Example:

  - echo: Hi                   # Print "hi"

  - skip: true
    echo: Hello                # No print "Hello"

  - echo: world                # Print "world"

skipNext

It's a property in a tag
Skip the next steps in the same parent group when done this

Example:

  - loop: ${ [1,2,3] }
    runs:
      - echo: begin                                          # Always print begin

      - echo: ${ this.parentProxy.loopValue }
        skipNext: ${ this.parentProxy.loopValue === 2 }      # When $loopValue is 2, skip the next step

      - echo: end                                            # Only print end when $loopValue is not equals 2

template

It's a property in a tag
Declare a template to extends later

Example:

  - ->: localhost           # Auto skip, not run it
    template:
      baseURL: http://localhost:3000

  - <-: localhost           # => Auto inherits "baseURL" from localhost
    http'get:
      url: /items

vars

It's a property in a tag

  • Set value in the item to global vars to reused later
  • 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 Variables:
  • $v, $vars: Reference to variables

Example:

A main scene file

  - echo: Hello world
    vars: helloText             # Save output from echo to global variable "helloText"
  - echo: ${$vars.helloText}    # => Hello world

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

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

  - fetch'get:
      url: http://localhost/data.json
    vars:
      myResponseData: ${ this.$.response.data }                         # Assign response data to scene variable
      MyResponseData: ${ this.$.response.data }                         # Assign response data to global variable
      _: ${ $parentState.responseDataInContext = this.$.response.data } # Assign response data to context variable

  - 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

md'doc

doc
Generate comment in a file to document

Example:

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

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

  - echo: Color is white

  - echo:
      styles: [red]
      content: Color is red
  - echo:
      styles: [red, bold]
      content: Content is red and bold

echo'debug

Add more information when print to console screen

Example:

Print a message

                                            # Default prepend execution time into log
  - echo'debug: Hello world                 # => 01:01:01.101    Hello world

  - echo'debug:
      formatTime: YYYY/MM/DD hh:mm:ss.ms    # Default format is "hh:mm:ss.ms"
      content: Hello                        # => 2023/01/01 01:01:01.101    Hello

clear

Clear console screen

Example:

  - clear:

event'emit

Send data via global event

Example:

  - name: send data to an event
    event'emit:
      name: test-event
      data:
        name: Test event
        data: Hello
      opts:
        - params 1
        - params 2

  - name: send data to multiple events
    event'emit:
      names:
        - test-event1
        - test-event2
        - test-event3
      data:
        name: Test event
        data: Hello
      opts:
        - params 1
        - params 2

event'on

Handle global events in app

Example:

  - name: listen to handle an events
    event'on:
      name: test-event
    runs:
      - echo: ${ $parentState.eventData }   # => { name: Test event, data: Hello }
      - echo: ${ $parentState.eventOpts }   # => [ params 1, params 2 ]

  - name: listen to handle multiple events
    event'on:
      names:
        - test-event1
        - test-event2
        - test-event3
    runs:
      - echo: ${ $parentState.eventData }   # => { name: Test event, data: Hello }
      - echo: ${ $parentState.eventOpts }   # => [ params 1, params 2 ]
  - event'emit:
      name: test-event
      data:
        name: Test event
        data: Hello
      opts:
        - params 1
        - params 2

fn-debounce

Debounce function (#Ref: lodash.debounce)

  • Without "wait" and "runs" then it's only touch with last agruments
  • Specific "wait" and "runs" then it's run with new agruments

Example:

  - fn-debounce:
      name: Delay to do something
      wait: 1s                # The number of milliseconds to delay.
      trailing: true          # Specify invoking on the trailing edge of the timeout. Default is true
      leading: false          # Specify invoking on the leading edge of the timeout. Default is false
      maxWait: 2s             # The maximum time func is allowed to be delayed before it's invoked.
      autoRemove: true        # Auto remove it when reached the event. Default is false.
    runs:
      - echo: Do this when it's free for 1s

  # touch if debounce is existed
  - fn-debounce:                          # Touch the existed throttle with last agruments
      name: Delay to do something
  # OR
  - fn-debounce: Delay to do something    # Touch the existed throttle with last agruments

fn-debounce'cancel

Cancel debounce function (#Ref: lodash.debounce)

Example:

  - fn-debounce'cancel:
      name: Delay to do something               # Debounce name to cancel
  # OR
  - fn-debounce'cancel: Delay to do something   # Debounce name to cancel
  # OR
  - fn-debounce'cancel:
      - delay1
      - delay2

fn-debounce'del

Cancel & remove debounce function (#Ref: lodash.debounce)

Example:

  - fn-debounce'del:
      name: Delay to do something               # Debounce name to delete
  # OR
  - fn-debounce'del: Delay to do something      # Debounce name to delete
  # OR
  - fn-debounce'del:
      - delay1
      - delay2

fn-debounce'flush

Force to call debounce function ASAP if it's called before that (#Ref: lodash.debounce)

Example:

  - fn-debounce'flush:
      name: Delay to do something                 # Debounce name to delete
  # OR
  - fn-debounce'flush: Delay to do something      # Debounce name to delete
  # OR
  - fn-debounce'flush:
      - delay1
      - delay2

fn-debounce'touch

touch debounce function. Reused last agruments(#Ref: lodash.debounce)

Example:

  - fn-debounce'touch:
      name: Delay to do something               # Debounce name to touch
  # OR
  - fn-debounce'touch: Delay to do something    # Debounce name to touch
  # OR
  - fn-debounce'touch:
      - delay1
      - delay2

fn-queue

Register a queue job

Example:

  - fn-queue:
      name: My Queue 1        # Use stateless queue, not reload after startup
      concurrent: 2
    runs:
      - echo: ${ $parentState.queueData.key1 } is ${ $parentState.queueData.value1 }

  - fn-queue'add:
      name: My Queue 1
      data:
        key1: value1
        key2: value 2
  - fn-queue:
      name: My Queue 1
      concurrent: 2
      skipError: false       # Not throw error when a job failed
      db:                    # Optional: Statefull queue, it's will reload after startup
        path: /tmp/db        #  - Optional: Default is "tempdir/queuename"
        password: abc        #  - Optional: Default is no encrypted by password
    runs:
      - echo: ${ $parentState.queueData.key1 } is ${ $parentState.queueData.value1 }

  - fn-queue'add:
      name: My Queue 1
      data:
        key1: value1
        key2: value 2

fn-queue'add

Add a job to an exsited queue

Example:

  - fn-queue'add:
      name: My Queue 1                 # Queue name to add
      data:                            # Job data
        key1: value1

fn-queue'del

Stop and remove a queue

Example:

  - fn-queue'del:
      name: My Queue 1                 # Queue name to delete
  # OR
  - fn-queue'del: My Queue 1           # Queue name to delete

fn-singleton

This is locked before run and unlock after done. When it's called many time, this is only run after unlock

Example:

  - fn-singleton:
      name: Only run 1 time
      trailing: true              # When someone call in the running but it's not finished yet, then it will run 1 time again after is unlocked
    runs:
      - echo: Do this when it's free for 1s

fn-singleton'del

Remove singleton function

Example:

  - fn-singleton'del:
      name: Delay to do something                 # Singleton name to delete
  # OR
  - fn-singleton'del: Delay to do something       # Singleton name to delete

fn-throttle

Throttle function (#Ref: lodash.throttle)

  • Without "wait" and "runs" then it's only touch with last agruments
  • Specific "wait" and "runs" then it's run with new agruments

Example:

  - fn-throttle:
      name: Delay to do something
      wait: 1s            # The number of milliseconds to throttle invocations to.
      trailing: true      # Specify invoking on the trailing edge of the timeout. Default is true
      leading: true       # Specify invoking on the leading edge of the timeout. Default is true
      autoRemove: true    # Auto remove it when reached the event. Default is false
    runs:
      - echo: Do this when it's free for 1s

  # Call if throttle is existed
  - fn-throttle:                         # Touch the existed throttle with last agruments
      name: Delay to do something
  # OR
  - fn-throttle: Delay to do something   # Touch the existed throttle with last agruments

fn-throttle'cancel

Cancel throttle function (#Ref: lodash.throttle)

Example:

  - fn-throttle'cancel:
      name: Delay to do something               # Throttle name to cancel
  # OR
  - fn-throttle'cancel: Delay to do something   # Throttle name to cancel
  # OR
  - fn-throttle'cancel:
      - delay1
      - delay2

fn-throttle'del

Cancel & remove throttle function (#Ref: lodash.throttle)

Example:

  - fn-throttle'del:
      name: Delay to do something               # Throttle name to delete
  # OR
  - fn-throttle'del: Delay to do something      # Throttle name to delete
  # OR
  - fn-throttle'del:
      - delay1
      - delay2

fn-throttle'flush

Force to call throttle function ASAP if it's called before that (#Ref: lodash.throttle)

Example:

  - fn-throttle'flush:
      name: Delay to do something                 # Throttle name to delete
  # OR
  - fn-throttle'flush: Delay to do something      # Throttle name to delete
  # OR
  - fn-throttle'flush:
      - delay1
      - delay2

fn-throttle'touch

touch throttle function. Reused last agruments (#Ref: lodash.throttle)

Example:

  - fn-throttle'touch:
      name: Delay to do something               # Throttle name to touch
  # OR
  - fn-throttle'touch: Delay to do something   # Throttle name to touch
  # OR
  - fn-throttle'touch:
      - delay1
      - delay2

exec

Execute a program

Example:

Execute a bash script

  - name: Run a bash script
    exec:
      exitCodes: [0, 1] # expect exit code is 0, 1 is success
      commands:
        - /bin/sh
        - /startup.sh
      opts:
        cwd: /home/user/app

Execute a python app

  - exec:
      - python
      - app.py

exec'js

Execute a nodejs code

Example:

Refers to "js" tag document

exec'sh

Execute a shell script

Example:

Refers to "sh" tag document

exit

Stop then quit the program

Example:

  - exit: 0

  - name: Throw error
    exit: 1

fetch'del

Send a http request with DELETE method

Example:

  # DELETE http://localhost:3000/posts/1?method=check_existed
  - name: Delete a post
    fetch'del:
      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}

fetch'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
  - name: Get list posts
    fetch'get:
      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
  - name: Download a file
    fetch'get:
      baseURL: http://localhost:3000
      url: /posts
      query:
        category: users
      headers:
        authorization: Bearer TOKEN
      saveTo: /tmp/post.json

fetch'head

Send a http request with HEAD method

Example:

  # HEAD http://localhost:3000/posts/1?method=check_existed
  - name: Check post is existed or not
    fetch'head:
      baseURL: http://localhost:
      timeout: 5000                   # !optional - Request timeout. Default is no timeout
                                      # supported: d h m s ~ day, hour, minute, seconds
                                      # example: 1h2m3s ~ 1 hour, 2 minutes, 3 seconds
      url: /posts/1
      query:
        method: check_existed
      headers:
        authorization: Bearer TOKEN
    vars:
      status: ${this.response?.status}

fetch'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
  - name: Update a post
    fetch'patch:
      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
  - name: Upload and update data
    fetch'patch:
      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}

fetch'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
  - name: Create a new post
    fetch'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
  - name: Upload a new avatar
    fetch'post:
      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}

fetch'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
  - name: Update a post
    fetch'put:
      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
  - name: Upload and update data
    fetch'put:
      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}

file'read

Read a file then load data into a variable

Example:

Read a json file

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

Read a yaml file

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

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

http'del

Send a http request with DELETE method

Example:

  # DELETE http://localhost:3000/posts/1?method=check_existed
  - name: Delete a post
    http'del:
      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
  - name: Get list posts
    http'get:
      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
  - name: Download a file
    http'get:
      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
  - name: Check post is existed or not
    http'head:
      baseURL: http://localhost:
      timeout: 5000                   # !optional - Request timeout. Default is no timeout
                                      # supported: d h m s ~ day, hour, minute, seconds
                                      # example: 1h2m3s ~ 1 hour, 2 minutes, 3 seconds
      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
  - name: Update a post
    http'patch:
      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
  - name: Upload and update data
    http'patch:
      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
  - name: Create a new post
    http'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
  - name: Upload a new avatar
    http'post:
      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
  - name: Update a post
    http'put:
      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
  - name: Upload and update data
    http'put:
      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'server

Create a http server to serve content via http

Example:

  - http'server:
      address: 0.0.0.0:8811                   # Address to listen
      auth:                                   # Check authentication
        basic:                                # 'Basic ' + base64(`${username}:${password}`)
          username: username
          password: password
        custom:
          secret: 'SERVER_SECRET_TOKEN'
          secretKey: SECRET_HEADER_KEY
          verify(): |
            return $parentState.headers[this.secretKey] === this.secret
    runs:                                   # Execute when a request comes
      - echo: ${ $parentState.path }        # Get request path
      - echo: ${ $parentState.method }      # Get request method
      - echo: ${ $parentState.headers }     # Get request headers
      - echo: ${ $parentState.query }       # Get request query string
      - echo: ${ $parentState.body }        # Get request body
      - echo: ${ $parentState.response }    # Set response data
                                            # - status: 200       - http response status
                                            # - statusMessage: OK - http response status message
                                            # - headers: {}       - Set response headers
                                            # - data: {}          - Set response data
      - echo: ${ $parentState.req }         # Ref to req in http.IncomingMessage in nodejs
      - echo: ${ $parentState.res }         # Ref to res in http.ServerResponse in nodejs
      - js: |                               # Handle response by yourself (When $parentState.response is undefined)
          $parentState.res.status = 200
          $parentState.res.statusMessage = 'OK'
          $parentState.res.write('OK')
          $parentState.res.end()

include

Include a scene file or list scene files in a folder

Example:

  - include: ./my-scenes/scene1.yaml  # Includes a only file "scene1.yaml"

  - include:
      file: ./my-scenes               # Includes all of files (.yaml, .yml) which in the directory (./my-scenes)
      cached: true                    # Load file for the first time, the next will get from caches

input'confirm

Get user confirm (yes/no)

Example:

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

input'multiselect

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

Example:

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

input'number

Get user input from keyboard then convert to number

Example:

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

input'password

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

Example:

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

input'select

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

Example:

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

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
      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
    vars: hobby

input'text

Get user input from keyboard then convert to text

Example:

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

js

Execute a nodejs code

Example:

Set value to a variable

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

Write a file

  - name: Write a file
    js:
      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

npm'install

Install librarries to use in the scene.

Example:

  - npm'install: module1, module2

  - npm'install:
      - module1
      - myapp: git+ssh:[email protected]:...

  - Always get latest ymlr-telegram librarry
    npm'install: [lodash, ymlr-telegram@latest]

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

  - echo: ${$vars.newObject}

Install from github

  - name: Install from github
    if: ${$vars.useExternalPackage}
    npm'install:
      - myapp: git+ssh:[email protected]:...
      - ymlr...

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

npm'uninstall

Uninstall librarries to use in the scene.

Example:

  - npm'uninstall: module1, module2

  - npm'uninstall:
      - module1
      - myapp

  - name: Uninstall librarry
    npm'uninstall: [ymlr-telegram, ymlr...]

pause

Pause the program then wait to user enter to continue

Example:

  - pause:

  - name: Pause here
    pause:

runs

Group elements

Example:

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

scene

Load another scene into the running program

Example:

  - name: A scene from remote server
    # scene: ./another.yaml             # path can be URL or local path
    scene:
      name: Scene name
      path: https://.../another.yaml    # path can be URL or local path
      cached: false                     # caches yaml content to ram to prevent reload content from a file
      password:                         # password to decode when the file is encrypted
      env:                              # Set to env variable. Support an array or object (- key=value) (key: value)
        NODE_ENV: production
        # Or
        - NODE_ENV=production
      vars:                             # They will only overrides vars in the parents to this scene
                                        # - Global variables is always passed into this scene
        foo: scene bar                  # First is lowercase is vars which is used in scenes
        Foo: Global bar                 # First is uppercase is global vars which is used in the program
        localVars: ${ $vars.parentVar } # This will get value of "$vars.parentVar" in the parent then pass it into "$vars.localVars" which is used in this scene
      envFiles:                         # Load env variable from files (string | string[])
        - .env
        - .env.dev
      varsFiles:                        # Load vars from json or yaml files (string | string[])
        - ./var1.json
        - ./var2.yaml

scene'returns

Return value to parent scene

Example:

Scene sum.yaml

  vars:
    x: 0
    y: 0
  runs:
    - vars:
        result: ${ $vars.x + $vars.y }

    - scene'returns: ${ $vars.result }

Main scene index.yaml

  - name: Load a scene to sum 2 digits
    scene:
      path: .../sum.yaml
      vars:
        x: 10
        y: 20
    vars: sumOfXY

  - echo: ${ $vars.sumOfXY }    # => 30

scene'thread

Same "scene" but it run in a new thread

Example:

  - name: A scene run in a new thread
    # scene'thread: ./another.yaml     # path can be URL or local path
    scene'thread:
      id: #newID                        # thread id (optional)
      name: Scene name
      path: https://.../another.yaml    # path can be URL or local path
      password:                         # password to decode when the file is encrypted
      vars:                             # They will only overrides vars in the parents to this scene
                                        # - Global variables is always passed into this scene
        foo: scene bar                  # First is lowercase is vars which is used in scenes
        Foo: Global bar                 # First is uppercase is global vars which is used in the program
        localVars: ${ $vars.parentVar } # This will get value of "$vars.parentVar" in the parent then pass it into "$vars.localVars" which is used in this scene

Send data via global event between threads and each others. (Includes main thread) main.yaml

  name: This is main thread
  runs:
    - name: Run in a new thread 1
      detach: true
      scene'thread:
        id: thread1
        path: ./new_thread.yaml
        vars:
          name: thread 1
    - name: Run in a new thread 2
      detach: true
      scene'thread:
        id: thread2
        path: ./new_thread.yaml
        tagDirs:                  # Custom tagDirs in the scene'thread. If not specific then default is inherit
          - ...                   # Inherits tags dirs in application. Ref to "-x" in cli
          - ./project1/dist
          - ./project2/dist
        vars:
          name: thread 2

    - sleep: 1s

    - name: Listen data from childs thread
      ~event'on:
        name: ${ $const.FROM_GLOBAL_EVENT }
      runs:
        - name: Received data from thread ID ${ $parentState.eventOpt.fromID }
          echo: ${ $parentState.eventData }

    - name: Emit data to childs threads
      ~event'emit:
        name: ${ $const.TO_GLOBAL_EVENT }
        data:
          name: this is data from main thread

new_thread.yaml

  vars:
    name: Thread name will be overried by parent scene
  runs:
    - event'on:
        name: ${ $const.FROM_GLOBAL_EVENT }
      runs:
        - name: Thread ${ $vars.name } is received data from thread ID ${ $parentState.eventOpt.fromID }
          echo: ${ $parentState.eventData }

        - name: Thead ${ $vars.name } sent data to global event
          event'emit:
            name: ${ $const.TO_GLOBAL_EVENT }
            data:
              name: this is data from thread ${ $vars.name }
            # opts:
            #  toIDs: ['thread1']             # Specific the thread ID to send. Default it send to all
        - sleep: 2s
        - stop:

sh

Execute a shell script

Example:

Execute a sh file

  - name: Write a hello file
    sh:
      path: /sayHello.sh              # Path of sh file (Use only "path" OR "script")
    vars: log       # !optional

Execute a bash script

  - name: Write a hello file
    sh:
      exitCodes: [0, 1]               # expect exit code is 0, 1 is success. Default is [0]
      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
      timeout: 10m                    # Time to run before force quit
      process: true                   # Create a new child process to execute it. Default is false
      opts:                           # Ref: "SpawnOptionsWithoutStdio", "ExecFileOptions" in nodeJS
        detached: true
        ...
    vars: log                         # !optional

sleep

Sleep the program then wait to user enter to continue

Example:

Sleep for a time

  • 1d = 1 day
  • 1h = 1 hour
  • 1m = 1 minute
  • 1s = 1 second
  • 1ms = 1 milisecond
  - sleep: 10000            # Sleep 10s then keep continue
  - sleep: 10s              # Sleep 10s then keep continue
  - sleep: 1h1m20s          # Sleep in 1 hour, 1 minute and 20 seconds then keep continue

Full props

  - name: Sleep 10s
    sleep: 10000          # Sleep 10s then keep continue

  - name: sleep infinity
    sleep:

tag'register

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

Example:

Register custom tags from a file

  - tag'register:
      test1: /workspaces/ymlr/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
          }
        }

  - 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
          }
        }

  - newOne:
      name: foo

test

Check conditions in the program

Example:

Quick test

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

  - 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')

view'flow

View flows in a scene

Example:

Quick test

  - view'flow:
      file: ~/index.yaml        # Path of a scene file
      saveTo: /tmp/index.txt    # Save the result to file or console. Default is console (Optional)

$utils.base64

Utility function
Base64 encrypt/decrypt a string

Example:

  - echo: ${ $utils.base64.encode('hello world') }

  - echo: ${ $utils.base64.decrypt('$ENCODED_STRING') }

$utils.base64

Utility function
AES encrypt/decrypt a string

Example:

  - echo: ${ $utils.aes.encrypt('hello world') }

  - echo: ${ $utils.aes.decrypt('$ENCRYPTED_STRING') }

$utils.debounceManager

Utility function
Return using map debounce function via fn-debounce

Example:

- fn-debounce:
    name: testDebounce
    wait: 5s
  runs:
    - echo: Hello
- js: |
    const count = $utils.debounceManager.size()
    const hasDebounce = $utils.debounceManager.has('testDebounce')
    $utils.debounceManager.get('testDebounce').flush()  


## <a id="$utils.format"></a>$utils.format  
`Utility function`  
Formater  

Example:  

```yaml
- echo: ${ $utils.format.fileName('a@(*&#à.jpg', ' ') }                             # => a a.jpg

- echo: ${ $utils.format.number(1000000) }                                          # => 1,000,000

- echo: ${ $utils.format.number(1000000) }                                          # => 1,000,000

- echo: ${ $utils.format.fixLengthNumber(1, 2) }                                    # => 001
- echo: ${ $utils.format.fixLengthNumber(10, 2) }                                   # => 010

- echo: ${ $utils.format.formatTextToMs('1d 1h 1m 1s 100') }                        # => 90061100

- echo: ${ $utils.format.formatTextToMs(new Date(), 'DD/MM/YYYY hh:mm:ss.ms') }     # => 01/12/2023 23:59:59.0

- echo: ${ $utils.format.yaml({name: 'yaml title'})}                                # => name: yaml title

$utils.globalEvent

Utility function
Reference global event in application

Example:

  - js: |
      $utils.globalEvent.on('say', (name) => {
        this.logger.info('Hello', name)
      })

  - js: |
      $utils.globalEvent.emit('say', 'Thanh 01')

$utils.md5

Utility function
Encrypt a string to md5

Example:

  - echo: ${ $utils.md5.encrypt('hello world') }

$utils.parse

Utility function
Parser

Example:

- echo: ${ $utils.parse.yaml('title: "yaml title"') }       # => { "title": "yaml title" }  


## <a id="$utils.sleep"></a>$utils.sleep  
`Utility function`  
Sleep before do the next  

Example:  

```yaml
- js: |
    this.logger.info('Sleep 5s')
    await $utils.sleep('5s')
    this.logger.info('Do it')  


## <a id="$utils.styles"></a>$utils.styles  
`Utility function`  
Return [chalk](https://www.npmjs.com/package/chalk) which decorate text style (color, italic, bold, bgColor....)  

Example:  

```yaml
- js: |
    this.logger.debug($utils.styles.red('Red text'))
    this.logger.debug($utils.styles.blue.italic('Blue and italic text'))  


## <a id="$utils.throttleManager"></a>$utils.throttleManager  
`Utility function`  
Return using map throttle function via fn-throttle  

Example:  

```yaml
- fn-throttle:
    name: testThrottle
    wait: 5s
  runs:
    - echo: Hello
- js: |
    const count = $utils.throttleManager.size()
    const hasThrottle = $utils.throttleManager.has('testThro