first commit
This commit is contained in:
26
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/ast-utils.d.ts
generated
vendored
Normal file
26
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/ast-utils.d.ts
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { TSESTree } from '@typescript-eslint/utils';
|
||||
export declare function isNodeTypeClass(node: TSESTree.ClassDeclaration): boolean;
|
||||
export declare function isCredentialTypeClass(node: TSESTree.ClassDeclaration): boolean;
|
||||
export declare function findClassProperty(node: TSESTree.ClassDeclaration, propertyName: string): TSESTree.PropertyDefinition | null;
|
||||
export declare function findObjectProperty(obj: TSESTree.ObjectExpression, propertyName: string): TSESTree.Property | null;
|
||||
export declare function getLiteralValue(node: TSESTree.Node | null): string | boolean | number | null;
|
||||
export declare function getStringLiteralValue(node: TSESTree.Node | null): string | null;
|
||||
export declare function getModulePath(node: TSESTree.Node | null): string | null;
|
||||
export declare function getBooleanLiteralValue(node: TSESTree.Node | null): boolean | null;
|
||||
export declare function findArrayLiteralProperty(obj: TSESTree.ObjectExpression, propertyName: string): TSESTree.ArrayExpression | null;
|
||||
export declare function hasArrayLiteralValue(node: TSESTree.PropertyDefinition, searchValue: string): boolean;
|
||||
export declare function getTopLevelObjectInJson(node: TSESTree.ObjectExpression): TSESTree.ObjectExpression | null;
|
||||
export declare function isFileType(filename: string, extension: string): boolean;
|
||||
export declare function isDirectRequireCall(node: TSESTree.CallExpression): boolean;
|
||||
export declare function isRequireMemberCall(node: TSESTree.CallExpression): boolean;
|
||||
export declare function extractCredentialInfoFromArray(element: TSESTree.ArrayExpression['elements'][number]): {
|
||||
name: string;
|
||||
testedBy?: string;
|
||||
node: TSESTree.Node;
|
||||
} | null;
|
||||
export declare function extractCredentialNameFromArray(element: TSESTree.ArrayExpression['elements'][number]): {
|
||||
name: string;
|
||||
node: TSESTree.Node;
|
||||
} | null;
|
||||
export declare function findSimilarStrings(target: string, candidates: Set<string>, maxDistance?: number, maxResults?: number): string[];
|
||||
//# sourceMappingURL=ast-utils.d.ts.map
|
||||
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/ast-utils.d.ts.map
generated
vendored
Normal file
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/ast-utils.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ast-utils.d.ts","sourceRoot":"","sources":["../../src/utils/ast-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAezD,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,GAAG,OAAO,CAUxE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,GAAG,OAAO,CAE9E;AAED,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,EAC/B,YAAY,EAAE,MAAM,GAClB,QAAQ,CAAC,kBAAkB,GAAG,IAAI,CAQpC;AAED,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,QAAQ,CAAC,gBAAgB,EAC9B,YAAY,EAAE,MAAM,GAClB,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAQ1B;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,CAK5F;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG/E;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAevE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAGjF;AAED,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,QAAQ,CAAC,gBAAgB,EAC9B,YAAY,EAAE,MAAM,GAClB,QAAQ,CAAC,eAAe,GAAG,IAAI,CAMjC;AAED,wBAAgB,oBAAoB,CACnC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,EACjC,WAAW,EAAE,MAAM,GACjB,OAAO,CAST;AAED,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,GAC7B,QAAQ,CAAC,gBAAgB,GAAG,IAAI,CAKlC;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,GAAG,OAAO,CAM1E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,GAAG,OAAO,CAO1E;AAED,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GACnD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAA;CAAE,GAAG,IAAI,CA6BjE;AAED,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GACnD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAA;CAAE,GAAG,IAAI,CAG9C;AAED,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,WAAW,GAAE,MAAU,EACvB,UAAU,GAAE,MAAU,GACpB,MAAM,EAAE,CAeV"}
|
||||
135
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/ast-utils.js
generated
vendored
Normal file
135
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/ast-utils.js
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
|
||||
import { distance } from 'fastest-levenshtein';
|
||||
function implementsInterface(node, interfaceName) {
|
||||
return (node.implements?.some((impl) => impl.type === AST_NODE_TYPES.TSClassImplements &&
|
||||
impl.expression.type === AST_NODE_TYPES.Identifier &&
|
||||
impl.expression.name === interfaceName) ?? false);
|
||||
}
|
||||
export function isNodeTypeClass(node) {
|
||||
if (implementsInterface(node, 'INodeType')) {
|
||||
return true;
|
||||
}
|
||||
if (node.superClass?.type === AST_NODE_TYPES.Identifier && node.superClass.name === 'Node') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export function isCredentialTypeClass(node) {
|
||||
return implementsInterface(node, 'ICredentialType');
|
||||
}
|
||||
export function findClassProperty(node, propertyName) {
|
||||
const property = node.body.body.find((member) => member.type === AST_NODE_TYPES.PropertyDefinition &&
|
||||
member.key?.type === AST_NODE_TYPES.Identifier &&
|
||||
member.key.name === propertyName);
|
||||
return property?.type === AST_NODE_TYPES.PropertyDefinition ? property : null;
|
||||
}
|
||||
export function findObjectProperty(obj, propertyName) {
|
||||
const property = obj.properties.find((prop) => prop.type === AST_NODE_TYPES.Property &&
|
||||
prop.key.type === AST_NODE_TYPES.Identifier &&
|
||||
prop.key.name === propertyName);
|
||||
return property?.type === AST_NODE_TYPES.Property ? property : null;
|
||||
}
|
||||
export function getLiteralValue(node) {
|
||||
if (node?.type === AST_NODE_TYPES.Literal) {
|
||||
return node.value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
export function getStringLiteralValue(node) {
|
||||
const value = getLiteralValue(node);
|
||||
return typeof value === 'string' ? value : null;
|
||||
}
|
||||
export function getModulePath(node) {
|
||||
const stringValue = getStringLiteralValue(node);
|
||||
if (stringValue) {
|
||||
return stringValue;
|
||||
}
|
||||
if (node?.type === AST_NODE_TYPES.TemplateLiteral &&
|
||||
node.expressions.length === 0 &&
|
||||
node.quasis.length === 1) {
|
||||
return node.quasis[0]?.value.cooked ?? null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
export function getBooleanLiteralValue(node) {
|
||||
const value = getLiteralValue(node);
|
||||
return typeof value === 'boolean' ? value : null;
|
||||
}
|
||||
export function findArrayLiteralProperty(obj, propertyName) {
|
||||
const property = findObjectProperty(obj, propertyName);
|
||||
if (property?.value.type === AST_NODE_TYPES.ArrayExpression) {
|
||||
return property.value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
export function hasArrayLiteralValue(node, searchValue) {
|
||||
if (node.value?.type !== AST_NODE_TYPES.ArrayExpression)
|
||||
return false;
|
||||
return node.value.elements.some((element) => element?.type === AST_NODE_TYPES.Literal &&
|
||||
typeof element.value === 'string' &&
|
||||
element.value === searchValue);
|
||||
}
|
||||
export function getTopLevelObjectInJson(node) {
|
||||
if (node.parent?.type === AST_NODE_TYPES.Property) {
|
||||
return null;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
export function isFileType(filename, extension) {
|
||||
return filename.endsWith(extension);
|
||||
}
|
||||
export function isDirectRequireCall(node) {
|
||||
return (node.callee.type === AST_NODE_TYPES.Identifier &&
|
||||
node.callee.name === 'require' &&
|
||||
node.arguments.length > 0);
|
||||
}
|
||||
export function isRequireMemberCall(node) {
|
||||
return (node.callee.type === AST_NODE_TYPES.MemberExpression &&
|
||||
node.callee.object.type === AST_NODE_TYPES.Identifier &&
|
||||
node.callee.object.name === 'require' &&
|
||||
node.arguments.length > 0);
|
||||
}
|
||||
export function extractCredentialInfoFromArray(element) {
|
||||
if (!element)
|
||||
return null;
|
||||
const stringValue = getStringLiteralValue(element);
|
||||
if (stringValue) {
|
||||
return { name: stringValue, node: element };
|
||||
}
|
||||
if (element.type === AST_NODE_TYPES.ObjectExpression) {
|
||||
const nameProperty = findObjectProperty(element, 'name');
|
||||
const testedByProperty = findObjectProperty(element, 'testedBy');
|
||||
if (nameProperty) {
|
||||
const nameValue = getStringLiteralValue(nameProperty.value);
|
||||
const testedByValue = testedByProperty
|
||||
? getStringLiteralValue(testedByProperty.value)
|
||||
: undefined;
|
||||
if (nameValue) {
|
||||
return {
|
||||
name: nameValue,
|
||||
testedBy: testedByValue ?? undefined,
|
||||
node: nameProperty.value,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
export function extractCredentialNameFromArray(element) {
|
||||
const info = extractCredentialInfoFromArray(element);
|
||||
return info ? { name: info.name, node: info.node } : null;
|
||||
}
|
||||
export function findSimilarStrings(target, candidates, maxDistance = 3, maxResults = 3) {
|
||||
const matches = [];
|
||||
for (const candidate of candidates) {
|
||||
const levenshteinDistance = distance(target.toLowerCase(), candidate.toLowerCase());
|
||||
if (levenshteinDistance <= maxDistance) {
|
||||
matches.push({ name: candidate, distance: levenshteinDistance });
|
||||
}
|
||||
}
|
||||
return matches
|
||||
.sort((a, b) => a.distance - b.distance)
|
||||
.slice(0, maxResults)
|
||||
.map((match) => match.name);
|
||||
}
|
||||
//# sourceMappingURL=ast-utils.js.map
|
||||
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/ast-utils.js.map
generated
vendored
Normal file
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/ast-utils.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
26
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/file-utils.d.ts
generated
vendored
Normal file
26
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/file-utils.d.ts
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Checks if the given childPath is contained within the parentPath. Resolves
|
||||
* the paths before comparing them, so that relative paths are also supported.
|
||||
*/
|
||||
export declare function isContainedWithin(parentPath: string, childPath: string): boolean;
|
||||
/**
|
||||
* Joins the given paths to the parentPath, ensuring that the resulting path
|
||||
* is still contained within the parentPath. If not, it throws an error to
|
||||
* prevent path traversal vulnerabilities.
|
||||
*
|
||||
* @throws {UnexpectedError} If the resulting path is not contained within the parentPath.
|
||||
*/
|
||||
export declare function safeJoinPath(parentPath: string, ...paths: string[]): string;
|
||||
export declare function findPackageJson(startPath: string): string | null;
|
||||
export declare function readPackageJsonCredentials(packageJsonPath: string): Set<string>;
|
||||
export declare function extractCredentialNameFromFile(credentialFilePath: string): string | null;
|
||||
export declare function validateIconPath(iconPath: string, baseDir: string): {
|
||||
isValid: boolean;
|
||||
isFile: boolean;
|
||||
isSvg: boolean;
|
||||
exists: boolean;
|
||||
};
|
||||
export declare function readPackageJsonNodes(packageJsonPath: string): string[];
|
||||
export declare function areAllCredentialUsagesTestedByNodes(credentialName: string, packageDir: string): boolean;
|
||||
export declare function findSimilarSvgFiles(targetPath: string, baseDir: string): string[];
|
||||
//# sourceMappingURL=file-utils.d.ts.map
|
||||
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/file-utils.d.ts.map
generated
vendored
Normal file
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/file-utils.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/utils/file-utils.ts"],"names":[],"mappings":"AAgBA;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAShF;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAU3E;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAahE;AAyCD,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAkB/E;AAED,wBAAgB,6BAA6B,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA4BvF;AAED,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACb;IACF,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CAChB,CAcA;AAED,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,CAItE;AAED,wBAAgB,mCAAmC,CAClD,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GAChB,OAAO,CAoBT;AA+DD,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAuBjF"}
|
||||
221
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/file-utils.js
generated
vendored
Normal file
221
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/file-utils.js
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
import { parse, simpleTraverse, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree';
|
||||
import { readFileSync, existsSync, readdirSync } from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import { dirname, parse as parsePath } from 'node:path';
|
||||
import { isCredentialTypeClass, isNodeTypeClass, findClassProperty, getStringLiteralValue, findArrayLiteralProperty, extractCredentialInfoFromArray, findSimilarStrings, } from './ast-utils.js';
|
||||
/**
|
||||
* Checks if the given childPath is contained within the parentPath. Resolves
|
||||
* the paths before comparing them, so that relative paths are also supported.
|
||||
*/
|
||||
export function isContainedWithin(parentPath, childPath) {
|
||||
parentPath = path.resolve(parentPath);
|
||||
childPath = path.resolve(childPath);
|
||||
if (parentPath === childPath) {
|
||||
return true;
|
||||
}
|
||||
return childPath.startsWith(parentPath + path.sep);
|
||||
}
|
||||
/**
|
||||
* Joins the given paths to the parentPath, ensuring that the resulting path
|
||||
* is still contained within the parentPath. If not, it throws an error to
|
||||
* prevent path traversal vulnerabilities.
|
||||
*
|
||||
* @throws {UnexpectedError} If the resulting path is not contained within the parentPath.
|
||||
*/
|
||||
export function safeJoinPath(parentPath, ...paths) {
|
||||
const candidate = path.join(parentPath, ...paths);
|
||||
if (!isContainedWithin(parentPath, candidate)) {
|
||||
throw new Error(`Path traversal detected, refusing to join paths: ${parentPath} and ${JSON.stringify(paths)}`);
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
export function findPackageJson(startPath) {
|
||||
let currentDir = path.dirname(startPath);
|
||||
while (parsePath(currentDir).dir !== parsePath(currentDir).root) {
|
||||
const testPath = safeJoinPath(currentDir, 'package.json');
|
||||
if (fileExistsWithCaseSync(testPath)) {
|
||||
return testPath;
|
||||
}
|
||||
currentDir = dirname(currentDir);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function isValidPackageJson(obj) {
|
||||
return typeof obj === 'object' && obj !== null;
|
||||
}
|
||||
function readPackageJsonN8n(packageJsonPath) {
|
||||
try {
|
||||
const content = readFileSync(packageJsonPath, 'utf8');
|
||||
const parsed = JSON.parse(content);
|
||||
if (isValidPackageJson(parsed)) {
|
||||
return parsed.n8n ?? {};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
function resolveN8nFilePaths(packageJsonPath, filePaths) {
|
||||
const packageDir = dirname(packageJsonPath);
|
||||
const resolvedFiles = [];
|
||||
for (const filePath of filePaths) {
|
||||
const sourcePath = filePath.replace(/^dist\//, '').replace(/\.js$/, '.ts');
|
||||
const fullSourcePath = safeJoinPath(packageDir, sourcePath);
|
||||
if (existsSync(fullSourcePath)) {
|
||||
resolvedFiles.push(fullSourcePath);
|
||||
}
|
||||
}
|
||||
return resolvedFiles;
|
||||
}
|
||||
export function readPackageJsonCredentials(packageJsonPath) {
|
||||
const n8nConfig = readPackageJsonN8n(packageJsonPath);
|
||||
const credentialPaths = n8nConfig.credentials ?? [];
|
||||
const credentialFiles = resolveN8nFilePaths(packageJsonPath, credentialPaths);
|
||||
const credentialNames = [];
|
||||
for (const credentialFile of credentialFiles) {
|
||||
try {
|
||||
const credentialName = extractCredentialNameFromFile(credentialFile);
|
||||
if (credentialName) {
|
||||
credentialNames.push(credentialName);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// Silently continue if file can't be parsed
|
||||
}
|
||||
}
|
||||
return new Set(credentialNames);
|
||||
}
|
||||
export function extractCredentialNameFromFile(credentialFilePath) {
|
||||
try {
|
||||
const sourceCode = readFileSync(credentialFilePath, 'utf8');
|
||||
const ast = parse(sourceCode, {
|
||||
jsx: false,
|
||||
range: true,
|
||||
});
|
||||
let credentialName = null;
|
||||
simpleTraverse(ast, {
|
||||
enter(node) {
|
||||
if (node.type === AST_NODE_TYPES.ClassDeclaration && isCredentialTypeClass(node)) {
|
||||
const nameProperty = findClassProperty(node, 'name');
|
||||
if (nameProperty) {
|
||||
const nameValue = getStringLiteralValue(nameProperty.value);
|
||||
if (nameValue) {
|
||||
credentialName = nameValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
return credentialName;
|
||||
}
|
||||
catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
export function validateIconPath(iconPath, baseDir) {
|
||||
const isFile = iconPath.startsWith('file:');
|
||||
const relativePath = iconPath.replace(/^file:/, '');
|
||||
const isSvg = relativePath.endsWith('.svg');
|
||||
// Should not use safeJoinPath here because iconPath can be outside of the node class folder
|
||||
const fullPath = path.join(baseDir, relativePath);
|
||||
const exists = fileExistsWithCaseSync(fullPath);
|
||||
return {
|
||||
isValid: isFile && isSvg && exists,
|
||||
isFile,
|
||||
isSvg,
|
||||
exists,
|
||||
};
|
||||
}
|
||||
export function readPackageJsonNodes(packageJsonPath) {
|
||||
const n8nConfig = readPackageJsonN8n(packageJsonPath);
|
||||
const nodePaths = n8nConfig.nodes ?? [];
|
||||
return resolveN8nFilePaths(packageJsonPath, nodePaths);
|
||||
}
|
||||
export function areAllCredentialUsagesTestedByNodes(credentialName, packageDir) {
|
||||
const packageJsonPath = safeJoinPath(packageDir, 'package.json');
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
return false;
|
||||
}
|
||||
const nodeFiles = readPackageJsonNodes(packageJsonPath);
|
||||
let hasAnyCredentialUsage = false;
|
||||
for (const nodeFile of nodeFiles) {
|
||||
const result = checkCredentialUsageInFile(nodeFile, credentialName);
|
||||
if (result.hasUsage) {
|
||||
hasAnyCredentialUsage = true;
|
||||
if (!result.allTestedBy) {
|
||||
return false; // Found usage without testedBy
|
||||
}
|
||||
}
|
||||
}
|
||||
return hasAnyCredentialUsage;
|
||||
}
|
||||
function checkCredentialUsageInFile(nodeFile, credentialName) {
|
||||
try {
|
||||
const sourceCode = readFileSync(nodeFile, 'utf8');
|
||||
const ast = parse(sourceCode, { jsx: false, range: true });
|
||||
let hasUsage = false;
|
||||
let allTestedBy = true;
|
||||
simpleTraverse(ast, {
|
||||
enter(node) {
|
||||
if (node.type === AST_NODE_TYPES.ClassDeclaration && isNodeTypeClass(node)) {
|
||||
const descriptionProperty = findClassProperty(node, 'description');
|
||||
if (!descriptionProperty?.value ||
|
||||
descriptionProperty.value.type !== AST_NODE_TYPES.ObjectExpression) {
|
||||
return;
|
||||
}
|
||||
const credentialsArray = findArrayLiteralProperty(descriptionProperty.value, 'credentials');
|
||||
if (!credentialsArray) {
|
||||
return;
|
||||
}
|
||||
for (const element of credentialsArray.elements) {
|
||||
const credentialInfo = extractCredentialInfoFromArray(element);
|
||||
if (credentialInfo?.name === credentialName) {
|
||||
hasUsage = true;
|
||||
if (!credentialInfo.testedBy) {
|
||||
allTestedBy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
return { hasUsage, allTestedBy };
|
||||
}
|
||||
catch {
|
||||
return { hasUsage: false, allTestedBy: true };
|
||||
}
|
||||
}
|
||||
function fileExistsWithCaseSync(filePath) {
|
||||
try {
|
||||
const dir = path.dirname(filePath);
|
||||
const file = path.basename(filePath);
|
||||
const files = new Set(readdirSync(dir));
|
||||
return files.has(file);
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export function findSimilarSvgFiles(targetPath, baseDir) {
|
||||
try {
|
||||
const targetFileName = path.basename(targetPath, path.extname(targetPath));
|
||||
const targetDir = path.dirname(targetPath);
|
||||
// Should not use safeJoinPath here because iconPath can be outside of the node class folder
|
||||
const searchDir = path.join(baseDir, targetDir);
|
||||
if (!existsSync(searchDir)) {
|
||||
return [];
|
||||
}
|
||||
const files = readdirSync(searchDir);
|
||||
const svgFileNames = files
|
||||
.filter((file) => file.endsWith('.svg'))
|
||||
.map((file) => path.basename(file, '.svg'));
|
||||
const candidateNames = new Set(svgFileNames);
|
||||
const similarNames = findSimilarStrings(targetFileName, candidateNames);
|
||||
return similarNames.map((name) => path.join(targetDir, `${name}.svg`));
|
||||
}
|
||||
catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=file-utils.js.map
|
||||
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/file-utils.js.map
generated
vendored
Normal file
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/file-utils.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/index.d.ts
generated
vendored
Normal file
4
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './ast-utils.js';
|
||||
export * from './file-utils.js';
|
||||
export * from './rule-creator.js';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/index.d.ts.map
generated
vendored
Normal file
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/index.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
|
||||
4
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/index.js
generated
vendored
Normal file
4
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/index.js
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './ast-utils.js';
|
||||
export * from './file-utils.js';
|
||||
export * from './rule-creator.js';
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/index.js.map
generated
vendored
Normal file
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/index.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
|
||||
3
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/rule-creator.d.ts
generated
vendored
Normal file
3
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/rule-creator.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import { ESLintUtils } from '@typescript-eslint/utils';
|
||||
export declare const createRule: <Options extends readonly unknown[], MessageIds extends string>({ meta, name, ...rule }: Readonly<ESLintUtils.RuleWithMetaAndName<Options, MessageIds, unknown>>) => ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
|
||||
//# sourceMappingURL=rule-creator.d.ts.map
|
||||
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/rule-creator.d.ts.map
generated
vendored
Normal file
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/rule-creator.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"rule-creator.d.ts","sourceRoot":"","sources":["../../src/utils/rule-creator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAKvD,eAAO,MAAM,UAAU,qPAA2E,CAAC"}
|
||||
5
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/rule-creator.js
generated
vendored
Normal file
5
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/rule-creator.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import { ESLintUtils } from '@typescript-eslint/utils';
|
||||
const REPO_URL = 'https://github.com/n8n-io/n8n';
|
||||
const DOCS_PATH = 'blob/master/packages/@n8n/eslint-plugin-community-nodes/docs/rules';
|
||||
export const createRule = ESLintUtils.RuleCreator((name) => `${REPO_URL}/${DOCS_PATH}/${name}.md`);
|
||||
//# sourceMappingURL=rule-creator.js.map
|
||||
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/rule-creator.js.map
generated
vendored
Normal file
1
node_modules/@n8n/eslint-plugin-community-nodes/dist/utils/rule-creator.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"rule-creator.js","sourceRoot":"","sources":["../../src/utils/rule-creator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,MAAM,QAAQ,GAAG,+BAA+B,CAAC;AACjD,MAAM,SAAS,GAAG,oEAAoE,CAAC;AAEvF,MAAM,CAAC,MAAM,UAAU,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,QAAQ,IAAI,SAAS,IAAI,IAAI,KAAK,CAAC,CAAC"}
|
||||
Reference in New Issue
Block a user