{"id":15015906,"url":"https://github.com/ember-codemods/ember-angle-brackets-codemod","last_synced_at":"2025-10-08T01:33:42.569Z","repository":{"id":34301794,"uuid":"175910831","full_name":"ember-codemods/ember-angle-brackets-codemod","owner":"ember-codemods","description":"Codemod to convert curly braces syntax to angle brackets syntax","archived":false,"fork":false,"pushed_at":"2024-06-03T07:16:15.000Z","size":2767,"stargazers_count":60,"open_issues_count":34,"forks_count":32,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-06T10:37:00.937Z","etag":null,"topics":["codemod","ember","emberjs","jscodeshift"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ember-codemods.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":"2019-03-16T01:10:57.000Z","updated_at":"2024-05-30T02:21:03.000Z","dependencies_parsed_at":"2024-02-14T18:33:45.939Z","dependency_job_id":"275f3555-6526-41a0-89c6-66a7229760a4","html_url":"https://github.com/ember-codemods/ember-angle-brackets-codemod","commit_stats":{"total_commits":418,"total_committers":22,"mean_commits":19.0,"dds":0.5287081339712918,"last_synced_commit":"2fabf88e4ccb1cc2bcf09765ec75a14ba65757d9"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ember-codemods%2Fember-angle-brackets-codemod","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ember-codemods%2Fember-angle-brackets-codemod/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ember-codemods%2Fember-angle-brackets-codemod/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ember-codemods%2Fember-angle-brackets-codemod/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ember-codemods","download_url":"https://codeload.github.com/ember-codemods/ember-angle-brackets-codemod/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248666938,"owners_count":21142347,"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":["codemod","ember","emberjs","jscodeshift"],"created_at":"2024-09-24T19:48:08.004Z","updated_at":"2025-10-08T01:33:37.526Z","avatar_url":"https://github.com/ember-codemods.png","language":"JavaScript","readme":"# ember-angle-brackets-codemod\n\n[![Ember Observer Score](https://emberobserver.com/badges/ember-angle-brackets-codemod.svg)](https://emberobserver.com/addons/ember-angle-brackets-codemod)\n[![Build Status](https://travis-ci.org/ember-codemods/ember-angle-brackets-codemod.svg?branch=master)](https://travis-ci.org/ember-codemods/ember-angle-brackets-codemod)\n[![Coverage Status](https://coveralls.io/repos/github/ember-codemods/ember-angle-brackets-codemod/badge.svg?branch=master)](https://coveralls.io/github/ember-codemods/ember-angle-brackets-codemod?branch=master)\n[![npm version](http://img.shields.io/npm/v/ember-angle-brackets-codemod.svg?style=flat)](https://npmjs.org/package/ember-angle-brackets-codemod 'View this project on npm')\n[![dependencies Status](https://david-dm.org/ember-codemods/ember-angle-brackets-codemod/status.svg)](https://david-dm.org/ember-codemods/ember-angle-brackets-codemod)\n[![devDependencies Status](https://david-dm.org/ember-codemods/ember-angle-brackets-codemod/dev-status.svg)](https://david-dm.org/ember-codemods/ember-angle-brackets-codemod?type=dev)\n\nA [jscodeshift](https://github.com/facebook/jscodeshift) Codemod to convert curly braces syntax to angle brackets syntax for templates\nin an Ember.js app\n\nRefer to this [RFC](https://github.com/emberjs/rfcs/blob/master/text/0311-angle-bracket-invocation.md) for more details on Angle brackets invocation syntax.\n\n## Requirements\n\nThis codemod currently only supports Ember's classic filesystem layout, meaning it won't work if your app uses pods. For more info, [see this issue](https://github.com/ember-codemods/ember-angle-brackets-codemod/issues/217).\n\n## Usage\n\n**WARNING**: `jscodeshift`, and thus this codemod, **edits your files in place**.\nIt does not make a copy. Make sure your code is checked into a source control\nrepository like Git and that you have no outstanding changes to commit before\nrunning this tool.\n\n1. Start your ember development server\n2. Run Codemod, pointing it at the address of the development server\n\n```sh\n$ cd my-ember-app-or-addon\n$ npx ember-angle-brackets-codemod --telemetry=http://localhost:4200 ./path/of/files/ or ./some**/*glob.hbs\n```\n\nTelemetry helpers runs the app, grabs basic info about all of the modules at runtime. This allows the codemod to know the names of every helper, component, route, controller, etc. in the app without guessing / relying on static analysis. They basically help you to create \"runtime assisted codemods\".\n\nSee \"Gathering runtime data\" section of [ember-native-class-codemod](https://github.com/ember-codemods/ember-native-class-codemod#gathering-runtime-data) for some additonal information.\n\n### Running the codemod without Telemetry\n\n```sh\n$ cd my-ember-app-or-addon\n$ npx ember-angle-brackets-codemod ./path/of/files/ or ./some**/*glob.hbs\n```\n\n**NOTE** If you are not using telemetry, you will probably need to [manually configure the codemod to at least skip any helpers](#skipping-helpers) that are invoked in the template files you are running it on.\n\n## From\n\n```hbs\n{{site-header user=this.user class=(if this.user.isAdmin \"admin\")}}\n\n{{#super-select selected=this.user.country as |s|}}\n  {{#each this.availableCountries as |country|}}\n    {{#s.option value=country}}{{country.name}}{{/s.option}}\n  {{/each}}\n{{/super-select}}\n\n{{ui/button text=\"Click me\"}}\n```\n\n## To\n\n```hbs\n\u003cSiteHeader @user={{this.user}} class={{if this.user.isAdmin \"admin\"}} /\u003e\n\u003cSuperSelect @selected={{this.user.country}} as |s|\u003e\n  {{#each this.availableCountries as |country|}}\n    \u003cs.option @value={{country}}\u003e\n      {{country.name}}\n    \u003c/s.option\u003e\n  {{/each}}\n\u003c/SuperSelect\u003e\n\n\u003cUi::Button @text=\"Click me\" /\u003e\n```\n\n## Advanced Usage\n\n### Skipping helpers\n\nTo help the codemod disambiguate components and helpers, you can define a list of helpers from your application in a configuration file as follows:\n\n**config/anglebrackets-codemod-config.json**\n\n```js\n{\n  \"helpers\": [\n    \"date-formatter\",\n    \"info-pill\"\n  ]\n}\n```\n\nThe codemod will then ignore the above list of helpers and prevent them from being transformed into the new angle-brackets syntax.\n\nYou can also disable the conversion of the built-in components `{{link-to}}`, `{{input}}` and `{{textarea}}` as follows:\n\n**config/anglebrackets-codemod-config.json**\n\n```js\n{\n  \"helpers\": [],\n  \"skipBuiltInComponents\": true\n}\n```\n\nYou can execute the codemod with custom configuration by specifying a `--config` command line option as follows:\n\n```sh\n$ cd my-ember-app-or-addon\n$ npx ember-angle-brackets-codemod angle-brackets app/templates --config ./config/anglebrackets-codemod-config.json\n```\n\nTo get a list of helpers in your app you can do this in the Developer Console in your browser inside of your app:\n\n```js\nvar componentLikeHelpers = Object.keys(require.entries)\n  .filter(name =\u003e name.includes('/helpers/') || name.includes('/helper'))\n  .filter(name =\u003e !name.includes('/-'))\n  .map(name =\u003e {\n    let path = name.split('/helpers/');\n    return path.pop();\n  })\n  .filter(name =\u003e !name.includes('/'))\n  .uniq();\n\ncopy(JSON.stringify(componentLikeHelpers));\n```\n\n### Skipping some files\n\nIf there are files that don't convert well, you can skip them by specifying an optional `skipFilesThatMatchRegex` configuration setting. For example, with the configuration below, all files that contain `\"foo\"` or `\"bar\"` will be skipped:\n\n**config/anglebrackets-codemod-config.json**\n\n```js\n{\n  \"helpers\": [],\n  \"skipBuiltInComponents\": true,\n  \"skipFilesThatMatchRegex\": \"foo|bar\"\n}\n```\n\n### Skipping some attributes\n\nIf there are cases where some attributes should not be prefixed with `@`, you can skip them by specifying an optional `skipAttributesThatMatchRegex` configuration setting.\nFor example, with the configuration below, all attributes that matches either `/data-/gim` or `/aria-/gim` will not be prefixed with `@`:\n\n### Processing valueless data test attributes\n\nCurly invocations that have `data-test-` attributes with no value are not processed by default. The configuration below will cause them to be processed:\n\n**config/anglebrackets-codemod-config.json**\n\n```js\n{\n  \"includeValuelessDataTestAttributes\": true\n}\n```\n\n**config/anglebrackets-codemod-config.json**\n\n```js\n{\n  \"helpers\": [],\n  \"skipBuiltInComponents\": true,\n  \"skipAttributesThatMatchRegex\": [\"/data-/gim\", \"/aria-/gim\"]\n}\n```\n\nInput:\n\n```js\n  {{some-component data-test-foo=true aria-label=\"bar\" foo=true}}\n```\n\nOutput:\n\n```js\n  \u003cSomeComponent data-test-foo={{true}} aria-label=\"bar\" @foo={{true}} /\u003e\n```\n\n### Converting specific components only\n\nIf you would like to only convert certain component invocations to use the angle brackets syntax, use the `components` configuration setting and specify component names. For example, with the configuration below, only the `{{baz}}` and `{{bat}}` components will be converted, leaving everything else intact.\n\n**config/anglebrackets-codemod-config.json**\n\n```js\n{\n  \"components\": [\"baz\", \"bat\"]\n}\n```\n\n### Making helper invocations unambiguous\n\nYou may want to convert invocations like `{{concat \"foo\" \"bar\"}}` into `{{(concat \"foo\" \"bar\")}}`, which may be useful as a temporary step when upgrading to strict-mode Embroider.\n\nIn your **config/anglebrackets-codemod-config.json**, add this:\n\n```js\n{\n  \"unambiguousHelpers\": true\n}\n```\n\nNote that unambiguous helpers do not work in non-Embroider Ember, as of January 2024.\n\nNote that ambiguous invocations that cannot be statically distinguished between a helper, a property and a component — will not be modified.\n\n## Debugging Workflow\n\nOftentimes, you want to debug the codemod or the transform to identify issues with the code or to understand\nhow the transforms are working, or to troubleshoot why some tests are failing.\n\nHence we recommend a debugging work-flow like below to quickly find out what is causing the issue.\n\n### 1. Place `debugger` statements\n\nAdd `debugger` statements, in appropriate places in the code. For example:\n\n```js\n...\nconst params = a.value.params.map(p =\u003e {\n  debugger;\n  if(p.type === \"SubExpression\") {\n    return transformNestedSubExpression(p)\n...\n```\n\n### 2. Inspect the process with node debug\n\nHere we are going to start the tests selectively in node debug mode. Since the\ncodemod is using [jest](https://jestjs.io/) in turn\nto run the tests, jest is having an option `-t \u003cname-of-spec\u003e` to run a particular\nset of tests instead of running the whole test suite.\n\nWe are making use of both these features to start our tests in this particular fashion.\nFor more details on node debug, visit the [official](https://nodejs.org/en/docs/guides/debugging-getting-started/)\nNode.js debugging guide, and for jest documentation on tests, please refer [here](https://jestjs.io/docs/en/cli).\n\n```sh\nnode --inspect-brk ./node_modules/.bin/jest --runInBand --testNamePattern \u003ctest-name\u003e \n```\n\nFor example, if you want to debug the `null-subexp` test or only that particular test case is failing because of an issue.\n\n```sh\nnode --inspect-brk ./node_modules/.bin/jest --runInBand --testNamePattern 'null-subexp' \n```\n\nOr you can make use of the npm scripts defined in package.json. All you need to pass the test name as the extra parameter with the script.\n\n```sh\nnpm run debug:test 'null-subexp'\n```\n\nUsing yarn\n```sh\nyarn debug:test 'null-subexp'\n```\n\nOnce you run the above command, your tests will start running in debug mode and your breakpoints will be\ntriggered appropriately when that particular block of code gets executed. You can run the debugger inside\nChrome browser dev-tools. More details on [here](https://developers.google.com/web/tools/chrome-devtools/javascript/)\n\n## AST Explorer playground\n\n1. Go to the [AST Explorer](https://astexplorer.net/#/gist/b128d5545d7ccc52400b922f3b5010b4/642c6a8d3cc021257110bcf6b1714d1065891aec)\n2. Paste your curly brace syntax code in the top left corner window (Source)\n3. You will get the converted angle bracket syntax in the bottom right corner window (Transform Output)\n\n## RFC\n\n- [Angle Bracket Invocation](https://github.com/emberjs/rfcs/blob/master/text/0311-angle-bracket-invocation.md)\n- [Angle Bracket Invocations For Built-in Components](https://github.com/emberjs/rfcs/blob/32a25b31d67d67bc7581dd0bead559063b06f076/text/0459-angle-bracket-built-in-components.md)\n\n## Known issues\n\n- No formatting preserved\n\n## References:\n\n- https://github.com/glimmerjs/glimmer-vm/issues/685\n- https://github.com/q2ebanking/ember-template-rewrite\n- https://github.com/ember-template-lint/ember-template-recast\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fember-codemods%2Fember-angle-brackets-codemod","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fember-codemods%2Fember-angle-brackets-codemod","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fember-codemods%2Fember-angle-brackets-codemod/lists"}