|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- const fs = require('fs-extra');
- const { clone } = require('../core/util');
-
- module.exports = {
-
- wait: function(options) {
- let delay = this.parseOptional(options.delay, 'number', 1000);
- return new Promise(resolve => setTimeout(resolve, delay))
- },
-
- log: function(options) {
- let message = this.parse(options.message);
- console.log(message);
- return message;
- },
-
- repeat: async function(options) {
- let repeater = this.parseRequired(options.repeat, '*', 'core.repeater: repeat is required.');
- let outputFilter = this.parseOptional(options.outputFilter, 'string', 'include'); // include/exclude
- let outputFields = this.parseOptional(options.outputFields, 'object'/*array[string]*/, []);
- let index = 0, data = [], parentData = this.data;
-
- switch (typeof repeater) {
- case 'boolean':
- repeater = repeater ? [0] : [];
- break;
-
- case 'string':
- repeater = repeater.split(',');
- break;
-
- case 'number':
- repeater = (n => {
- let a = [], i = 0;
- while (i < n) a.push(i++);
- return a;
- })(repeater);
- break;
- }
-
- if (!(Array.isArray(repeater) || repeater instanceof Object)) {
- throw new Error('Repeater data is not an array or object');
- }
-
- for (let key in repeater) {
- if (repeater.hasOwnProperty(key)) {
- let scope = {};
- this.data = {};
-
- if (repeater[key] instanceof Object) {
- for (var prop in repeater[key]) {
- if (repeater[key].hasOwnProperty(prop)) {
- scope[prop] = repeater[key][prop];
-
- if (outputFilter == 'exclude') {
- if (!outputFields.includes(prop)) {
- this.data[prop] = repeater[key][prop];
- }
- } else {
- if (outputFields.includes(prop)) {
- this.data[prop] = repeater[key][prop];
- }
- }
- }
- }
- }
-
- scope.$key = key;
- scope.$name = key;
- scope.$value = clone(repeater[key]);
- scope.$index = index;
- scope.$number = index + 1;
- scope.$oddeven = index % 2;
-
- if (repeater[key] == null) {
- repeater[key] = {};
- }
-
- this.scope = this.scope.create(scope, clone(repeater[key]));
- await this.exec(options.exec, true);
- this.scope = this.scope.parent;
-
- data.push({ ...this.data });
-
- index++;
- }
- }
-
- this.data = parentData;
-
- return data;
- },
-
- while: async function(options) {
- let max = this.parseOptional(options.max, 'number', Number.MAX_SAFE_INTEGER);
- let i = 0;
-
- while (this.parse(options.while)) {
- await this.exec(options.exec, true);
- if (++i == max) break;
- }
- },
-
- condition: async function(options) {
- let condition = this.parse(options.if);
-
- if (!!condition) {
- if (options.then) {
- await this.exec(options.then, true);
- }
- } else if (options.else) {
- await this.exec(options.else, true);
- }
- },
-
- conditions: async function(options) {
- if (Array.isArray(options.conditions)) {
- for (let condition of options.conditions) {
- let when = this.parse(condition.when);
-
- if (!!when) {
- return this.exec(condition.then, true);
- }
- }
- }
- },
-
- select: async function(options) {
- let expression = this.parse(options.expression);
-
- if (Array.isArray(options.cases)) {
- for (let item of options.cases) {
- let value = this.parse(item.value);
-
- if (expression === value) {
- return this.exec(item.exec, true);
- }
- }
- }
- },
-
- setvalue: function(options) {
- let key = this.parseOptional(options.key, 'string', '');
- let value = this.parse(options.value);
- if (key) this.set(key, value);
- return value;
- },
-
- setsession: function(options, name) {
- let value = this.parse(options.value);
- this.req.session[name] = value;
- return value;
- },
-
- removesession: function(options, name) {
- delete this.req.session[name];
- },
-
- setcookie: function(options, name) {
- options = this.parse(options);
-
- let cookieOptions = {
- domain: options.domain || undefined,
- httpOnly: !!options.httpOnly,
- maxAge: options.expires === 0 ? undefined : (options.expires || 30) * 24 * 60 * 60 * 1000, // from days to ms
- path: options.path || '/',
- secure: !!options.secure,
- sameSite: options.sameSite || false
- };
-
- this.setCookie(name, options.value, cookieOptions);
- },
-
- removecookie: function(options, name) {
- options = this.parse(options);
-
- let cookieOptions = {
- domain: options.domain || undefined,
- httpOnly: !!options.httpOnly,
- maxAge: options.expires === 0 ? undefined : (options.expires || 30) * 24 * 60 * 60 * 1000, // from days to ms
- path: options.path || '/',
- secure: !!options.secure,
- sameSite: !!options.sameSite
- };
-
- this.removeCookie(name, cookieOptions);
- },
-
- response: function(options) {
- let data = this.parseOptional(options.data, '*', null);
- let status = this.parseOptional(options.status, 'number', 200);
- let contentType = this.parseOptional(options.contentType, 'string', 'application/json');
- if (contentType != 'application/json') {
- this.res.set('Content-Type', contentType);
- this.res.status(status).send(data);
- } else {
- this.res.status(status).json(data);
- }
- },
-
- error: function(options) {
- let message = this.parseRequired(options.message, 'string', 'core.error: message is required.');
- throw new Error(message);
- },
-
- redirect: function(options) {
- let url = this.parseRequired(options.url, 'string', 'core.redirect: url is required.');
- let status = this.parseOptional(options.status, 'number', 302);
-
- this.res.redirect(status == 301 ? 301 : 302, url);
- },
-
- trycatch: async function(options) {
- try {
- await this.exec(options.try, true);
- } catch (error) {
- this.scope.set('$_ERROR', error.message || error);
- this.error = false;
- if (options.catch) {
- await this.exec(options.catch, true);
- }
- }
- },
-
- exec: async function(options) {
- var data = {};
-
- if (options.exec && fs.existsSync(`app/modules/lib/${options.exec}.json`)) {
- let parentData = this.data;
- this.data = {};
- this.scope = this.scope.create({ $_PARAM: this.parse(options.params) });
- await this.exec(await fs.readJSON(`app/modules/lib/${options.exec}.json`), true);
- data = this.data;
- this.scope = this.scope.parent;
- this.data = parentData;
- } else {
- throw new Error(`There is no action called '${options.exec}' found in the library.`);
- }
-
- return data;
- },
-
- group: async function(options, name) {
- if (name) {
- return this.sub(options.exec);
- } else {
- return this.exec(options.exec, true);
- }
- },
-
- parallel: async function(options, name) {
- let actions = options.exec.steps || options.exec;
- if (!Array.isArray(actions)) actions = [actions];
- return await Promise.all(actions.map(exec => {
- if (name) {
- return this.sub(exec);
- } else {
- return this.exec(exec, true);
- }
- }));
- },
-
- randomUUID: function(options) {
- const { randomUUID } = require('crypto');
- const { v4: uuidv4 } = require('uuid');
- return randomUUID ? randomUUID() : uuidv4();
- },
-
- };
|