Static

Static Decorators

Using static decorators, a script can declare environment behavior that is picked up and merged into the runtime. Because static decorators are processed at compile-time, they must not include variables in their declarations.

Only object expressions, array literals, primitives, and numeric literals preceded by the - unary expression are allowed.

const { job } = require('decorators'),
      cron = '*/10 * * * *'

class Jobs {

  @job(cron) // invalid. contains a variable
  @job('*/10 * * * *') // valid
  @job('*/10 * * * *', { weight: -1 }) // valid
  @job('*/10 * * * *', { weight: +1 }) // invalid
  @job('*/10 * * * *', { weight: 1 }) // valid
  @job('*/10 * * * *', { principal: script.principal }) // invalid
  @job('*/10 * * * *', { principal: consts.principals.anonymous }) // invalid. contains a variable
  @job('*/10 * * * *', { principal: 'anonymous' }) // valid
  doJob() {
  }
}

Stored objects, scripts and policies can be named, and must be unique. If declared with a static decorator, a developer can override named items by duplicating the name and assigning a greater weight. See each decorator's documentation for runtime sorting details. the default weight is 0.

const { job } = require('decorators')     

// overrides a saved job script by the same name
class Jobs {

  @job('*/10 * * * *', { name: 'c_existing_job', weight: 1})
  doJob() {    
  }  
}

// overrides the statically declared job of the same name and changes the job frequency
class CustomJobs extends Jobs {

  @job('*/5 * * * *', { name: 'c_existing_job', weight: 2})
  doJob(...args) {    
    super.doJob(...args)
  }  
}

Any number of decorators may stack on top of one another and will all be added to the runtime. Although their order is determined by weight and priority (depending on the type), not the order in which they are declared.

const { route, trigger } = require('decorators')
class Foo {

  @route('GET foos/:param') // called second
  getFoos() {    
  }  

  @route('GET foos/bars', { priority: 10 }) // called first.        
  getFooBars() {
  } 

}

If two or more similarly named static decorator declarations are made that share the same weight, the one selected is arbitrary and must be determined via examining the environment runtime to determined which was selected (org.runtime). As such, it's recommended to always assign weights to named declarations.

const { route } = require('decorators')
class Foo {

  @route('GET foos', { c_name: 'c_existing_saved_foo_route' }) // may or may not be selected, though only 1 will be added.
  getFoos() {  
  }  

  @route('GET bars', { c_name: 'c_existing_saved_bar_route', weight: 1 }) // overrides saved route script with default weight
  getBars() {  
  }

  @route('GET foos', { priority: 999 }) // no name, so will stack and run based on priority alone.
  @route('GET bars', { priority: 999 }) 
  getBeforeBars({ body, next }) {
    if (body.isArray()) {
      body(body.getLength(), 'pushed')
    }
    next() // allow the next route to run.
  }

}

When combining static environment decorators with runtime decorators, the order of the decorators does not apply; static decorators are always applied prior to the script being allocated a sandbox.

In the following example, the principal will be c_service_account_with_site_manager_role even though @as precedes @route (which runs as the runtime caller by default) because @as is evaluated at runtime. Also, the route will only allow a caller with the c_site_manager role to run the route because the @as decorator does not assign the c_service_account_with_site_manager_role until after the @route has been evaluated.

const { as, route } = require('decorators')
class Foo {

  @as('c_service_account_with_site_manager_role')
  @route('GET foos', { acl: 'role.c_site_manager'})
  getFoos() {
    return script.principal // c_service_account
  }  

}

Last updated