@putout/plugin-putout
v21.4.0
Published
πPutout plugin helps with plugins development
Downloads
66,774
Maintainers
Readme
@putout/plugin-putout
πPutout plugin helps with plugins development.
Install
npm i @putout/plugin-putout -D
Rules
- β add-await-to-progress;
- β add-index-to-import;
- β add-places-to-compare-places;
- β add-path-arg-to-fix;
- β add-test-args;
- β add-traverse-args;
- β add-track-file;
- β apply-async-formatter;
- β apply-create-test;
- β apply-declare;
- β apply-for-of-to-track-file;
- β apply-insert-after;
- β apply-insert-before;
- β apply-namespace-specifier;
- β apply-processors-destructuring;
- β apply-remove;
- β apply-rename;
- β apply-short-processors;
- β check-match;
- β check-replace-code;
- β convert-add-argument-to-add-args;
- β convert-babel-types;
- β convert-destructuring-to-identifier;
- β convert-dirname-to-url;
- β convert-find-to-traverse;
- β convert-get-rule-to-require;
- β convert-match-to-function;
- β convert-method-to-property;
- β convert-node-to-path-in-get-template-values;
- β convert-number-to-numeric;
- β convert-process-to-find;
- β convert-progress-to-track-file;
- β convert-putout-test-to-create-test;
- β convert-replace-to-function;
- β convert-replace-with;
- β convert-replace-with-multiple;
- β convert-report-to-function;
- β convert-to-no-transform-code;
- β convert-traverse-to-include;
- β convert-traverse-to-replace;
- β convert-traverse-to-scan;
- β convert-url-to-dirname;
- β create-test;
- β declare;
- β includer;
- β move-require-on-top-level;
- β remove-empty-array-from-process;
- β remove-unused-get-properties-argument;
- β rename-operate-to-operator;
- β replace-operate-with-operator;
- β replace-test-message;
- β shorten-imports;
- β simplify-replace-template;
Config
{
"rules": {
"putout/add-places-to-compare-places": "on",
"putout/add-path-arg-to-fix": "on",
"putout/add-test-args": "on",
"putout/add-traverse-args": "on",
"putout/add-track-file": "on",
"putout/add-await-to-progress": "on",
"putout/add-index-to-import": "on",
"putout/apply-create-test": "on",
"putout/apply-processors-destructuring": "on",
"putout/apply-async-formatter": "on",
"putout/apply-declare": "on",
"putout/apply-rename": "on",
"putout/apply-remove": "on",
"putout/apply-insert-before": "on",
"putout/apply-insert-after": "on",
"putout/apply-short-processors": "on",
"putout/apply-namespace-specifier": "on",
"putout/apply-for-of-to-track-file": "on",
"putout/check-match": "on",
"putout/check-replace-code": ["on", {
"once": true
}],
"putout/convert-putout-test-to-create-test": "on",
"putout/convert-to-no-transform-code": "on",
"putout/convert-number-to-numeric": "on",
"putout/convert-replace-with": "on",
"putout/convert-replace-with-multiple": "on",
"putout/convert-replace-to-function": "on",
"putout/convert-match-to-function": "on",
"putout/convert-babel-types": "on",
"putout/convert-destructuring-to-identifier": "on",
"putout/convert-node-to-path-in-get-template-values": "on",
"putout/convert-traverse-to-include": "on",
"putout/convert-traverse-to-replace": "on",
"putout/convert-traverse-to-scan": "on",
"putout/convert-process-to-find": "on",
"putout/convert-method-to-property": "on",
"putout/convert-add-argument-to-add-args": "on",
"putout/convert-dirname-to-url": "on",
"putout/convert-url-to-dirname": "on",
"putout/convert-report-to-function": "on",
"putout/convert-get-rule-to-require": "on",
"putout/convert-progress-to-track-file": "on",
"putout/create-test": "on",
"putout/shorten-imports": "on",
"putout/declare": "on",
"putout/includer": "on",
"putout/move-require-on-top-level": "on",
"putout/replace-test-message": "on",
"putout/remove-unused-get-properties-argument": "on",
"putout/remove-empty-array-from-process": "on",
"putout/simplify-replace-template": "on"
}
}
apply-processors-destructuring
β Example of incorrect code
test('', async (t) => {
await t.process({});
});
β Example of correct code
test('', async ({process}) => {
await process({});
});
apply-short-processors
Apply short names of processors, for example __json
instead of __putout_processor_json
. Checkout out in πPutout Editor.
β Example of incorrect code
export const match = () => ({
'__putout_processor_ignore(__a)': ({__a}) => {
const list = __a.elements.map(getValue);
},
'__putout_processor_filesystem(__a)': ({__a}) => {
const list = __a.elements.map(getValue);
},
});
β Example of correct code
export const match = () => ({
[__ignore]: ({__array}) => {
const list = __array.elements.map(getValue);
},
[__filesystem]: ({__object}) => {
const list = __object.elements.map(getValue);
},
});
apply-rename
Better use rename(path, from, to)
method of operator
.
Check out in πPutout Editor.
β Example of incorrect code
export const fix = ({path, from, to}) => {
path.scope.rename(from, to);
};
β Example of correct code
import {operator} from 'putout';
const {rename} = operator;
export const fix = ({path, from, to}) => {
rename(path, from, to);
};
apply-remove
Better to use remove(path)
method of operator
.
It helps to preserve comments.
β Example of incorrect code
export const fix = (path) => {
path.remove();
};
β Example of correct code
import {operator} from 'putout';
const {remove} = operator;
export const fix = (path) => {
remove(path);
};
apply-insert-before
Better to use insertBefore(a, b)
method of operator
.
β Example of incorrect code
export const fix = (path) => {
path.insertBefore(path.get('init'));
};
β Example of correct code
import {operator} from 'putout';
const {insertBefore} = operator;
export const fix = (path) => {
insertBefore(path, path.get('init'));
};
apply-insert-after
Better to use insertAfter(a, b)
method of operator
.
It helps to avoid duplication of comments.
β Example of incorrect code
export const fix = (path) => {
path.insertAfter(path.get('init'));
};
β Example of correct code
import {operator} from 'putout';
const {insertAfter} = operator;
export const fix = (path) => {
insertAfter(path, path.get('init'));
};
apply-declare
Better to use Declareator
instead of operator.declare()
.
Check out in πPutout Editor.
β Example of incorrect code
const {operator} = require('putout');
const {declare} = operator;
module.exports = declare({
tryCatch: `import tryCatch from 'try-catch'`,
tryToCatch: `import tryToCatch from 'try-to-catch'`,
});
β Example of correct code
module.exports.declare = () => ({
tryCatch: `import tryCatch from 'try-catch'`,
tryToCatch: `import tryToCatch from 'try-to-catch'`,
});
apply-async-formatter
β Example of incorrect code
test('formatter: codeframea', (t) => {
t.format(codeframe, 1);
t.end();
});
β Example of correct code
test('formatter: codeframea', async ({format}) => {
await format(codeframe, 1);
});
apply-create-test
β Example of incorrect code
const test = require('@putout/test')({
'remove-debugger': plugin,
});
β Example of correct code
const {createTest} = require('@putout/test');
const test = createTest({
'remove-debugger': plugin,
});
apply-for-of-to-track-file
The Generator object is returned by a
generator function
and it conforms to both the iterable protocol and theiterator
protocol.(c) MDN
trackFile
is generator function used to count progress that can be used in Scanner.
Checkout in πPutout Editor
β Example of incorrect code
module.exports.scan = (path, {push, trackFile}) => {
trackFile(path, '*.swp').map(push);
};
β Example of correct code
module.exports.scan = (path, {push, trackFile}) => {
for (const file of trackFile(path, '*.swp')) {
push(file);
}
};
create-test
Add properties to createTest
options, here is exmample of .putout.json
:
{
"rules": {
"putout/create-test": ["on", {
"add": [
["printer", "putout"]
]
}]
}
}
Check it out in πPutout Editor.
β Example of incorrect code
createTest(__dirname, {
'putout/create-test': plugin,
});
β Example of correct code
createTest(__dirname, {
printer: 'putout',
plugins: [
['putout/create-test', plugin],
],
});
convert-number-to-numeric
Prevent Babel
warning: The node type NumberLiteral has been renamed to NumericLiteral
.
β Example of incorrect code
const {isNumberLiteral} = types;
isNumberLiteral(node);
β Example of correct code
const {isNumericLiteral} = types;
isNumericLiteral(node);
convert-putout-test-to-create-test
Fixes results of @putout/convert-commonjs-to-esm work.
β Example of incorrect code
import putoutTest from '@putout/test';
const test = putoutTest(__dirname, {
'remove-unused-variables': rmVars,
});
β Example of correct code
import {createTest} from '@putout/test';
const test = createTest(__dirname, {
'remove-unused-variables': rmVars,
});
convert-to-no-transform-code
β Example of incorrect code
test('plugin-apply-destructuring: transform: array: destructuring', (t) => {
const code = 'const {name} = array[0]';
t.transform(code, '');
t.end();
});
β Example of correct code
test('plugin-apply-destructuring: transform: array: destructuring', (t) => {
const code = 'const {name} = array[0]';
t.noTransformCode(code);
t.end();
});
convert-replace-with
β Example of incorrect code
module.exports.fix = (path) => {
path.replaceWith(Identifier('hello'));
};
β Example of correct code
const {replaceWith} = require('putout').operator;
module.exports.fix = (path) => {
replaceWith(path, Identifier('hello'));
};
convert-replace-with-multiple
β Example of incorrect code
module.exports.fix = (path) => {
path.replaceWithMultiple([
Identifier('hello'),
]);
};
β Example of correct code
const {replaceWithMultiple} = require('putout').operator;
module.exports.fix = (path) => {
replaceWithMultiple(path, [
Identifier('hello'),
]);
};
convert-replace-to-function
β Example of incorrect code
module.exports.replace = {
'let __a = __b': 'const __b = __a',
};
β Example of correct code
module.exports.replace = () => ({
'let __a = __b': 'const __b = __a',
});
convert-match-to-function
β Example of incorrect code
module.exports.match = {
'let __a = __b': () => false,
};
β Example of correct code
module.exports.match = () => ({
'let __a = __b': () => false,
});
convert-babel-types
β Example of incorrect code
const {
ObjectExpression,
SpreadElement,
isObjectExpression,
isIdentifier,
} = require('@babel/types');
β Example of correct code
const {
ObjectExpression,
SpreadElement,
isObjectExpression,
isIdentifier,
} = require('putout').types;
convert-destructuring-to-identifier
β Example of incorrect code
module.exports.replace = () => ({
'const __a = __b': ({}) => {},
'const __c = __d': ({}, path) => {},
});
β Example of correct code
module.exports.replace = () => ({
'const __a = __b': (vars) => {},
'const __c = __d': (vars, path) => {},
});
convert-node-to-path-in-get-template-values
β Example of incorrect code
const {__a, __b} = getTemplateValues(path.node, 'const __a = __b');
β Example of correct code
const {__a, __b} = getTemplateValues(path, 'const __a = __b');
shorten-imports
β Example of incorrect code
const parseOptions = require('putout/lib/parse-options');
β Example of correct code
const parseOptions = require('putout/parse-options');
convert-traverse-to-include
β Example of incorrect code
module.exports.traverse = ({push}) => ({
TSTypeAssertion(path) {
push(path);
},
});
β Example of correct code
module.exports.include = () => [
'TSTypeAssertion',
];
convert-traverse-to-replace
β Example of incorrect code
module.exports.traverse = () => ({
'async (__a) => __b': 'async ({process}) => __b',
});
β Example of correct code
module.exports.replace = () => ({
'async (__a) => __b': 'async ({process}) => __b',
});
convert-traverse-to-scan
Checkout in πPutout Editor:
β Example of incorrect code
module.exports.traverse = ({push, options}) => ({
[__filesystem](path) {
const {names} = options;
for (const name of names) {
const files = findFile(path, name);
for (const file of files) {
push({
name,
path: file,
});
}
}
},
});
β Example of correct code
module.exports.scan = (path, {push, options}) => {
const {names} = options;
for (const name of names) {
const files = findFile(path, name);
for (const file of files) {
push(file, {
name,
});
}
}
};
convert-process-to-find
β Example of incorrect code
module.exports.preProcess = () => {};
module.exports.postProcess = () => {};
β Example of correct code
module.exports.branch = (rawSource) => [];
module.exports.merge = (processedSource, list) => '';
convert-method-to-property
- property simpler to work with;
- support of
convert-destructuring-to-identifier
which isReplacer
, whileconvert-method-to-property
isIncluder
(searches forObjectMethod
node);
β Example of incorrect code
module.exports.match = () => ({
'module.exports.traverse = __a'({}, path) {},
});
β Example of correct code
module.exports.match = () => ({
'module.exports.traverse = __a': ({}, path) => {},
});
check-replace-code
Checks that Replacer transform is possible.
Pass once=false
to always fail no matter how many fixCounts
passed.
β Example of incorrect code
module.exports.replace = () => ({
'if (__a = __b) __body': 'if (__a === "__b") __body',
});
βοΈ There is no fix
for this rule, it used internally to be more confident about test coverage
, because of declaration form, transforms cannon be checked by nyc
and c8
, and uncovered lines can find unfixable false positives when running on code.
This is additional tests, if you forget to test some case (from a big list of rules that is supported) it will be checked with this rule
and make transforms more stable.
check-match
Checks that Replacer match()
keys exists in replace
.
Checkout in πPutout Editor.
β Example of incorrect code
module.exports.match = () => ({
'__a = __b': (vars, path) => {},
});
module.exports.replace = () => ({
'__a = __': '__a',
});
βοΈ There is no fix
for this rule, it used internally to be more confident about test coverage
, because of declaration form, transforms cannon be checked by nyc
and c8
, and uncovered lines can find unfixable false positives when running on code.
This is additional tests, if you forget to test some case (from a big list of rules that is supported) it will be checked with this rule
and make transforms more stable.
declare
Depends on @putout/convert-esm-to-commonjs and @putout/declare.
β Example of incorrect code
compare(a, 'const __a = __b');
isIdentifier(a);
β Example of correct code
const {operator, types} = require('putout');
const {compare} = operator;
const {isIdentifier} = types;
compare(a, 'const __a = __b');
isIdentifier(a);
add-places-to-compare-places"
β Example of incorrect code
comparePlaces
takes two or more arguments.
Checkout in πPutout Editor.
comparePlaces('hello');
β Example of correct code
comparePlaces('hello', []);
add-path-arg-to-fix
Checkout in πPutout Editor.
β Example of incorrect code
export const fix = () => {
path.remove();
};
β Example of correct code
export const fix = (path) => {
path.remove();
};
add-test-args
β Example of incorrect code
test('', () => {
comparePlaces();
});
β Example of correct code
test('', ({comparePlaces}) => {
comparePlaces();
});
add-traverse-args
Checkout in πPutout Editor. Supported args:
push
:
β Example of incorrect code
module.exports.traverse = () => ({
'__a.replace(/__b/g, __c)': (path) => {
push(path);
},
});
β Example of correct code
module.exports.traverse = ({push}) => ({
'__a.replace(/__b/g, __c)': (path) => {
push(path);
},
});
β Example of incorrect code
module.exports.traverse = () => ({
ImportDeclaration(path) {
const {node} = path;
const {name} = node.specifiers[0].local;
store('name', name);
},
});
β Example of correct code
module.exports.traverse = ({store}) => ({
ImportDeclaration(path) {
const {node} = path;
const {name} = node.specifiers[0].local;
store('name', name);
},
});
β Example of incorrect code
export const traverse = () => ({
ImportDeclaration(path) {
listStore(path);
},
});
β Example of correct code
module.exports.traverse = ({listStore}) => ({
ImportDeclaration(path) {
listStore(path);
},
});
β Example of incorrect code
export const traverse = () => ({
'module.exports.match = __object': pathStore,
});
β Example of correct code
export const traverse = ({pathStore}) => ({
'module.exports.match = __object': pathStore,
});
add-await-to-progress
Checkout in πPutout Editor.
β Example of incorrect code
test('', ({progress}) => {
progress();
});
β Example of correct code
test('', async ({progress}) => {
await progress();
});
add-track-file
Checkout in πPutout Editor.
β Example of incorrect code
export const scan = (root, {push, progress}) => {
trackFile();
};
β Example of correct code
export const scan = (root, {push, progress, trackFile}) => {
trackFile();
};
add-index-to-import
ESM doesn't add index.js
, so it can be left after @putout/plugin-convert-esm-to-commonjs
.
Checkout in πPutout Editor.
β Example of incorrect code
import insertRust from './insert-rust.js';
import addAction from './add-action.js';
export const rules = {};
β Example of correct code
import insertRust from './insert-rust/index.js';
import addAction from './add-action/index.js';
export const rules = {};
convert-add-argument-to-add-args
β Example of incorrect code
const {operator} = require('putout');
const {addArgument} = operator;
module.exports = addArgument({
t: ['t', 'test("__a", (__args) => __body)'],
});
β Example of correct code
const {operator} = require('putout');
const {addArgs} = operator;
module.exports = addArgs({
t: ['t', 'test("__a", (__args) => __body)'],
});
convert-dirname-to-url
β Example of incorrect code
import {createTest} from '@putout/test';
import plugin from '@putout/plugin-debugger';
import {createSimport} from 'simport';
const {__dirname} = createSimport(import.meta.url);
const test = createTest(__dirname, {
'remove-debugger': plugin,
});
β Example of correct code
import {createTest} from '@putout/test';
import plugin from '@putout/plugin-debugger';
const test = createTest(import.meta.url, {
'remove-debugger': plugin,
});
convert-url-to-dirname
β Example of incorrect code
const {createTest} = require('@putout/test');
const plugin = require('@putout/plugin-debugger');
const test = createTest(__dirname, {
'remove-debugger': plugin,
});
β Example of correct code
const {createTest} = require('@putout/test');
const plugin = require('@putout/plugin-debugger');
const test = createTest(import.meta.url, {
'remove-debugger': plugin,
});
convert-report-to-function
β Example of incorrect code
module.exports.report = `'report' should be a 'function'`;
β Example of correct code
module.exports.report = () => `'report' should be a 'function'`;
convert-progress-to-track
Checkout in πPutout Editor.
β Example of incorrect code
module.exports.scan = (root, {push, progress}) => {
const files = findFile(root, ['*']);
const n = files.length;
for (const [i, file] of files.entries()) {
push(file);
progress({
i,
n,
});
}
};
β Example of correct code
module.exports.scan = (root, {push, trackFile}) => {
for (const file of trackFile(root, ['*'])) {
push(file);
}
};
convert-get-rule-to-require
- β import Nested plugins in Deno and Browser;
- β
easier bundle with rollup without
dynamicRequireTargets
; - β easier to migrate to ESM;
Checkout in πPutout Editor.
β Example of incorrect code
module.exports.rules = {
...getRule('remove-unused-variables'),
};
β Example of correct code
const removeUnusedVariables = require('./remove-unused-variables');
module.exports.rules = {
'remove-unused-variables': removeUnusedVariables,
};
move-require-on-top-level
β Example of incorrect code
const test = require('@putout/test')(__dirname, {
'remove-debugger': require('..'),
});
test('remove debugger: report', (t) => {
t.transform('debugger', {
'remove-debugger': require('..'),
});
t.end();
});
β Example of correct code
const removeDebugger = require('..');
const test = require('@putout/test')(__dirname, {
'remove-debugger': removeDebugger,
});
test('remove debugger: report', (t) => {
t.transform('debugger', {
'remove-debugger': removeDebugger,
});
t.end();
});
includer
β Example of incorrect code
module.exports.include = () => 'cons __a = __b';
module.exports.exclude = () => 'var __a = __b';
module.exports.include = 'cons __a = __b';
module.exports.exclude = 'var __a = __b';
module.exports.include = [
'cons __a = __b',
];
module.exports.exclude = [
'var __a = __b',
];
β Example of correct code
module.exports.include = () => [
'cons __a = __b',
];
module.exports.exclude = () => [
'var __a = __b',
];
module.exports.include = () => [
'cons __a = __b',
];
module.exports.exclude = () => [
'var __a = __b',
];
module.exports.include = () => [
'cons __a = __b',
];
module.exports.exclude = () => [
'var __a = __b',
];
replace-test-message
Checks that test message
and used operator
are synchronized.
Check it out in πPutout Editor.
β Example of incorrect code
test('plugin-putout: rename-operate-to-operator: transform: operator exist', (t) => {
t.noTransform('operator');
t.end();
});
test('plugin-putout: rename-operate-to-operator: report: operator exist', (t) => {
t.noReport('operator');
t.end();
});
β Example of correct code
test('plugin-putout: rename-operate-to-operator: no transform: operator exist', (t) => {
t.noTransform('operator');
t.end();
});
test('plugin-putout: rename-operate-to-operator: no report: operator exist', (t) => {
t.noReport('operator');
t.end();
});
remove-empty-array-from-process
Check it out in πPutout Editor.
β Example of incorrect code
await process('input', []);
β Example of correct code
await process('input');
remove-unused-get-properties-argument
Check it out in πPutout Editor.
β Example of incorrect code
const {
overridesPath,
parserPath,
rulesPath,
} = getProperties(__jsonPath, [
'parser',
'rules',
'overrides',
'extends',
]);
β Example of correct code
const {
overridesPath,
parserPath,
rulesPath,
} = getProperties(__jsonPath, ['parser', 'rules', 'extends']);
simplify-replace-template
Checkout in πPutout Editor.
β Example of incorrect code
module.exports.replace = () => ({
'if (__a) {__b} else {__c}': () => 'if (__a) __b; else __c',
});
β Example of correct code
module.exports.replace = () => ({
'if (__a) {__b} else {__c}': 'if (__a) __b; else __c',
});
License
MIT