{"id":47870933,"url":"https://github.com/axetroy/ecma-evaluator","last_synced_at":"2026-04-04T00:51:00.827Z","repository":{"id":324189302,"uuid":"1096297061","full_name":"axetroy/ecma-evaluator","owner":"axetroy","description":"A tiny, fast, and secure JavaScript expression evaluator for safely evaluating expressions and template strings in a sandboxed environment.","archived":false,"fork":false,"pushed_at":"2026-01-12T08:31:05.000Z","size":247,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-07T22:35:04.463Z","etag":null,"topics":["ecma","ecmascript","evaluator","expression-evaluator","javascript-library","template-engine"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/ecma-evaluator","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/axetroy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"axetroy","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":"https://github.com/axetroy/buy-me-a-cup-of-tea"}},"created_at":"2025-11-14T08:11:38.000Z","updated_at":"2026-01-12T08:31:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/axetroy/ecma-evaluator","commit_stats":null,"previous_names":["axetroy/evaluator.js","axetroy/ecma-evaluator"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/axetroy/ecma-evaluator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axetroy%2Fecma-evaluator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axetroy%2Fecma-evaluator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axetroy%2Fecma-evaluator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axetroy%2Fecma-evaluator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/axetroy","download_url":"https://codeload.github.com/axetroy/ecma-evaluator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axetroy%2Fecma-evaluator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31383635,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T23:20:52.058Z","status":"ssl_error","status_checked_at":"2026-04-03T23:20:51.675Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ecma","ecmascript","evaluator","expression-evaluator","javascript-library","template-engine"],"created_at":"2026-04-04T00:51:00.246Z","updated_at":"2026-04-04T00:51:00.820Z","avatar_url":"https://github.com/axetroy.png","language":"JavaScript","funding_links":["https://github.com/sponsors/axetroy","https://github.com/axetroy/buy-me-a-cup-of-tea"],"categories":[],"sub_categories":[],"readme":"# ecma-evaluator\n\n[![Badge](https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg?style=flat-square)](https://996.icu/#/en_US)\n[![LICENSE](https://img.shields.io/badge/license-Anti%20996-blue.svg?style=flat-square)](https://github.com/996icu/996.ICU/blob/master/LICENSE)\n![Node](https://img.shields.io/badge/node-%3E=14-blue.svg?style=flat-square)\n[![npm version](https://badge.fury.io/js/ecma-evaluator.svg)](https://badge.fury.io/js/ecma-evaluator)\n\nA tiny, fast, and **secure** JavaScript expression evaluator for safely evaluating expressions and template strings in a sandboxed environment.\n\nEnglish | [简体中文](./README.zh-CN.md)\n\n## Features\n\n-   ✨ **Secure by design** - Sandboxed; blocks mutations/side effects\n-   🚀 **Fast \u0026 lightweight** - Minimal dependencies, uses the efficient `acorn` parser\n-   📦 **Zero configuration** - Works out of the box with sensible defaults\n-   🎯 **Rich feature set** - Most JS expressions/functions\n-   🔒 **No eval()** - Does not use `eval()` or `Function()` constructor\n-   💪 **TypeScript support** - Includes TypeScript type definitions\n-   📝 **Template strings** - Evaluate expressions within template strings using `{{ }}` syntax\n\n## Installation\n\n```bash\nnpm install ecma-evaluator\n```\n\n## Quick Start\n\n```js\nimport { evalExpression, evalTemplate } from \"ecma-evaluator\";\n\n// Evaluate expression\nconst result = evalExpression(\"a + b * c\", { a: 1, b: 2, c: 3 });\nconsole.log(result); // Output: 7\n\n// Evaluate template\nconst text = evalTemplate(\"Hello {{ name }}!\", { name: \"World\" });\nconsole.log(text); // Output: \"Hello World!\"\n```\n\n## API Reference\n\n### `evalExpression(expression, context?)`\n\nEvaluates a JavaScript expression with an optional context.\n\n**Parameters:**\n\n-   `expression` (string): The JavaScript expression to evaluate\n-   `context` (object, optional): An object containing variables to use in the expression\n\n**Returns:** The result of evaluating the expression\n\n**Example:**\n\n```js\nimport { evalExpression } from \"ecma-evaluator\";\n\n// Basic arithmetic\nevalExpression(\"2 + 3 * 4\"); // 14\n\n// With variables\nevalExpression(\"x + y\", { x: 10, y: 20 }); // 30\n\n// Using built-in functions\nevalExpression(\"Math.max(a, b, c)\", { a: 5, b: 15, c: 10 }); // 15\n\n// String operations\nevalExpression(\"greeting + ', ' + name\", {\n\tgreeting: \"Hello\",\n\tname: \"Alice\",\n}); // \"Hello, Alice\"\n\n// Array methods\nevalExpression(\"[1, 2, 3].map(x =\u003e x * 2)\"); // [2, 4, 6]\n\n// Conditional expressions\nevalExpression(\"score \u003e= 60 ? 'Pass' : 'Fail'\", { score: 75 }); // \"Pass\"\n```\n\n### `evalTemplate(template, context?, templateParserOptions?)`\n\nEvaluates a template string by replacing `{{ expression }}` patterns with their evaluated values.\n\n**Parameters:**\n\n-   `template` (string): The template string to evaluate\n-   `context` (object, optional): An object containing variables to use in the template\n-   `templateParserOptions` (object, optional): Options for the template parser\n\n**Returns:** The evaluated template string\n\n**Example:**\n\n```js\nimport { evalTemplate } from \"ecma-evaluator\";\n\n// Basic variable replacement\nevalTemplate(\"Hello, {{ name }}!\", { name: \"World\" });\n// Output: \"Hello, World!\"\n\n// Multiple expressions\nevalTemplate(\"{{ a }} + {{ b }} = {{ a + b }}\", { a: 10, b: 20 });\n// Output: \"10 + 20 = 30\"\n\n// Complex expressions\nevalTemplate(\"The sum is {{ [1, 2, 3].reduce((a, b) =\u003e a + b, 0) }}\");\n// Output: \"The sum is 6\"\n\n// Template literals within expressions\nevalTemplate(\"{{ `Hello ${name}, welcome!` }}\", { name: \"Alice\" });\n// Output: \"Hello Alice, welcome!\"\n\n// Date formatting\nevalTemplate(\"Today is {{ new Date().toLocaleDateString() }}\");\n// Output: \"Today is 11/18/2025\" (varies by locale)\n\n// Conditional rendering\nevalTemplate(\"Status: {{ isActive ? 'Active' : 'Inactive' }}\", { isActive: true });\n// Output: \"Status: Active\"\n\n// Optional chaining\nevalTemplate(\"Value: {{ obj?.prop?.value ?? 'N/A' }}\", { obj: null });\n// Output: \"Value: N/A\"\n```\n\n### Error Handling\n\nWhen an undefined variable is referenced in a template, it's replaced with `\"undefined\"` instead of throwing an error:\n\n```js\nevalTemplate(\"Hello {{ name }}!\", {}); // \"Hello undefined!\"\n```\n\nFor other errors (syntax errors, type errors, etc.), an exception will be thrown:\n\n```js\nevalTemplate(\"{{ 1 + }}\", {}); // Throws SyntaxError\nevalTemplate(\"{{ obj.prop }}\", { obj: null }); // Throws TypeError\n```\n\n## Supported JavaScript Features\n\n### Operators\n\n#### Arithmetic Operators\n\n```js\nevalExpression(\"10 + 5\"); // 15 (addition)\nevalExpression(\"10 - 5\"); // 5 (subtraction)\nevalExpression(\"10 * 5\"); // 50 (multiplication)\nevalExpression(\"10 / 5\"); // 2 (division)\nevalExpression(\"10 % 3\"); // 1 (modulo)\nevalExpression(\"2 ** 3\"); // 8 (exponentiation)\n```\n\n#### Comparison Operators\n\n```js\nevalExpression(\"5 \u003e 3\"); // true\nevalExpression(\"5 \u003e= 5\"); // true\nevalExpression(\"5 \u003c 3\"); // false\nevalExpression(\"5 \u003c= 5\"); // true\nevalExpression(\"5 == '5'\"); // true (loose equality)\nevalExpression(\"5 === '5'\"); // false (strict equality)\nevalExpression(\"5 != '5'\"); // false (loose inequality)\nevalExpression(\"5 !== '5'\"); // true (strict inequality)\n```\n\n#### Logical Operators\n\n```js\nevalExpression(\"true \u0026\u0026 false\"); // false (AND)\nevalExpression(\"true || false\"); // true (OR)\nevalExpression(\"null ?? 'default'\"); // \"default\" (nullish coalescing)\nevalExpression(\"!true\"); // false (NOT)\n```\n\n#### Bitwise Operators\n\n```js\nevalExpression(\"5 \u0026 3\"); // 1 (AND)\nevalExpression(\"5 | 3\"); // 7 (OR)\nevalExpression(\"5 ^ 3\"); // 6 (XOR)\nevalExpression(\"~5\"); // -6 (NOT)\nevalExpression(\"5 \u003c\u003c 1\"); // 10 (left shift)\nevalExpression(\"5 \u003e\u003e 1\"); // 2 (right shift)\nevalExpression(\"5 \u003e\u003e\u003e 1\"); // 2 (unsigned right shift)\n```\n\n#### Unary Operators\n\n```js\nevalExpression(\"-5\"); // -5 (negation)\nevalExpression(\"+5\"); // 5 (unary plus)\nevalExpression(\"typeof 5\"); // \"number\"\nevalExpression(\"void 0\"); // undefined\n```\n\n### Data Types\n\n#### Literals\n\n```js\nevalExpression(\"42\"); // Number\nevalExpression(\"'hello'\"); // String\nevalExpression(\"true\"); // Boolean\nevalExpression(\"null\"); // null\nevalExpression(\"undefined\"); // undefined\n```\n\n#### Arrays\n\n```js\nevalExpression(\"[1, 2, 3]\"); // [1, 2, 3]\nevalExpression(\"[1, 2, 3][1]\"); // 2\nevalExpression(\"[1, 2, 3].length\"); // 3\nevalExpression(\"[1, 2, 3].map(x =\u003e x * 2)\"); // [2, 4, 6]\nevalExpression(\"[1, 2, 3].filter(x =\u003e x \u003e 1)\"); // [2, 3]\nevalExpression(\"[1, 2, 3].reduce((a, b) =\u003e a + b, 0)\"); // 6\n```\n\n#### Objects\n\n```js\nevalExpression(\"{ a: 1, b: 2 }\"); // { a: 1, b: 2 }\nevalExpression(\"({ a: 1, b: 2 }).a\"); // 1\nevalExpression(\"({ a: 1, b: 2 })['b']\"); // 2\n```\n\n#### Template Literals\n\n```js\nevalExpression(\"`Hello ${'World'}`\"); // \"Hello World\"\nevalExpression(\"`2 + 2 = ${2 + 2}`\", {}); // \"2 + 2 = 4\"\nevalExpression(\"`Hello ${name}`\", { name: \"Bob\" }); // \"Hello Bob\"\n```\n\n### Functions\n\n#### Arrow Functions\n\n```js\nevalExpression(\"((x) =\u003e x * 2)(5)\"); // 10\nevalExpression(\"[1, 2, 3].map(x =\u003e x * 2)\"); // [2, 4, 6]\nevalExpression(\"((a, b) =\u003e a + b)(3, 4)\"); // 7\n```\n\n#### Built-in Objects and Functions\n\n```js\n// Math\nevalExpression(\"Math.max(1, 2, 3)\"); // 3\nevalExpression(\"Math.min(1, 2, 3)\"); // 1\nevalExpression(\"Math.round(4.7)\"); // 5\nevalExpression(\"Math.floor(4.7)\"); // 4\nevalExpression(\"Math.ceil(4.3)\"); // 5\nevalExpression(\"Math.abs(-5)\"); // 5\nevalExpression(\"Math.sqrt(16)\"); // 4\n\n// String methods\nevalExpression(\"'hello'.toUpperCase()\"); // \"HELLO\"\nevalExpression(\"'HELLO'.toLowerCase()\"); // \"hello\"\nevalExpression(\"'hello world'.split(' ')\"); // [\"hello\", \"world\"]\n\n// Array methods (non-mutating only)\nevalExpression(\"[1,2,3].join(', ')\"); // \"1, 2, 3\"\nevalExpression(\"[1,2,3].slice(1)\"); // [2, 3]\nevalExpression(\"[1,2,3].concat([4,5])\"); // [1, 2, 3, 4, 5]\n\n// JSON\nevalExpression(\"JSON.stringify({ a: 1 })\"); // '{\"a\":1}'\nevalExpression(\"JSON.parse('{\\\"a\\\":1}')\"); // { a: 1 }\n\n// Date\nevalExpression(\"new Date(0).getTime()\"); // 0\nevalExpression(\"new Date().getFullYear()\"); // current year\n\n// Object methods\nevalExpression(\"Object.keys({ a: 1, b: 2 })\"); // [\"a\", \"b\"]\nevalExpression(\"Object.values({ a: 1, b: 2 })\"); // [1, 2]\n\n// Number methods\nevalExpression(\"Number.parseInt('42')\"); // 42\nevalExpression(\"Number.parseFloat('3.14')\"); // 3.14\nevalExpression(\"Number.isNaN(NaN)\"); // true\nevalExpression(\"Number.isFinite(42)\"); // true\n\n// Global functions\nevalExpression(\"isNaN(NaN)\"); // true\nevalExpression(\"isFinite(Infinity)\"); // false\nevalExpression(\"parseInt('42')\"); // 42\nevalExpression(\"parseFloat('3.14')\"); // 3.14\nevalExpression(\"encodeURIComponent('hello world')\"); // \"hello%20world\"\nevalExpression(\"decodeURIComponent('hello%20world')\"); // \"hello world\"\n```\n\n### Advanced Features\n\n#### Conditional (Ternary) Operator\n\n```js\nevalExpression(\"5 \u003e 3 ? 'yes' : 'no'\"); // \"yes\"\nevalExpression(\"age \u003e= 18 ? 'adult' : 'minor'\", { age: 20 }); // \"adult\"\n```\n\n#### Optional Chaining\n\n```js\nevalExpression(\"obj?.prop\", { obj: null }); // undefined\nevalExpression(\"obj?.prop?.value\", { obj: {} }); // undefined\nevalExpression(\"arr?.[0]\", { arr: null }); // undefined\nevalExpression(\"func?.()\", { func: null }); // undefined\n```\n\n#### Member Access\n\n```js\nevalExpression(\"obj.prop\", { obj: { prop: 42 } }); // 42\nevalExpression(\"obj['prop']\", { obj: { prop: 42 } }); // 42\nevalExpression(\"arr[0]\", { arr: [1, 2, 3] }); // 1\n```\n\n#### Constructor Expressions\n\n```js\nevalExpression(\"new Date(2024, 0, 1)\"); // Date object\nevalExpression(\"new Array(1, 2, 3)\"); // [1, 2, 3]\nevalExpression(\"new Set([1, 2, 2, 3])\"); // Set {1, 2, 3}\nevalExpression(\"new Map([['a', 1], ['b', 2]])\"); // Map {\"a\" =\u003e 1, \"b\" =\u003e 2}\n```\n\n## Security Features\n\n### Sandboxed Environment\n\n`ecma-evaluator` runs expressions in a sandboxed environment with several security features:\n\n1. **No access to `eval()` or `Function()` constructor** - Prevents dynamic code execution\n2. **Blocked mutable methods** - Methods that mutate objects are blocked to prevent side effects：\n\n    - Array: `push`, `pop`, `shift`, `unshift`, `splice`, `reverse`, `sort`, `fill`, `copyWithin`\n    - Object: `freeze`, `defineProperty`, `defineProperties`, `preventExtensions`, `setPrototypeOf`, `assign`\n    - Set/Map: `add`, `set`, `delete`, `clear`\n    - Date: All setter methods (`setDate`, `setFullYear`, etc.)\n    - TypedArray: `set`, `fill`, `copyWithin`, `reverse`, `sort`\n\n3. **No `delete` operator** - The `delete` operator is blocked as it's a mutating operation\n4. **Limited global scope** - Only safe built-in objects are available (Math, JSON, Array, Object, etc.)\n5. **No file system or network access** - Cannot access Node.js APIs or perform I/O operations\n6. **No access to process or global variables** - Cannot access `process`, `global`, `require`, etc.\n7. **Prevention of prototype pollution** - Accessing prototype properties (e.g., `__proto__`) is blocked\n\n### Safe Built-in Objects\n\nThe following built-in objects are available in the sandboxed environment:\n\n-   **Numbers \u0026 Math**: `Number`, `Math`, `Infinity`, `NaN`, `isNaN`, `isFinite`, `parseInt`, `parseFloat`\n-   **Strings**: `String`, `encodeURI`, `encodeURIComponent`, `decodeURI`, `decodeURIComponent`\n-   **Data Structures**: `Array`, `Object`, `Set`, `WeakSet`, `Map`, `WeakMap`\n-   **Date \u0026 Time**: `Date`\n-   **JSON**: `JSON`\n-   **Types**: `Boolean`, `Symbol`, `BigInt`, `RegExp`\n-   **TypedArrays**: `Int8Array`, `Uint8Array`, `Int16Array`, `Uint16Array`, `Int32Array`, `Uint32Array`, `Float32Array`, `Float64Array`, `BigInt64Array`, `BigUint64Array`\n-   **Errors**: `Error`, `EvalError`, `RangeError`, `ReferenceError`, `SyntaxError`, `TypeError`, `URIError`\n-   **Promises**: `Promise`\n\n\n### Error Prevention\n\n```js\n// ❌ These will throw errors:\nevalExpression(\"arr.push(1)\", { arr: [1, 2, 3] });\n// Error: Array.prototype.push is not allow\n\nevalExpression(\"new Function('return 1')\");\n// Error: Cannot use new with Function constructor\n\nevalExpression(\"delete obj.prop\", { obj: { prop: 1 } });\n// Error: Delete operator is not allow\n```\n\n## Use Cases\n\n### Configuration \u0026 Rules Engine\n\n```js\n// Evaluate business rules\nconst rule = \"age \u003e= 18 \u0026\u0026 country === 'US'\";\nconst isEligible = evalExpression(rule, { age: 25, country: \"US\" }); // true\n\n// Dynamic pricing\nconst priceFormula = \"basePrice * (1 - discount / 100)\";\nconst finalPrice = evalExpression(priceFormula, {\n\tbasePrice: 100,\n\tdiscount: 20,\n}); // 80\n```\n\n### Template Rendering\n\n```js\n// Email templates\nconst emailTemplate = `\nHello {{ user.name }},\n\nYour order #{{ order.id }} has been {{ order.status }}.\nTotal: {{ order.total.toFixed(2) }}\n\nThank you for shopping with us!\n`;\n\nconst email = evalTemplate(emailTemplate, {\n\tuser: { name: \"John Doe\" },\n\torder: { id: 12345, status: \"shipped\", total: 99.99 },\n});\n\n// Dynamic content\nconst greeting = evalTemplate(\"Good {{ hour \u003c 12 ? 'morning' : hour \u003c 18 ? 'afternoon' : 'evening' }}, {{ name }}!\", {\n\thour: new Date().getHours(),\n\tname: \"Alice\",\n});\n```\n\n### Data Transformation\n\n```js\n// Transform API responses\nconst transform = \"data.items.filter(x =\u003e x.active).map(x =\u003e x.name)\";\nconst result = evalExpression(transform, {\n\tdata: {\n\t\titems: [\n\t\t\t{ name: \"Item 1\", active: true },\n\t\t\t{ name: \"Item 2\", active: false },\n\t\t\t{ name: \"Item 3\", active: true },\n\t\t],\n\t},\n}); // [\"Item 1\", \"Item 3\"]\n```\n\n### Form Validation\n\n```js\n// Conditional validation\nconst validationRule = \"email.includes('@') \u0026\u0026 password.length \u003e= 8\";\nconst isValid = evalExpression(validationRule, {\n\temail: \"user@example.com\",\n\tpassword: \"secretpassword\",\n}); // true\n```\n\n## Limitations\n\n1. **No statements** - Only expressions are supported, not statements (no `if`, `for`, `while`, etc.)\n2. **No variable assignment** - Cannot use assignment operators (`=`, `+=`, etc.)\n3. **No mutable operations** - Mutable array/object methods are blocked\n4. **No async operations** - Promises work but cannot use `await`\n5. **No function declarations** - Only arrow functions in expressions are supported\n6. **Limited error recovery** - Syntax errors will throw immediately\n7. **No imports/requires** - Cannot import external modules\n8. **Cloneable context only** - Context objects must be cloneable (no functions, DOM nodes, etc.)\n\n## Advanced Usage\n\n### Custom Evaluator Instance\n\n```js\nimport { Evaluator } from \"ecma-evaluator\";\n\n// Create a reusable evaluator with fixed context\nconst evaluator = new Evaluator({ x: 10, y: 20 });\n\n// Evaluate multiple expressions with the same context\nconsole.log(evaluator.evaluate(\"x + y\")); // 30\nconsole.log(evaluator.evaluate(\"x * y\")); // 200\nconsole.log(evaluator.evaluate(\"Math.max(x, y)\")); // 20\n```\n\n### Custom Template Parser\n\n```js\nimport { evalTemplate } from \"ecma-evaluator\";\n\nevalTemplate(\n\t\"Hello ${ name }!\",\n\t{ name: \"World\" },\n\t{\n\t\texpressionStart: \"${\",\n\t\texpressionEnd: \"}\",\n\t\tpreserveWhitespace: false,\n\t}\n);\n// Output: \"Hello World!\"\n```\n\n## Performance Tips\n\n1. **Reuse evaluator instances** when evaluating multiple expressions with the same context\n2. **Avoid complex nested expressions** - Break them into smaller parts if possible\n3. **Cache parsed templates** if you're rendering the same template multiple times\n4. **Use simple variable access** instead of complex property chains when possible\n\n## TypeScript Support\n\nThe package includes TypeScript type definitions:\n\n## Compatibility\n\nCompatible with Nodejs and major browsers. For older environments, use Babel for transpilation and polyfills.\n\n```js\nimport 'core-js/actual/structured-clone.js';\nimport 'core-js/actual/object/has-own.js';\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nThe [Anti 996 License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxetroy%2Fecma-evaluator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faxetroy%2Fecma-evaluator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxetroy%2Fecma-evaluator/lists"}