@hapify/ejs
Advanced tools
+16
| # Changelog | ||
| All notable changes to this project will be documented in this file. See | ||
| [Conventional Commits](https://conventionalcommits.org) for commit guidelines. | ||
| # @hapify/ejs 1.0.0 (2021-04-16) | ||
| ### Bug Fixes | ||
| * **ejs:** remove repository ([ecfd351](https://github.com/hapify/hapify/commit/ecfd3519dfb433d19928defd4a49f0bf5287d0c8)) | ||
| ### Features | ||
| * add ejs package ([#15](https://github.com/hapify/hapify/issues/15)) ([b8fe5f7](https://github.com/hapify/hapify/commit/b8fe5f7eae35dd1c6296c7e10e7b0dacc43cee02)) |
| export declare class EjsEvaluationError extends Error { | ||
| code: number; | ||
| name: string; | ||
| lineNumber: number; | ||
| details: string; | ||
| } |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.EjsEvaluationError = void 0; | ||
| class EjsEvaluationError extends Error { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.code = 7001; | ||
| this.name = 'EjsEvaluationError'; | ||
| this.lineNumber = null; | ||
| this.details = null; | ||
| } | ||
| } | ||
| exports.EjsEvaluationError = EjsEvaluationError; | ||
| //# sourceMappingURL=EjsEvaluationError.js.map |
| {"version":3,"file":"EjsEvaluationError.js","sourceRoot":"","sources":["../../src/errors/EjsEvaluationError.ts"],"names":[],"mappings":";;;AAAA,MAAa,kBAAmB,SAAQ,KAAK;IAA7C;;QACE,SAAI,GAAG,IAAI,CAAC;QAEZ,SAAI,GAAG,oBAAoB,CAAC;QAE5B,eAAU,GAAW,IAAI,CAAC;QAE1B,YAAO,GAAW,IAAI,CAAC;IACzB,CAAC;CAAA;AARD,gDAQC"} |
Sorry, the diff of this file is not supported yet
+2
-7
@@ -0,10 +1,6 @@ | ||
| import { EjsEvaluationError } from './errors/EjsEvaluationError'; | ||
| interface HapifyEJSOptions { | ||
| timeout: number; | ||
| } | ||
| export declare class EjsEvaluationError extends Error { | ||
| code: number; | ||
| name: string; | ||
| lineNumber: number; | ||
| details: string; | ||
| } | ||
| export { EjsEvaluationError }; | ||
| export declare class HapifyEJS { | ||
@@ -27,2 +23,1 @@ /** Default options */ | ||
| } | ||
| export {}; |
+12
-16
@@ -7,19 +7,13 @@ "use strict"; | ||
| exports.HapifyEJS = exports.EjsEvaluationError = void 0; | ||
| const vm_1 = require("@hapify/vm"); | ||
| const fs_1 = require("fs"); | ||
| const path_1 = require("path"); | ||
| const vm_1 = require("@hapify/vm"); | ||
| const pkg_dir_1 = __importDefault(require("pkg-dir")); | ||
| const EjsEvaluationError_1 = require("./errors/EjsEvaluationError"); | ||
| Object.defineProperty(exports, "EjsEvaluationError", { enumerable: true, get: function () { return EjsEvaluationError_1.EjsEvaluationError; } }); | ||
| const SECOND = 1000; | ||
| const RootDir = pkg_dir_1.default.sync(__dirname); | ||
| const EjsLibContent = fs_1.readFileSync(path_1.join(RootDir, 'libs', 'ejs.js'), { encoding: 'utf8' }); | ||
| class EjsEvaluationError extends Error { | ||
| constructor() { | ||
| super(...arguments); | ||
| this.code = 7001; | ||
| this.name = 'EjsEvaluationError'; | ||
| this.lineNumber = null; | ||
| this.details = null; | ||
| } | ||
| } | ||
| exports.EjsEvaluationError = EjsEvaluationError; | ||
| const EjsLibContent = fs_1.readFileSync(path_1.join(RootDir, 'libs', 'ejs.js'), { | ||
| encoding: 'utf8', | ||
| }); | ||
| class HapifyEJS { | ||
@@ -32,3 +26,3 @@ /** Constructor */ | ||
| }; | ||
| this.options = Object.assign({}, this.defaultOptions, options); | ||
| this.options = Object.assign(Object.assign({}, this.defaultOptions), options); | ||
| } | ||
@@ -50,3 +44,3 @@ /** Wrap content in ejs compiler */ | ||
| const wrappedContent = this.wrapWithEjs(content); | ||
| const options = Object.assign({}, this.options, { eval: true }); | ||
| const options = Object.assign(Object.assign({}, this.options), { eval: true }); | ||
| const vm = new vm_1.HapifyVM(options); | ||
@@ -71,5 +65,7 @@ let result; | ||
| const lineNumberMatches = /Error: ejs:([0-9]+)/.exec(lines[0]); | ||
| const lineNumber = lineNumberMatches ? Number(lineNumberMatches[1]) : null; | ||
| const lineNumber = lineNumberMatches | ||
| ? Number(lineNumberMatches[1]) | ||
| : null; | ||
| const details = lines.join('\n').trim(); | ||
| const ejsError = new EjsEvaluationError(lastLine); | ||
| const ejsError = new EjsEvaluationError_1.EjsEvaluationError(lastLine); | ||
| ejsError.details = details; | ||
@@ -76,0 +72,0 @@ ejsError.lineNumber = lineNumber; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,2BAAkC;AAClC,+BAA4B;AAE5B,mCAAuD;AACvD,sDAA6B;AAE7B,oEAAiE;AAYxD,mGAZA,uCAAkB,OAYA;AAV3B,MAAM,MAAM,GAAG,IAAI,CAAC;AACpB,MAAM,OAAO,GAAG,iBAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACvC,MAAM,aAAa,GAAG,iBAAY,CAAC,WAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE;IAClE,QAAQ,EAAE,MAAM;CACjB,CAAC,CAAC;AAQH,MAAa,SAAS;IASpB,kBAAkB;IAClB,YAAY,UAAqC,EAAE;QATnD,sBAAsB;QACd,mBAAc,GAAqB;YACzC,OAAO,EAAE,MAAM;SAChB,CAAC;QAOA,IAAI,CAAC,OAAO,mCAAQ,IAAI,CAAC,cAAc,GAAK,OAAO,CAAE,CAAC;IACxD,CAAC;IAED,mCAAmC;IAC3B,WAAW,CAAC,OAAe;QACjC,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO,GAAG,aAAa;oBACP,cAAc;;GAE/B,CAAC;IACF,CAAC;IAED,iCAAiC;IACzB,aAAa,CAAC,OAAe;QACnC,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED,sBAAsB;IACtB,GAAG,CAAC,OAAe,EAAE,OAA+B;QAClD,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,OAAO,mCAAQ,IAAI,CAAC,OAAO,KAAE,IAAI,EAAE,IAAI,GAAE,CAAC;QAChD,MAAM,EAAE,GAAG,IAAI,aAAQ,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,MAAM,CAAC;QAEX,IAAI;YACF,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;SAC9C;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;SACrC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,iBAAiB,CACvB,KAA8B;QAE9B,IAAI,KAAK,YAAY,oBAAe,EAAE;YACpC,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;gBAC5D,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAExC,MAAM,QAAQ,GAAG,KAAK;qBACnB,GAAG,EAAE;qBACL,OAAO,CAAC,iCAAiC,EAAE,EAAE,CAAC;qBAC9C,IAAI,EAAE,CAAC;gBAEV,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/D,MAAM,UAAU,GAAG,iBAAiB;oBAClC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;oBAC9B,CAAC,CAAC,IAAI,CAAC;gBAET,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBAExC,MAAM,QAAQ,GAAG,IAAI,uCAAkB,CAAC,QAAQ,CAAC,CAAC;gBAClD,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC;gBAC3B,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;gBAEjC,OAAO,QAAQ,CAAC;aACjB;SACF;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAxED,8BAwEC"} |
+404
-410
| // This is a minimalist version of EJS 3.1.5 without usage of require, cache or filesystem | ||
| //========================================================================== | ||
@@ -21,15 +20,15 @@ // utils.js | ||
| utils.escapeRegExpChars = function (string) { | ||
| // istanbul ignore if | ||
| if (!string) { | ||
| return ''; | ||
| } | ||
| return String(string).replace(regExpChars, '\\$&'); | ||
| // istanbul ignore if | ||
| if (!string) { | ||
| return ''; | ||
| } | ||
| return String(string).replace(regExpChars, '\\$&'); | ||
| }; | ||
| const _ENCODE_HTML_RULES = { | ||
| '&': '&', | ||
| '<': '<', | ||
| '>': '>', | ||
| '"': '"', | ||
| "'": ''' | ||
| '&': '&', | ||
| '<': '<', | ||
| '>': '>', | ||
| '"': '"', | ||
| "'": ''', | ||
| }; | ||
@@ -39,3 +38,3 @@ const _MATCH_HTML = /[&<>'"]/g; | ||
| function encode_char(c) { | ||
| return _ENCODE_HTML_RULES[c] || c; | ||
| return _ENCODE_HTML_RULES[c] || c; | ||
| } | ||
@@ -53,13 +52,13 @@ | ||
| const escapeFuncStr = | ||
| 'const _ENCODE_HTML_RULES = {\n' | ||
| + ' "&": "&"\n' | ||
| + ' , "<": "<"\n' | ||
| + ' , ">": ">"\n' | ||
| + ' , \'"\': """\n' | ||
| + ' , "\'": "'"\n' | ||
| + ' }\n' | ||
| + ' , _MATCH_HTML = /[&<>\'"]/g;\n' | ||
| + 'function encode_char(c) {\n' | ||
| + ' return _ENCODE_HTML_RULES[c] || c;\n' | ||
| + '};\n'; | ||
| 'const _ENCODE_HTML_RULES = {\n' + | ||
| ' "&": "&"\n' + | ||
| ' , "<": "<"\n' + | ||
| ' , ">": ">"\n' + | ||
| ' , \'"\': """\n' + | ||
| ' , "\'": "'"\n' + | ||
| ' }\n' + | ||
| ' , _MATCH_HTML = /[&<>\'"]/g;\n' + | ||
| 'function encode_char(c) {\n' + | ||
| ' return _ENCODE_HTML_RULES[c] || c;\n' + | ||
| '};\n'; | ||
@@ -79,9 +78,6 @@ /** | ||
| utils.escapeXML = function (markup) { | ||
| return markup == undefined | ||
| ? '' | ||
| : String(markup) | ||
| .replace(_MATCH_HTML, encode_char); | ||
| return markup == undefined ? '' : String(markup).replace(_MATCH_HTML, encode_char); | ||
| }; | ||
| utils.escapeXML.toString = function () { | ||
| return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr; | ||
| return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr; | ||
| }; | ||
@@ -94,4 +90,4 @@ | ||
| */ | ||
| utils.basename =function (path) { | ||
| return path.split('/').reverse()[0]; | ||
| utils.basename = function (path) { | ||
| return path.split('/').reverse()[0]; | ||
| }; | ||
@@ -104,4 +100,4 @@ | ||
| */ | ||
| utils.extname = function(filename) { | ||
| return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined; | ||
| utils.extname = function (filename) { | ||
| return /[.]/.exec(filename) ? /[^.]+$/.exec(filename) : undefined; | ||
| }; | ||
@@ -136,27 +132,24 @@ | ||
| function rethrow(err, str, flnm, lineno, esc) { | ||
| const lines = str.split('\n'); | ||
| const start = Math.max(lineno - 3, 0); | ||
| const end = Math.min(lines.length, lineno + 3); | ||
| const filename = esc(flnm); | ||
| // Error context | ||
| const context = lines.slice(start, end).map(function (line, i){ | ||
| const curr = i + start + 1; | ||
| return (curr == lineno ? ' >> ' : ' ') | ||
| + curr | ||
| + '| ' | ||
| + line; | ||
| }).join('\n'); | ||
| const lines = str.split('\n'); | ||
| const start = Math.max(lineno - 3, 0); | ||
| const end = Math.min(lines.length, lineno + 3); | ||
| const filename = esc(flnm); | ||
| // Error context | ||
| const context = lines | ||
| .slice(start, end) | ||
| .map(function (line, i) { | ||
| const curr = i + start + 1; | ||
| return (curr == lineno ? ' >> ' : ' ') + curr + '| ' + line; | ||
| }) | ||
| .join('\n'); | ||
| // Alter exception message | ||
| err.path = filename; | ||
| err.message = (filename || 'ejs') + ':' | ||
| + lineno + '\n' | ||
| + context + '\n\n' | ||
| + err.message; | ||
| // Alter exception message | ||
| err.path = filename; | ||
| err.message = (filename || 'ejs') + ':' + lineno + '\n' + context + '\n\n' + err.message; | ||
| throw err; | ||
| throw err; | ||
| } | ||
| function stripSemi(str){ | ||
| return str.replace(/;(\s*$)/, '$1'); | ||
| function stripSemi(str) { | ||
| return str.replace(/;(\s*$)/, '$1'); | ||
| } | ||
@@ -178,19 +171,19 @@ | ||
| ejs.compile = function compile(template, opts) { | ||
| let templ; | ||
| let templ; | ||
| // v1 compat | ||
| // 'scope' is 'context' | ||
| // FIXME: Remove this in a future version | ||
| if (opts && opts.scope) { | ||
| if (!scopeOptionWarned){ | ||
| console.warn('`scope` option is deprecated and will be removed in EJS 3'); | ||
| scopeOptionWarned = true; | ||
| } | ||
| if (!opts.context) { | ||
| opts.context = opts.scope; | ||
| } | ||
| delete opts.scope; | ||
| } | ||
| templ = new Template(template, opts); | ||
| return templ.compile(); | ||
| // v1 compat | ||
| // 'scope' is 'context' | ||
| // FIXME: Remove this in a future version | ||
| if (opts && opts.scope) { | ||
| if (!scopeOptionWarned) { | ||
| console.warn('`scope` option is deprecated and will be removed in EJS 3'); | ||
| scopeOptionWarned = true; | ||
| } | ||
| if (!opts.context) { | ||
| opts.context = opts.scope; | ||
| } | ||
| delete opts.scope; | ||
| } | ||
| templ = new Template(template, opts); | ||
| return templ.compile(); | ||
| }; | ||
@@ -205,379 +198,380 @@ | ||
| function Template(text, opts) { | ||
| opts = opts || {}; | ||
| const options = {}; | ||
| this.templateText = text; | ||
| /** @type {string | null} */ | ||
| this.mode = null; | ||
| this.truncate = false; | ||
| this.currentLine = 1; | ||
| this.source = ''; | ||
| options.client = opts.client || false; | ||
| options.escapeFunction = opts.escape || opts.escapeFunction || utils.escapeXML; | ||
| options.compileDebug = opts.compileDebug !== false; | ||
| options.debug = !!opts.debug; | ||
| options.filename = opts.filename; | ||
| options.openDelimiter = opts.openDelimiter || _DEFAULT_OPEN_DELIMITER; | ||
| options.closeDelimiter = opts.closeDelimiter || _DEFAULT_CLOSE_DELIMITER; | ||
| options.delimiter = opts.delimiter || _DEFAULT_DELIMITER; | ||
| options.strict = opts.strict || false; | ||
| options.context = opts.context; | ||
| options.rmWhitespace = opts.rmWhitespace; | ||
| options.root = opts.root; | ||
| options.includer = opts.includer; | ||
| options.outputFunctionName = opts.outputFunctionName; | ||
| options.localsName = opts.localsName || _DEFAULT_LOCALS_NAME; | ||
| options.views = opts.views; | ||
| options.async = opts.async; | ||
| options.destructuredLocals = opts.destructuredLocals; | ||
| options.legacyInclude = typeof opts.legacyInclude != 'undefined' ? !!opts.legacyInclude : true; | ||
| opts = opts || {}; | ||
| const options = {}; | ||
| this.templateText = text; | ||
| /** @type {string | null} */ | ||
| this.mode = null; | ||
| this.truncate = false; | ||
| this.currentLine = 1; | ||
| this.source = ''; | ||
| options.client = opts.client || false; | ||
| options.escapeFunction = opts.escape || opts.escapeFunction || utils.escapeXML; | ||
| options.compileDebug = opts.compileDebug !== false; | ||
| options.debug = !!opts.debug; | ||
| options.filename = opts.filename; | ||
| options.openDelimiter = opts.openDelimiter || _DEFAULT_OPEN_DELIMITER; | ||
| options.closeDelimiter = opts.closeDelimiter || _DEFAULT_CLOSE_DELIMITER; | ||
| options.delimiter = opts.delimiter || _DEFAULT_DELIMITER; | ||
| options.strict = opts.strict || false; | ||
| options.context = opts.context; | ||
| options.rmWhitespace = opts.rmWhitespace; | ||
| options.root = opts.root; | ||
| options.includer = opts.includer; | ||
| options.outputFunctionName = opts.outputFunctionName; | ||
| options.localsName = opts.localsName || _DEFAULT_LOCALS_NAME; | ||
| options.views = opts.views; | ||
| options.async = opts.async; | ||
| options.destructuredLocals = opts.destructuredLocals; | ||
| options.legacyInclude = typeof opts.legacyInclude != 'undefined' ? !!opts.legacyInclude : true; | ||
| if (options.strict) { | ||
| options._with = false; | ||
| } | ||
| else { | ||
| options._with = typeof opts._with != 'undefined' ? opts._with : true; | ||
| } | ||
| if (options.strict) { | ||
| options._with = false; | ||
| } else { | ||
| options._with = typeof opts._with != 'undefined' ? opts._with : true; | ||
| } | ||
| this.opts = options; | ||
| this.opts = options; | ||
| this.regex = this.createRegex(); | ||
| this.regex = this.createRegex(); | ||
| } | ||
| Template.modes = { | ||
| EVAL: 'eval', | ||
| ESCAPED: 'escaped', | ||
| RAW: 'raw', | ||
| COMMENT: 'comment', | ||
| LITERAL: 'literal' | ||
| EVAL: 'eval', | ||
| ESCAPED: 'escaped', | ||
| RAW: 'raw', | ||
| COMMENT: 'comment', | ||
| LITERAL: 'literal', | ||
| }; | ||
| Template.prototype = { | ||
| createRegex: function () { | ||
| let str = _REGEX_STRING; | ||
| const delim = utils.escapeRegExpChars(this.opts.delimiter); | ||
| const open = utils.escapeRegExpChars(this.opts.openDelimiter); | ||
| const close = utils.escapeRegExpChars(this.opts.closeDelimiter); | ||
| str = str.replace(/%/g, delim) | ||
| .replace(/</g, open) | ||
| .replace(/>/g, close); | ||
| return new RegExp(str); | ||
| }, | ||
| createRegex: function () { | ||
| let str = _REGEX_STRING; | ||
| const delim = utils.escapeRegExpChars(this.opts.delimiter); | ||
| const open = utils.escapeRegExpChars(this.opts.openDelimiter); | ||
| const close = utils.escapeRegExpChars(this.opts.closeDelimiter); | ||
| str = str.replace(/%/g, delim).replace(/</g, open).replace(/>/g, close); | ||
| return new RegExp(str); | ||
| }, | ||
| compile: function () { | ||
| /** @type {string} */ | ||
| let src; | ||
| /** @type {ClientFunction} */ | ||
| let fn; | ||
| const opts = this.opts; | ||
| let prepended = ''; | ||
| let appended = ''; | ||
| /** @type {EscapeCallback} */ | ||
| const escapeFn = opts.escapeFunction; | ||
| /** @type {FunctionConstructor} */ | ||
| let ctor; | ||
| compile: function () { | ||
| /** @type {string} */ | ||
| let src; | ||
| /** @type {ClientFunction} */ | ||
| let fn; | ||
| const opts = this.opts; | ||
| let prepended = ''; | ||
| let appended = ''; | ||
| /** @type {EscapeCallback} */ | ||
| const escapeFn = opts.escapeFunction; | ||
| /** @type {FunctionConstructor} */ | ||
| let ctor; | ||
| if (!this.source) { | ||
| this.generateSource(); | ||
| prepended += | ||
| ' let __output = "";\n' + | ||
| ' function __append(s) { if (s !== undefined && s !== null) __output += s }\n'; | ||
| if (opts.outputFunctionName) { | ||
| prepended += ' let ' + opts.outputFunctionName + ' = __append;' + '\n'; | ||
| } | ||
| if (opts.destructuredLocals && opts.destructuredLocals.length) { | ||
| let destructuring = ' let __locals = (' + opts.localsName + ' || {}),\n'; | ||
| for (let i = 0; i < opts.destructuredLocals.length; i++) { | ||
| const name = opts.destructuredLocals[i]; | ||
| if (i > 0) { | ||
| destructuring += ',\n '; | ||
| } | ||
| destructuring += name + ' = __locals.' + name; | ||
| } | ||
| prepended += destructuring + ';\n'; | ||
| } | ||
| if (opts._with !== false) { | ||
| prepended += ' with (' + opts.localsName + ' || {}) {' + '\n'; | ||
| appended += ' }' + '\n'; | ||
| } | ||
| appended += ' return __output;' + '\n'; | ||
| this.source = prepended + this.source + appended; | ||
| } | ||
| if (!this.source) { | ||
| this.generateSource(); | ||
| prepended += ' let __output = "";\n' + ' function __append(s) { if (s !== undefined && s !== null) __output += s }\n'; | ||
| if (opts.outputFunctionName) { | ||
| prepended += ' let ' + opts.outputFunctionName + ' = __append;' + '\n'; | ||
| } | ||
| if (opts.destructuredLocals && opts.destructuredLocals.length) { | ||
| let destructuring = ' let __locals = (' + opts.localsName + ' || {}),\n'; | ||
| for (let i = 0; i < opts.destructuredLocals.length; i++) { | ||
| const name = opts.destructuredLocals[i]; | ||
| if (i > 0) { | ||
| destructuring += ',\n '; | ||
| } | ||
| destructuring += name + ' = __locals.' + name; | ||
| } | ||
| prepended += destructuring + ';\n'; | ||
| } | ||
| if (opts._with !== false) { | ||
| prepended += ' with (' + opts.localsName + ' || {}) {' + '\n'; | ||
| appended += ' }' + '\n'; | ||
| } | ||
| appended += ' return __output;' + '\n'; | ||
| this.source = prepended + this.source + appended; | ||
| } | ||
| if (opts.compileDebug) { | ||
| src = 'let __line = 1' + '\n' | ||
| + ' , __lines = ' + JSON.stringify(this.templateText) + '\n' | ||
| + ' , __filename = ' + (opts.filename ? | ||
| JSON.stringify(opts.filename) : 'undefined') + ';' + '\n' | ||
| + 'try {' + '\n' | ||
| + this.source | ||
| + '} catch (e) {' + '\n' | ||
| + ' rethrow(e, __lines, __filename, __line, escapeFn);' + '\n' | ||
| + '}' + '\n'; | ||
| } | ||
| else { | ||
| src = this.source; | ||
| } | ||
| if (opts.compileDebug) { | ||
| src = | ||
| 'let __line = 1' + | ||
| '\n' + | ||
| ' , __lines = ' + | ||
| JSON.stringify(this.templateText) + | ||
| '\n' + | ||
| ' , __filename = ' + | ||
| (opts.filename ? JSON.stringify(opts.filename) : 'undefined') + | ||
| ';' + | ||
| '\n' + | ||
| 'try {' + | ||
| '\n' + | ||
| this.source + | ||
| '} catch (e) {' + | ||
| '\n' + | ||
| ' rethrow(e, __lines, __filename, __line, escapeFn);' + | ||
| '\n' + | ||
| '}' + | ||
| '\n'; | ||
| } else { | ||
| src = this.source; | ||
| } | ||
| if (opts.client) { | ||
| src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\n' + src; | ||
| if (opts.compileDebug) { | ||
| src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '\n' + src; | ||
| } | ||
| } | ||
| if (opts.client) { | ||
| src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\n' + src; | ||
| if (opts.compileDebug) { | ||
| src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '\n' + src; | ||
| } | ||
| } | ||
| if (opts.strict) { | ||
| src = '"use strict";\n' + src; | ||
| } | ||
| if (opts.debug) { | ||
| console.log(src); | ||
| } | ||
| if (opts.compileDebug && opts.filename) { | ||
| src = src + '\n' | ||
| + '//# sourceURL=' + opts.filename + '\n'; | ||
| } | ||
| if (opts.strict) { | ||
| src = '"use strict";\n' + src; | ||
| } | ||
| if (opts.debug) { | ||
| console.log(src); | ||
| } | ||
| if (opts.compileDebug && opts.filename) { | ||
| src = src + '\n' + '//# sourceURL=' + opts.filename + '\n'; | ||
| } | ||
| try { | ||
| if (opts.async) { | ||
| // Have to use generated function for this, since in envs without support, | ||
| // it breaks in parsing | ||
| try { | ||
| ctor = (new Function('return (async function(){}).constructor;'))(); | ||
| } | ||
| catch(e) { | ||
| if (e instanceof SyntaxError) { | ||
| throw new Error('This environment does not support async/await'); | ||
| } | ||
| else { | ||
| throw e; | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| ctor = Function; | ||
| } | ||
| fn = new ctor(opts.localsName + ', escapeFn, include, rethrow', src); | ||
| } | ||
| catch(e) { | ||
| // istanbul ignore else | ||
| if (e instanceof SyntaxError) { | ||
| if (opts.filename) { | ||
| e.message += ' in ' + opts.filename; | ||
| } | ||
| e.message += ' while compiling ejs\n\n'; | ||
| e.message += 'If the above error is not helpful, you may want to try EJS-Lint:\n'; | ||
| e.message += 'https://github.com/RyanZim/EJS-Lint'; | ||
| if (!opts.async) { | ||
| e.message += '\n'; | ||
| e.message += 'Or, if you meant to create an async function, pass `async: true` as an option.'; | ||
| } | ||
| } | ||
| throw e; | ||
| } | ||
| try { | ||
| if (opts.async) { | ||
| // Have to use generated function for this, since in envs without support, | ||
| // it breaks in parsing | ||
| try { | ||
| ctor = new Function('return (async function(){}).constructor;')(); | ||
| } catch (e) { | ||
| if (e instanceof SyntaxError) { | ||
| throw new Error('This environment does not support async/await'); | ||
| } else { | ||
| throw e; | ||
| } | ||
| } | ||
| } else { | ||
| ctor = Function; | ||
| } | ||
| fn = new ctor(opts.localsName + ', escapeFn, include, rethrow', src); | ||
| } catch (e) { | ||
| // istanbul ignore else | ||
| if (e instanceof SyntaxError) { | ||
| if (opts.filename) { | ||
| e.message += ' in ' + opts.filename; | ||
| } | ||
| e.message += ' while compiling ejs\n\n'; | ||
| e.message += 'If the above error is not helpful, you may want to try EJS-Lint:\n'; | ||
| e.message += 'https://github.com/RyanZim/EJS-Lint'; | ||
| if (!opts.async) { | ||
| e.message += '\n'; | ||
| e.message += 'Or, if you meant to create an async function, pass `async: true` as an option.'; | ||
| } | ||
| } | ||
| throw e; | ||
| } | ||
| // Return a callable function which will execute the function | ||
| // created by the source-code, with the passed data as locals | ||
| // Adds a local `include` function which allows full recursive include | ||
| const returnedFn = opts.client ? fn : function anonymous(data) { | ||
| const include = function (path, includeData) { | ||
| throw new Error('Cannot use include'); | ||
| }; | ||
| return fn.apply(opts.context, [data || {}, escapeFn, include, rethrow]); | ||
| }; | ||
| if (opts.filename && typeof Object.defineProperty === 'function') { | ||
| const filename = opts.filename; | ||
| const basename = utils.basename(filename, utils.extname(filename)); | ||
| try { | ||
| Object.defineProperty(returnedFn, 'name', { | ||
| value: basename, | ||
| writable: false, | ||
| enumerable: false, | ||
| configurable: true | ||
| }); | ||
| } catch (e) {/* ignore */} | ||
| } | ||
| return returnedFn; | ||
| }, | ||
| // Return a callable function which will execute the function | ||
| // created by the source-code, with the passed data as locals | ||
| // Adds a local `include` function which allows full recursive include | ||
| const returnedFn = opts.client | ||
| ? fn | ||
| : function anonymous(data) { | ||
| const include = function (path, includeData) { | ||
| throw new Error('Cannot use include'); | ||
| }; | ||
| return fn.apply(opts.context, [data || {}, escapeFn, include, rethrow]); | ||
| }; | ||
| if (opts.filename && typeof Object.defineProperty === 'function') { | ||
| const filename = opts.filename; | ||
| const basename = utils.basename(filename, utils.extname(filename)); | ||
| try { | ||
| Object.defineProperty(returnedFn, 'name', { | ||
| value: basename, | ||
| writable: false, | ||
| enumerable: false, | ||
| configurable: true, | ||
| }); | ||
| } catch (e) { | ||
| /* ignore */ | ||
| } | ||
| } | ||
| return returnedFn; | ||
| }, | ||
| generateSource: function () { | ||
| const opts = this.opts; | ||
| generateSource: function () { | ||
| const opts = this.opts; | ||
| if (opts.rmWhitespace) { | ||
| // Have to use two separate replace here as `^` and `$` operators don't | ||
| // work well with `\r` and empty lines don't work well with the `m` flag. | ||
| this.templateText = | ||
| this.templateText.replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, ''); | ||
| } | ||
| if (opts.rmWhitespace) { | ||
| // Have to use two separate replace here as `^` and `$` operators don't | ||
| // work well with `\r` and empty lines don't work well with the `m` flag. | ||
| this.templateText = this.templateText.replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, ''); | ||
| } | ||
| // Slurp spaces and tabs before <%_ and after _%> | ||
| this.templateText = | ||
| this.templateText.replace(/[ \t]*<%_/gm, '<%_').replace(/_%>[ \t]*/gm, '_%>'); | ||
| // Slurp spaces and tabs before <%_ and after _%> | ||
| this.templateText = this.templateText.replace(/[ \t]*<%_/gm, '<%_').replace(/_%>[ \t]*/gm, '_%>'); | ||
| const self = this; | ||
| const matches = this.parseTemplateText(); | ||
| const d = this.opts.delimiter; | ||
| const o = this.opts.openDelimiter; | ||
| const c = this.opts.closeDelimiter; | ||
| const self = this; | ||
| const matches = this.parseTemplateText(); | ||
| const d = this.opts.delimiter; | ||
| const o = this.opts.openDelimiter; | ||
| const c = this.opts.closeDelimiter; | ||
| if (matches && matches.length) { | ||
| matches.forEach(function (line, index) { | ||
| let closing; | ||
| // If this is an opening tag, check for closing tags | ||
| // FIXME: May end up with some false positives here | ||
| // Better to store modes as k/v with openDelimiter + delimiter as key | ||
| // Then this can simply check against the map | ||
| if ( line.indexOf(o + d) === 0 // If it is a tag | ||
| && line.indexOf(o + d + d) !== 0) { // and is not escaped | ||
| closing = matches[index + 2]; | ||
| if (!(closing == d + c || closing == '-' + d + c || closing == '_' + d + c)) { | ||
| throw new Error('Could not find matching close tag for "' + line + '".'); | ||
| } | ||
| } | ||
| self.scanLine(line); | ||
| }); | ||
| } | ||
| if (matches && matches.length) { | ||
| matches.forEach(function (line, index) { | ||
| let closing; | ||
| // If this is an opening tag, check for closing tags | ||
| // FIXME: May end up with some false positives here | ||
| // Better to store modes as k/v with openDelimiter + delimiter as key | ||
| // Then this can simply check against the map | ||
| if ( | ||
| line.indexOf(o + d) === 0 && // If it is a tag | ||
| line.indexOf(o + d + d) !== 0 | ||
| ) { | ||
| // and is not escaped | ||
| closing = matches[index + 2]; | ||
| if (!(closing == d + c || closing == '-' + d + c || closing == '_' + d + c)) { | ||
| throw new Error('Could not find matching close tag for "' + line + '".'); | ||
| } | ||
| } | ||
| self.scanLine(line); | ||
| }); | ||
| } | ||
| }, | ||
| }, | ||
| parseTemplateText: function () { | ||
| let str = this.templateText; | ||
| const pat = this.regex; | ||
| let result = pat.exec(str); | ||
| const arr = []; | ||
| let firstPos; | ||
| parseTemplateText: function () { | ||
| let str = this.templateText; | ||
| const pat = this.regex; | ||
| let result = pat.exec(str); | ||
| const arr = []; | ||
| let firstPos; | ||
| while (result) { | ||
| firstPos = result.index; | ||
| while (result) { | ||
| firstPos = result.index; | ||
| if (firstPos !== 0) { | ||
| arr.push(str.substring(0, firstPos)); | ||
| str = str.slice(firstPos); | ||
| } | ||
| if (firstPos !== 0) { | ||
| arr.push(str.substring(0, firstPos)); | ||
| str = str.slice(firstPos); | ||
| } | ||
| arr.push(result[0]); | ||
| str = str.slice(result[0].length); | ||
| result = pat.exec(str); | ||
| } | ||
| arr.push(result[0]); | ||
| str = str.slice(result[0].length); | ||
| result = pat.exec(str); | ||
| } | ||
| if (str) { | ||
| arr.push(str); | ||
| } | ||
| if (str) { | ||
| arr.push(str); | ||
| } | ||
| return arr; | ||
| }, | ||
| return arr; | ||
| }, | ||
| _addOutput: function (line) { | ||
| if (this.truncate) { | ||
| // Only replace single leading linebreak in the line after | ||
| // -%> tag -- this is the single, trailing linebreak | ||
| // after the tag that the truncation mode replaces | ||
| // Handle Win / Unix / old Mac linebreaks -- do the \r\n | ||
| // combo first in the regex-or | ||
| line = line.replace(/^(?:\r\n|\r|\n)/, ''); | ||
| this.truncate = false; | ||
| } | ||
| if (!line) { | ||
| return line; | ||
| } | ||
| _addOutput: function (line) { | ||
| if (this.truncate) { | ||
| // Only replace single leading linebreak in the line after | ||
| // -%> tag -- this is the single, trailing linebreak | ||
| // after the tag that the truncation mode replaces | ||
| // Handle Win / Unix / old Mac linebreaks -- do the \r\n | ||
| // combo first in the regex-or | ||
| line = line.replace(/^(?:\r\n|\r|\n)/, ''); | ||
| this.truncate = false; | ||
| } | ||
| if (!line) { | ||
| return line; | ||
| } | ||
| // Preserve literal slashes | ||
| line = line.replace(/\\/g, '\\\\'); | ||
| // Preserve literal slashes | ||
| line = line.replace(/\\/g, '\\\\'); | ||
| // Convert linebreaks | ||
| line = line.replace(/\n/g, '\\n'); | ||
| line = line.replace(/\r/g, '\\r'); | ||
| // Convert linebreaks | ||
| line = line.replace(/\n/g, '\\n'); | ||
| line = line.replace(/\r/g, '\\r'); | ||
| // Escape double-quotes | ||
| // - this will be the delimiter during execution | ||
| line = line.replace(/"/g, '\\"'); | ||
| this.source += ' ; __append("' + line + '")' + '\n'; | ||
| }, | ||
| // Escape double-quotes | ||
| // - this will be the delimiter during execution | ||
| line = line.replace(/"/g, '\\"'); | ||
| this.source += ' ; __append("' + line + '")' + '\n'; | ||
| }, | ||
| scanLine: function (line) { | ||
| const self = this; | ||
| const d = this.opts.delimiter; | ||
| const o = this.opts.openDelimiter; | ||
| const c = this.opts.closeDelimiter; | ||
| let newLineCount = 0; | ||
| scanLine: function (line) { | ||
| const self = this; | ||
| const d = this.opts.delimiter; | ||
| const o = this.opts.openDelimiter; | ||
| const c = this.opts.closeDelimiter; | ||
| let newLineCount = 0; | ||
| newLineCount = line.split('\n').length - 1; | ||
| newLineCount = (line.split('\n').length - 1); | ||
| switch (line) { | ||
| case o + d: | ||
| case o + d + '_': | ||
| this.mode = Template.modes.EVAL; | ||
| break; | ||
| case o + d + '=': | ||
| this.mode = Template.modes.ESCAPED; | ||
| break; | ||
| case o + d + '-': | ||
| this.mode = Template.modes.RAW; | ||
| break; | ||
| case o + d + '#': | ||
| this.mode = Template.modes.COMMENT; | ||
| break; | ||
| case o + d + d: | ||
| this.mode = Template.modes.LITERAL; | ||
| this.source += ' ; __append("' + line.replace(o + d + d, o + d) + '")' + '\n'; | ||
| break; | ||
| case d + d + c: | ||
| this.mode = Template.modes.LITERAL; | ||
| this.source += ' ; __append("' + line.replace(d + d + c, d + c) + '")' + '\n'; | ||
| break; | ||
| case d + c: | ||
| case '-' + d + c: | ||
| case '_' + d + c: | ||
| if (this.mode == Template.modes.LITERAL) { | ||
| this._addOutput(line); | ||
| } | ||
| switch (line) { | ||
| case o + d: | ||
| case o + d + '_': | ||
| this.mode = Template.modes.EVAL; | ||
| break; | ||
| case o + d + '=': | ||
| this.mode = Template.modes.ESCAPED; | ||
| break; | ||
| case o + d + '-': | ||
| this.mode = Template.modes.RAW; | ||
| break; | ||
| case o + d + '#': | ||
| this.mode = Template.modes.COMMENT; | ||
| break; | ||
| case o + d + d: | ||
| this.mode = Template.modes.LITERAL; | ||
| this.source += ' ; __append("' + line.replace(o + d + d, o + d) + '")' + '\n'; | ||
| break; | ||
| case d + d + c: | ||
| this.mode = Template.modes.LITERAL; | ||
| this.source += ' ; __append("' + line.replace(d + d + c, d + c) + '")' + '\n'; | ||
| break; | ||
| case d + c: | ||
| case '-' + d + c: | ||
| case '_' + d + c: | ||
| if (this.mode == Template.modes.LITERAL) { | ||
| this._addOutput(line); | ||
| } | ||
| this.mode = null; | ||
| this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0; | ||
| break; | ||
| default: | ||
| // In script mode, depends on type of tag | ||
| if (this.mode) { | ||
| // If '//' is found without a line break, add a line break. | ||
| switch (this.mode) { | ||
| case Template.modes.EVAL: | ||
| case Template.modes.ESCAPED: | ||
| case Template.modes.RAW: | ||
| if (line.lastIndexOf('//') > line.lastIndexOf('\n')) { | ||
| line += '\n'; | ||
| } | ||
| } | ||
| switch (this.mode) { | ||
| // Just executing code | ||
| case Template.modes.EVAL: | ||
| this.source += ' ; ' + line + '\n'; | ||
| break; | ||
| // Exec, esc, and output | ||
| case Template.modes.ESCAPED: | ||
| this.source += ' ; __append(escapeFn(' + stripSemi(line) + '))' + '\n'; | ||
| break; | ||
| // Exec and output | ||
| case Template.modes.RAW: | ||
| this.source += ' ; __append(' + stripSemi(line) + ')' + '\n'; | ||
| break; | ||
| case Template.modes.COMMENT: | ||
| // Do nothing | ||
| break; | ||
| // Literal <%% mode, append as raw output | ||
| case Template.modes.LITERAL: | ||
| this._addOutput(line); | ||
| break; | ||
| } | ||
| } | ||
| // In string mode, just add the output | ||
| else { | ||
| this._addOutput(line); | ||
| } | ||
| } | ||
| this.mode = null; | ||
| this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0; | ||
| break; | ||
| default: | ||
| // In script mode, depends on type of tag | ||
| if (this.mode) { | ||
| // If '//' is found without a line break, add a line break. | ||
| switch (this.mode) { | ||
| case Template.modes.EVAL: | ||
| case Template.modes.ESCAPED: | ||
| case Template.modes.RAW: | ||
| if (line.lastIndexOf('//') > line.lastIndexOf('\n')) { | ||
| line += '\n'; | ||
| } | ||
| } | ||
| switch (this.mode) { | ||
| // Just executing code | ||
| case Template.modes.EVAL: | ||
| this.source += ' ; ' + line + '\n'; | ||
| break; | ||
| // Exec, esc, and output | ||
| case Template.modes.ESCAPED: | ||
| this.source += ' ; __append(escapeFn(' + stripSemi(line) + '))' + '\n'; | ||
| break; | ||
| // Exec and output | ||
| case Template.modes.RAW: | ||
| this.source += ' ; __append(' + stripSemi(line) + ')' + '\n'; | ||
| break; | ||
| case Template.modes.COMMENT: | ||
| // Do nothing | ||
| break; | ||
| // Literal <%% mode, append as raw output | ||
| case Template.modes.LITERAL: | ||
| this._addOutput(line); | ||
| break; | ||
| } | ||
| } | ||
| // In string mode, just add the output | ||
| else { | ||
| this._addOutput(line); | ||
| } | ||
| } | ||
| if (self.opts.compileDebug && newLineCount) { | ||
| this.currentLine += newLineCount; | ||
| this.source += ' ; __line = ' + this.currentLine + '\n'; | ||
| } | ||
| } | ||
| if (self.opts.compileDebug && newLineCount) { | ||
| this.currentLine += newLineCount; | ||
| this.source += ' ; __line = ' + this.currentLine + '\n'; | ||
| } | ||
| }, | ||
| }; | ||
+22
-34
| { | ||
| "name": "@hapify/ejs", | ||
| "version": "0.4.1", | ||
| "version": "1.0.0", | ||
| "description": "Sandbox for EJS templates", | ||
| "main": "dist/index.js", | ||
| "types": "dist/index.d.ts", | ||
| "scripts": { | ||
| "update": "npm-check -u", | ||
| "test": "nyc mocha", | ||
| "lint": "prettier --write '**/*.ts'", | ||
| "build": "rimraf dist && tsc -p ." | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+ssh://git@github.com:hapify/ejs.git" | ||
| }, | ||
| "keywords": [ | ||
@@ -22,23 +10,29 @@ "hapify", | ||
| ], | ||
| "license": "MIT", | ||
| "author": "Edouard Demotes-Mainard <edouard@tractr.net>", | ||
| "license": "MIT", | ||
| "homepage": "https://github.com/hapify/ejs#readme", | ||
| "homepage": "https://github.com/hapify/hapify", | ||
| "main": "dist/index.js", | ||
| "types": "dist/index.d.ts", | ||
| "scripts": { | ||
| "build": "rimraf dist && tsc -p .", | ||
| "clean": "rimraf dist node_modules coverage .nyc_output", | ||
| "prepublishOnly": "npm run build", | ||
| "lint": "npm run lint:tsc && npm run lint:prettier && npm run lint:eslint", | ||
| "lint:eslint": "eslint \"{src,test}/**/*.{ts,js}\"", | ||
| "lint:eslint:fix": "npm run lint:eslint -- --fix", | ||
| "lint:fix": "npm run lint:tsc:fix && npm run lint:prettier:fix && npm run lint:eslint:fix", | ||
| "lint:prettier": "prettier --check \"{src,test}/**/*.{ts,js}\"", | ||
| "lint:prettier:fix": "prettier --write \"{src,test}/**/*.{ts,js}\"", | ||
| "lint:tsc": "tsc --noEmit", | ||
| "lint:tsc:fix": "npm run lint:tsc", | ||
| "test": "nyc mocha", | ||
| "update": "npm-check -u" | ||
| }, | ||
| "devDependencies": { | ||
| "@commitlint/cli": "^11.0.0", | ||
| "@commitlint/config-conventional": "^11.0.0", | ||
| "@hapi/code": "^8.0.2", | ||
| "@types/mocha": "^8.2.0", | ||
| "@types/node": "^14.14.22", | ||
| "husky": "^4.3.8", | ||
| "mocha": "^8.2.1", | ||
| "npm-check": "^5.9.2", | ||
| "nyc": "^15.1.0", | ||
| "prettier": "^2.2.1", | ||
| "pretty-quick": "^3.1.0", | ||
| "rimraf": "^3.0.2", | ||
| "ts-node": "^9.1.1", | ||
| "typescript": "^4.1.3" | ||
| "mocha": "^8.2.1" | ||
| }, | ||
| "dependencies": { | ||
| "@hapify/vm": "^0.3.6", | ||
| "@hapify/vm": "1.1.0", | ||
| "pkg-dir": "^5.0.0" | ||
@@ -48,9 +42,3 @@ }, | ||
| "node": ">=12" | ||
| }, | ||
| "husky": { | ||
| "hooks": { | ||
| "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", | ||
| "pre-commit": "pretty-quick --staged --pattern \"**/*.ts\"" | ||
| } | ||
| } | ||
| } |
+1
-1
@@ -7,3 +7,3 @@ # Hapify EJS | ||
| [](https://travis-ci.org/hapify/ejs) [](https://codecov.io/gh/hapify/ejs) | ||
| [](https://api.travis-ci.com/hapify/ejs) [](https://codecov.io/gh/hapify/ejs) | ||
@@ -10,0 +10,0 @@ ## Usage |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
34732
24.32%3
-78.57%12
71.43%631
1.28%0
-100%3
50%+ Added
- Removed
Updated