eslint-plugin-boundaries 5.0.2 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +184 -19
  2. package/dist/configs/Config.types.d.ts +41 -0
  3. package/dist/configs/Config.types.js +2 -0
  4. package/dist/configs/config.d.ts +40 -0
  5. package/dist/configs/config.js +116 -0
  6. package/dist/configs/recommended.d.ts +10 -0
  7. package/dist/configs/recommended.js +36 -0
  8. package/dist/configs/strict.d.ts +8 -0
  9. package/dist/configs/strict.js +26 -0
  10. package/dist/constants/DependencyInfo.types.d.ts +9 -0
  11. package/dist/constants/DependencyInfo.types.js +2 -0
  12. package/dist/constants/ElementsInfo.types.d.ts +24 -0
  13. package/dist/constants/ElementsInfo.types.js +2 -0
  14. package/dist/constants/Options.types.d.ts +180 -0
  15. package/dist/constants/Options.types.js +23 -0
  16. package/dist/constants/plugin.d.ts +7 -0
  17. package/dist/constants/plugin.js +10 -0
  18. package/dist/constants/rules.d.ts +67 -0
  19. package/dist/constants/rules.js +70 -0
  20. package/dist/constants/settings.d.ts +278 -0
  21. package/dist/constants/settings.js +186 -0
  22. package/dist/core/cache.d.ts +22 -0
  23. package/dist/core/cache.js +54 -0
  24. package/dist/core/dependencyInfo.d.ts +4 -0
  25. package/dist/core/dependencyInfo.js +73 -0
  26. package/dist/core/elementsInfo.d.ts +4 -0
  27. package/dist/core/elementsInfo.js +271 -0
  28. package/dist/helpers/Helpers.types.d.ts +5 -0
  29. package/dist/helpers/Helpers.types.js +2 -0
  30. package/dist/helpers/Rules.types.d.ts +10 -0
  31. package/dist/helpers/Rules.types.js +2 -0
  32. package/dist/helpers/debug.d.ts +4 -0
  33. package/dist/helpers/debug.js +44 -0
  34. package/dist/helpers/messages.d.ts +13 -0
  35. package/dist/helpers/messages.js +147 -0
  36. package/dist/helpers/rules.d.ts +37 -0
  37. package/dist/helpers/rules.js +206 -0
  38. package/dist/helpers/settings.d.ts +7 -0
  39. package/dist/helpers/settings.js +94 -0
  40. package/dist/helpers/utils.d.ts +10 -0
  41. package/dist/helpers/utils.js +49 -0
  42. package/dist/helpers/validations.d.ts +131 -0
  43. package/dist/helpers/validations.js +241 -0
  44. package/dist/index.d.ts +8 -0
  45. package/dist/index.js +76 -0
  46. package/dist/rules/element-types.d.ts +2 -0
  47. package/dist/rules/element-types.js +51 -0
  48. package/dist/rules/entry-point.d.ts +2 -0
  49. package/dist/rules/entry-point.js +63 -0
  50. package/dist/rules/external.d.ts +3 -0
  51. package/dist/rules/external.js +169 -0
  52. package/dist/rules/no-ignored.d.ts +2 -0
  53. package/dist/rules/no-ignored.js +21 -0
  54. package/dist/rules/no-private.d.ts +2 -0
  55. package/dist/rules/no-private.js +49 -0
  56. package/dist/rules/no-unknown-files.d.ts +3 -0
  57. package/dist/rules/no-unknown-files.js +27 -0
  58. package/dist/rules/no-unknown.d.ts +2 -0
  59. package/dist/rules/no-unknown.js +21 -0
  60. package/dist/rules-factories/DependencyRule.types.d.ts +19 -0
  61. package/dist/rules-factories/DependencyRule.types.js +2 -0
  62. package/dist/rules-factories/dependency-rule.d.ts +5 -0
  63. package/dist/rules-factories/dependency-rule.js +55 -0
  64. package/dist/types/Config.types.d.ts +2 -0
  65. package/dist/types/Config.types.js +20 -0
  66. package/dist/types/Rules.types.d.ts +5 -0
  67. package/dist/types/Rules.types.js +11 -0
  68. package/dist/types/Settings.types.d.ts +2 -0
  69. package/dist/types/Settings.types.js +12 -0
  70. package/dist/types/index.d.ts +3 -0
  71. package/dist/types/index.js +19 -0
  72. package/package.json +46 -7
  73. package/index.js +0 -1
  74. package/resolver-legacy-alias/index.js +0 -32
  75. package/src/configs/recommended.js +0 -31
  76. package/src/configs/strict.js +0 -17
  77. package/src/constants/plugin.js +0 -7
  78. package/src/constants/rules.js +0 -9
  79. package/src/constants/settings.js +0 -90
  80. package/src/core/cache.js +0 -57
  81. package/src/core/dependencyInfo.js +0 -88
  82. package/src/core/elementsInfo.js +0 -307
  83. package/src/helpers/debug.js +0 -46
  84. package/src/helpers/messages.js +0 -199
  85. package/src/helpers/rules.js +0 -276
  86. package/src/helpers/settings.js +0 -65
  87. package/src/helpers/utils.js +0 -51
  88. package/src/helpers/validations.js +0 -274
  89. package/src/index.js +0 -30
  90. package/src/rules/element-types.js +0 -74
  91. package/src/rules/entry-point.js +0 -88
  92. package/src/rules/external.js +0 -222
  93. package/src/rules/no-ignored.js +0 -21
  94. package/src/rules/no-private.js +0 -53
  95. package/src/rules/no-unknown-files.js +0 -26
  96. package/src/rules/no-unknown.js +0 -21
  97. package/src/rules-factories/dependency-rule.js +0 -62
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build status][build-image]][build-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Quality Gate][quality-gate-image]][quality-gate-url]
1
+ [![Build status][build-image]][build-url] [![Coverage Status][coveralls-image]][coveralls-url] <!-- [![Quality Gate][quality-gate-image]][quality-gate-url] -->
2
2
 
3
3
  [![Renovate](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com) [![Last commit][last-commit-image]][last-commit-url] [![Last release][release-image]][release-url]
4
4
 
@@ -28,13 +28,15 @@ By default, __the plugin works by checking `import` statements, but it is also a
28
28
  - [Configuration](#configuration)
29
29
  * [Global settings](#global-settings)
30
30
  * [Predefined configurations](#predefined-configurations)
31
+ * [createConfig helper](#createconfig-helper)
31
32
  * [Rules configuration](#rules-configuration)
32
33
  * [Main format of rules options](#main-format-of-rules-options)
33
- * [Elements matchers](#elements-matchers)
34
+ * [Elements selectors](#elements-selectors)
34
35
  * [Error messages](#error-messages)
35
36
  * [Advanced example](#advanced-example)
36
37
  - [Resolvers](#resolvers)
37
- - [Usage with TypeScript](#usage-with-typescript)
38
+ - [TypeScript Support](#typescript-support)
39
+ * [Exported Types](#exported-types)
38
40
  - [Migration guides](#migration-guides)
39
41
  - [Debug mode](#debug-mode)
40
42
  - [Acknowledgements](#acknowledgements)
@@ -70,7 +72,7 @@ export default [
70
72
  ];
71
73
  ```
72
74
 
73
- > [!NOTE]
75
+ > [!NOTE]
74
76
  > From version `5.0.0`, this plugin is compatible with eslint v9 and above. It may be also compatible with previous eslint versions, but you might read the [documentation of the `4.2.2` version](https://github.com/javierbrea/eslint-plugin-boundaries/tree/v4.2.2) to know how to configure it properly using the legacy configuration format.
75
77
 
76
78
  ## Overview
@@ -173,7 +175,7 @@ Read the [docs of the `boundaries/entry-point` rule](docs/rules/entry-point.md)
173
175
 
174
176
  #### __`boundaries/elements`__
175
177
 
176
- Define patterns to recognize each file in the project as one of this element types. All rules need this setting to be configured properly to work. The plugin tries to identify each file being analyzed or `import` statement in rules as one of the defined element types. The assigned element type will be that with the first matching pattern, in the same order that elements are defined in the array, so you __should sort them from the most accurate patterns to the less ones__. Properties of each `element`:
178
+ Define element descriptors to recognize each file in the project as one of this element types. All rules need this setting to be configured properly to work. The plugin tries to identify each file being analyzed or `import` statement in rules as one of the defined element types. The assigned element type will be that with the first matching pattern, in the same order that elements are defined in the array, so you __should sort them from the most accurate patterns to the less ones__. Properties of each `element`:
177
179
 
178
180
  * __`type`__: `<string>` Element type to be assigned to files or imports matching the `pattern`. This type will be used afterwards in the rules configuration.
179
181
  * __`pattern`__: `<string>|<array>` [`micromatch` pattern](https://github.com/micromatch/micromatch). __By default the plugin will try to match this pattern progressively starting from the right side of each file path.__ This means that you don't have to define patterns matching from the base project path, but only the last part of the path that you want to be matched. This is made because the plugin supports elements being children of other elements, and otherwise it could wrongly recognize children elements as a part of the parent one. <br/>For example, given a path `src/helpers/awesome-helper/index.js`, it will try to assign the element to a pattern matching `index.js`, then `awesome-helper/index.js`, then `helpers/awesome-helper/index.js`, etc. Once a pattern matches, it assign the correspondent element type, and continues searching for parents elements with the same logic until the full path has been analyzed. __This behavior can be disabled setting the `mode` option to `full`__, then the provided pattern will try to match the full path.
@@ -328,26 +330,107 @@ We recommend to use this setting if you are applying the plugin to an already ex
328
330
 
329
331
  ```js
330
332
  import boundaries from "eslint-plugin-boundaries";
333
+ import { recommended } from "eslint-plugin-boundaries/config";
331
334
 
332
335
  export default [{
336
+ plugins: {
337
+ boundaries,
338
+ },
339
+ settings: {
340
+ ...recommended.settings,
341
+ // Define your own element descriptors here
342
+ "boundaries/elements": [
343
+ {
344
+ type: "helpers",
345
+ pattern: "helpers/*"
346
+ },
347
+ ]
348
+ },
333
349
  rules: {
334
- ...boundaries.configs.recommended.rules,
350
+ ...recommended.rules,
351
+ "boundaries/element-types": [2, {
352
+ // Define your own options here
353
+ }],
335
354
  }
336
355
  }]
337
356
  ```
338
357
 
339
358
  #### Strict
340
359
 
341
- All rules are enabled, so all elements in the project will be compliant with your architecture boundaries. 😃
360
+ All rules are enabled by default, so all elements in the project will be compliant with your architecture boundaries. 😃
361
+
362
+ Follow the same example as in "recommended" configuration, but importing `strict` instead of `recommended`.
342
363
 
343
364
  ```js
344
- import boundaries from "eslint-plugin-boundaries";
365
+ import { strict } from "eslint-plugin-boundaries/config";
366
+ ```
345
367
 
346
- export default [{
368
+ ### createConfig helper
369
+
370
+ A `createConfig` helper is also available for making configurations easier.
371
+
372
+ It enforces valid types for settings and rules and automatically:
373
+
374
+ * Adds the plugin to the plugins property
375
+ * Includes JavaScript and TypeScript file patterns in the files property
376
+ * Validates that all provided settings and rules belong to the plugin
377
+
378
+ ```js
379
+ import { createConfig, recommended } from "eslint-plugin-boundaries/config";
380
+
381
+ const config = createConfig({
382
+ settings: {
383
+ ...recommended.settings,
384
+ "boundaries/elements": [],
385
+ "boundaries/ignore": ["**/ignored/**/*.js"],
386
+ },
347
387
  rules: {
348
- ...boundaries.configs.strict.rules,
388
+ ...recommended.rules,
389
+ "boundaries/element-types": ["error", { default: "disallow" }],
349
390
  }
350
- }]
391
+ });
392
+
393
+ export default [config];
394
+ ```
395
+
396
+ You can also rename the plugin by passing a second argument. The helper will rename all rules from `boundaries/` prefix to the provided one, so recommended or strict configs can be used as a base without issues.
397
+
398
+ ```js
399
+ import { createConfig, recommended } from "eslint-plugin-boundaries/config";
400
+
401
+ const config = createConfig({
402
+ settings: {
403
+ ...recommended.settings,
404
+ "boundaries/elements": [], // Note the original prefix here
405
+ },
406
+ rules: {
407
+ ...recommended.rules,
408
+ "custom-boundaries/element-types": ["error", { default: "disallow" }], // Note the renamed prefix here
409
+ "boundaries/entry-point": 0, // The original prefix still works too
410
+ // @ts-expect-error Any other prefix raises an error
411
+ "foo/entry-point": 2, // This rule does not match the new plugin name nor the original one
412
+ }
413
+ }, "custom-boundaries");
414
+
415
+ export default [config];
416
+ ```
417
+
418
+ > [!WARNING]
419
+ > Note that the settings still must use the `boundaries/` prefix — ESLint doesn’t namespace settings by plugin name.
420
+
421
+ The plugin also exports constants and type guard methods for settings keys, rule names, and other configuration-related values. You can use them when defining your configuration. For example:
422
+
423
+ ```ts
424
+ import {
425
+ RULE_NAMES_MAP,
426
+ isRuleName,
427
+ SETTINGS_KEYS_MAP,
428
+ isSettingsKey,
429
+ ELEMENT_DESCRIPTOR_MODES_MAP,
430
+ isElementDescriptorMode,
431
+ RULE_POLICIES_MAP,
432
+ isRulePolicy,
433
+ } from "eslint-plugin-boundaries/config";
351
434
  ```
352
435
 
353
436
  ### Rules configuration
@@ -397,26 +480,26 @@ Remember that:
397
480
 
398
481
  ##### Rules options properties
399
482
 
400
- * __`from/target`__: `<element matchers>` Depending of the rule to which the options are for, the rule will be applied only if the file being analyzed matches with this element matcher (`from`), or the dependency being imported matches with this element matcher (`target`).
401
- * __`disallow/allow`__: `<value matchers>` If the plugin rule target matches with this, then the result of the rule will be "disallow/allow". Each rule will require a type of value here depending of what it is checking. In the case of the `element-types` rule, for example, another `<element matcher>` has to be provided in order to check the type of the local dependency.
483
+ * __`from/target`__: `<element selectors>` Depending of the rule to which the options are for, the rule will be applied only if the file being analyzed matches with this element selector (`from`), or the dependency being imported matches with this element selector (`target`).
484
+ * __`disallow/allow`__: `<selectors>` If the plugin rule target matches with this, then the result of the rule will be "disallow/allow". Each rule will require a type of value here depending of what it is checking. In the case of the `element-types` rule, for example, another `<element selector>` has to be provided in order to check the type of the local dependency.
402
485
  * __`importKind`__: `<string>` _Optional_. It is useful only when using TypeScript, because it allows to define if the rule applies when the dependency is being imported as a value or as a type. It can be also defined as an array of strings, or a micromatch pattern. Note that possible values to match with are `"value"`, `"type"` or `"typeof"`. For example, you could define that "components" can import "helpers" as a value, but not as a type. So, `import { helper } from "helpers/helper-a"` would be allowed, but `import type { Helper } from "helpers/helper-a"` would be disallowed.
403
486
  * __`message`__: `<string>` Optional. If the rule results in an error, the plugin will return this message instead of the default one. Read [error messages](#error-messages) for further info.
404
487
 
405
- > Tip: Properties `from/target` and `disallow/allow` can receive a single matcher, or an array of matchers.
488
+ > Tip: Properties `from/target` and `disallow/allow` can receive a single selector, or an array of selectors.
406
489
 
407
- ##### Elements matchers
490
+ ##### Elements selectors
408
491
 
409
- Elements matchers used in the rules options can have the next formats:
492
+ Elements selectors used in the rules options can have the next formats:
410
493
 
411
494
  * __`<string>`__: Will return `true` when the element type matches with this [`micromatch` pattern](https://github.com/micromatch/micromatch). It [supports templating](#templating) for using values from captured values.
412
- * __`[<string>, <capturedValuesObject>]`__: Will return `true` whe when the element type matches with the first element in the array, and all of the captured values also match. <br/>The `<capturedValuesObject>` has to be an object containing `capture` keys from the [`boundaries/element-types` setting](#boundarieselement-types) of the element as keys, and [`micromatch` patterns](https://github.com/micromatch/micromatch) as values. (values also support [templating](#templating)) <br/>For example, for an element of type "helpers" with settings as `{ type: "helpers", pattern": "helpers/*/*.js", "capture": ["category", "elementName"]}`, you could write element matchers as:
495
+ * __`[<string>, <capturedValuesObject>]`__: Will return `true` whe when the element type matches with the first element in the array, and all of the captured values also match. <br/>The `<capturedValuesObject>` has to be an object containing `capture` keys from the [`boundaries/element-types` setting](#boundarieselement-types) of the element as keys, and [`micromatch` patterns](https://github.com/micromatch/micromatch) as values. (values also support [templating](#templating)) <br/>For example, for an element of type "helpers" with settings as `{ type: "helpers", pattern": "helpers/*/*.js", "capture": ["category", "elementName"]}`, you could write element selectors as:
413
496
  * `["helpers", { category: "data", elementName: "parsers"}]`: Will only match with helpers with category "data" and elementName "parsers" (`helpers/data/parsers.js`).
414
497
  * `["helpers", { category: "data" }]`: Will match with all helpers with category "data" (`helpers/data/*.js`)
415
498
  * `["data-${from.elementName}", { category: "${from.category}" }]`: Will only match with helpers with the type equals to the `elementName` of the file importing plus a `data-` prefix, and the category being equal to the `category` of the file importing the dependency.
416
499
 
417
500
  ##### Templating
418
501
 
419
- When defining [__Element matchers__](#elements-matchers), the values captured both from the element importing ("from") and from the imported element ("target") are available to be replaced. They are replaced both in the main string and in the `<capturedValuesObject>`.
502
+ When defining [__Element selectors__](#elements-selectors), the values captured both from the element importing ("from") and from the imported element ("target") are available to be replaced. They are replaced both in the main string and in the `<capturedValuesObject>`.
420
503
 
421
504
  Templates must be defined with the format `${from.CAPTURED_PROPERTY}` or `${target.CAPTURED_PROPERTY}`.
422
505
 
@@ -541,7 +624,7 @@ export default [{
541
624
  }]
542
625
  ```
543
626
 
544
- ## Usage with TypeScript
627
+ ## TypeScript Support
545
628
 
546
629
  This plugin can be used also in [TypeScript](https://www.typescriptlang.org/) projects using `@typescript-eslint/eslint-plugin`. Follow next steps to configure it:
547
630
 
@@ -580,6 +663,88 @@ export default [{
580
663
 
581
664
  In case you face any issue configuring it, you can also [use this repository as a guide](https://github.com/javierbrea/epb-ts-example). It contains a fully working and tested example.
582
665
 
666
+ ### Exported Types
667
+
668
+ The main type exported by the plugin is `Config`, which represents a fully typed [Flat Config](https://eslint.org/docs/latest/use/core-concepts/glossary#flat-config).
669
+
670
+ ```ts
671
+ import type { Config } from "eslint-plugin-boundaries";
672
+
673
+ const config: Config = {
674
+ plugins: {
675
+ boundaries,
676
+ },
677
+ settings: {
678
+ "boundaries/elements": [],
679
+ "boundaries/ignore": ["**/ignored/**/*.js"],
680
+ },
681
+ rules: {
682
+ "boundaries/element-types": [
683
+ "error",
684
+ { default: "disallow", rules: [] },
685
+ ],
686
+ },
687
+ };
688
+ ```
689
+
690
+ Types also support renaming the plugin when loading it in the `plugins` property, so rules and must be defined using the new name:
691
+
692
+ ```ts
693
+ import type { Config } from "eslint-plugin-boundaries";
694
+
695
+ const config: Config<"custom-boundaries"> = {
696
+ plugins: {
697
+ "custom-boundaries": boundaries, // NOTE the renamed prefix here
698
+ },
699
+ settings: {
700
+ "boundaries/elements": [],
701
+ "boundaries/ignore": ["**/ignored/**/*.js"],
702
+ },
703
+ rules: {
704
+ "custom-boundaries/element-types": 2, // NOTE the renamed prefix here
705
+ },
706
+ };
707
+ ```
708
+
709
+ > [!WARNING]
710
+ > Note that the settings still use the `boundaries/` prefix — ESLint doesn’t namespace settings by plugin name.
711
+
712
+ In addition, individual subtypes are available for each part of the configuration, such as:
713
+
714
+ * `Settings`, `Rules`, `ElementDescriptor`, `ElementTypesRule`, `ElementTypesRuleOptions`, `ElementSelector`, `IgnoreSetting`, etc.
715
+
716
+ This allows you to import only what you need and get full autocompletion and type safety.
717
+
718
+ ```ts
719
+ import type {
720
+ Config,
721
+ Settings,
722
+ Rules,
723
+ ElementDescriptor,
724
+ ElementTypesRuleOptions,
725
+ } from "eslint-plugin-boundaries";
726
+
727
+ const moduleDescriptor: ElementDescriptor = {
728
+ type: "module",
729
+ pattern: "src/modules/*",
730
+ capture: ["module"],
731
+ };
732
+
733
+ const settings: Settings = {
734
+ "boundaries/elements": [moduleDescriptor],
735
+ };
736
+
737
+ const rules: Rules = {
738
+ "boundaries/element-types": ["error", { default: "disallow", rules: [] }],
739
+ };
740
+
741
+ const config: Config = {
742
+ files: ["**/*.js", "**/*.ts"],
743
+ settings,
744
+ rules,
745
+ };
746
+ ```
747
+
583
748
  ## Migration guides
584
749
 
585
750
  ### Migrating from v4.x
@@ -0,0 +1,41 @@
1
+ import type { ESLint, Linter, Rule } from "eslint";
2
+ import type { ElementTypesRuleOptions, EntryPointRuleOptions, ExternalRuleOptions, NoPrivateOptions } from "../constants/Options.types";
3
+ import type { PLUGIN_NAME } from "../constants/plugin";
4
+ import type { RuleShortName, ELEMENT_TYPES, ENTRY_POINT, EXTERNAL, NO_IGNORED, NO_PRIVATE, NO_UNKNOWN, NO_UNKNOWN_FILES } from "../constants/rules";
5
+ import type { Settings } from "../constants/settings";
6
+ /**
7
+ * Eslint boundaries plugin rules.
8
+ * By default, rule names are prefixed with "boundaries/", but it can be customized via the `PluginName` generic parameter.
9
+ *
10
+ * @template PluginName - The name of the plugin, defaults to "boundaries". It defines the prefix for the rule names.
11
+ */
12
+ export type Rules<PluginName extends string = typeof PLUGIN_NAME> = {
13
+ [K in `${PluginName}/${typeof ELEMENT_TYPES | typeof ENTRY_POINT | typeof EXTERNAL | typeof NO_IGNORED | typeof NO_PRIVATE | typeof NO_UNKNOWN_FILES | typeof NO_UNKNOWN}`]?: K extends `${PluginName}/${typeof ELEMENT_TYPES}` ? Linter.RuleEntry<ElementTypesRuleOptions[]> : K extends `${PluginName}/${typeof ENTRY_POINT}` ? Linter.RuleEntry<EntryPointRuleOptions[]> : K extends `${PluginName}/${typeof EXTERNAL}` ? Linter.RuleEntry<ExternalRuleOptions[]> : K extends `${PluginName}/${typeof NO_PRIVATE}` ? Linter.RuleEntry<NoPrivateOptions[]> : Linter.RuleEntry<never>;
14
+ };
15
+ /**
16
+ * ESLint configuration with optional settings and rules specific to the boundaries plugin.
17
+ */
18
+ export interface Config<PluginName extends string = typeof PLUGIN_NAME> extends Linter.Config {
19
+ /**
20
+ * Optional settings specific to the boundaries plugin.
21
+ */
22
+ settings?: Settings;
23
+ /**
24
+ * Optional rules specific to the boundaries plugin.
25
+ */
26
+ rules?: Rules<PluginName>;
27
+ }
28
+ /**
29
+ * ESLint plugin interface for the boundaries plugin, including metadata, rules, and configurations.
30
+ */
31
+ export interface PluginBoundaries extends ESLint.Plugin {
32
+ meta: {
33
+ name: string;
34
+ version: string;
35
+ };
36
+ rules: Record<RuleShortName, Rule.RuleModule>;
37
+ configs: {
38
+ recommended: Config;
39
+ strict: Config;
40
+ };
41
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,40 @@
1
+ import type { Linter } from "eslint";
2
+ import { PLUGIN_NAME } from "../constants/plugin";
3
+ import type { PluginBoundaries, Config } from "./Config.types";
4
+ export * from "../types";
5
+ type PluginFullConfig<PluginName extends string = typeof PLUGIN_NAME> = {
6
+ plugins: Record<PluginName, PluginBoundaries>;
7
+ files: Linter.Config["files"];
8
+ } & Omit<Config<PluginName>, "plugins">;
9
+ /**
10
+ * Returns an ESLint config object with the boundaries plugin registered, providing default JS and TS file patterns
11
+ * and enforcing valid types for settings and rules. Supports renaming the plugin. Rules can be prefixed with either
12
+ * the original plugin name or the provided plugin name.
13
+ *
14
+ * @param config - ESLint config object without the plugins field.
15
+ * @param name - The name of the plugin to register. Defaults to "boundaries".
16
+ * @returns {Linter.Config} The ESLint config object with the boundaries plugin registered and the provided config merged in.
17
+ * @throws {Error} If settings or rules are not from eslint-plugin-boundaries.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { createConfig, recommended } from "eslint-plugin-boundaries/config";
22
+ *
23
+ * const config = createConfig({
24
+ * settings: {
25
+ * ...recommended.settings,
26
+ * "boundaries/elements": [],
27
+ * "boundaries/ignore": ["ignored/*.js"],
28
+ * },
29
+ * rules: {
30
+ * ...recommended.rules,
31
+ * "boundaries/element-types": ["error", { default: "disallow" }],
32
+ * }
33
+ * });
34
+ *
35
+ * export default [config];
36
+ * ```
37
+ */
38
+ export declare function createConfig<PluginName extends string = typeof PLUGIN_NAME>(config: Omit<Config<PluginName> | Config, "plugins">, name?: PluginName): PluginFullConfig<PluginName>;
39
+ export declare const recommended: Config<"boundaries">;
40
+ export declare const strict: Config<"boundaries">;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.strict = exports.recommended = void 0;
21
+ exports.createConfig = createConfig;
22
+ const plugin_1 = require("../constants/plugin");
23
+ const rules_1 = require("../constants/rules");
24
+ const settings_1 = require("../constants/settings");
25
+ const index_1 = __importDefault(require("../index"));
26
+ const recommended_1 = __importDefault(require("./recommended"));
27
+ const strict_1 = __importDefault(require("./strict"));
28
+ __exportStar(require("../types"), exports);
29
+ function renamePluginRules(rules, pluginName = plugin_1.PLUGIN_NAME) {
30
+ if (!rules) {
31
+ return {};
32
+ }
33
+ const allowedPrefixes = [plugin_1.PLUGIN_NAME, pluginName];
34
+ // Return the same rules objects, but converting plugin default rule keys with provided plugin name
35
+ return Object.entries(rules).reduce((acc, [key, value]) => {
36
+ if (!key.includes("/")) {
37
+ throw new Error(`Invalid rule key "${key}". When using createConfig, all rules must belong to eslint-plugin-boundaries. You can prefix them with the original plugin name "${plugin_1.PLUGIN_NAME}/", or with the provided plugin name "${pluginName}/".`);
38
+ }
39
+ const splittedRuleKey = key.split("/");
40
+ const rulePrefix = splittedRuleKey[0];
41
+ const ruleName = splittedRuleKey[1];
42
+ if (!allowedPrefixes.includes(rulePrefix)) {
43
+ throw new Error(`Invalid rule key "${key}". When using createConfig, all rules must belong to eslint-plugin-boundaries. You can prefix them with the original plugin name "${plugin_1.PLUGIN_NAME}/", or with the provided plugin name "${pluginName}/".`);
44
+ }
45
+ if (!(0, rules_1.isRuleShortName)(ruleName)) {
46
+ throw new Error(`Invalid rule name "${ruleName}". When using createConfig, all rules must belong to eslint-plugin-boundaries.`);
47
+ }
48
+ const newKey = rulePrefix === plugin_1.PLUGIN_NAME
49
+ ? `${pluginName}/${key.slice(`${plugin_1.PLUGIN_NAME}/`.length)}`
50
+ : key;
51
+ acc[newKey] = value;
52
+ return acc;
53
+ }, {});
54
+ }
55
+ /**
56
+ * Returns an ESLint config object with the boundaries plugin registered, providing default JS and TS file patterns
57
+ * and enforcing valid types for settings and rules. Supports renaming the plugin. Rules can be prefixed with either
58
+ * the original plugin name or the provided plugin name.
59
+ *
60
+ * @param config - ESLint config object without the plugins field.
61
+ * @param name - The name of the plugin to register. Defaults to "boundaries".
62
+ * @returns {Linter.Config} The ESLint config object with the boundaries plugin registered and the provided config merged in.
63
+ * @throws {Error} If settings or rules are not from eslint-plugin-boundaries.
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * import { createConfig, recommended } from "eslint-plugin-boundaries/config";
68
+ *
69
+ * const config = createConfig({
70
+ * settings: {
71
+ * ...recommended.settings,
72
+ * "boundaries/elements": [],
73
+ * "boundaries/ignore": ["ignored/*.js"],
74
+ * },
75
+ * rules: {
76
+ * ...recommended.rules,
77
+ * "boundaries/element-types": ["error", { default: "disallow" }],
78
+ * }
79
+ * });
80
+ *
81
+ * export default [config];
82
+ * ```
83
+ */
84
+ function createConfig(config, name = plugin_1.PLUGIN_NAME) {
85
+ const pluginsRegistration = {
86
+ [name]: index_1.default,
87
+ };
88
+ if (Object.prototype.hasOwnProperty.call(config, "plugins")) {
89
+ throw new Error("The 'plugins' field is managed by createConfig and should not be provided in the config argument.");
90
+ }
91
+ if (Object.prototype.hasOwnProperty.call(config, "settings")) {
92
+ const settings = config.settings;
93
+ if (settings) {
94
+ for (const key of Object.keys(settings)) {
95
+ if (!(0, settings_1.isSettingsKey)(key)) {
96
+ throw new Error(`Invalid settings key "${key}". When using createConfig, all settings keys must belong to eslint-plugin-boundaries.`);
97
+ }
98
+ }
99
+ }
100
+ }
101
+ return {
102
+ files: [
103
+ "**/*.js",
104
+ "**/*.jsx",
105
+ "**/*.ts",
106
+ "**/*.tsx",
107
+ "**/*.mjs",
108
+ "**/*.cjs",
109
+ ],
110
+ ...config,
111
+ plugins: pluginsRegistration,
112
+ rules: renamePluginRules(config.rules, name),
113
+ };
114
+ }
115
+ exports.recommended = recommended_1.default;
116
+ exports.strict = strict_1.default;
@@ -0,0 +1,10 @@
1
+ import type { Config } from "./Config.types";
2
+ /**
3
+ * Recommended configuration for eslint-plugin-boundaries.
4
+ *
5
+ * It is recommended for applying the plugin to an already existing project.
6
+ * Rules `boundaries/no-unknown`, `boundaries/no-unknown-files` and `boundaries/no-ignored` are disabled,
7
+ * so it allows to have parts of the project non-compliant with defined rules, allowing to refactor the code progressively.
8
+ */
9
+ declare const config: Config;
10
+ export default config;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const settings_1 = require("../constants/settings");
4
+ const { ELEMENTS,
5
+ // rules
6
+ RULE_ELEMENT_TYPES, RULE_ENTRY_POINT, RULE_EXTERNAL, RULE_NO_IGNORED, RULE_NO_PRIVATE, RULE_NO_UNKNOWN_FILES, RULE_NO_UNKNOWN, } = settings_1.SETTINGS;
7
+ // TODO In next major version: Export also files, plugin, etc.
8
+ /**
9
+ * Recommended configuration for eslint-plugin-boundaries.
10
+ *
11
+ * It is recommended for applying the plugin to an already existing project.
12
+ * Rules `boundaries/no-unknown`, `boundaries/no-unknown-files` and `boundaries/no-ignored` are disabled,
13
+ * so it allows to have parts of the project non-compliant with defined rules, allowing to refactor the code progressively.
14
+ */
15
+ const config = {
16
+ rules: {
17
+ [RULE_ELEMENT_TYPES]: [2],
18
+ [RULE_ENTRY_POINT]: [2],
19
+ [RULE_EXTERNAL]: [2],
20
+ [RULE_NO_IGNORED]: 0,
21
+ [RULE_NO_PRIVATE]: [
22
+ 2,
23
+ {
24
+ allowUncles: true,
25
+ },
26
+ ],
27
+ [RULE_NO_UNKNOWN_FILES]: 0,
28
+ [RULE_NO_UNKNOWN]: 0,
29
+ },
30
+ settings: {
31
+ [ELEMENTS]: [],
32
+ },
33
+ };
34
+ exports.default = config;
35
+ // For CommonJS compatibility
36
+ module.exports = config;
@@ -0,0 +1,8 @@
1
+ import type { Config } from "./Config.types";
2
+ /**
3
+ * Strict configuration for eslint-plugin-boundaries.
4
+ *
5
+ * It enables all rules, enforcing full compliance with defined boundaries. Unknown files and importing ignored files are not allowed.
6
+ */
7
+ declare const config: Config;
8
+ export default config;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const settings_1 = require("../constants/settings");
7
+ const recommended_1 = __importDefault(require("./recommended"));
8
+ const { RULE_NO_IGNORED, RULE_NO_UNKNOWN_FILES, RULE_NO_UNKNOWN } = settings_1.SETTINGS;
9
+ // TODO In next major version: Export also files, plugin, etc.
10
+ /**
11
+ * Strict configuration for eslint-plugin-boundaries.
12
+ *
13
+ * It enables all rules, enforcing full compliance with defined boundaries. Unknown files and importing ignored files are not allowed.
14
+ */
15
+ const config = {
16
+ ...recommended_1.default,
17
+ rules: {
18
+ ...recommended_1.default.rules,
19
+ [RULE_NO_IGNORED]: 2,
20
+ [RULE_NO_UNKNOWN_FILES]: 2,
21
+ [RULE_NO_UNKNOWN]: 2,
22
+ },
23
+ };
24
+ exports.default = config;
25
+ // For CommonJS compatibility
26
+ module.exports = config;
@@ -0,0 +1,9 @@
1
+ import type { ImportInfo } from "./ElementsInfo.types";
2
+ import type { ImportKind } from "./settings";
3
+ export type ElementsRelationship = "internal" | "child" | "descendant" | "brother" | "parent" | "uncle" | "ancestor" | null;
4
+ export type DependencyInfo = ImportInfo & {
5
+ importKind: ImportKind;
6
+ relationship: ElementsRelationship;
7
+ isInternal: boolean;
8
+ baseModule: string | null;
9
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,24 @@
1
+ import type { CapturedValues } from "./Options.types";
2
+ export type PathCapturedValues = string[];
3
+ export type ElementInfo = {
4
+ elementPath: string;
5
+ type: string | null;
6
+ parents: Pick<ElementInfo, "elementPath" | "type" | "capture" | "capturedValues">[];
7
+ capture: string[] | null;
8
+ capturedValues: CapturedValues;
9
+ internalPath: string | null;
10
+ };
11
+ export type ImportInfo = {
12
+ source: string;
13
+ path: string;
14
+ isIgnored: boolean;
15
+ isLocal: boolean;
16
+ isBuiltIn: boolean;
17
+ isExternal: boolean;
18
+ baseModule: string | null;
19
+ specifiers?: string[];
20
+ } & ElementInfo;
21
+ export type FileInfo = ElementInfo & {
22
+ path: string;
23
+ isIgnored: boolean;
24
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });