Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

ember-template-recast

ember-template-lint758.9kMIT6.1.5TypeScript support: included

Non-destructive template transformer.

codemod, ember, glimmer, handlebars, recast, templates

readme

ember-template-recast

NPM version

With ember-template-recast, transform a template's AST and reprint it. Its formatting will be preserved.

For instance, it is possible to change a component's property while preserving its formatting:

const recast = require('ember-template-recast');

const template = `
<Sidebar
  foo="bar"
     item={{hmmm}}
/>
`;

// parse
let ast = recast.parse(template);

// transform
ast.body[1].attributes[1].value.path = builders.path('this.hmmm');

// print
let ouput = recast.print(ast);

output === `
<Sidebar
  foo="bar"
     item={{this.hmmm}}
/>
`; // is true!

Command Line Usage

ember-template-recast comes with a binary for running a transform across multiple files, similar to jscodeshift.

npx ember-template-recast directory/of/templates -t transform.js

Example transform plugin:

module.exports = (env) => {
  let { builders: b } = env.syntax;

  return {
    MustacheStatement() {
      return b.mustache(b.path('wat-wat'));
    },
  };
};

APIs

parse

Used to parse a given template string into an AST. Generally speaking, this AST can be mutated and passed into print (docs below).

const templateRecast = require('ember-template-recast');
const template = `
{{foo-bar
  baz="stuff"
}}
`;
let ast = templateRecast.parse(template);
// now you can work with `ast`

print

Used to generate a new template string representing the provided AST.

const templateRecast = require('ember-template-recast');
const template = `
{{foo-bar
  baz="stuff"
}}
`;
let ast = templateRecast.parse(template);
ast.body[0].hash[0].key = 'derp';

templateRecast.print(ast);

    {{foo-bar
      derp="stuff"
    }}

transform

Used to easily traverse (and possibly mutate) a given template. Returns the resulting AST and the printed template.

The plugin argument has roughly the following interface:

export interface Syntax {
  parse: typeof preprocess;
  builders: typeof builders;
  print: typeof print;
  traverse: typeof traverse;
  Walker: typeof Walker;
}

export interface TransformPluginEnv {
  syntax: Syntax;
  contents: string;
  filePath?: string;
  parseOptions: {
    srcName?: string;
  };
}

export interface TransformPluginBuilder {
  (env: TransformPluginEnv): NodeVisitor;
}

The list of known builders on the env.syntax.builders are found here, although there are a few small extensions related to formatting in custom-nodes.ts

Example:

const { transform } = require('ember-template-recast');

const template = `
{{foo-bar
  baz="stuff"
}}
`;

let { code } = transform({
  template,
  plugin(env) {
    let { builders: b } = env.syntax;

    return {
      MustacheStatement() {
        return b.mustache(b.path('wat-wat'));
      },
    };
  }
});

console.log(code); // => {{wat-wat}}

SemVer Policy

Due to usage of TypeScript and bundling external APIs this project has somewhat unique SemVer commitments. A high level summary is:

Major Version

The following are scenarios that would cause a major version (aka breaking change) release:

  • Dropping support for Node versions (e.g. dropping Node 12 support)
  • Non-additive changes to the underlying AST (which we bundle from @glimmer/syntax)
  • Breaking changes to the @glimmer/syntax builder APIs

Minor Version

The following are scenarios that would cause a minor version (aka new feature) release:

  • Changes to TypeScript version used internally by ember-template-recast
  • Changes to make the types used by ember-template-recast to be more accurate (e.g. narrowing / broadening of previously published types).
  • Adding new features

Patch Version

The following are scenarios that would cause a patch release:

  • Bug fixes to internal re-writing logic
  • Bug fix releases of @glimmer/syntax

License

This project is distributed under the MIT license, see LICENSE for details.

changelog

Changelog

v6.1.4 (2023-03-28)

:bug: Bug Fix

Committers: 1

v6.1.3 (2022-01-14)

:bug: Bug Fix

Committers: 1

v6.1.2 (2021-12-10)

:bug: Bug Fix

Committers: 1

v6.1.1 (2021-12-08)

:bug: Bug Fix

:house: Internal

Committers: 3

v6.1.0 (2021-11-18)

:rocket: Enhancement

  • #653 Allow updating quoteType and isValueless of AttrNodes, and quoteType of StringLiterals (@courajs)

:bug: Bug Fix

Committers: 2

v6.0.0 (2021-11-08)

:boom: Breaking Change

:bug: Bug Fix

:house: Internal

Committers: 3

v5.0.3 (2021-05-19)

:bug: Bug Fix

  • #555 Fix extra quoting being applied to ConcatStatement (@dcyriller)

Committers: 1

v5.0.2 (2021-05-19)

:rocket: Enhancement

  • #569 Export AST and NodeVisitor types from @glimmer/syntax. (@rwjblue)

Committers: 2

v5.0.1 (2020-11-16)

:bug: Bug Fix

:house: Internal

Committers: 1

v5.0.0 (2020-11-04)

:boom: Breaking Change

:house: Internal

Committers: 2

v4.3.0 (2020-11-04)

:rocket: Enhancement

Committers: 1

v4.2.1 (2020-10-14)

:bug: Bug Fix

  • #368 Ensure whitespace inside (and trailing) a text area is preserved. (@rwjblue)

:house: Internal

  • #362 Add a test showing how attribute-indentation might be fixable. (@rwjblue)

Committers: 1

v4.2.0 (2020-10-02)

:rocket: Enhancement

Committers: 1

v4.1.7 (2020-10-02)

:bug: Bug Fix

  • #299 Ensure replacement of an ElementNode's attribute preserves its original position. (@lifeart)

:memo: Documentation

Committers: 3

v4.1.6 (2020-09-28)

:bug: Bug Fix

Committers: 2

v4.1.5 (2020-07-15)

:bug: Bug Fix

  • #303 Preserve formatting when switching a template's body (@dcyriller)
  • #302 Improve whitespace preservation around dirty attributes / comments / modifiers (@dcyriller)

:memo: Documentation

Committers: 2

v4.1.4 (2020-04-27)

:bug: Bug Fix

  • #279 Ensure reusing an empty hash does not add extraneous whitespace (@rwjblue)

Committers: 2

v4.1.3 (2020-04-15)

:bug: Bug Fix

:house: Internal

Committers: 1

v4.1.2 (2020-04-04)

:bug: Bug Fix

  • #251 Fix issue when swapping ElementNode from self closing with attributes to block. (@rwjblue)

:house: Internal

Committers: 2

v4.1.1 (2020-02-27)

:bug: Bug Fix

  • #223 Ensure updating self-closing ElementNode preserves trailing whitespace. (@rwjblue)

Committers: 1

v4.1.0 (2020-02-20)

:rocket: Enhancement

  • #219 Expose metadata (isValueless / quoteType) on AttrNode's (@rwjblue)

Committers: 1

v4.0.1 (2020-02-20)

:bug: Bug Fix

  • #216 Fix quoting for TextNode's originally used as an AttrNode value. (@rwjblue)

:house: Internal

Committers: 2

v4.0.0 (2020-01-06)

:boom: Breaking Change

Committers: 1

v3.3.3 (2020-01-06)

:bug: Bug Fix

  • #198 Fix issue when reusing an existing Hash in a new MustacheStatement/SubExpression (@tylerturdenpants)

Committers: 1

v3.3.2 (2020-01-03)

:bug: Bug Fix

:house: Internal

  • #183 Ensure attributes, params, hash are only joined with whitespace. (@rwjblue)

Committers: 3

v3.3.1 (2019-12-16)

:bug: Bug Fix

  • #181 Fix issue with mutation of ElementNode's attributes when the first attribute value is ="" (@Turbo87)

Committers: 1

v3.3.0 (2019-12-09)

:rocket: Enhancement

  • #179 Reexport traverse function from @glimmer/syntax (@Turbo87)

:house: Internal

  • #164 Add .gitattributes file to better simulate a Windows environment (@kellyselden)

Committers: 3

v3.2.8 (2019-10-28)

:bug: Bug Fix

  • #159 Ensure templates with whitespace control are codemoded properly. (@rwjblue)

:memo: Documentation

Committers: 3

v3.2.7 (2019-10-25)

:rocket: Enhancement

:house: Internal

  • #153 Remove redundant ignoreStandalone option passed to @glimmer/syntax (@dcyriller)

Committers: 1

v3.2.6 (2019-10-22)

:bug: Bug Fix

  • #152 Fully print if/else-if/else chains (GH #149) (@zimmi88)

Committers: 1

v3.2.5 (2019-10-17)

:bug: Bug Fix

  • #148 Fix invalid recursive dirtying when mutating nodes (significant performance improvement). (@zimmi88)

Committers: 1

v3.2.4 (2019-10-16)

:bug: Bug Fix

  • #147 Fix ember-template-recast bin script file selection for Windows users (@rwjblue)

:house: Internal

Committers: 1

v3.2.3 (2019-10-15)

:bug: Bug Fix

  • #140 Avoid invalid quotes when changing an AttrNode value from TextNode to MustacheStatement (@zimmi88)

Committers: 1

v3.2.2 (2019-10-11)

:bug: Bug Fix

  • #137 Ensure AttrNode and HashPair values are preserved if changing name/key. (@rwjblue)
  • #136 Fix issues with adding to a ConcatStatement (@rwjblue)
  • #135 Ensure TextNodes are quoted in AttrNode.value (@rwjblue)

:house: Internal

Committers: 2

v3.2.1 (2019-10-10)

:bug: Bug Fix

  • #132 Ensure chained inverses are properly printed. (@rwjblue)

Committers: 2

v3.2.0 (2019-10-02)

:rocket: Enhancement

:memo: Documentation

  • #93 Add tests ensuring hash mutation order does not matter. (@rwjblue)

:house: Internal

Committers: 3

v3.1.3 (2019-08-16)

:bug: Bug Fix

  • #92 Fix mutating an element attribute with an initial valueless attribute. (@rwjblue)
  • #91 Ensure updating a void element does not print a closing tag. (@rwjblue)

Committers: 1

v3.1.2 (2019-08-15)

:bug: Bug Fix

  • #90 Ensure proxy mapping is maintained during set/delete. (@rwjblue)

Committers: 2

v3.1.1 (2019-07-11)

:house: Internal

  • #75 Remove duplicated @glimmer/syntax printer implementation. (@rwjblue)

Committers: 1

v3.1.0 (2019-07-11)

:rocket: Enhancement

:house: Internal

Committers: 2

v3.0.0 (2019-07-09)

:boom: Breaking Change

:rocket: Enhancement

Committers: 1

v2.0.2 (2019-07-05)

:bug: Bug Fix

  • #69 Ensure returning an array from a visitor is handled properly (@lifeart)

Committers: 1

v2.0.1 (2019-07-05)

:bug: Bug Fix

v2.0.0 (2019-06-21)

:boom: Breaking Change

:rocket: Enhancement

:bug: Bug Fix

:house: Internal

Committers: 4

Change Log

v1.2.5 (2019-04-30)

:bug: Bug Fix

  • #22 Adding named arguments when none existed previously. (@zimmi88)

Committers: 1

v1.2.4 (2019-04-18)

:bug: Bug Fix

:memo: Documentation

  • #18 Fixes README example for template transform. (@scalvert)

:house: Internal

  • #17 [PACKAGE UPDATE] Bump @glimmer/syntax to 0.39.3. (@rajasegar)

Committers: 3

v1.2.3 (2019-01-28)

:rocket: Enhancement

Committers: 1

v1.2.2 (2019-01-11)

:bug: Bug Fix

  • #14 Fix: Improve handling of removed hash pairs. (@zimmi88)

Committers: 1

v1.2.1 (2018-12-19)

:bug: Bug Fix

  • #12 Fix: Closing tags on block statements. (@zimmi88)

Committers: 1

v1.2.0 (2018-06-26)

:rocket: Enhancement

  • #8 Add a binary for running transforms across multiple files. (@lennyburdette)

:bug: Bug Fix

  • #9 Ensure parseInt is called with the correct radix.. (@rwjblue)

Committers: 2

v1.1.3 (2018-05-19)

:bug: Bug Fix

  • #6 Allow for many returning an array of nodes during transform. (@chadhietala)

Committers: 2

v1.1.2 (2018-05-19)

:bug: Bug Fix

Committers: 1

v1.1.1 (2018-05-19)

:rocket: Enhancement

:bug: Bug Fix

Committers: 1

v1.1.0 (2018-05-17)

:rocket: Enhancement

Committers: 1