{"_id":"@hypnosphi/jscodeshift","_rev":"471191","name":"@hypnosphi/jscodeshift","description":"A toolkit for JavaScript codemods","dist-tags":{"latest":"0.6.4"},"maintainers":[{"name":"hypnosphi","email":""}],"time":{"modified":"2021-08-05T08:19:01.000Z","created":"2019-10-21T21:00:38.925Z","0.6.4":"2019-10-21T21:00:38.925Z"},"users":{},"author":{"name":"Felix Kling"},"repository":{"type":"git","url":"https://github.com/facebook/jscodeshift.git"},"versions":{"0.6.4":{"name":"@hypnosphi/jscodeshift","version":"0.6.4","description":"A toolkit for JavaScript codemods","repository":{"type":"git","url":"https://github.com/facebook/jscodeshift.git"},"bugs":{"url":"https://github.com/facebook/jscodeshift/issues"},"main":"index.js","scripts":{"prepare":"cp -R src/ dist/","test":"jest --bail","docs":"rm -rf docs && jsdoc -d docs -R README.md src/collections/* src/core.js src/Collection.js"},"bin":{"jscodeshift":"./bin/jscodeshift.js"},"keywords":["codemod","recast","babel"],"author":{"name":"Felix Kling"},"dependencies":{"@babel/core":"^7.1.6","@babel/parser":"^7.1.6","@babel/plugin-proposal-class-properties":"^7.1.0","@babel/plugin-proposal-object-rest-spread":"^7.0.0","@babel/preset-env":"^7.1.6","@babel/preset-flow":"^7.0.0","@babel/preset-typescript":"^7.1.0","@babel/register":"^7.0.0","babel-core":"^7.0.0-bridge.0","colors":"^1.1.2","flow-parser":"0.*","graceful-fs":"^4.1.11","micromatch":"^3.1.10","neo-async":"^2.5.0","node-dir":"^0.1.17","recast":"^0.18.1","temp":"^0.8.1","write-file-atomic":"^2.3.0"},"devDependencies":{"babel-eslint":"^10.0.1","eslint":"^5.9.0","jest":"^21","jsdoc":"^3.4.0","mkdirp":"^0.5.1"},"jest":{"roots":["src","bin","sample"]},"licenseText":"MIT License\n\nCopyright (c) Facebook, Inc. and its affiliates.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","license":"MIT","_id":"@hypnosphi/jscodeshift@0.6.4","dist":{"shasum":"49a3be6ac515af831f8a3e630380e3511c8c0fb7","size":485788,"noattachment":false,"key":"/@hypnosphi/jscodeshift/-/@hypnosphi/jscodeshift-0.6.4.tgz","tarball":"http://registry.cnpm.dingdandao.com/@hypnosphi/jscodeshift/download/@hypnosphi/jscodeshift-0.6.4.tgz"},"maintainers":[{"name":"hypnosphi","email":""}],"_npmUser":{"name":"hypnosphi","email":"talpa@yandex.ru"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/jscodeshift_0.6.4_1571691638709_0.1981624610682804"},"_hasShrinkwrap":false,"publish_time":1571691638925,"_cnpm_publish_time":1571691638925}},"readme":"# jscodeshift [![Build Status](https://travis-ci.org/facebook/jscodeshift.svg?branch=master)](https://travis-ci.org/facebook/jscodeshift)\n\njscodeshift is a toolkit for running codemods over multiple JavaScript or \nTypeScript files.\nIt provides:\n\n- A runner, which executes the provided transform for each file passed to it.\n  It also outputs a summary of how many files have (not) been transformed.\n- A wrapper around [recast][], providing a different API.  Recast is an\n  AST-to-AST transform tool and also tries to preserve the style of original code\n  as much as possible.\n\n## Install\n\nGet jscodeshift from [npm][]:\n\n```\n$ npm install -g jscodeshift\n```\n\nThis will install the runner as `jscodeshift`.\n\n## Usage (CLI)\n\nThe CLI provides the following options:\n\n```\n$ jscodeshift --help\n\nUsage: jscodeshift [OPTION]... PATH...\n  or:  jscodeshift [OPTION]... -t TRANSFORM_PATH PATH...\n  or:  jscodeshift [OPTION]... -t URL PATH...\n  or:  jscodeshift [OPTION]... --stdin < file_list.txt\n\nApply transform logic in TRANSFORM_PATH (recursively) to every PATH.\nIf --stdin is set, each line of the standard input is used as a path.\n\nOptions:\n\"...\" behind an option means that it can be supplied multiple times.\nAll options are also passed to the transformer, which means you can supply custom options that are not listed here.\n\n      --(no-)babel              apply babeljs to the transform file\n                                (default: true)\n  -c, --cpus=N                  start at most N child processes to process source files\n                                (default: max(all - 1, 1))\n  -d, --(no-)dry                dry run (no changes are made to files)\n                                (default: false)\n      --extensions=EXT          transform files with these file extensions (comma separated list)\n                                (default: js)\n  -h, --help                    print this help and exit\n      --ignore-config=FILE ...  ignore files if they match patterns sourced from a configuration file (e.g. a .gitignore)\n      --ignore-pattern=GLOB ...  ignore files that match a provided glob expression\n      --parser=babel|babylon|flow|ts|tsx  the parser to use for parsing the source files\n                                          (default: babel)\n      --parser-config=FILE      path to a JSON file containing a custom parser configuration for flow or babylon\n  -p, --(no-)print              print transformed files to stdout, useful for development\n                                (default: false)\n      --(no-)run-in-band        run serially in the current process\n                                (default: false)\n  -s, --(no-)silent             do not write to stdout or stderr\n                                (default: false)\n      --(no-)stdin              read file/directory list from stdin\n                                (default: false)\n  -t, --transform=FILE          path to the transform file. Can be either a local path or url\n                                (default: ./transform.js)\n  -v, --verbose=0|1|2           show more information about the transform process\n                                (default: 0)\n      --version                 print version and exit\n```\n\nThis passes the source of all passed through the transform module specified\nwith `-t` or `--transform` (defaults to `transform.js` in the current\ndirectory). The next section explains the structure of the transform module.\n\n## Transform module\n\nThe transform is simply a module that exports a function of the form:\n\n```js\nmodule.exports = function(fileInfo, api, options) {\n  // transform `fileInfo.source` here\n  // ...\n  // return changed source\n  return source;\n};\n```\n\nAs of v0.6.1, this module can also be written in TypeScript.\n\n### Arguments\n\n#### `fileInfo`\n\nHolds information about the currently processed file.\n\nProperty    | Description\n------------|------------\npath        | File path\nsource      | File content\n\n#### `api`\n\nThis object exposes the `jscodeshift` library and helper functions from the\nrunner.\n\nProperty    | Description\n------------|------------\njscodeshift | A reference to the jscodeshift library\nstats       | A function to collect statistics during `--dry` runs\nreport      | Prints the passed string to stdout\n\n`jscodeshift` is a reference to the wrapper around recast and provides a\njQuery-like API to navigate and transform the AST. Here is a quick example,\na more detailed description can be found below.\n\n```js\n/**\n * This replaces every occurrence of variable \"foo\".\n */\nmodule.exports = function(fileInfo, api) {\n  return api.jscodeshift(fileInfo.source)\n    .findVariableDeclarators('foo')\n    .renameTo('bar')\n    .toSource();\n}\n```\n\n**Note:** This API is exposed for convenience, but you don't have to use it.\nYou can use any tool to modify the source.\n\n`stats` is a function that only works when the `--dry` options is set. It accepts\na string, and will simply count how often it was called with that value.\n\nAt the end, the CLI will report those values. This can be useful while\ndeveloping the transform, e.g. to find out how often a certain construct\nappears in the source(s).\n\n**`report`** allows you do print arbitrary strings to stdout. This can be\nuseful when other tools consume the output of jscodeshift. The reason to not\ndirectly use `process.stdout` in transform code is to avoid mangled output when\nmany files are processed.\n\n#### `options`\n\nContains all options that have been passed to runner. This allows you to pass\nadditional options to the transform. For example, if the CLI is called with\n\n```\n$ jscodeshift -t myTransforms fileA fileB --foo=bar\n```\n\n`options` would contain `{foo: 'bar'}`.\n\n### Return value\n\nThe return value of the function determines the status of the transformation:\n\n- If a string is returned and it is different from passed source, the\n  transform is considered to be successful.\n- If a string is returned but it's the same as the source, the transform\n  is considered to be unsuccessful.\n- If nothing is returned, the file is not supposed to be transformed (which is\n  ok).\n\nThe CLI provides a summary of the transformation at the end. You can get more\ndetailed information by setting the `-v` option to `1` or `2`.\n\nYou can collect even more stats via the `stats` function as explained above.\n\n### Parser\n\nThe transform can let jscodeshift know with which parser to parse the source \nfiles (and features like templates).\n\nTo do that, the transform module can export `parser`, which can either be one \nof the strings `\"babel\"`, `\"babylon\"`, `\"flow\"`, `\"ts\"`, or `\"tsx\"`,\nor it can be a parser object that is compatible with recast.\n\nFor example:\n\n```js\nmodule.exports.parser = 'flow'; // use the flow parser\n// or\nmodule.exports.parser = {\n  parse: function(source) {\n    // return estree compatible AST\n  },\n};\n```\n\n### Example output\n\n```text\n$ jscodeshift -t myTransform.js src\nProcessing 10 files...\nSpawning 2 workers with 5 files each...\nAll workers done.\nResults: 0 errors 2 unmodified 3 skipped 5 ok\n```\n\n## The jscodeshift API\n\nAs already mentioned, jscodeshift also provides a wrapper around [recast][].\nIn order to properly use the jscodeshift API, one has to understand the basic\nbuilding blocks of recast (and ASTs) as well.\n\n### Core Concepts\n\n#### AST nodes\n\nAn AST node is a plain JavaScript object with a specific set of fields, in\naccordance with the [Mozilla Parser API][]. The primary way to identify nodes\nis via their `type`.\n\nFor example, string literals are represented via `Literal` nodes, which\nhave the structure\n\n```js\n// \"foo\"\n{\n  type: 'Literal',\n  value: 'foo',\n  raw: '\"foo\"'\n}\n```\n\nIt's OK to not know the structure of every AST node type.\nThe [(esprima) AST explorer][ast-explorer] is an online tool to inspect the AST\nfor a given piece of JS code.\n\n#### Path objects\n\nRecast itself relies heavily on [ast-types][] which defines methods to traverse\nthe AST, access node fields and build new nodes. ast-types wraps every AST node\ninto a *path object*. Paths contain meta-information and helper methods to\nprocess AST nodes.\n\nFor example, the child-parent relationship between two nodes is not explicitly\ndefined. Given a plain AST node, it is not possible to traverse the tree *up*.\nGiven a path object however, the parent can be traversed to via `path.parent`.\n\nFor more information about the path object API, please have a look at\n[ast-types][].\n\n#### Builders\n\nTo make creating AST nodes a bit simpler and \"safer\", ast-types defines a couple\nof *builder methods*, which are also exposed on `jscodeshift`.\n\nFor example, the following creates an AST equivalent to `foo(bar)`:\n\n```js\n// inside a module transform\nvar j = jscodeshift;\n// foo(bar);\nvar ast = j.callExpression(\n  j.identifier('foo'),\n  [j.identifier('bar')]\n);\n```\n\nThe signature of each builder function is best learned by having a look at the\n[definition files](https://github.com/benjamn/ast-types/blob/master/def/).\n\n### Collections and Traversal\n\nIn order to transform the AST, you have to traverse it and find the nodes that\nneed to be changed. jscodeshift is built around the idea of **collections** of\npaths and thus provides a different way of processing an AST than recast or\nast-types.\n\nA collection has methods to process the nodes inside a collection, often\nresulting in a new collection. This results in a fluent interface, which can\nmake the transform more readable.\n\nCollections are \"typed\" which means that the type of a collection is the\n\"lowest\" type all AST nodes in the collection have in common. That means you\ncannot call a method for a `FunctionExpression` collection on an `Identifier`\ncollection.\n\nHere is an example of how one would find/traverse all `Identifier` nodes with\njscodeshift and with recast:\n\n```js\n// recast\nvar ast = recast.parse(src);\nrecast.visit(ast, {\n  visitIdentifier: function(path) {\n    // do something with path\n    return false;\n  }\n});\n\n// jscodeshift\njscodeshift(src)\n  .find(jscodeshift.Identifier)\n  .forEach(function(path) {\n    // do something with path\n  });\n```\n\nTo learn about the provided methods, have a look at the\n[Collection.js](src/Collection.js) and its [extensions](src/collections/).\n\n### Extensibility\n\njscodeshift provides an API to extend collections. By moving common operators\ninto helper functions (which can be stored separately in other modules), a\ntransform can be made more readable.\n\nThere are two types of extensions: generic extensions and type-specific\nextensions. **Generic extensions** are applicable to all collections. As such,\nthey typically don't access specific node data, but rather traverse the AST from\nthe nodes in the collection. **Type-specific** extensions work only on specific\nnode types and are not callable on differently typed collections.\n\n#### Examples\n\n```js\n// Adding a method to all Identifiers\njscodeshift.registerMethods({\n\tlogNames: function() {\n\t\treturn this.forEach(function(path) {\n\t\t\tconsole.log(path.node.name);\n\t\t});\n\t}\n}, jscodeshift.Identifier);\n\n// Adding a method to all collections\njscodeshift.registerMethods({\n\tfindIdentifiers: function() {\n\t\treturn this.find(jscodeshift.Identifier);\n\t}\n});\n\njscodeshift(ast).findIdentifiers().logNames();\njscodeshift(ast).logNames(); // error, unless `ast` only consists of Identifier nodes\n```\n\n### Passing options to [recast]\n\nYou may want to change some of the output settings (like setting `'` instead of `\"`).\nThis can be done by passing config options to [recast].\n\n```js\n.toSource({quote: 'single'}); // sets strings to use single quotes in transformed code.\n```\n\nYou can also pass options to recast's `parse` method by passing an object to \njscodeshift as second argument:\n\n```js\njscodeshift(source, {...})\n```\n\nMore on config options [here](https://github.com/benjamn/recast/blob/52a7ec3eaaa37e78436841ed8afc948033a86252/lib/options.js#L61)\n\n### Unit Testing\n\njscodeshift comes with a simple utility to allow easy unit testing with [Jest](https://facebook.github.io/jest/), without having to write a lot of boilerplate code. This utility makes some assumptions in order to reduce the amount of configuration required:\n\n - The test is located in a subdirectory under the directory the transform itself is located in (eg. `__tests__`)\n - Test fixtures are located in a `__testfixtures__` directory\n\nThis results in a directory structure like this:\n\n```\n/MyTransform.js\n/__tests__/MyTransform-test.js\n/__testfixtures__/MyTransform.input.js\n/__testfixtures__/MyTransform.output.js\n```\n\nA simple example of unit tests is bundled in the [sample directory](sample).\n\nThe `testUtils` module exposes a number of useful helpers for unit testing.\n\n#### `defineTest`\n\nDefines a Jest/Jasmine test for a jscodeshift transform which depends on fixtures\n\n```js\njest.autoMockOff();\nconst defineTest = require('jscodeshift/dist/testUtils').defineTest;\ndefineTest(__dirname, 'MyTransform');\n```\n\nAn alternate fixture filename can be provided as the fourth argument to `defineTest`.\nThis also means that multiple test fixtures can be provided:\n\n```js\ndefineTest(__dirname, 'MyTransform', null, 'FirstFixture');\ndefineTest(__dirname, 'MyTransform', null, 'SecondFixture');\n```\n\nThis will run two tests: \n- `__testfixtures__/FirstFixture.input.js`\n- `__testfixtures__/SecondFixture.input.js`\n\n#### `defineInlineTest`\n\nDefines a Jest/Jasmine test suite for a jscodeshift transform which accepts inline values\n\nThis is a more flexible alternative to `defineTest`, as this allows to also provide options to your transform\n\n```js\nconst defineInlineTest = require('jscodeshift/dist/testUtils').defineInlineTest;\nconst transform = require('../myTransform');\nconst transformOptions = {};\ndefineInlineTest(transform, transformOptions, 'input', 'expected output', 'test name (optional)');\n```\n\n#### `defineSnapshotTest`\n\nSimilar to `defineInlineTest` but instead of requiring an output value, it uses Jest's `toMatchSnapshot()` \n\n```js\nconst defineSnapshotTest = require('jscodeshift/dist/testUtils').defineSnapshotTest;\nconst transform = require('../myTransform');\nconst transformOptions = {};\ndefineSnapshotTest(transform, transformOptions, 'input', 'test name (optional)');\n```\n\nFor more information on snapshots, check out [Jest's docs](https://jestjs.io/docs/en/snapshot-testing)\n\n#### `applyTransform`\n\nExecutes your transform using the options and the input given and returns the result. \nThis function is used internally by the other helpers, but it can prove useful in other cases.\n\n```js\nconst applyTransform = require('jscodeshift/dist/testUtils').applyTransform;\nconst transform = require('../myTransform');\nconst transformOptions = {};\nconst output = applyTransform(transform, transformOptions, 'input');\n```\n\n### Example Codemods\n\n- [react-codemod](https://github.com/reactjs/react-codemod) - React codemod scripts to update React APIs.\n- [js-codemod](https://github.com/cpojer/js-codemod/) - Codemod scripts to transform code to next generation JS.\n- [js-transforms](https://github.com/jhgg/js-transforms) - Some documented codemod experiments to help you learn.\n\n### Recipes\n\n- [Retain leading comment(s) in file when replacing/removing first statement](recipes/retain-first-comment.md)\n\n[npm]: https://www.npmjs.com/\n[Mozilla Parser API]: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API\n[recast]: https://github.com/benjamn/recast\n[ast-types]: https://github.com/benjamn/ast-types\n[ast-explorer]: http://astexplorer.net/\n","_attachments":{},"bugs":{"url":"https://github.com/facebook/jscodeshift/issues"},"license":"MIT"}