eslint-plugin-boundaries
Version:
Eslint plugin checking architecture boundaries between elements
279 lines (278 loc) • 13 kB
TypeScript
export declare function isString(object: unknown): object is string;
export declare const IMPORT_KIND_TYPE: "type";
export declare const IMPORT_KIND_VALUE: "value";
/**
* Map of the kinds of import, either a type import or a value import.
*/
export declare const IMPORT_KINDS_MAP: {
/**
* Type import, e.g., `import type { X } from 'module'`
*/
readonly TYPE: "type";
/**
* Value import, e.g., `import x from 'module'` or `const x = require('module')`
*/
readonly VALUE: "value";
};
/**
* Kind of import, either a type import or a value import.
*/
export type ImportKind = (typeof IMPORT_KINDS_MAP)[keyof typeof IMPORT_KINDS_MAP];
export declare const DEPENDENCY_NODE_REQUIRE: "require";
export declare const DEPENDENCY_NODE_IMPORT: "import";
export declare const DEPENDENCY_NODE_DYNAMIC_IMPORT: "dynamic-import";
export declare const DEPENDENCY_NODE_EXPORT: "export";
/**
* Type guard to check if a value is a valid ImportKind.
* @param value The value to check.
* @returns True if the value is a valid ImportKind, false otherwise.
*/
export declare function isImportKind(value: unknown): value is ImportKind;
/**
* Different types of dependency nodes supported by the plugin by default.
* Each type corresponds to a common way of importing or requiring modules in JavaScript/TypeScript.
*/
export declare const DEPENDENCY_NODE_KEYS_MAP: {
/**
* CommonJS require statements, e.g., `const module = require('module')`.
*/
readonly REQUIRE: "require";
/**
* ES6 import statements, e.g., `import module from 'module'`.
*/
readonly IMPORT: "import";
/**
* Dynamic import statements, e.g., `import('module')`.
*/
readonly DYNAMIC_IMPORT: "dynamic-import";
/**
* Export statements, e.g., `export { module } from 'source'`.
*/
readonly EXPORT: "export";
};
/**
* Keys of the different types of dependency nodes supported by the plugin by default.
*/
export type DependencyNodeKey = (typeof DEPENDENCY_NODE_KEYS_MAP)[keyof typeof DEPENDENCY_NODE_KEYS_MAP];
/**
* Type guard to check if a value is a valid DependencyNodeKey.
* @param value The value to check.
* @returns True if the value is a valid DependencyNodeKey, false otherwise.
*/
export declare function isDependencyNodeKey(value: unknown): value is DependencyNodeKey;
/**
* Additional custom dependency node selector to consider when analyzing dependencies.
* Each entry defines a selector and its kind (either 'type' or 'value').
* This allows for extending the default dependency nodes with project-specific patterns.
*/
export type DependencyNodeSelector = {
/**
* A selector string to identify the dependency node in the AST.
*/
selector: string;
/**
* The kind of import, either 'type' or 'value'.
*/
kind: ImportKind;
};
export declare const SETTINGS: {
readonly ELEMENTS: "boundaries/elements";
readonly IGNORE: "boundaries/ignore";
readonly INCLUDE: "boundaries/include";
readonly ROOT_PATH: "boundaries/root-path";
readonly DEPENDENCY_NODES: "boundaries/dependency-nodes";
readonly ADDITIONAL_DEPENDENCY_NODES: "boundaries/additional-dependency-nodes";
readonly DEBUG: "ESLINT_PLUGIN_BOUNDARIES_DEBUG";
readonly ENV_ROOT_PATH: "ESLINT_PLUGIN_BOUNDARIES_ROOT_PATH";
readonly RULE_ELEMENT_TYPES: "boundaries/element-types";
readonly RULE_ENTRY_POINT: "boundaries/entry-point";
readonly RULE_EXTERNAL: "boundaries/external";
readonly RULE_NO_IGNORED: "boundaries/no-ignored";
readonly RULE_NO_PRIVATE: "boundaries/no-private";
readonly RULE_NO_UNKNOWN_FILES: "boundaries/no-unknown-files";
readonly RULE_NO_UNKNOWN: "boundaries/no-unknown";
readonly TYPES: "boundaries/types";
readonly ALIAS: "boundaries/alias";
readonly VALID_MODES: readonly ["folder", "file", "full"];
readonly VALID_DEPENDENCY_NODE_KINDS: readonly ["value", "type"];
readonly DEFAULT_DEPENDENCY_NODES: {
readonly require: readonly [{
readonly selector: "CallExpression[callee.name=require] > Literal";
readonly kind: "value";
}];
readonly import: readonly [{
readonly selector: "ImportDeclaration:not([importKind=type]) > Literal";
readonly kind: "value";
}, {
readonly selector: "ImportDeclaration[importKind=type] > Literal";
readonly kind: "type";
}];
readonly "dynamic-import": readonly [{
readonly selector: "ImportExpression > Literal";
readonly kind: "value";
}];
readonly export: readonly [{
readonly selector: "ExportAllDeclaration:not([exportKind=type]) > Literal";
readonly kind: "value";
}, {
readonly selector: "ExportAllDeclaration[exportKind=type] > Literal";
readonly kind: "type";
}, {
readonly selector: "ExportNamedDeclaration:not([exportKind=type]) > Literal";
readonly kind: "value";
}, {
readonly selector: "ExportNamedDeclaration[exportKind=type] > Literal";
readonly kind: "type";
}];
};
};
/**
* Map of the valid keys for the plugin settings.
*/
export declare const SETTINGS_KEYS_MAP: {
readonly ELEMENTS: "boundaries/elements";
readonly IGNORE: "boundaries/ignore";
readonly INCLUDE: "boundaries/include";
readonly ROOT_PATH: "boundaries/root-path";
readonly DEPENDENCY_NODES: "boundaries/dependency-nodes";
readonly ADDITIONAL_DEPENDENCY_NODES: "boundaries/additional-dependency-nodes";
/** @deprecated Use 'ELEMENTS' instead */
readonly TYPES: "boundaries/types";
/** @deprecated Use import/resolver settings instead */
readonly ALIAS: "boundaries/alias";
};
/**
* Valid keys for the plugin settings.
*/
export type SettingsKey = (typeof SETTINGS_KEYS_MAP)[keyof typeof SETTINGS_KEYS_MAP];
/**
* Type guard to check if a value is a valid key for the plugin settings.
* @param value - The value to check.
* @returns True if the value is a valid settings key, false otherwise.
*/
export declare function isSettingsKey(value: unknown): value is SettingsKey;
/**
* List of glob patterns to include when analyzing dependencies.
* If specified, only files matching these patterns will be included in the plugin analysis.
*/
export type IncludeSetting = string | string[];
/**
* List of glob patterns to ignore when analyzing dependencies.
* Files matching these patterns will be excluded from the plugin analysis.
*/
export type IgnoreSetting = string | string[];
/**
* Root path of the project. This is used to resolve relative paths in element patterns.
* Can also be set via the ESLINT_PLUGIN_BOUNDARIES_ROOT_PATH environment variable.
*/
export type RootPathSetting = string;
/**
* Alias settings to define path aliases for module resolution.
* Each key is an alias and its value is the corresponding path.
* @deprecated Use "import/resolver" settings instead
*/
export type AliasSetting = Record<string, string>;
/**
* Map of the modes to interpret the pattern in an ElementDescriptor.
*/
export declare const ELEMENT_DESCRIPTOR_MODES_MAP: {
readonly FOLDER: "folder";
readonly FILE: "file";
readonly FULL: "full";
};
/**
* Mode to interpret the pattern in an ElementDescriptor.
*/
export type ElementDescriptorMode = (typeof ELEMENT_DESCRIPTOR_MODES_MAP)[keyof typeof ELEMENT_DESCRIPTOR_MODES_MAP];
/**
* Type guard to check if a value is a valid ElementDescriptorMode.
* @param value The value to check.
* @returns True if the value is a valid ElementDescriptorMode, false otherwise.
*/
export declare function isElementDescriptorMode(value: unknown): value is ElementDescriptorMode;
/**
* Descriptor for an element (or layer) in the project.
* Defines the type of the element, the pattern to match files, and optional settings like mode and capture groups.
*/
export type ElementDescriptor = {
/** Type of the element (e.g., "service", "component", "util"). */
type: string;
/** Micromatch pattern(s) to match files belonging to this element. */
pattern: string | string[];
/**
* Optional micromatch pattern. If provided, the left side of the element path must match also with this pattern from the root of the project (like if pattern is [basePattern]/** /[pattern]).
* This option is useful when using the option mode with file or folder values, but capturing fragments from the rest of the full path is also needed
**/
basePattern?: string;
/**
* Mode to interpret the pattern. Can be "folder" (default), "file", or "full".
* - "folder": Default value. the element type will be assigned to the first file's parent folder matching the pattern.
* In the practice, it is like adding ** /* to the given pattern, but the plugin makes it by itself because it needs to know exactly which parent folder has to be considered the element.
* - "file": The given pattern will not be modified, but the plugin will still try to match the last part of the path.
* So, a pattern like *.model.js would match with paths src/foo.model.js, src/modules/foo/foo.model.js, src/modules/foo/models/foo.model.js, etc.
* - "full": The given pattern will only match with patterns matching the full path.
* This means that you will have to provide patterns matching from the base project path.
* So, in order to match src/modules/foo/foo.model.js you'll have to provide patterns like ** /*.model.js, ** /* /*.model.js, src/* /* /*.model.js, etc. (the chosen pattern will depend on what do you want to capture from the path)
*/
mode?: ElementDescriptorMode;
/**
* It allows to capture values of some fragments in the matching path to use them later in the rules configuration.
* Must be an array of strings representing the names of the capture groups in the pattern.
* The number of capture names must be equal to the number of capturing groups in the pattern.
* For example, if the pattern is "src/modules/(* *)/(* *).service.js" the capture could be ["module", "service"].
* Then, in the rules configuration, you could use ["service", { module: "auth" }] to match only services from the auth module.
*/
capture?: string[];
/**
* Like capture, but for the basePattern.
* This allows to capture values from the left side of the path, which is useful when using the basePattern option.
* The captured values will be merged with the ones from the capture option.
*/
baseCapture?: string[];
};
/**
* Descriptors of the elements (or layers) in the project.
* Defines the types of elements, their patterns, and optional settings like mode and capture groups for each one.
*/
export type ElementDescriptors = ElementDescriptor[];
/**
* Settings for the eslint-plugin-boundaries plugin.
*/
export type Settings = {
/**
* Element descriptors to define the different elements (or layers) in your project.
* Each element descriptor includes a type, a pattern to match files, and optional settings like mode and capture groups.
*/
[SETTINGS_KEYS_MAP.ELEMENTS]?: ElementDescriptors;
/**
* List of glob patterns to ignore when analyzing dependencies.
* Files matching these patterns will be excluded from the plugin analysis.
*/
[SETTINGS_KEYS_MAP.IGNORE]?: IgnoreSetting;
/**
* List of glob patterns to include when analyzing dependencies.
* If specified, only files matching these patterns will be included in the plugin analysis.
*/
[SETTINGS_KEYS_MAP.INCLUDE]?: IncludeSetting;
/**
* Root path of the project. This is used to resolve relative paths in element patterns.
* Can also be set via the ESLINT_PLUGIN_BOUNDARIES_ROOT_PATH environment variable.
*/
[SETTINGS_KEYS_MAP.ROOT_PATH]?: RootPathSetting;
/**
* Specifies which dependency nodes (import types) to consider when analyzing dependencies.
* Each key corresponds to a type of dependency node (e.g., import, require, dynamic-import, export) and maps to an array of selectors defining how to identify those nodes in the AST.
* If not specified, only 'import' nodes will be considered by default.
*/
[SETTINGS_KEYS_MAP.DEPENDENCY_NODES]?: DependencyNodeKey[];
/**
* Additional custom dependency node selectors to consider when analyzing dependencies.
* Each entry defines a selector and its kind (either 'type' or 'value').
* This allows for extending the default dependency nodes with project-specific patterns.
*/
[SETTINGS_KEYS_MAP.ADDITIONAL_DEPENDENCY_NODES]?: DependencyNodeSelector[];
/** @deprecated Use "boundaries/elements" setting instead */
[SETTINGS_KEYS_MAP.TYPES]?: ElementDescriptors;
/** @deprecated Use "import/resolver" setting instead */
[SETTINGS_KEYS_MAP.ALIAS]?: AliasSetting;
};