{"id":22281044,"url":"https://github.com/peerigon/angular-expressions","last_synced_at":"2025-05-16T03:03:04.611Z","repository":{"id":14925297,"uuid":"17649598","full_name":"peerigon/angular-expressions","owner":"peerigon","description":"Angular expressions as standalone module","archived":false,"fork":false,"pushed_at":"2025-04-17T06:30:53.000Z","size":1088,"stargazers_count":97,"open_issues_count":3,"forks_count":23,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-19T04:16:44.166Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peerigon.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"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}},"created_at":"2014-03-12T00:01:12.000Z","updated_at":"2025-04-17T06:30:51.000Z","dependencies_parsed_at":"2024-03-17T19:23:53.152Z","dependency_job_id":"0f7aec01-eb4a-470b-b436-19dccc0ac8ad","html_url":"https://github.com/peerigon/angular-expressions","commit_stats":{"total_commits":93,"total_committers":7,"mean_commits":"13.285714285714286","dds":0.6021505376344086,"last_synced_commit":"5810f9abbb651ad2defc8837e22496a6ffec08c5"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Fangular-expressions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Fangular-expressions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Fangular-expressions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peerigon%2Fangular-expressions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peerigon","download_url":"https://codeload.github.com/peerigon/angular-expressions/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254459083,"owners_count":22074604,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-12-03T16:13:04.376Z","updated_at":"2025-05-16T03:02:59.601Z","avatar_url":"https://github.com/peerigon.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# angular-expressions\n\n**[angular's nicest part](https://github.com/angular/angular.js/blob/6b049c74ccc9ee19688bb9bbe504c300e61776dc/src/ng/parse.js) extracted as a standalone module for the browser and node.**\n\n[![build status](https://travis-ci.org/peerigon/angular-expressions.svg)](http://travis-ci.org/peerigon/angular-expressions)\n\n**angular-expressions** exposes a `.compile()`-method which can be used to compile evaluable expressions:\n\n```javascript\nvar expressions = require(\"angular-expressions\");\n\nevaluate = expressions.compile(\"1 + 1\");\nevaluate(); // returns 2\n```\n\nYou can also set and get values on a given `scope`:\n\n```javascript\nevaluate = expressions.compile(\"name\");\nscope = { name: \"Jenny\" };\nevaluate(scope); // returns 'Jenny'\n\nevaluate = expressions.compile(\"ship.pirate.name = 'Störtebeker'\");\nevaluate(scope); // won't throw an error because angular's expressions are forgiving\nconsole.log(scope.ship.pirate.name); // prints 'Störtebeker'\n```\n\nFor assigning values, you can also use `.assign()`:\n\n```javascript\nevaluate = expressions.compile(\"ship.pirate.name\");\nevaluate.assign(scope, \"Störtebeker\");\nconsole.log(scope.ship.pirate.name); // prints 'Störtebeker'\n```\n\nCheck out [their readme](http://docs.angularjs.org/guide/expression) for further information.\n\n\u003cbr /\u003e\n\n## Setup\n\n[![npm status](https://nodei.co/npm/angular-expressions.svg?downloads=true\u0026stars=true\u0026downloadRank=true)](https://npmjs.org/package/angular-expressions)\n\n\u003cbr /\u003e\n\n## Filters\n\nAngular provides a mechanism to define filters on expressions:\n\n```javascript\nexpressions.filters.uppercase = (input) =\u003e input.toUpperCase();\n\nexpr = expressions.compile(\"'arr' | uppercase\");\nexpr(); // returns 'ARR'\n```\n\nArguments are evaluated against the scope:\n\n```javascript\nexpressions.filters.currency = (input, currency, digits) =\u003e {\n  input = input.toFixed(digits);\n\n  if (currency === \"EUR\") {\n    return input + \"€\";\n  } else {\n    return input + \"$\";\n  }\n};\n\nexpr = expressions.compile(\"1.2345 | currency:selectedCurrency:2\");\nexpr({\n  selectedCurrency: \"EUR\",\n}); // returns '1.23€'\n```\n\nIf you need an isolated `filters` object, this can be achieved by setting the `filters` attribute in the `options` argument. Global cache is disabled if using `options.filters`. To setup an isolated cache, you can also set the `cache` attribute in the `options` argument:\n\n```javascript\nvar isolatedFilters = {\n  transform: (input) =\u003e input.toLowerCase(),\n};\nvar isolatedCache = {};\n\nvar resultOne = expressions.compile(\"'Foo Bar' | transform\", {\n  filters: isolatedFilters,\n  cache: isolatedCache,\n});\n\nconsole.log(resultOne()); // prints 'foo bar'\nconsole.log(isolatedCache); // prints '{\"'Foo Bar' | transform\": [Function fn] }'\n```\n\n\u003cbr /\u003e\n\n## API\n\n### exports\n\n#### .compile(src): Function\n\nCompiles `src` and returns a function `evaluate()`. The compiled function is cached under `compile.cache[src]` to speed up further calls.\n\nCompiles also export the AST.\n\nExample output of: `compile(\"tmp + 1\").ast`\n\n```\n{ type: 'Program',\n  body:\n   [ { type: 'ExpressionStatement',\n       expression:\n        { type: 'Identifier',\n          name: 'tmp',\n          constant: false,\n          toWatch: [ [Circular] ] } } ],\n  constant: false }\n```\n\n_NOTE_ angular \\$parse do not export ast variable it's done by this library.\n\n#### .compile.cache = Object.create(null)\n\nA cache containing all compiled functions. The src is used as key. Set this on `false` to disable the cache.\n\n#### .filters = {}\n\nAn empty object where you may define your custom filters.\n\n#### .Lexer\n\nThe internal [Lexer](https://github.com/angular/angular.js/blob/6b049c74ccc9ee19688bb9bbe504c300e61776dc/src/ng/parse.js#L116).\n\n#### .Parser\n\nThe internal [Parser](https://github.com/angular/angular.js/blob/6b049c74ccc9ee19688bb9bbe504c300e61776dc/src/ng/parse.js#L390).\n\n---\n\n### evaluate(scope?): \\*\n\nEvaluates the compiled `src` and returns the result of the expression. Property look-ups or assignments are executed on a given `scope`.\n\n### evaluate.assign(scope, value): \\*\n\nTries to assign the given `value` to the result of the compiled expression on the given `scope` and returns the result of the assignment.\n\n\u003cbr /\u003e\n\n## In the browser\n\nThere is no `dist` build because it's not 2005 anymore. Use a module bundler like [webpack](http://webpack.github.io/) or [browserify](http://browserify.org/). They're both capable of CommonJS and AMD.\n\n\u003cbr /\u003e\n\n## Security\n\nThe code of angular was not secured from reading prototype, and since version 1.0.1 of angular-expressions, the module disallows reading properties that are not ownProperties. See [this blog post](http://blog.angularjs.org/2016/09/angular-16-expression-sandbox-removal.html) for more details about the sandbox that got removed completely in angular 1.6.\n\nComment from `angular.js/src/ng/parse.js`:\n\n---\n\nAngular expressions are generally considered safe because these expressions only have direct\naccess to \\$scope and locals. However, one can obtain the ability to execute arbitrary JS code by\nobtaining a reference to native JS functions such as the Function constructor.\n\nAs an example, consider the following Angular expression:\n\n```javascript\n{}.toString.constructor(alert(\"evil JS code\"))\n```\n\nWe want to prevent this type of access. For the sake of performance, during the lexing phase we\ndisallow any \"dotted\" access to any member named \"constructor\".\n\nFor reflective calls (a[b]) we check that the value of the lookup is not the Function constructor\nwhile evaluating the expression, which is a stronger but more expensive test. Since reflective\ncalls are expensive anyway, this is not such a big deal compared to static dereferencing.\nThis sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits\nagainst the expression language, but not to prevent exploits that were enabled by exposing\nsensitive JavaScript or browser apis on Scope. Exposing such objects on a Scope is never a good\npractice and therefore we are not even trying to protect against interaction with an object\nexplicitly exposed in this way.\n\nA developer could foil the name check by aliasing the Function constructor under a different\nname on the scope.\n\nIn general, it is not possible to access a Window object from an angular expression unless a\nwindow or some DOM object that has a reference to window is published onto a Scope.\n\n---\n\n\u003cbr /\u003e\n\n## Authorship\n\nKudos go entirely to the great angular.js team, it's their implementation!\n\n\u003cbr /\u003e\n\n## Contributing\n\nSuggestions and bug-fixes are always appreciated. Don't hesitate to create an issue or pull-request. All contributed code should pass\n\n1. the tests in node.js by running `npm test`\n2. the tests in all major browsers by running `npm run test-browser` and then visiting `http://localhost:8080/bundle`\n\n\u003cbr /\u003e\n\n## License\n\n[Unlicense](http://unlicense.org/)\n\n## Sponsors\n\n[\u003cimg src=\"https://assets.peerigon.com/peerigon/logo/peerigon-logo-flat-spinat.png\" width=\"150\" /\u003e](https://peerigon.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeerigon%2Fangular-expressions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeerigon%2Fangular-expressions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeerigon%2Fangular-expressions/lists"}