Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eslint-codemod-utils

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-codemod-utils - npm Package Compare versions

Comparing version 0.1.2 to 0.1.3

6

CHANGELOG.md
# eslint-codemod-utils
## 0.1.3
### Patch Changes
- dd41354: Updates literal and identifiers to support primitive types being passed directly as arguments to AST utility functions.
## 0.1.2

@@ -4,0 +10,0 @@

@@ -52,1 +52,25 @@ "use strict";

});
describe('insertImportSpecifier', () => {
test('basic', () => {
const { body } = espree.parse(`import x from 'place'`, ESPREE_OPTIONS);
expect((0, utils_1.insertImportSpecifier)(body[0], 'name').toString()).eq(`import x, { name } from 'place'`);
});
test('no default', () => {
const { body } = espree.parse(`import { nothing } from 'place'`, ESPREE_OPTIONS);
expect((0, utils_1.insertImportSpecifier)(body[0], 'name').toString()).eq(`import { nothing, name } from 'place'`);
});
test('with alias', () => {
const { body } = espree.parse(`import x from 'place'`, ESPREE_OPTIONS);
expect((0, utils_1.insertImportSpecifier)(body[0], 'name', 'alias').toString()).eq(`import x, { name as alias } from 'place'`);
});
});
describe('removeImportSpecifier', () => {
test('no default', () => {
const { body } = espree.parse(`import { nothing, name } from 'place'`, ESPREE_OPTIONS);
expect((0, utils_1.removeImportSpecifier)(body[0], 'name').toString()).eq(`import { nothing } from 'place'`);
});
test('with alias', () => {
const { body } = espree.parse(`import x, { name as alias } from 'place'`, ESPREE_OPTIONS);
expect((0, utils_1.removeImportSpecifier)(body[0], 'name').toString()).eq(`import x from 'place'`);
});
});

47

dist/jsx-nodes.d.ts

@@ -1,21 +0,26 @@

import { Comment, JSXAttribute, JSXClosingElement, JSXClosingFragment, JSXElement, JSXEmptyExpression, JSXExpressionContainer, JSXFragment, JSXIdentifier, JSXMemberExpression, JSXOpeningElement, JSXOpeningFragment, JSXSpreadAttribute, JSXSpreadChild, JSXText, SourceLocation } from 'estree-jsx';
import type { StringableASTNodeFn } from './types';
export declare const whiteSpace: (loc?: SourceLocation | undefined) => string;
export declare const comments: (comments?: Comment[]) => {
comments: Comment[];
import type * as estree from 'estree-jsx';
import type { StringableASTNode, StringableASTNodeFn, WithoutType } from './types';
export declare const whiteSpace: (loc?: estree.SourceLocation | undefined) => string;
export declare const comments: (comments?: estree.Comment[]) => {
comments: estree.Comment[];
toString: () => string;
};
export declare const comment: ({ value, type, loc }: Comment) => {
export declare const comment: ({ value, type, loc }: estree.Comment) => {
value: string;
type: "Line" | "Block";
__pragma: string;
toString: () => string;
};
export declare const jsxIdentifier: StringableASTNodeFn<JSXIdentifier>;
export declare const jsxOpeningFragment: StringableASTNodeFn<JSXOpeningFragment>;
export declare const jsxClosingFragment: StringableASTNodeFn<JSXClosingFragment>;
export declare const jsxFragment: StringableASTNodeFn<JSXFragment>;
export declare const jsxSpreadChild: StringableASTNodeFn<JSXSpreadChild>;
export declare const jsxMemberExpression: StringableASTNodeFn<JSXMemberExpression>;
/**
* __JSXIdentifier__
*
* @param param Takes a string or the shape of a {estree.JSXIdentifier} node
* @returns {estree.JSXIdentifier} node
*/
export declare const jsxIdentifier: (param: WithoutType<estree.JSXIdentifier> | string) => StringableASTNode<estree.JSXIdentifier>;
export declare const jsxOpeningFragment: StringableASTNodeFn<estree.JSXOpeningFragment>;
export declare const jsxClosingFragment: StringableASTNodeFn<estree.JSXClosingFragment>;
export declare const jsxFragment: StringableASTNodeFn<estree.JSXFragment>;
export declare const jsxSpreadChild: StringableASTNodeFn<estree.JSXSpreadChild>;
export declare const jsxMemberExpression: StringableASTNodeFn<estree.JSXMemberExpression>;
/**
* __JSXElement__

@@ -45,3 +50,3 @@ *

*/
export declare const jsxElement: StringableASTNodeFn<JSXElement>;
export declare const jsxElement: StringableASTNodeFn<estree.JSXElement>;
/**

@@ -69,4 +74,4 @@ * __JSXSpreadAttribute__

*/
export declare const jsxSpreadAttribute: StringableASTNodeFn<JSXSpreadAttribute>;
export declare const jsxOpeningElement: StringableASTNodeFn<JSXOpeningElement>;
export declare const jsxSpreadAttribute: StringableASTNodeFn<estree.JSXSpreadAttribute>;
export declare const jsxOpeningElement: StringableASTNodeFn<estree.JSXOpeningElement>;
/**

@@ -85,3 +90,3 @@ * __JSXClosingElement__

*/
export declare const jsxClosingElement: StringableASTNodeFn<JSXClosingElement>;
export declare const jsxClosingElement: StringableASTNodeFn<estree.JSXClosingElement>;
/**

@@ -100,5 +105,5 @@ * __JSXText__

*/
export declare const jsxText: StringableASTNodeFn<JSXText>;
export declare const jsxEmptyExpression: StringableASTNodeFn<JSXEmptyExpression>;
export declare const jsxExpressionContainer: StringableASTNodeFn<JSXExpressionContainer>;
export declare const jsxText: StringableASTNodeFn<estree.JSXText>;
export declare const jsxEmptyExpression: StringableASTNodeFn<estree.JSXEmptyExpression>;
export declare const jsxExpressionContainer: StringableASTNodeFn<estree.JSXExpressionContainer>;
/**

@@ -117,2 +122,2 @@ * __JSXAttribute__

*/
export declare const jsxAttribute: StringableASTNodeFn<JSXAttribute>;
export declare const jsxAttribute: StringableASTNodeFn<estree.JSXAttribute>;

@@ -16,12 +16,19 @@ "use strict";

type,
__pragma: 'ecu',
toString: () => (0, exports.whiteSpace)(loc) + (type === 'Line' ? `// ${value}` : `/* ${value} */`),
});
exports.comment = comment;
const jsxIdentifier = ({ name, }) => ({
name,
type: 'JSXIdentifier',
__pragma: 'ecu',
toString: () => name,
});
/**
* __JSXIdentifier__
*
* @param param Takes a string or the shape of a {estree.JSXIdentifier} node
* @returns {estree.JSXIdentifier} node
*/
const jsxIdentifier = (param) => {
const name = typeof param === 'string' ? param : param.name;
return {
name,
type: 'JSXIdentifier',
toString: () => name,
};
};
exports.jsxIdentifier = jsxIdentifier;

@@ -31,3 +38,2 @@ const jsxOpeningFragment = ({ ...other }) => {

...other,
__pragma: 'ecu',
type: 'JSXOpeningFragment',

@@ -41,3 +47,2 @@ toString: () => `<>`,

...other,
__pragma: 'ecu',
type: 'JSXClosingFragment',

@@ -54,3 +59,2 @@ toString: () => `</>`,

type: 'JSXFragment',
__pragma: 'ecu',
toString: () => {

@@ -68,3 +72,2 @@ return `${(0, node_1.node)(openingFragment)}${children

expression,
__pragma: 'ecu',
type: 'JSXSpreadChild',

@@ -75,5 +78,4 @@ toString: () => `{...${(0, node_1.node)(expression)}}`,

exports.jsxSpreadChild = jsxSpreadChild;
const jsxMemberExpression = ({ object, property, }) => ({
const jsxMemberExpression = ({ object, property }) => ({
type: 'JSXMemberExpression',
__pragma: 'ecu',
object,

@@ -127,3 +129,2 @@ property,

type: 'JSXElement',
__pragma: 'ecu',
toString: () => {

@@ -160,4 +161,3 @@ const indent = (0, exports.whiteSpace)(loc);

*/
const jsxSpreadAttribute = ({ argument, }) => ({
__pragma: 'ecu',
const jsxSpreadAttribute = ({ argument }) => ({
type: 'JSXSpreadAttribute',

@@ -168,3 +168,3 @@ argument,

exports.jsxSpreadAttribute = jsxSpreadAttribute;
const jsxOpeningElement = ({ name, attributes = [], selfClosing = false, leadingComments = [], }) => ({
const jsxOpeningElement = ({ name, attributes = [], selfClosing = false, leadingComments = [] }) => ({
type: 'JSXOpeningElement',

@@ -174,3 +174,2 @@ name,

selfClosing,
__pragma: 'ecu',
toString: () => `${(0, exports.comments)(leadingComments)}<${name.type === 'JSXIdentifier'

@@ -210,6 +209,5 @@ ? (0, exports.jsxIdentifier)(name)

*/
const jsxClosingElement = ({ name, }) => {
const jsxClosingElement = ({ name }) => {
return {
type: 'JSXClosingElement',
__pragma: 'ecu',
name,

@@ -233,7 +231,6 @@ toString: () => `</${(0, node_1.node)(name)}>`,

*/
const jsxText = ({ value, raw }) => ({
const jsxText = ({ value, raw, }) => ({
type: 'JSXText',
value,
raw,
__pragma: 'ecu',
toString: () => value,

@@ -246,3 +243,2 @@ });

type: 'JSXEmptyExpression',
__pragma: 'ecu',
toString: () => `{}`,

@@ -255,3 +251,2 @@ };

type: 'JSXExpressionContainer',
__pragma: 'ecu',
toString: () => {

@@ -284,3 +279,2 @@ if (expression.type === 'JSXEmptyExpression') {

type: 'JSXAttribute',
__pragma: 'ecu',
name,

@@ -287,0 +281,0 @@ value,

@@ -1,3 +0,3 @@

import * as estree from 'estree';
import { StringableASTNodeFn } from './types';
import type * as estree from 'estree-jsx';
import type { StringableASTNode, StringableASTNodeFn, WithoutType } from './types';
/**

@@ -246,4 +246,4 @@ * __CallExpression__

export declare const regExpLiteral: StringableASTNodeFn<estree.RegExpLiteral>;
export declare const literal: StringableASTNodeFn<estree.Literal>;
export declare const identifier: StringableASTNodeFn<estree.Identifier>;
export declare const literal: (n: WithoutType<estree.Literal> | (string | number | boolean | null)) => StringableASTNode<estree.Literal>;
export declare const identifier: (param: WithoutType<estree.Identifier> | string) => StringableASTNode<estree.Identifier>;
export declare const doWhileStatement: StringableASTNodeFn<estree.DoWhileStatement>;

@@ -250,0 +250,0 @@ export declare const whileStatement: StringableASTNodeFn<estree.WhileStatement>;

@@ -669,3 +669,4 @@ "use strict";

const leadOrEndSpecifier = otherSpecifiers.length > 4 ? '\n' : ' ';
return `import ${defaultSpecifier ? defaultSpecifier.local.name : ''}${otherSpecifiers.length
// @ts-ignore technically not part of espree but the typescript parser does inject it - will support it for now
return `import ${other['importKind'] === 'type' ? 'type ' : ''}${defaultSpecifier ? defaultSpecifier.local.name : ''}${otherSpecifiers.length
? defaultSpecifier

@@ -705,2 +706,14 @@ ? `, {${leadOrEndSpecifier}${otherSpecifiers

const literal = (n) => {
if (typeof n === 'string' ||
typeof n === 'boolean' ||
typeof n === 'number' ||
typeof n === 'undefined' ||
n === null) {
return {
raw: String(n),
value: n,
type: 'Literal',
toString: () => String(n),
};
}
if ('bigint' in n) {

@@ -716,3 +729,2 @@ return (0, exports.bigIntLiteral)(n);

type: 'Literal',
__pragma: 'ecu',
toString: () => n.raw || String(n.value),

@@ -723,12 +735,13 @@ };

exports.literal = literal;
const identifier = ({ name, }) => ({
type: 'Identifier',
__pragma: 'ecu',
name,
toString: () => name,
});
const identifier = (param) => {
const name = typeof param === 'string' ? param : param.name;
return {
type: 'Identifier',
name,
toString: () => name,
};
};
exports.identifier = identifier;
const doWhileStatement = ({ test, body, ...other }) => ({
...other,
__pragma: 'ecu',
test,

@@ -735,0 +748,0 @@ body,

import type { Node as BaseNode, JSXSpreadChild } from 'estree-jsx';
import type { Rule } from 'eslint';
export declare type EslintCodemodUtilsBaseNode = BaseNode | JSXSpreadChild;
export declare type WithoutType<T extends EslintCodemodUtilsBaseNode> = Omit<T, 'type'>;
export declare type RuleListener<T extends EslintNode = EslintNode> = {

@@ -10,3 +11,3 @@ [E in T as E['type']]?: (eventNodeListener: E) => void;

};
export declare type StringableASTNodeFn<EstreeNodeType extends EslintCodemodUtilsBaseNode> = (node: Omit<EstreeNodeType, 'type'>) => StringableASTNode<EstreeNodeType>;
export declare type StringableASTNodeFn<EstreeNodeType extends EslintCodemodUtilsBaseNode> = (node: WithoutType<EstreeNodeType>) => StringableASTNode<EstreeNodeType>;
export declare type EslintNode = Rule.NodeParentExtension & EslintCodemodUtilsBaseNode;

@@ -1,6 +0,24 @@

import type { JSXElement } from 'estree-jsx';
import type { EslintCodemodUtilsBaseNode, EslintNode } from '../types';
export declare function isNode<T extends EslintCodemodUtilsBaseNode, K extends EslintCodemodUtilsBaseNode>(node: T, type: K['type']): boolean;
export declare function closestOfType<T extends EslintNode>(node: T, type: EslintNode['type']): EslintNode | null;
import { ImportDeclaration, JSXElement } from 'estree-jsx';
import type { EslintCodemodUtilsBaseNode, EslintNode, StringableASTNode } from '../types';
export declare function isNodeOfType<T extends EslintCodemodUtilsBaseNode>(node: EslintCodemodUtilsBaseNode, type: T['type']): node is T;
export declare function closestOfType<T extends EslintNode>(node: EslintNode, type: T['type']): EslintNode | null;
export declare function hasJSXAttribute(node: JSXElement, attributeName: string): boolean;
export declare function hasJSXChild(node: JSXElement, childIdentifier: string): boolean;
/**
* Appends or adds an import specifier to an existing import declaration.
*
* @param declaration
* @param specifierId
* @param specifierAlias
* @returns {StringableASTNode<ImportDeclaration>}
*/
export declare function insertImportSpecifier(declaration: ImportDeclaration, specifierId: string, specifierAlias?: string): StringableASTNode<ImportDeclaration>;
/**
* Removes an import specifier to an existing import declaration.
*
* @param declaration
* @param specifierId
* @param specifierAlias
* @returns {StringableASTNode<ImportDeclaration>}
*/
export declare function removeImportSpecifier(declaration: ImportDeclaration, specifierId: string): StringableASTNode<ImportDeclaration>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasJSXChild = exports.hasJSXAttribute = exports.closestOfType = exports.isNode = void 0;
function isNode(node, type) {
exports.removeImportSpecifier = exports.insertImportSpecifier = exports.hasJSXChild = exports.hasJSXAttribute = exports.closestOfType = exports.isNodeOfType = void 0;
const nodes_1 = require("../nodes");
function isNodeOfType(node, type) {
return node.type === type;
}
exports.isNode = isNode;
exports.isNodeOfType = isNodeOfType;
function closestOfType(node, type) {
if (isNode(node, type)) {
if (isNodeOfType(node, type)) {
return node;

@@ -23,3 +24,4 @@ }

return false;
return node.openingElement.attributes.some((attr) => attr.type === 'JSXAttribute' && attr.name.name === attributeName);
return node.openingElement.attributes.some((attr) => isNodeOfType(attr, 'JSXAttribute') &&
attr.name.name === attributeName);
}

@@ -37,5 +39,39 @@ exports.hasJSXAttribute = hasJSXAttribute;

node.children
.filter((child) => isNode(child, 'JSXElement'))
.filter((child) => isNodeOfType(child, 'JSXElement'))
.find((child) => hasJSXChild(child, childIdentifier))));
}
exports.hasJSXChild = hasJSXChild;
/**
* Appends or adds an import specifier to an existing import declaration.
*
* @param declaration
* @param specifierId
* @param specifierAlias
* @returns {StringableASTNode<ImportDeclaration>}
*/
function insertImportSpecifier(declaration, specifierId, specifierAlias) {
const id = (0, nodes_1.identifier)(specifierId);
return (0, nodes_1.importDeclaration)({
...declaration,
specifiers: declaration.specifiers.concat((0, nodes_1.importSpecifier)({
imported: (0, nodes_1.identifier)(specifierId),
local: specifierAlias ? (0, nodes_1.identifier)(specifierAlias) : id,
})),
});
}
exports.insertImportSpecifier = insertImportSpecifier;
/**
* Removes an import specifier to an existing import declaration.
*
* @param declaration
* @param specifierId
* @param specifierAlias
* @returns {StringableASTNode<ImportDeclaration>}
*/
function removeImportSpecifier(declaration, specifierId) {
return (0, nodes_1.importDeclaration)({
...declaration,
specifiers: declaration.specifiers.filter((spec) => !(spec.type === 'ImportSpecifier' && spec.imported.name === specifierId)),
});
}
exports.removeImportSpecifier = removeImportSpecifier;
import * as espree from 'espree'
import { closestOfType, hasJSXAttribute } from '../utils/utils'
import {
closestOfType,
hasJSXAttribute,
insertImportSpecifier,
removeImportSpecifier,
} from '../utils/utils'

@@ -41,1 +46,49 @@ const ESPREE_OPTIONS = {

})
describe('insertImportSpecifier', () => {
test('basic', () => {
const { body } = espree.parse(`import x from 'place'`, ESPREE_OPTIONS)
expect(insertImportSpecifier(body[0], 'name').toString()).eq(
`import x, { name } from 'place'`
)
})
test('no default', () => {
const { body } = espree.parse(
`import { nothing } from 'place'`,
ESPREE_OPTIONS
)
expect(insertImportSpecifier(body[0], 'name').toString()).eq(
`import { nothing, name } from 'place'`
)
})
test('with alias', () => {
const { body } = espree.parse(`import x from 'place'`, ESPREE_OPTIONS)
expect(insertImportSpecifier(body[0], 'name', 'alias').toString()).eq(
`import x, { name as alias } from 'place'`
)
})
})
describe('removeImportSpecifier', () => {
test('no default', () => {
const { body } = espree.parse(
`import { nothing, name } from 'place'`,
ESPREE_OPTIONS
)
expect(removeImportSpecifier(body[0], 'name').toString()).eq(
`import { nothing } from 'place'`
)
})
test('with alias', () => {
const { body } = espree.parse(
`import x, { name as alias } from 'place'`,
ESPREE_OPTIONS
)
expect(removeImportSpecifier(body[0], 'name').toString()).eq(
`import x from 'place'`
)
})
})

@@ -1,28 +0,15 @@

import {
Comment,
JSXAttribute,
JSXClosingElement,
JSXClosingFragment,
JSXElement,
JSXEmptyExpression,
JSXExpressionContainer,
JSXFragment,
JSXIdentifier,
JSXMemberExpression,
JSXOpeningElement,
JSXOpeningFragment,
JSXSpreadAttribute,
JSXSpreadChild,
JSXText,
SourceLocation,
} from 'estree-jsx'
import type * as estree from 'estree-jsx'
import { DEFAULT_WHITESPACE } from './constants'
import type { StringableASTNodeFn } from './types'
import type {
StringableASTNode,
StringableASTNodeFn,
WithoutType,
} from './types'
import { node } from './utils/node'
export const whiteSpace = (loc?: SourceLocation) =>
export const whiteSpace = (loc?: estree.SourceLocation) =>
''.padStart(loc?.start?.column || 0, ' ')
export const comments = (comments: Comment[] = []) => ({
export const comments = (comments: estree.Comment[] = []) => ({
comments,

@@ -33,6 +20,5 @@ toString: () =>

export const comment = ({ value, type, loc }: Comment) => ({
export const comment = ({ value, type, loc }: estree.Comment) => ({
value,
type,
__pragma: 'ecu',
toString: () =>

@@ -42,17 +28,24 @@ whiteSpace(loc!) + (type === 'Line' ? `// ${value}` : `/* ${value} */`),

export const jsxIdentifier: StringableASTNodeFn<JSXIdentifier> = ({
name,
}) => ({
name,
type: 'JSXIdentifier',
__pragma: 'ecu',
toString: () => name,
})
/**
* __JSXIdentifier__
*
* @param param Takes a string or the shape of a {estree.JSXIdentifier} node
* @returns {estree.JSXIdentifier} node
*/
export const jsxIdentifier = (
param: WithoutType<estree.JSXIdentifier> | string
): StringableASTNode<estree.JSXIdentifier> => {
const name = typeof param === 'string' ? param : param.name
return {
name,
type: 'JSXIdentifier',
toString: () => name,
}
}
export const jsxOpeningFragment: StringableASTNodeFn<JSXOpeningFragment> = ({
...other
}) => {
export const jsxOpeningFragment: StringableASTNodeFn<
estree.JSXOpeningFragment
> = ({ ...other }) => {
return {
...other,
__pragma: 'ecu',
type: 'JSXOpeningFragment',

@@ -63,8 +56,7 @@ toString: () => `<>`,

export const jsxClosingFragment: StringableASTNodeFn<JSXClosingFragment> = ({
...other
}) => {
export const jsxClosingFragment: StringableASTNodeFn<
estree.JSXClosingFragment
> = ({ ...other }) => {
return {
...other,
__pragma: 'ecu',
type: 'JSXClosingFragment',

@@ -75,3 +67,3 @@ toString: () => `</>`,

export const jsxFragment: StringableASTNodeFn<JSXFragment> = ({
export const jsxFragment: StringableASTNodeFn<estree.JSXFragment> = ({
openingFragment,

@@ -87,3 +79,2 @@ closingFragment,

type: 'JSXFragment',
__pragma: 'ecu',
toString: () => {

@@ -97,3 +88,3 @@ return `${node(openingFragment)}${children

export const jsxSpreadChild: StringableASTNodeFn<JSXSpreadChild> = ({
export const jsxSpreadChild: StringableASTNodeFn<estree.JSXSpreadChild> = ({
expression,

@@ -105,3 +96,2 @@ ...other

expression,
__pragma: 'ecu',
type: 'JSXSpreadChild',

@@ -112,8 +102,6 @@ toString: () => `{...${node(expression)}}`,

export const jsxMemberExpression: StringableASTNodeFn<JSXMemberExpression> = ({
object,
property,
}) => ({
export const jsxMemberExpression: StringableASTNodeFn<
estree.JSXMemberExpression
> = ({ object, property }) => ({
type: 'JSXMemberExpression',
__pragma: 'ecu',
object,

@@ -129,3 +117,3 @@ property,

const DEFAULT_LOC: SourceLocation = {
const DEFAULT_LOC: estree.SourceLocation = {
start: {

@@ -166,3 +154,3 @@ column: 0,

*/
export const jsxElement: StringableASTNodeFn<JSXElement> = ({
export const jsxElement: StringableASTNodeFn<estree.JSXElement> = ({
openingElement,

@@ -178,3 +166,2 @@ closingElement,

type: 'JSXElement',
__pragma: 'ecu',
toString: (): string => {

@@ -213,6 +200,5 @@ const indent = whiteSpace(loc!)

*/
export const jsxSpreadAttribute: StringableASTNodeFn<JSXSpreadAttribute> = ({
argument,
}) => ({
__pragma: 'ecu',
export const jsxSpreadAttribute: StringableASTNodeFn<
estree.JSXSpreadAttribute
> = ({ argument }) => ({
type: 'JSXSpreadAttribute',

@@ -223,8 +209,5 @@ argument,

export const jsxOpeningElement: StringableASTNodeFn<JSXOpeningElement> = ({
name,
attributes = [],
selfClosing = false,
leadingComments = [],
}) => ({
export const jsxOpeningElement: StringableASTNodeFn<
estree.JSXOpeningElement
> = ({ name, attributes = [], selfClosing = false, leadingComments = [] }) => ({
type: 'JSXOpeningElement',

@@ -234,3 +217,2 @@ name,

selfClosing,
__pragma: 'ecu',
toString: () =>

@@ -274,8 +256,8 @@ `${comments(leadingComments)}<${

*/
export const jsxClosingElement: StringableASTNodeFn<JSXClosingElement> = ({
name,
}) => {
export const jsxClosingElement: StringableASTNodeFn<
estree.JSXClosingElement
> = ({ name }) => {
return {
type: 'JSXClosingElement',
__pragma: 'ecu',
name,

@@ -299,17 +281,18 @@ toString: () => `</${node(name)}>`,

*/
export const jsxText: StringableASTNodeFn<JSXText> = ({ value, raw }) => ({
export const jsxText: StringableASTNodeFn<estree.JSXText> = ({
value,
raw,
}) => ({
type: 'JSXText',
value,
raw,
__pragma: 'ecu',
toString: () => value,
})
export const jsxEmptyExpression: StringableASTNodeFn<JSXEmptyExpression> = (
node
) => {
export const jsxEmptyExpression: StringableASTNodeFn<
estree.JSXEmptyExpression
> = (node) => {
return {
...node,
type: 'JSXEmptyExpression',
__pragma: 'ecu',
toString: () => `{}`,

@@ -320,7 +303,6 @@ }

export const jsxExpressionContainer: StringableASTNodeFn<
JSXExpressionContainer
estree.JSXExpressionContainer
> = ({ expression }) => ({
expression,
type: 'JSXExpressionContainer',
__pragma: 'ecu',
toString: () => {

@@ -353,3 +335,3 @@ if (expression.type === 'JSXEmptyExpression') {

*/
export const jsxAttribute: StringableASTNodeFn<JSXAttribute> = ({
export const jsxAttribute: StringableASTNodeFn<estree.JSXAttribute> = ({
name,

@@ -359,3 +341,2 @@ value,

type: 'JSXAttribute',
__pragma: 'ecu',
name,

@@ -371,3 +352,3 @@ value,

? jsxElement(value)
: jsxExpressionContainer(value as JSXExpressionContainer)
: jsxExpressionContainer(value as estree.JSXExpressionContainer)
}`

@@ -374,0 +355,0 @@ : ''

@@ -1,4 +0,8 @@

import * as estree from 'estree'
import type * as estree from 'estree-jsx'
import { StringableASTNodeFn } from './types'
import type {
StringableASTNode,
StringableASTNodeFn,
WithoutType,
} from './types'
import { node } from './utils/node'

@@ -849,3 +853,6 @@ import { DEFAULT_WHITESPACE } from './constants'

return `import ${defaultSpecifier ? defaultSpecifier.local.name : ''}${
// @ts-ignore technically not part of espree but the typescript parser does inject it - will support it for now
return `import ${other['importKind'] === 'type' ? 'type ' : ''}${
defaultSpecifier ? defaultSpecifier.local.name : ''
}${
otherSpecifiers.length

@@ -900,3 +907,20 @@ ? defaultSpecifier

export const literal: StringableASTNodeFn<estree.Literal> = (n) => {
export const literal = (
n: WithoutType<estree.Literal> | (string | number | boolean | null)
): StringableASTNode<estree.Literal> => {
if (
typeof n === 'string' ||
typeof n === 'boolean' ||
typeof n === 'number' ||
typeof n === 'undefined' ||
n === null
) {
return {
raw: String(n),
value: n,
type: 'Literal',
toString: () => String(n),
}
}
if ('bigint' in n) {

@@ -910,3 +934,2 @@ return bigIntLiteral(n as estree.BigIntLiteral)

type: 'Literal',
__pragma: 'ecu',
toString: () => n.raw || String(n.value),

@@ -917,10 +940,12 @@ }

export const identifier: StringableASTNodeFn<estree.Identifier> = ({
name,
}) => ({
type: 'Identifier',
__pragma: 'ecu',
name,
toString: () => name,
})
export const identifier = (
param: WithoutType<estree.Identifier> | string
): StringableASTNode<estree.Identifier> => {
const name = typeof param === 'string' ? param : param.name
return {
type: 'Identifier',
name,
toString: () => name,
}
}

@@ -933,3 +958,2 @@ export const doWhileStatement: StringableASTNodeFn<estree.DoWhileStatement> = ({

...other,
__pragma: 'ecu',
test,

@@ -936,0 +960,0 @@ body,

@@ -5,2 +5,3 @@ import type { Node as BaseNode, JSXSpreadChild } from 'estree-jsx'

export type EslintCodemodUtilsBaseNode = BaseNode | JSXSpreadChild
export type WithoutType<T extends EslintCodemodUtilsBaseNode> = Omit<T, 'type'>

@@ -18,4 +19,4 @@ export type RuleListener<T extends EslintNode = EslintNode> = {

EstreeNodeType extends EslintCodemodUtilsBaseNode
> = (node: Omit<EstreeNodeType, 'type'>) => StringableASTNode<EstreeNodeType>
> = (node: WithoutType<EstreeNodeType>) => StringableASTNode<EstreeNodeType>
export type EslintNode = Rule.NodeParentExtension & EslintCodemodUtilsBaseNode

@@ -1,8 +0,18 @@

import type { JSXElement, JSXIdentifier } from 'estree-jsx'
import type { EslintCodemodUtilsBaseNode, EslintNode } from '../types'
import {
ImportDeclaration,
JSXAttribute,
JSXElement,
JSXIdentifier,
} from 'estree-jsx'
import { identifier, importDeclaration, importSpecifier } from '../nodes'
import type {
EslintCodemodUtilsBaseNode,
EslintNode,
StringableASTNode,
} from '../types'
export function isNode<
T extends EslintCodemodUtilsBaseNode,
K extends EslintCodemodUtilsBaseNode
>(node: T, type: K['type']) {
export function isNodeOfType<T extends EslintCodemodUtilsBaseNode>(
node: EslintCodemodUtilsBaseNode,
type: T['type']
): node is T {
return node.type === type

@@ -12,6 +22,6 @@ }

export function closestOfType<T extends EslintNode>(
node: T,
type: EslintNode['type']
node: EslintNode,
type: T['type']
): EslintNode | null {
if (isNode(node, type)) {
if (isNodeOfType(node, type)) {
return node

@@ -33,3 +43,5 @@ }

return node.openingElement.attributes.some(
(attr) => attr.type === 'JSXAttribute' && attr.name.name === attributeName
(attr) =>
isNodeOfType<JSXAttribute>(attr, 'JSXAttribute') &&
attr.name.name === attributeName
)

@@ -56,3 +68,5 @@ }

node.children
.filter((child): child is JSXElement => isNode(child, 'JSXElement'))
.filter((child): child is JSXElement =>
isNodeOfType(child, 'JSXElement')
)
.find((child) => hasJSXChild(child, childIdentifier))

@@ -62,1 +76,47 @@ )

}
/**
* Appends or adds an import specifier to an existing import declaration.
*
* @param declaration
* @param specifierId
* @param specifierAlias
* @returns {StringableASTNode<ImportDeclaration>}
*/
export function insertImportSpecifier(
declaration: ImportDeclaration,
specifierId: string,
specifierAlias?: string
): StringableASTNode<ImportDeclaration> {
const id = identifier(specifierId)
return importDeclaration({
...declaration,
specifiers: declaration.specifiers.concat(
importSpecifier({
imported: identifier(specifierId),
local: specifierAlias ? identifier(specifierAlias) : id,
})
),
})
}
/**
* Removes an import specifier to an existing import declaration.
*
* @param declaration
* @param specifierId
* @param specifierAlias
* @returns {StringableASTNode<ImportDeclaration>}
*/
export function removeImportSpecifier(
declaration: ImportDeclaration,
specifierId: string
): StringableASTNode<ImportDeclaration> {
return importDeclaration({
...declaration,
specifiers: declaration.specifiers.filter(
(spec) =>
!(spec.type === 'ImportSpecifier' && spec.imported.name === specifierId)
),
})
}
{
"name": "eslint-codemod-utils",
"version": "0.1.2",
"version": "0.1.3",
"description": "A collection of AST helper functions for more complex ESLint rule fixes.",

@@ -5,0 +5,0 @@ "source": "lib/index.ts",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc