eslint-plugin-pipedream
Advanced tools
Comparing version 0.2.1 to 0.2.2
41
index.js
@@ -9,6 +9,3 @@ function isModuleExports(node) { | ||
function isDefaultExport(node) { | ||
if (!node) return false; | ||
if (node.type !== "Program" || !node.body || !node.body.length) return false; | ||
if (node?.body[0]?.type !== "ExportDefaultDeclaration") return false; | ||
return true; | ||
return node?.type === "ExportDefaultDeclaration"; | ||
} | ||
@@ -53,3 +50,3 @@ | ||
if (isDefaultExport(node)) { | ||
component = node?.body[0]?.declaration; | ||
component = node.declaration; | ||
} | ||
@@ -90,5 +87,4 @@ | ||
if (isDefaultExport(node)) { | ||
component = node?.body[0]?.declaration; | ||
component = node.declaration; | ||
} | ||
if (node.expression) { | ||
@@ -131,3 +127,3 @@ const { | ||
if (isDefaultExport(node)) { | ||
component = node?.body[0]?.declaration; | ||
component = node.declaration; | ||
} | ||
@@ -179,3 +175,3 @@ | ||
if (isDefaultExport(node)) { | ||
component = node?.body[0]?.declaration; | ||
component = node.declaration; | ||
} | ||
@@ -229,3 +225,3 @@ | ||
if (isDefaultExport(node)) { | ||
component = node?.body[0]?.declaration; | ||
component = node.declaration; | ||
} | ||
@@ -256,3 +252,4 @@ | ||
// Rules run on two different AST node types: ExpressionStatement (CJS) and Program (ESM) | ||
// Rules run on two different AST node types: ExpressionStatement (CJS) and | ||
// ExportDefaultDeclaration (ESM) | ||
module.exports = { | ||
@@ -266,3 +263,3 @@ rules: { | ||
}, | ||
Program(node) { | ||
ExportDefaultDeclaration(node) { | ||
componentContainsPropertyCheck(context, node, "key"); | ||
@@ -279,3 +276,3 @@ }, | ||
}, | ||
Program(node) { | ||
ExportDefaultDeclaration(node) { | ||
componentContainsPropertyCheck(context, node, "name"); | ||
@@ -292,3 +289,3 @@ }, | ||
}, | ||
Program(node) { | ||
ExportDefaultDeclaration(node) { | ||
componentContainsPropertyCheck(context, node, "version"); | ||
@@ -305,3 +302,3 @@ }, | ||
}, | ||
Program(node) { | ||
ExportDefaultDeclaration(node) { | ||
componentContainsPropertyCheck(context, node, "description"); | ||
@@ -318,3 +315,3 @@ }, | ||
}, | ||
Program(node) { | ||
ExportDefaultDeclaration(node) { | ||
componentContainsPropertyCheck(context, node, "type", "Components must export a type property (\"source\" or \"action\")"); | ||
@@ -331,3 +328,3 @@ }, | ||
}, | ||
Program(node) { | ||
ExportDefaultDeclaration(node) { | ||
componentPropsContainsPropertyCheck(context, node, "label"); | ||
@@ -344,3 +341,3 @@ }, | ||
}, | ||
Program(node) { | ||
ExportDefaultDeclaration(node) { | ||
componentPropsContainsPropertyCheck(context, node, "description"); | ||
@@ -357,3 +354,3 @@ }, | ||
}, | ||
Program(node) { | ||
ExportDefaultDeclaration(node) { | ||
optionalComponentPropsHaveDefaultProperty(context, node); | ||
@@ -370,3 +367,3 @@ }, | ||
}, | ||
Program(node) { | ||
ExportDefaultDeclaration(node) { | ||
componentSourceNameCheck(context, node); | ||
@@ -383,3 +380,3 @@ }, | ||
}, | ||
Program(node) { | ||
ExportDefaultDeclaration(node) { | ||
componentSourceDescriptionCheck(context, node); | ||
@@ -396,3 +393,3 @@ }, | ||
}, | ||
Program(node) { | ||
ExportDefaultDeclaration(node) { | ||
componentVersionTsMacroCheck(context, node); | ||
@@ -399,0 +396,0 @@ }, |
{ | ||
"name": "eslint-plugin-pipedream", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"description": "ESLint plugin for Pipedream components: https://pipedream.com/docs/components/api/", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -34,319 +34,155 @@ const RuleTester = require("eslint").RuleTester; | ||
ruleTester.run("required-properties-key-test", rules["required-properties-key"], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(valid), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(valid), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(requiredPropertyKeyMissing), | ||
errors: [ | ||
{ | ||
message: "Components must export a key property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(requiredPropertyKeyMissing), | ||
errors: [ | ||
{ | ||
message: "Components must export a key property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
function withPrecedingStatement(code) { | ||
return ` | ||
import foo from "bar"; | ||
${code} | ||
`; | ||
} | ||
ruleTester.run("required-properties-name-test", rules["required-properties-name"], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(valid), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(valid), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(requiredPropertyNameMissing), | ||
errors: [ | ||
{ | ||
message: "Components must export a name property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(requiredPropertyNameMissing), | ||
errors: [ | ||
{ | ||
message: "Components must export a name property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
function makeComponentTestCase ({ | ||
ruleName, | ||
name = `${ruleName}-test`, | ||
validComponent = valid, | ||
invalidComponent, | ||
errorMessage, | ||
}) { | ||
return { | ||
name, | ||
ruleName, | ||
validComponent, | ||
invalidComponent, | ||
errorMessage, | ||
}; | ||
} | ||
ruleTester.run("required-properties-description-test", rules["required-properties-description"], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(valid), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(valid), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(requiredPropertyDescriptionMissing), | ||
errors: [ | ||
{ | ||
message: "Components must export a description property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(requiredPropertyDescriptionMissing), | ||
errors: [ | ||
{ | ||
message: "Components must export a description property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
const componentTestConfigs = [ | ||
{ | ||
ruleName: "required-properties-key", | ||
invalidComponent: requiredPropertyKeyMissing, | ||
errorMessage: "Components must export a key property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
{ | ||
ruleName: "required-properties-name", | ||
invalidComponent: requiredPropertyNameMissing, | ||
errorMessage: "Components must export a name property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
{ | ||
ruleName: "required-properties-description", | ||
invalidComponent: requiredPropertyDescriptionMissing, | ||
errorMessage: "Components must export a description property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
{ | ||
ruleName: "required-properties-version", | ||
invalidComponent: requiredPropertyVersionMissing, | ||
errorMessage: "Components must export a version property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
{ | ||
ruleName: "required-properties-type", | ||
invalidComponent: requiredPropertyTypeMissing, | ||
errorMessage: "Components must export a type property (\"source\" or \"action\")", | ||
}, | ||
{ | ||
ruleName: "default-value-required-for-optional-props", | ||
invalidComponent: optionalPropWithoutDefaultValue, | ||
errorMessage: "Component prop test is marked \"optional\", so it may need a \"default\" property. See https://pipedream.com/docs/components/guidelines/#default-values", | ||
}, | ||
{ | ||
ruleName: "props-label", | ||
invalidComponent: missingPropsLabel, | ||
errorMessage: "Component prop test must have a label. See https://pipedream.com/docs/components/guidelines/#props", | ||
}, | ||
{ | ||
ruleName: "props-description", | ||
invalidComponent: missingPropsDescription, | ||
errorMessage: "Component prop test must have a description. See https://pipedream.com/docs/components/guidelines/#props", | ||
}, | ||
{ | ||
ruleName: "source-name", | ||
invalidComponent: badSourceName, | ||
errorMessage: "Source names should start with \"New\". See https://pipedream.com/docs/components/guidelines/#source-name", | ||
}, | ||
{ | ||
ruleName: "source-description", | ||
invalidComponent: badSourceDescription, | ||
errorMessage: "Source descriptions should start with \"Emit new\". See https://pipedream.com/docs/components/guidelines/#source-description", | ||
}, | ||
{ | ||
name: "ts-version-test", | ||
ruleName: "no-ts-version", | ||
invalidComponent: tsVersion, | ||
errorMessage: "{{ts}} macro should be removed before committing", | ||
}, | ||
]; | ||
ruleTester.run("required-properties-version-test", rules["required-properties-version"], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(valid), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(valid), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(requiredPropertyVersionMissing), | ||
errors: [ | ||
{ | ||
message: "Components must export a version property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(requiredPropertyVersionMissing), | ||
errors: [ | ||
{ | ||
message: "Components must export a version property. See https://pipedream.com/docs/components/guidelines/#required-metadata", | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
const componentTestCases = componentTestConfigs.map(makeComponentTestCase); | ||
ruleTester.run("required-properties-type-test", rules["required-properties-type"], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(valid), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(valid), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(requiredPropertyTypeMissing), | ||
errors: [ | ||
{ | ||
message: "Components must export a type property (\"source\" or \"action\")", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(requiredPropertyTypeMissing), | ||
errors: [ | ||
{ | ||
message: "Components must export a type property (\"source\" or \"action\")", | ||
}, | ||
], | ||
}, | ||
], | ||
// Run `ruleTester.run` on each test case | ||
componentTestCases.forEach((testCase) => { | ||
const { | ||
name, | ||
ruleName, | ||
validComponent, | ||
invalidComponent, | ||
errorMessage, | ||
} = testCase; | ||
ruleTester.run(name, rules[ruleName], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(validComponent), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(validComponent), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(invalidComponent), | ||
errors: [ | ||
{ | ||
message: errorMessage, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(invalidComponent), | ||
errors: [ | ||
{ | ||
message: errorMessage, | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
}); | ||
ruleTester.run("default-value-required-for-optional-props-test", rules["default-value-required-for-optional-props"], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(valid), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(valid), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(optionalPropWithoutDefaultValue), | ||
errors: [ | ||
RuleTester.describe("On ESM export default with preceding statements", () => { | ||
// Run each test case on ESM default export components with preceding statements | ||
// (lines above the `export default` declaration) | ||
componentTestCases.forEach((testCase) => { | ||
const { | ||
name, | ||
ruleName, | ||
validComponent, | ||
invalidComponent, | ||
errorMessage, | ||
} = testCase; | ||
ruleTester.run(name, rules[ruleName], { | ||
valid: [ | ||
{ | ||
message: "Component prop test is marked \"optional\", so it may need a \"default\" property. See https://pipedream.com/docs/components/guidelines/#default-values", | ||
code: withPrecedingStatement(convertObjectToESMExportString(validComponent)), | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(optionalPropWithoutDefaultValue), | ||
errors: [ | ||
invalid: [ | ||
{ | ||
message: "Component prop test is marked \"optional\", so it may need a \"default\" property. See https://pipedream.com/docs/components/guidelines/#default-values", | ||
code: withPrecedingStatement(convertObjectToESMExportString(invalidComponent)), | ||
errors: [ | ||
{ | ||
message: errorMessage, | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
}); | ||
}); | ||
ruleTester.run("props-label-test", rules["props-label"], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(valid), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(valid), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(missingPropsLabel), | ||
errors: [ | ||
{ | ||
message: "Component prop test must have a label. See https://pipedream.com/docs/components/guidelines/#props", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(missingPropsLabel), | ||
errors: [ | ||
{ | ||
message: "Component prop test must have a label. See https://pipedream.com/docs/components/guidelines/#props", | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
ruleTester.run("props-description-test", rules["props-description"], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(valid), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(valid), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(missingPropsDescription), | ||
errors: [ | ||
{ | ||
message: "Component prop test must have a description. See https://pipedream.com/docs/components/guidelines/#props", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(missingPropsDescription), | ||
errors: [ | ||
{ | ||
message: "Component prop test must have a description. See https://pipedream.com/docs/components/guidelines/#props", | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
ruleTester.run("source-name-test", rules["source-name"], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(valid), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(valid), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(badSourceName), | ||
errors: [ | ||
{ | ||
message: "Source names should start with \"New\". See https://pipedream.com/docs/components/guidelines/#source-name", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(badSourceName), | ||
errors: [ | ||
{ | ||
message: "Source names should start with \"New\". See https://pipedream.com/docs/components/guidelines/#source-name", | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
ruleTester.run("source-description-test", rules["source-description"], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(valid), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(valid), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(badSourceDescription), | ||
errors: [ | ||
{ | ||
message: "Source descriptions should start with \"Emit new\". See https://pipedream.com/docs/components/guidelines/#source-description", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(badSourceDescription), | ||
errors: [ | ||
{ | ||
message: "Source descriptions should start with \"Emit new\". See https://pipedream.com/docs/components/guidelines/#source-description", | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
ruleTester.run("ts-version-test", rules["no-ts-version"], { | ||
valid: [ | ||
{ | ||
code: convertObjectToCJSExportString(valid), | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(valid), | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: convertObjectToCJSExportString(tsVersion), | ||
errors: [ | ||
{ | ||
message: "{{ts}} macro should be removed before committing", | ||
}, | ||
], | ||
}, | ||
{ | ||
code: convertObjectToESMExportString(tsVersion), | ||
errors: [ | ||
{ | ||
message: "{{ts}} macro should be removed before committing", | ||
}, | ||
], | ||
}, | ||
], | ||
}); |
130271
634