UNPKG

eslint-plugin-miniprogram

Version:
147 lines 6.14 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var utils_1 = __importDefault(require("eslint-plugin-vue/lib/utils")); var path_1 = __importDefault(require("path")); var kebabCase_1 = __importDefault(require("lodash/kebabCase")); var mina_sfc_1 = __importDefault(require("@tinajs/mina-sfc")); var json5_1 = __importDefault(require("json5")); var constants_1 = require("../constants"); var DEFAULT_LOC = { start: { line: 1, column: 0 }, end: { line: 1, column: 0 } }; var isBuildInComponents = function (name) { return constants_1.BUILD_IN_COMPONENTS.includes(name); }; var trimTail = function (name) { return path_1.default.basename(name.replace(/\.mina$/, "").replace(/\/index$/, "")); }; var getScopedSpecificPrefixHandling = function (componentPath) { var tokens = componentPath.split("/")[1].split("-"); var prefix = tokens[tokens.length - 1]; return prefix; }; exports.getExpectedComponentName = function (componentPath, contextPath) { var name = componentPath; name = trimTail(name); name = kebabCase_1.default(name); // special handling for airbnb components // TODO make this configurable if (componentPath.startsWith("~@")) { var prefix = getScopedSpecificPrefixHandling(componentPath); name = prefix + "-" + name; } return name; }; var RULE_DESCRIPTION = { componentName: "Enforce specific casing for the component naming style", unusedComponent: "Check unused components", unregisteredComponent: "Check unregistered components" }; exports.checkUsingComponents = function (intent) { return ({ meta: { type: "suggestion", docs: { description: RULE_DESCRIPTION[intent], category: "WeChat Mini Program Best Practices", recommended: false, url: "https://github.com/airbnb/eslint-plugin-miniprogram" } }, create: function (context) { var source = context.getSource(); var configData; try { var blocks = mina_sfc_1.default.parse(source); var configJson = blocks.config.content.trim(); if (!configJson) { return {}; } configData = json5_1.default.parse(configJson); } catch (error) { context.report({ loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 0 } }, message: "parse config error " + error.toString() }); } var usingComponents = configData.usingComponents || {}; if (intent === "componentName") { var filename = context.getFilename(); for (var _i = 0, _a = Object.entries(usingComponents); _i < _a.length; _i++) { var _b = _a[_i], componentName = _b[0], componentPath = _b[1]; var expectName = exports.getExpectedComponentName(componentPath, filename); if (expectName !== componentName) { context.report({ loc: DEFAULT_LOC, message: "prefer `" + expectName + "` instead of `" + componentName + "` for `" + componentPath + "`" }); } } return {}; } var registedComponents = new Set(); for (var _c = 0, _d = Object.keys(usingComponents); _c < _d.length; _c++) { var component = _d[_c]; registedComponents.add(component); } var usedComponents = new Set(); var usedComponentsNodeMap = new Map(); var addUsedComponents = function (componentName, node) { if (isBuildInComponents(componentName)) { return; } usedComponents.add(componentName); usedComponentsNodeMap.set(componentName, (usedComponentsNodeMap.get(componentName) || []).concat([ node ])); }; return utils_1.default.defineTemplateBodyVisitor(context, { VElement: function (node) { addUsedComponents(node.name, node); }, VAttribute: function attribute(node) { var attrName = node.key.name; if (!attrName.startsWith("generic:")) { return; } var componentName = node.value.value; addUsedComponents(componentName, node); }, "VElement[name='template']:exit": function exit() { if (intent === "unregisteredComponent") { for (var _i = 0, _a = Array.from(usedComponents); _i < _a.length; _i++) { var component = _a[_i]; if (!registedComponents.has(component)) { for (var _b = 0, _c = usedComponentsNodeMap.get(component) || []; _b < _c.length; _b++) { var componentNode = _c[_b]; context.report({ node: componentNode, message: "unregistered component `" + component + "` in `usingComponents`" }); } } } } if (intent === "unusedComponent") { for (var _d = 0, _e = Array.from(registedComponents); _d < _e.length; _d++) { var component = _e[_d]; if (!usedComponents.has(component)) { context.report({ loc: DEFAULT_LOC, message: "unused component `" + component + "` in `usingComponents`" }); } } } } }); } }); }; //# sourceMappingURL=check-using-components.js.map