lynx-framework
Version:
lynx is a NodeJS framework for Web Development, based on decorators and the async/await support.
855 lines (854 loc) • 59 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.app = exports.getLanguageFromRequest = exports.isProduction = void 0;
var express = require("express");
var http = require('http');
var nunjucks = require("nunjucks");
var fs = require("fs");
require("reflect-metadata");
var typeorm_1 = require("typeorm");
var session = require("express-session");
var bodyParser = require("body-parser");
var multer = require("multer");
var moment = require("moment");
var flash = require('express-flash');
var migration_entity_1 = require("./entities/migration.entity");
var error_controller_1 = require("./error.controller");
var expressGenerator = require("./express-generator");
var setup_1 = require("./entities/setup");
var jsonwebtoken_1 = require("jsonwebtoken");
var translations = {};
var routes = {};
var logger_1 = require("./logger");
var api_response_wrapper_1 = require("./api-response-wrapper");
var decorators_1 = require("./templating/decorators");
/**
* Utility function to check if we are in the production environment.
* @return true if the NODE_ENV is set to "production", false otherwise
*/
function isProduction() {
return process.env.NODE_ENV === 'production';
}
exports.isProduction = isProduction;
/**
* Retrieve the preferred language from an express request, using the accepts-languages
* header value.
* @param req the express request
* @return the two letter lower-cased language, or "*" (wildcard), or null
*/
function getLanguageFromRequest(req) {
var lang = req.acceptsLanguages()[0];
if (lang.indexOf('-') !== -1) {
lang = lang.split('-')[0];
}
if (lang) {
lang = lang.trim().toLowerCase();
}
return lang;
}
exports.getLanguageFromRequest = getLanguageFromRequest;
/**
* This function shall be called with the nunjucks environment as self parameter!
* It retrieve the language of the current request, using the default
* language set in the app as fallback.
*/
function retrieveLanguage(self) {
var lang = null;
try {
var req = self.ctx.req;
lang = getLanguageFromRequest(req);
if (lang === '*') {
lang = null;
}
}
catch (e) { }
try {
if (!lang) {
lang = self.getVariables()['lang'];
}
if (!lang) {
var app_1 = self.ctx.req.app.get('app');
lang = app_1.config.defaultLanguage;
}
}
catch (e) {
lang = exports.app.config.defaultLanguage;
}
return lang;
}
/**
* Implementation of the tr filer for the nunjucks engine.
* It trying to understand the current language from the request. The fallback
* uses the defaultLanguage set on the app.
*/
function translate(str) {
try {
var lang = retrieveLanguage(this);
return performTranslation(str, translations[lang]);
}
catch (e) {
logger_1.logger.info(e);
logger_1.logger.info(this);
}
return str;
}
function performTranslation(str, translations) {
var translation = translations[str];
if (translation !== null && translation !== undefined) {
return translation;
}
var start = str.indexOf('{{');
var end = str.indexOf('}}');
if (start != -1 && end != -1) {
var key = str.substring(start + 2, end);
translation = translations[key.trim()];
return str.replace('{{' + key + '}}', translation);
}
return str;
}
/**
* Implementation of the date filter using moment.
* The default implementation uses the "lll" string format, resulting in
* Feb 19, 2018 4:57 PM in English.
* @param d the date to format
* @param format the string to format the date, default to lll
* @return the formatted date
*/
function date(d, format) {
if (!d) {
return '';
}
var lang = retrieveLanguage(this);
var m = moment(d).locale(lang);
if (!format) {
format = 'lll';
}
return m.format(format);
}
/**
* Apply parameters to an URL. If a parameter is not found as path parameter,
* it is added as query parameter.
* @param url the url to compile
* @param parameters a plain object containing the parameters
* @return the compiled url
*/
function applyParametersToUrl(url, parameters) {
if (!parameters) {
return url;
}
if (url.indexOf('?') == -1) {
url += '?';
}
else {
url += '&';
}
for (var key in parameters) {
if (url.indexOf(':' + key) == -1) {
url += key + "=" + parameters[key] + "&";
}
else {
url = url.replace(':' + key, parameters[key]);
}
}
if (url.endsWith('?') || url.endsWith('&')) {
url = url.substring(0, url.length - 1);
}
return url;
}
/**
* Transform the route name to a URL and compile it with the given parameters.
* @param name the route name (or, eventually, the path)
* @param parameters a plain object containing the parameters
* @return the compiled url
*/
function route(name, parameters) {
var url = name;
if (routes[name]) {
url = routes[name];
}
return applyParametersToUrl(url, parameters);
}
/**
* Implementation of the old filter function. This function returns the previous
* value of the input form. Fallback to the defaultValue.
* @param name the name used in the form
* @param defaultValue a fallback value
* @return the previous value or defaultValue
*/
function old(name, defaultValue) {
var req = this.ctx.req;
if (req.body && req.body[name]) {
return req.body[name];
}
if (req.query[name]) {
return req.query[name];
}
return defaultValue;
}
/**
* Implementation of the format filter function to format a float number.
* By default, the number is formatted with 2 decimal numbers.
* @param val the number to format
* @param decimal the number of decimal number
* @return the formatted number as a string
*/
function format(val, decimal) {
if (decimal === void 0) { decimal = 2; }
return Number(val).toFixed(decimal);
}
/**
* Implementation of the resolvePath global function. Using this function, it is
* possible to refer to any views with a virtual folder containing all the available
* views.
* @param path the virtual absolute path of the view
* @return the absolute path of the view if resolved, or the original path otherwise
*/
function resolvePath(path) {
var normalizedPath = path;
if (normalizedPath.endsWith('.njk')) {
normalizedPath = normalizedPath.substring(0, normalizedPath.length - 4);
}
var _app;
try {
_app = this.ctx.req.app.get('app');
}
catch (e) {
_app = exports.app;
}
var resolved = _app.templateMap[path];
if (resolved) {
return resolved;
}
return path;
}
/**
* This function returns the current server url, with the used protocol and port.
* This function is available as global function on nunjucks.
*/
function currentHost() {
var req = this.ctx.req;
return req.protocol + '://' + req.get('host');
}
/**
* The App class contains the initialization code for a Lynx application.
*/
var App = /** @class */ (function () {
function App(config, modules) {
var _this = this;
this._modules = new Set();
this.apiResponseWrapper = new api_response_wrapper_1.DefaultAPIResponseWrapper();
this._config = config;
exports.app = this;
if (!config.onlyModules) {
logger_1.logger.warn('LEGACY MODE: loading both modules and a current application context is now deprecated.');
logger_1.logger.warn('LEGACY MODE: please reorganize your project folder in order to have ONLY modules, also for your current application context!');
}
if (modules) {
this._modules = new Set(modules);
this._modules.forEach(function (module) { return module.mount(_this._config); });
}
config.db.entities.unshift(__dirname + '/entities/*.entity.js');
config.middlewaresFolders.unshift(__dirname + '/middlewares');
config.viewFolders.unshift(__dirname + '/views');
if (!config.disabledDb) {
typeorm_1.createConnection(config.db)
.then(function (_) {
// here you can start to work with your entities
logger_1.logger.info('Connection to the db established!');
setup_1.setup(config.db.entities)
.then(function (_) {
_this._modules.forEach(function (module) {
return module.onDatabaseConnected();
});
if (!config.disableMigrations) {
_this.executeMigrations()
.catch(function (err) {
logger_1.logger.error(err);
process.exit(1);
})
.then(function () {
if (_this._config.onDatabaseInit) {
_this._config.onDatabaseInit();
}
});
}
else if (_this._config.onDatabaseInit) {
_this._config.onDatabaseInit();
}
})
.catch(function (error) {
logger_1.logger.error(error);
process.exit(1);
});
})
.catch(function (error) {
logger_1.logger.error(error);
process.exit(1);
});
}
else {
logger_1.logger.debug('The DB service is disabled');
}
this.express = express();
this.httpServer = http.createServer(this.express);
this.express.set('app', this);
this.express.use(function (_, res, next) {
res.setHeader('X-Powered-By', 'lynx-framework/express');
next();
});
for (var _i = 0, _a = this.config.globalInterceptors; _i < _a.length; _i++) {
var interceptor = _a[_i];
if (interceptor.onlyFor) {
this.express.use(interceptor.onlyFor, interceptor.cb);
}
else {
this.express.use(interceptor.cb);
}
}
if (this.config.jsonLimit) {
this.express.use(bodyParser.json({ limit: this.config.jsonLimit }));
}
else {
this.express.use(bodyParser.json());
}
this.express.use(bodyParser.urlencoded({ extended: true }));
var app_session_options = {
secret: config.sessionSecret,
resave: false,
saveUninitialized: true,
};
if (config.sessionStore) {
app_session_options.store = config.sessionStore;
}
this._appSession = session(app_session_options);
this.express.use(this._appSession);
this.express.use(flash());
this._upload = multer({ dest: config.uploadPath });
fs.exists(config.cachePath, function (exists) {
if (!exists) {
fs.mkdir(config.cachePath, function (err) {
if (err) {
logger_1.logger.error('Error creating the local cache directory', err);
}
});
}
});
for (var _b = 0, _c = config.publicFolders; _b < _c.length; _b++) {
var folder = _c[_b];
this.express.use(express.static(folder));
}
this.generateTemplateMap(config.viewFolders);
this._nunjucksEnvironment = nunjucks.configure(config.viewFolders, {
autoescape: true,
watch: true,
express: this.express,
});
this._nunjucksEnvironment.addFilter('tr', translate);
this._nunjucksEnvironment.addFilter('json', JSON.stringify);
this._nunjucksEnvironment.addFilter('format', format);
this._nunjucksEnvironment.addFilter('date', date);
this.loadTranslations(config.translationFolders);
this._nunjucksEnvironment.addGlobal('route', route);
this._nunjucksEnvironment.addGlobal('old', old);
this._nunjucksEnvironment.addGlobal('resolvePath', resolvePath);
this._nunjucksEnvironment.addGlobal('currentHost', currentHost);
for (var _d = 0, _e = config.templatingFolders; _d < _e.length; _d++) {
var path = _e[_d];
this.loadTemplating(path);
}
decorators_1.initializeTemplating(this);
for (var _f = 0, _g = config.middlewaresFolders; _f < _g.length; _f++) {
var path = _g[_f];
this.loadMiddlewares(path);
}
for (var _h = 0, _j = config.controllersFolders; _h < _j.length; _h++) {
var path = _j[_h];
this.loadControllers(path);
}
this._errorController = new error_controller_1.default(this);
this._mailClient = config.mailFactoryConstructor();
this._mailClient.init().catch(function (err) {
logger_1.logger.warn('Error trying to initialize the mailClient', err);
});
this._modules.forEach(function (module) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, module.onAppReady(this)];
case 1: return [2 /*return*/, _a.sent()];
}
}); }); });
}
Object.defineProperty(App.prototype, "config", {
get: function () {
return this._config;
},
enumerable: false,
configurable: true
});
Object.defineProperty(App.prototype, "templateMap", {
get: function () {
return this._templateMap;
},
enumerable: false,
configurable: true
});
Object.defineProperty(App.prototype, "nunjucksEnvironment", {
get: function () {
return this._nunjucksEnvironment;
},
enumerable: false,
configurable: true
});
Object.defineProperty(App.prototype, "upload", {
get: function () {
return this._upload;
},
enumerable: false,
configurable: true
});
Object.defineProperty(App.prototype, "mailClient", {
get: function () {
return this._mailClient;
},
enumerable: false,
configurable: true
});
Object.defineProperty(App.prototype, "appSession", {
get: function () {
return this._appSession;
},
enumerable: false,
configurable: true
});
Object.defineProperty(App.prototype, "customResizeFunction", {
/**
* If not null, contains a custom function that perform the resizing of an image
*/
get: function () {
return this._customResizeFunction;
},
/**
* Set a new image resizing function, that will be executed automatically when a new file is downloaded.
* The cache system will automatically work; this function shall only execute the image resizing.
*/
set: function (resizeFunction) {
this._customResizeFunction = resizeFunction;
},
enumerable: false,
configurable: true
});
Object.defineProperty(App.prototype, "customErrorController", {
/**
* This property allow the customization of the standard error controller.
* You need to create the controller using its standard constructor:
* new MyCustomErrorController(app)
*/
set: function (ctrl) {
this._errorController = ctrl;
},
enumerable: false,
configurable: true
});
App.prototype.recursiveGenerateTemplateMap = function (path, currentPath) {
var files = fs.readdirSync(path);
for (var index in files) {
var currentFilePath = path + '/' + files[index];
if (fs.lstatSync(currentFilePath).isDirectory()) {
this.recursiveGenerateTemplateMap(currentFilePath, currentPath + files[index] + '/');
continue;
}
var name = files[index].replace('.njk', '');
this._templateMap[currentPath + name] = currentFilePath;
}
};
App.prototype.generateTemplateMap = function (paths) {
this._templateMap = {};
for (var _i = 0, paths_1 = paths; _i < paths_1.length; _i++) {
var path = paths_1[_i];
this.recursiveGenerateTemplateMap(path, '/');
}
};
App.prototype.recursiveExecuteMigrations = function (path) {
return __awaiter(this, void 0, void 0, function () {
var files, _a, _b, _i, index, currentFilePath, m, entity, migration, e_1;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (!fs.existsSync(path)) {
logger_1.logger.warn('The migration folder ' + path + " doesn't exists!");
return [2 /*return*/];
}
files = fs.readdirSync(path).sort(function (a, b) { return a.localeCompare(b); });
_a = [];
for (_b in files)
_a.push(_b);
_i = 0;
_c.label = 1;
case 1:
if (!(_i < _a.length)) return [3 /*break*/, 13];
index = _a[_i];
currentFilePath = path + '/' + files[index];
if (!fs.lstatSync(currentFilePath).isDirectory()) return [3 /*break*/, 3];
return [4 /*yield*/, this.recursiveExecuteMigrations(currentFilePath)];
case 2:
_c.sent();
return [3 /*break*/, 12];
case 3:
if (currentFilePath.endsWith('ts'))
return [3 /*break*/, 12];
m = require(currentFilePath);
if (!m.default) {
throw new Error('Please define the migration as the export default class in file ' +
currentFilePath +
'.');
}
return [4 /*yield*/, migration_entity_1.default.findByName(currentFilePath)];
case 4:
entity = _c.sent();
if (entity && entity.wasExecuted()) {
return [3 /*break*/, 12];
}
if (!!entity) return [3 /*break*/, 6];
entity = new migration_entity_1.default();
entity.name = currentFilePath;
return [4 /*yield*/, entity.save()];
case 5:
_c.sent();
_c.label = 6;
case 6:
migration = new m.default();
_c.label = 7;
case 7:
_c.trys.push([7, 10, , 12]);
return [4 /*yield*/, migration.up()];
case 8:
_c.sent();
entity.setExecuted();
return [4 /*yield*/, entity.save()];
case 9:
_c.sent();
logger_1.logger.info('Migration ' + currentFilePath + ' executed!');
return [3 /*break*/, 12];
case 10:
e_1 = _c.sent();
entity.setFailed();
return [4 /*yield*/, entity.save()];
case 11:
_c.sent();
logger_1.logger.error('Error executing the migration ' + currentFilePath);
throw e_1;
case 12:
_i++;
return [3 /*break*/, 1];
case 13: return [2 /*return*/];
}
});
});
};
/**
* This method will execute the migrations.
* By default, this method will be executed automatically during the app
* startup. In some scenario, like hight-scalability, this behaviour could
* be unwanted. Thus, it is possibly otherwise to explicitly call this method
* in some other way (for example, connecting it to a standard http route).
*/
App.prototype.executeMigrations = function () {
return __awaiter(this, void 0, void 0, function () {
var _i, _a, path;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_i = 0, _a = this._config.migrationsFolders;
_b.label = 1;
case 1:
if (!(_i < _a.length)) return [3 /*break*/, 4];
path = _a[_i];
return [4 /*yield*/, this.recursiveExecuteMigrations(path)];
case 2:
_b.sent();
_b.label = 3;
case 3:
_i++;
return [3 /*break*/, 1];
case 4: return [2 /*return*/];
}
});
});
};
App.prototype.loadTranslations = function (paths) {
for (var _i = 0, paths_2 = paths; _i < paths_2.length; _i++) {
var path = paths_2[_i];
var files = fs.readdirSync(path);
for (var index in files) {
var nameWithExtension = files[index];
if (!nameWithExtension.endsWith('json'))
continue;
var name = nameWithExtension.substring(0, nameWithExtension.indexOf('.'));
var tmp = JSON.parse(fs.readFileSync(path + '/' + nameWithExtension, 'utf8'));
if (!translations[name]) {
translations[name] = {};
}
for (var key in tmp) {
translations[name][key] = tmp[key];
}
}
}
};
App.prototype.loadMiddlewares = function (path) {
if (!fs.existsSync(path)) {
logger_1.logger.warn('The middleares folder ' + path + " doesn't exists!");
return;
}
var middlewares = fs.readdirSync(path);
for (var index in middlewares) {
var currentFilePath = path + '/' + middlewares[index];
if (fs.lstatSync(currentFilePath).isDirectory()) {
this.loadMiddlewares(currentFilePath);
continue;
}
if (middlewares[index].endsWith('ts'))
continue;
var midd = require(currentFilePath);
if (!midd.default) {
throw new Error('Please define the middleware as the export default class in file ' +
currentFilePath +
'.');
}
expressGenerator.useMiddleware(this, midd.default);
}
};
App.prototype.loadControllers = function (path) {
var files = fs.readdirSync(path);
for (var index in files) {
var currentFilePath = path + '/' + files[index];
if (fs.lstatSync(currentFilePath).isDirectory()) {
this.loadControllers(currentFilePath);
continue;
}
if (files[index].endsWith('ts'))
continue;
var ctrl = require(currentFilePath);
if (!ctrl.default) {
throw new Error('Please define the controller as the export default class in file ' +
currentFilePath +
'.');
}
expressGenerator.useController(this, ctrl.default, routes);
}
};
App.prototype.loadTemplating = function (path) {
if (!fs.existsSync(path)) {
return;
}
var files = fs.readdirSync(path);
for (var index in files) {
var currentFilePath = path + '/' + files[index];
if (fs.lstatSync(currentFilePath).isDirectory()) {
this.loadTemplating(currentFilePath);
continue;
}
if (files[index].endsWith('ts'))
continue;
require(currentFilePath);
}
};
App.prototype.startServer = function (port) {
var _this = this;
this.express.use(function (req, res) {
_this._errorController
.onNotFound(req)
.then(function (r) {
if (!res.headersSent) {
res.status(404);
}
r.performResponse(req, res);
})
.catch(function (err) {
if (!res.headersSent) {
res.status(404);
}
res.send(err);
});
});
this.express.use(function (error, req, res, _) {
_this._errorController
.onError(error, req)
.then(function (r) {
if (!res.headersSent) {
res.status(500);
}
r.performResponse(req, res);
})
.catch(function (err) {
if (!res.headersSent) {
res.status(500);
}
res.send(err);
});
});
this.httpServer.listen(port, function () {
logger_1.logger.info("server is listening on " + port);
});
};
/**
* Proxy method to the usual `route` method available from the controller
* @param name the name of the route
* @param parameters an object containing the parameters of the route
* @returns the compiled url
*/
App.prototype.route = function (name, parameters) {
return route(name, parameters);
};
/**
* Request the translation of a string
* @param str the string to be translated
* @param req the request from which infer the language
* @param language optionally, the language can be forced using this variable
* @returns the translated string
*/
App.prototype.translate = function (str, req, language) {
try {
var lang = language !== null && language !== void 0 ? language : getLanguageFromRequest(req);
if (!lang) {
lang = this._config.defaultLanguage;
}
return performTranslation(str, translations[lang]);
}
catch (e) {
logger_1.logger.info(e);
}
return str;
};
/**
* Request the translation of a string, formatted with parameters.
* Each parameter should be encoded as {0}, {1}, etc...
* @param str the string key to be translated
* @param req the original request
* @param language optionally, the language can be forced using this variable
* @param args the arguments to format the string
*/
App.prototype.translateFormat = function (str, req, language) {
var args = [];
for (var _i = 3; _i < arguments.length; _i++) {
args[_i - 3] = arguments[_i];
}
var translated = this.translate(str, req, language);
return this.format.apply(this, __spreadArrays([translated], args));
};
App.prototype.format = function (fmt) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
if (!fmt.match(/^(?:(?:(?:[^{}]|(?:\{\{)|(?:\}\}))+)|(?:\{[0-9]+\}))+$/)) {
throw new Error('invalid format string.');
}
return fmt.replace(/((?:[^{}]|(?:\{\{)|(?:\}\}))+)|(?:\{([0-9]+)\})/g, function (_, str, index) {
if (str) {
return str.replace(/(?:{{)|(?:}})/g, function (m) { return m[0]; });
}
else {
if (index >= args.length) {
throw new Error('argument index is out of range in format');
}
return args[index];
}
});
};
/**
* Utility method to generate an user token
* @param user the user
* @returns the token for the user
*/
App.prototype.generateTokenForUser = function (user) {
return jsonwebtoken_1.sign({ id: user.id }, this._config.tokenSecret, {
expiresIn: '1y',
});
};
return App;
}());
exports.default = App;
Object.defineProperty(Array.prototype, 'serialize', {
enumerable: false,
configurable: true,
value: function () {
var r = [];
for (var _i = 0, _a = this; _i < _a.length; _i++) {
var el = _a[_i];
if (el.serialize) {
r.push(el.serialize());
}
else {
r.push(el);
}
}
return r;
},
});
Object.defineProperty(Array.prototype, 'addHiddenField', {
enumerable: false,
configurable: true,
value: function (field) {
for (var _i = 0, _a = this; _i < _a.length; _i++) {
var el = _a[_i];
if (el.addHiddenField) {
el.addHiddenField(field);
}
}
},
});
Object.defineProperty(Array.prototype, 'removeHiddenField', {
enumerable: false,
configurable: true,
value: function (field) {
for (var _i = 0, _a = this; _i < _a.length; _i++) {
var el = _a[_i];
if (el.removeHiddenField) {
el.removeHiddenField(field);
}
}
},
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,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