eslint-plugin-canonical
Version:
Canonical linting rules for ESLint.
124 lines (123 loc) • 5.79 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const types_1 = require("@typescript-eslint/types");
const utilities_1 = require("../utilities");
exports.default = (0, utilities_1.createRule)({
create(context) {
const imports = new Map();
const exports = {};
const appendToExports = (name, reportInfo) => {
exports[name] = [...(exports[name] ? exports[name] : []), reportInfo];
};
return {
// export * from 'app/CustomCustomButton'
ExportAllDeclaration(node) {
context.report({
data: {
name: node.source.value,
},
loc: node.loc,
messageId: 'noReExport',
});
},
ExportDefaultDeclaration(node) {
if (node.declaration.type === types_1.AST_NODE_TYPES.Identifier) {
// export default Button
appendToExports(node.declaration.name, {
location: node.declaration.loc,
type: 'ExportDefault',
});
}
},
ExportNamedDeclaration(node) {
var _a, _b, _c, _d, _e;
if (node.declaration &&
((_a = node.declaration) === null || _a === void 0 ? void 0 : _a.type) === types_1.AST_NODE_TYPES.VariableDeclaration &&
node.declaration.declarations) {
for (const declaration of node.declaration.declarations) {
if (((_b = declaration.init) === null || _b === void 0 ? void 0 : _b.type) === types_1.AST_NODE_TYPES.Identifier &&
((_c = declaration.init) === null || _c === void 0 ? void 0 : _c.name)) {
// export const CustomButtom = Button;
appendToExports(declaration.init.name, {
location: declaration.init.loc,
type: 'Variable',
});
}
else if (((_d = declaration.init) === null || _d === void 0 ? void 0 : _d.type) === types_1.AST_NODE_TYPES.ObjectExpression &&
declaration.init.properties) {
for (const property of declaration.init.properties) {
if ((property === null || property === void 0 ? void 0 : property.type) === types_1.AST_NODE_TYPES.Property &&
property.value.type === types_1.AST_NODE_TYPES.Identifier &&
((_e = property.value) === null || _e === void 0 ? void 0 : _e.name)) {
// export const CustomButton = { Button }
appendToExports(property.value.name, {
location: property.loc,
type: 'ObjectProperty',
});
}
}
}
}
}
else if (node.specifiers) {
for (const specifier of node.specifiers) {
if (node.source &&
specifier.exported.type === types_1.AST_NODE_TYPES.Identifier &&
specifier.local.type === types_1.AST_NODE_TYPES.Identifier &&
specifier.local.name === 'default') {
// export { default as Button } from 'app/CustomButtom';
appendToExports(specifier.exported.name, {
location: specifier.exported.loc,
type: 'DefaultReExport',
});
}
else if (specifier.local.type === types_1.AST_NODE_TYPES.Identifier) {
// export { Button }
appendToExports(specifier.local.name, {
location: specifier.local.loc,
type: 'ExportObject',
});
}
}
}
},
ImportDefaultSpecifier(node) {
imports.set(node.local.name, { node });
},
ImportNamespaceSpecifier(node) {
imports.set(node.local.name, { node });
},
ImportSpecifier(node) {
imports.set(node.local.name, { node });
},
'Program:exit': () => {
for (const exportName of Object.keys(exports)) {
const reportInfoList = exports[exportName];
for (const { location, type } of reportInfoList) {
if (imports.has(exportName) || type === 'DefaultReExport') {
context.report({
data: {
name: exportName,
},
loc: location,
messageId: 'noReExport',
});
}
}
}
},
};
},
defaultOptions: [],
meta: {
docs: {
description: 'Disallows re-exports of imports.',
},
messages: {
noReExport: "Do not re-export '{{name}}'",
},
schema: [],
type: 'layout',
},
name: 'no-re-export',
});