npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ts-clone-node

v4.0.0

Published

A library that helps you clone Nodes from a Typescript AST

Downloads

277,854

Readme

A library that helps you clone Nodes from a Typescript AST

Description

The Typescript Compiler API is very powerful and comes with a lot of create and update functions that can be used for creating and updating nodes in Custom transformers while visiting a SourceFile. Under such circumstances, it is easy to run into problems if you reuse a Node in another part of the tree without properly cloning it, since the parent chain, as well as the pos and end values will have wrong values and will lead to malformed output after your transformations have been applied.

This can be cumbersome for example when you want to simply add or remove a specific modifier from an arbitrary node in a given position. This library exports a cloneNode function that makes it easy to deep-clone a Node from a Typescript AST without any faulty parent links. Additionally, you get a simple hook with which you can do simple things such as edit the top-level properties of the cloned object such as its modifiers, decorators, etc.

Features

  • Simple to use
  • Extensible
  • Supports dynamic TypeScript versions

Backers

Patreon

Table of Contents

Install

npm

$ npm install ts-clone-node

Yarn

$ yarn add ts-clone-node

pnpm

$ pnpm add ts-clone-node

Peer Dependencies

ts-clone-node depends on typescript, so you need to manually install this as well.

Usage

To clone a Node from a Typescript AST, all you have to do is:

import {cloneNode} from "ts-clone-node";

// Clone the Node
const clonedNode = cloneNode(someNode);

Configuration

Hooking into and altering transformations

You can pass in a hook that enables you to modify the clone, agnostic to the kind of Node it is. For example:

import {cloneNode} from "ts-clone-node";

// Clone the Node, and alter the modifiers such that they don't include a modifier pointing
// to the 'declare' keyword
const clonedNode = cloneNode(someNode, {
	hook: node => {
		return {
			modifiers: modifiers => ensureNoDeclareModifier(modifiers)
		};
	}
});

There is also a 'finalize' which is invoked after a node has been cloned at any recursive step from the top node, allowing you to perform final alterations or track the node for other purposes.

const clonedNode = cloneNode(someNode, {
	finalize: (clonedNode, oldNode) => trackSomething(clonedNode, oldNode)
});

Passing in a specific TypeScript version

You can use pass a specific TypeScript to use as an option to cloneNode:

cloneNode(someNode, {
	typescript: specialTypescriptVersion
});

This can be useful, for example, in an environment where multiple packages in the same project depends on different TypeScript versions and you're relying on cloneNode.

Passing in a specific NodeFactory

From TypeScript v4 and forward, a NodeFactory can be retrieved from a TransformationContext to signal which transformer was responsible for creating or altering nodes. If you want to pass a specific NodeFactory, you can pass it as an option to cloneNode:

cloneNode(someNode, {
	factory: nodeFactoryFromTransformationContext
});

Setting parent pointers

By default, when you clone a node, it won't update the parent pointers such that you and TypeScripts compiler APIs can traverse the parent tree. You can toggle this behavior with the setParents option:

cloneNode(someNode, {
	setParents: true
});

Setting original node pointers

By default, when you clone a node, it won't keep references to the original nodes recursively. You can toggle this behavior with the setOriginalNodes option:

cloneNode(someNode, {
	setOriginalNodes: true
});

Preserving comments

By default, when you clone a node, comments will be preserved as much as possible and added to the cloned nodes as emitNodes. You can toggle this behavior with the preserveComments option:

cloneNode(someNode, {
	preserveComments: false
});

Preserving symbols

By default, when you clone a node, it won't preserve symbols from the original nodes. You can toggle this behavior with the preserveSymbols option:

cloneNode(someNode, {
	preserveSymbols: true
});

Contributing

Do you want to contribute? Awesome! Please follow these recommendations.

Maintainers

| | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Frederik WessbergTwitter: @FredWessbergGithub: @wessbergLead Developer |

FAQ

What is the point of this library

If you've run into the kind of trouble I'm explaining here, you'll understand. If not, I'm happy for you. You can move along!

License

MIT © Frederik Wessberg (@FredWessberg) (Website)