diff --git a/index.js b/index.js index 09b0ce9..ab8428a 100644 --- a/index.js +++ b/index.js @@ -20,13 +20,17 @@ function isObjectWithProperties(node) { return true; } -// Default interface props don't need labels and descriptions -function isDefaultInterfaceProperty(propertyName, properties) { - if (propertyName === "label" || propertyName === "description") { - const interfacePropValue = findPropertyWithName("type", properties)?.value; - return (interfacePropValue?.value === "$.interface.timer" || interfacePropValue?.value === "$.interface.http"); - } - return false; +// Check if a prop type is exempt from label/description requirements +function isExemptFromLabelDescriptionRequirement(propertyName, properties) { + if (propertyName !== "label" && propertyName !== "description") return false; + const typePropValue = findPropertyWithName("type", properties)?.value; + if (!typePropValue?.value) return false; + // Default interface props don't need labels and descriptions + const isDefaultInterface = typePropValue.value === "$.interface.timer" || + typePropValue.value === "$.interface.http"; + // Dir props don't need labels and descriptions + const isDirProp = typePropValue.value === "dir"; + return isDefaultInterface || isDirProp; } function getComponentFromNode(node) { @@ -111,7 +115,7 @@ function componentPropsContainsPropertyCheck(context, node, propertyName) { // We don't want to lint app props or props that are defined in propDefinitions if (!isObjectWithProperties(propDef)) continue; if (astIncludesProperty("propDefinition", propDef.properties)) continue; - if (isDefaultInterfaceProperty(propertyName, propDef.properties)) continue; + if (isExemptFromLabelDescriptionRequirement(propertyName, propDef.properties)) continue; if (!astIncludesProperty(propertyName, propDef.properties)) { context.report({ node: prop, diff --git a/package-lock.json b/package-lock.json index 7d83312..43f005d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@pipedream/eslint-plugin-pipedream", - "version": "0.2.4", + "version": "0.2.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5e33b04..b1eef55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/eslint-plugin-pipedream", - "version": "0.2.4", + "version": "0.2.5", "description": "ESLint plugin for Pipedream components: https://pipedream.com/docs/components/api/", "main": "index.js", "scripts": { diff --git a/tests/components.js b/tests/components.js index 3c0e2a7..85870d5 100644 --- a/tests/components.js +++ b/tests/components.js @@ -95,6 +95,18 @@ module.exports = { }, }, }, + missingPropsLabelDir: { + key: "test", + name: "Test", + description: "hello", + version: "0.0.1", + props: { + test: { + type: "dir", + description: "test", + }, + }, + }, missingPropsDescription: { key: "test", name: "Test", @@ -131,6 +143,18 @@ module.exports = { }, }, }, + missingPropsDescriptionDir: { + key: "test", + name: "Test", + description: "hello", + version: "0.0.1", + props: { + test: { + type: "dir", + label: "Test", + }, + }, + }, badSourceName: { key: "test", name: "Test", diff --git a/tests/rules.test.js b/tests/rules.test.js index 3d3d637..fd3ed82 100644 --- a/tests/rules.test.js +++ b/tests/rules.test.js @@ -11,9 +11,11 @@ const { missingPropsLabel, missingPropsLabelTimer, missingPropsLabelHttp, + missingPropsLabelDir, missingPropsDescription, missingPropsDescriptionTimer, missingPropsDescriptionHttp, + missingPropsDescriptionDir, badSourceName, badSourceDescription, tsVersion, @@ -45,14 +47,16 @@ function withPrecedingStatement(code) { function makeComponentTestCase ({ ruleName, name = `${ruleName}-test`, - validComponent = valid, + validComponents = [ + valid, + ], invalidComponent, errorMessage, }) { return { name, ruleName, - validComponent, + validComponents, invalidComponent, errorMessage, }; @@ -91,25 +95,21 @@ const componentTestConfigs = [ }, { ruleName: "props-label", - validComponent: missingPropsLabelTimer, - invalidComponent: missingPropsLabel, - errorMessage: "Component prop test must have a label. See https://pipedream.com/docs/components/guidelines/#props", - }, - { - ruleName: "props-label", - validComponent: missingPropsLabelHttp, + validComponents: [ + missingPropsLabelTimer, + missingPropsLabelHttp, + missingPropsLabelDir, + ], invalidComponent: missingPropsLabel, errorMessage: "Component prop test must have a label. See https://pipedream.com/docs/components/guidelines/#props", }, { ruleName: "props-description", - validComponent: missingPropsDescriptionTimer, - invalidComponent: missingPropsDescription, - errorMessage: "Component prop test must have a description. See https://pipedream.com/docs/components/guidelines/#props", - }, - { - ruleName: "props-description", - validComponent: missingPropsDescriptionHttp, + validComponents: [ + missingPropsDescriptionTimer, + missingPropsDescriptionHttp, + missingPropsDescriptionDir, + ], invalidComponent: missingPropsDescription, errorMessage: "Component prop test must have a description. See https://pipedream.com/docs/components/guidelines/#props", }, @@ -138,19 +138,19 @@ componentTestCases.forEach((testCase) => { const { name, ruleName, - validComponent, + validComponents, invalidComponent, errorMessage, } = testCase; ruleTester.run(name, rules[ruleName], { - valid: [ + valid: validComponents.map((component) => ([ { - code: convertObjectToCJSExportString(validComponent), + code: convertObjectToCJSExportString(component), }, { - code: convertObjectToESMExportString(validComponent), + code: convertObjectToESMExportString(component), }, - ], + ])).flat(), invalid: [ { code: convertObjectToCJSExportString(invalidComponent),