@starci/eslint-canon-be 1.2.0 → 1.2.2
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.
- package/CHANGELOG.md +7 -0
- package/README.md +70 -69
- package/authorization.mjs +106 -106
- package/cdc.mjs +150 -150
- package/comments.mjs +388 -389
- package/cqrs.mjs +302 -303
- package/data-access.mjs +306 -307
- package/e2e-flow.mjs +222 -222
- package/event-delivery.mjs +93 -93
- package/exception-identity.mjs +200 -200
- package/exceptions.mjs +262 -265
- package/index.mjs +107 -107
- package/lib/path.mjs +2 -0
- package/module-layering.mjs +426 -432
- package/naming.mjs +219 -220
- package/observability.mjs +275 -275
- package/package.json +4 -2
- package/testing.mjs +500 -454
- package/transport.mjs +168 -168
- package/type-safety.mjs +510 -380
package/index.mjs
CHANGED
|
@@ -1,107 +1,107 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The back-end plugin: every law's rules, gathered once.
|
|
3
|
-
*
|
|
4
|
-
* A consuming repository imports THIS and nothing below it. Registering rules one by one in the
|
|
5
|
-
* target's own plugin file is how the two lists drift: a law gains a rule here, nobody adds it there,
|
|
6
|
-
* and the rule ships as a document. That is not hypothetical for this axis - the back end kept a
|
|
7
|
-
* hand-written plugin whose names had already diverged from canon's, so `no-nest-logger` and
|
|
8
|
-
* `no-framework-logger` were one law wearing two names and no build could say which had fired.
|
|
9
|
-
*
|
|
10
|
-
* The target's `eslint.config.mjs` stays the authority on what is switched on, at what level and
|
|
11
|
-
* over which globs. That is a different question from what EXISTS, and this file answers only the
|
|
12
|
-
* second.
|
|
13
|
-
*
|
|
14
|
-
* WHAT THIS FILE REFUSES TO DO. It does not rename anything. A rule's published name is part of the
|
|
15
|
-
* law that declares it, because that name is what appears in a build log, in a disable comment and in
|
|
16
|
-
* every conversation about the failure. Aliasing one here to match a target's older spelling would
|
|
17
|
-
* leave two names for one rule and no way to tell which a message came from.
|
|
18
|
-
*/
|
|
19
|
-
import { recommended as authorizationRecommended, rules as authorizationRules } from "./authorization.mjs"
|
|
20
|
-
import { recommended as cdcRecommended, rules as cdcRules } from "./cdc.mjs"
|
|
21
|
-
import { recommended as commentsRecommended, rules as commentsRules } from "./comments.mjs"
|
|
22
|
-
import { recommended as cqrsRecommended, rules as cqrsRules } from "./cqrs.mjs"
|
|
23
|
-
import { recommended as dataAccessRecommended, rules as dataAccessRules } from "./data-access.mjs"
|
|
24
|
-
import { recommended as e2eFlowRecommended, rules as e2eFlowRules } from "./e2e-flow.mjs"
|
|
25
|
-
import { recommended as eventDeliveryRecommended, rules as eventDeliveryRules } from "./event-delivery.mjs"
|
|
26
|
-
import { recommended as exceptionIdentityRecommended, rules as exceptionIdentityRules } from "./exception-identity.mjs"
|
|
27
|
-
import { recommended as exceptionsRecommended, rules as exceptionsRules } from "./exceptions.mjs"
|
|
28
|
-
import { recommended as moduleLayeringRecommended, rules as moduleLayeringRules } from "./module-layering.mjs"
|
|
29
|
-
import { recommended as namingRecommended, rules as namingRules } from "./naming.mjs"
|
|
30
|
-
import { recommended as observabilityRecommended, rules as observabilityRules } from "./observability.mjs"
|
|
31
|
-
import { recommended as testingRecommended, rules as testingRules } from "./testing.mjs"
|
|
32
|
-
import { recommended as transportRecommended, rules as transportRules } from "./transport.mjs"
|
|
33
|
-
import { recommended as typeSafetyRecommended, rules as typeSafetyRules } from "./type-safety.mjs"
|
|
34
|
-
|
|
35
|
-
/** Each law's contribution, kept separate so a duplicate name is detectable rather than silent. */
|
|
36
|
-
const CONTRIBUTIONS = [
|
|
37
|
-
{ law: "authorization", rules: authorizationRules, recommended: authorizationRecommended },
|
|
38
|
-
{ law: "cdc", rules: cdcRules, recommended: cdcRecommended },
|
|
39
|
-
{ law: "comments", rules: commentsRules, recommended: commentsRecommended },
|
|
40
|
-
{ law: "cqrs", rules: cqrsRules, recommended: cqrsRecommended },
|
|
41
|
-
{ law: "data-access", rules: dataAccessRules, recommended: dataAccessRecommended },
|
|
42
|
-
{ law: "e2e-flow", rules: e2eFlowRules, recommended: e2eFlowRecommended },
|
|
43
|
-
{ law: "event-delivery", rules: eventDeliveryRules, recommended: eventDeliveryRecommended },
|
|
44
|
-
{ law: "exception-identity", rules: exceptionIdentityRules, recommended: exceptionIdentityRecommended },
|
|
45
|
-
{ law: "exceptions", rules: exceptionsRules, recommended: exceptionsRecommended },
|
|
46
|
-
{ law: "module-layering", rules: moduleLayeringRules, recommended: moduleLayeringRecommended },
|
|
47
|
-
{ law: "naming", rules: namingRules, recommended: namingRecommended },
|
|
48
|
-
{ law: "observability", rules: observabilityRules, recommended: observabilityRecommended },
|
|
49
|
-
{ law: "testing", rules: testingRules, recommended: testingRecommended },
|
|
50
|
-
{ law: "transport", rules: transportRules, recommended: transportRecommended },
|
|
51
|
-
{ law: "type-safety", rules: typeSafetyRules, recommended: typeSafetyRecommended },
|
|
52
|
-
]
|
|
53
|
-
|
|
54
|
-
/** Every gathered law. */
|
|
55
|
-
export const lawOwners = CONTRIBUTIONS.map((entry) => entry.law)
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Every (law, rule name) pair as DECLARED, before any collapsing.
|
|
59
|
-
*
|
|
60
|
-
* This exists because `ruleOwners` and `rules` below are both built with `Object.fromEntries`, which
|
|
61
|
-
* silently keeps the last writer when two laws declare one name. A test that walks either of them
|
|
62
|
-
* therefore cannot see a collision: the duplicate is already gone by the time it looks, so every
|
|
63
|
-
* name appears exactly once BY CONSTRUCTION and the check passes forever while being blind.
|
|
64
|
-
*
|
|
65
|
-
* That is exactly what happened - three back-end rules were declared by two laws each, one copy was
|
|
66
|
-
* discarded on import, and the guard reported green the whole time. A gate that cannot fail is
|
|
67
|
-
* indistinguishable from no gate, so the raw declarations are published here and the guard walks
|
|
68
|
-
* these instead.
|
|
69
|
-
*/
|
|
70
|
-
export const ruleDeclarations = CONTRIBUTIONS.flatMap((entry) =>
|
|
71
|
-
Object.keys(entry.rules).map((name) => ({ law: entry.law, name })),
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Which law declares each rule.
|
|
76
|
-
*
|
|
77
|
-
* Exported because a failing rule is a question about a LAW, and the shortest path from a build log
|
|
78
|
-
* to the document that explains it is this map. It answers "who owns this name" for a name that
|
|
79
|
-
* SHIPPED; proving no two laws claim one name is `ruleDeclarations`' job, not this map's.
|
|
80
|
-
*/
|
|
81
|
-
export const ruleOwners = Object.fromEntries(
|
|
82
|
-
CONTRIBUTIONS.flatMap((entry) => Object.keys(entry.rules).map((name) => [name, entry.law])),
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
/** Every rule this canon publishes, keyed by its published name. */
|
|
86
|
-
export const rules = Object.fromEntries(
|
|
87
|
-
CONTRIBUTIONS.flatMap((entry) => Object.entries(entry.rules)),
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* The levels this canon asks for, as the plugin's own opinion.
|
|
92
|
-
*
|
|
93
|
-
* Unlike the front end, this axis allows `warn`, and the allowance is the burn-down playbook rather
|
|
94
|
-
* than a softer standard: a rule measured with debt arrives at `warn` with a ledger entry naming the
|
|
95
|
-
* offenders, and flips to `error` the day that entry closes. Switching a rule on over existing
|
|
96
|
-
* offenders is what teaches an author to scroll past it, and a reader who has learned to scroll past
|
|
97
|
-
* one rule reads none of them.
|
|
98
|
-
*/
|
|
99
|
-
export const recommended = Object.fromEntries(
|
|
100
|
-
CONTRIBUTIONS.flatMap((entry) => Object.entries(entry.recommended)),
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
/** The plugin object, shaped the way a flat config expects it. */
|
|
104
|
-
export default {
|
|
105
|
-
meta: { name: "eslint-plugin-starci-be" },
|
|
106
|
-
rules,
|
|
107
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* The back-end plugin: every law's rules, gathered once.
|
|
3
|
+
*
|
|
4
|
+
* A consuming repository imports THIS and nothing below it. Registering rules one by one in the
|
|
5
|
+
* target's own plugin file is how the two lists drift: a law gains a rule here, nobody adds it there,
|
|
6
|
+
* and the rule ships as a document. That is not hypothetical for this axis - the back end kept a
|
|
7
|
+
* hand-written plugin whose names had already diverged from canon's, so `no-nest-logger` and
|
|
8
|
+
* `no-framework-logger` were one law wearing two names and no build could say which had fired.
|
|
9
|
+
*
|
|
10
|
+
* The target's `eslint.config.mjs` stays the authority on what is switched on, at what level and
|
|
11
|
+
* over which globs. That is a different question from what EXISTS, and this file answers only the
|
|
12
|
+
* second.
|
|
13
|
+
*
|
|
14
|
+
* WHAT THIS FILE REFUSES TO DO. It does not rename anything. A rule's published name is part of the
|
|
15
|
+
* law that declares it, because that name is what appears in a build log, in a disable comment and in
|
|
16
|
+
* every conversation about the failure. Aliasing one here to match a target's older spelling would
|
|
17
|
+
* leave two names for one rule and no way to tell which a message came from.
|
|
18
|
+
*/
|
|
19
|
+
import { recommended as authorizationRecommended, rules as authorizationRules } from "./authorization.mjs"
|
|
20
|
+
import { recommended as cdcRecommended, rules as cdcRules } from "./cdc.mjs"
|
|
21
|
+
import { recommended as commentsRecommended, rules as commentsRules } from "./comments.mjs"
|
|
22
|
+
import { recommended as cqrsRecommended, rules as cqrsRules } from "./cqrs.mjs"
|
|
23
|
+
import { recommended as dataAccessRecommended, rules as dataAccessRules } from "./data-access.mjs"
|
|
24
|
+
import { recommended as e2eFlowRecommended, rules as e2eFlowRules } from "./e2e-flow.mjs"
|
|
25
|
+
import { recommended as eventDeliveryRecommended, rules as eventDeliveryRules } from "./event-delivery.mjs"
|
|
26
|
+
import { recommended as exceptionIdentityRecommended, rules as exceptionIdentityRules } from "./exception-identity.mjs"
|
|
27
|
+
import { recommended as exceptionsRecommended, rules as exceptionsRules } from "./exceptions.mjs"
|
|
28
|
+
import { recommended as moduleLayeringRecommended, rules as moduleLayeringRules } from "./module-layering.mjs"
|
|
29
|
+
import { recommended as namingRecommended, rules as namingRules } from "./naming.mjs"
|
|
30
|
+
import { recommended as observabilityRecommended, rules as observabilityRules } from "./observability.mjs"
|
|
31
|
+
import { recommended as testingRecommended, rules as testingRules } from "./testing.mjs"
|
|
32
|
+
import { recommended as transportRecommended, rules as transportRules } from "./transport.mjs"
|
|
33
|
+
import { recommended as typeSafetyRecommended, rules as typeSafetyRules } from "./type-safety.mjs"
|
|
34
|
+
|
|
35
|
+
/** Each law's contribution, kept separate so a duplicate name is detectable rather than silent. */
|
|
36
|
+
const CONTRIBUTIONS = [
|
|
37
|
+
{ law: "authorization", rules: authorizationRules, recommended: authorizationRecommended },
|
|
38
|
+
{ law: "cdc", rules: cdcRules, recommended: cdcRecommended },
|
|
39
|
+
{ law: "comments", rules: commentsRules, recommended: commentsRecommended },
|
|
40
|
+
{ law: "cqrs", rules: cqrsRules, recommended: cqrsRecommended },
|
|
41
|
+
{ law: "data-access", rules: dataAccessRules, recommended: dataAccessRecommended },
|
|
42
|
+
{ law: "e2e-flow", rules: e2eFlowRules, recommended: e2eFlowRecommended },
|
|
43
|
+
{ law: "event-delivery", rules: eventDeliveryRules, recommended: eventDeliveryRecommended },
|
|
44
|
+
{ law: "exception-identity", rules: exceptionIdentityRules, recommended: exceptionIdentityRecommended },
|
|
45
|
+
{ law: "exceptions", rules: exceptionsRules, recommended: exceptionsRecommended },
|
|
46
|
+
{ law: "module-layering", rules: moduleLayeringRules, recommended: moduleLayeringRecommended },
|
|
47
|
+
{ law: "naming", rules: namingRules, recommended: namingRecommended },
|
|
48
|
+
{ law: "observability", rules: observabilityRules, recommended: observabilityRecommended },
|
|
49
|
+
{ law: "testing", rules: testingRules, recommended: testingRecommended },
|
|
50
|
+
{ law: "transport", rules: transportRules, recommended: transportRecommended },
|
|
51
|
+
{ law: "type-safety", rules: typeSafetyRules, recommended: typeSafetyRecommended },
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
/** Every gathered law. */
|
|
55
|
+
export const lawOwners = CONTRIBUTIONS.map((entry) => entry.law)
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Every (law, rule name) pair as DECLARED, before any collapsing.
|
|
59
|
+
*
|
|
60
|
+
* This exists because `ruleOwners` and `rules` below are both built with `Object.fromEntries`, which
|
|
61
|
+
* silently keeps the last writer when two laws declare one name. A test that walks either of them
|
|
62
|
+
* therefore cannot see a collision: the duplicate is already gone by the time it looks, so every
|
|
63
|
+
* name appears exactly once BY CONSTRUCTION and the check passes forever while being blind.
|
|
64
|
+
*
|
|
65
|
+
* That is exactly what happened - three back-end rules were declared by two laws each, one copy was
|
|
66
|
+
* discarded on import, and the guard reported green the whole time. A gate that cannot fail is
|
|
67
|
+
* indistinguishable from no gate, so the raw declarations are published here and the guard walks
|
|
68
|
+
* these instead.
|
|
69
|
+
*/
|
|
70
|
+
export const ruleDeclarations = CONTRIBUTIONS.flatMap((entry) =>
|
|
71
|
+
Object.keys(entry.rules).map((name) => ({ law: entry.law, name })),
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Which law declares each rule.
|
|
76
|
+
*
|
|
77
|
+
* Exported because a failing rule is a question about a LAW, and the shortest path from a build log
|
|
78
|
+
* to the document that explains it is this map. It answers "who owns this name" for a name that
|
|
79
|
+
* SHIPPED; proving no two laws claim one name is `ruleDeclarations`' job, not this map's.
|
|
80
|
+
*/
|
|
81
|
+
export const ruleOwners = Object.fromEntries(
|
|
82
|
+
CONTRIBUTIONS.flatMap((entry) => Object.keys(entry.rules).map((name) => [name, entry.law])),
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
/** Every rule this canon publishes, keyed by its published name. */
|
|
86
|
+
export const rules = Object.fromEntries(
|
|
87
|
+
CONTRIBUTIONS.flatMap((entry) => Object.entries(entry.rules)),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The levels this canon asks for, as the plugin's own opinion.
|
|
92
|
+
*
|
|
93
|
+
* Unlike the front end, this axis allows `warn`, and the allowance is the burn-down playbook rather
|
|
94
|
+
* than a softer standard: a rule measured with debt arrives at `warn` with a ledger entry naming the
|
|
95
|
+
* offenders, and flips to `error` the day that entry closes. Switching a rule on over existing
|
|
96
|
+
* offenders is what teaches an author to scroll past it, and a reader who has learned to scroll past
|
|
97
|
+
* one rule reads none of them.
|
|
98
|
+
*/
|
|
99
|
+
export const recommended = Object.fromEntries(
|
|
100
|
+
CONTRIBUTIONS.flatMap((entry) => Object.entries(entry.recommended)),
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
/** The plugin object, shaped the way a flat config expects it. */
|
|
104
|
+
export default {
|
|
105
|
+
meta: { name: "eslint-plugin-starci-be" },
|
|
106
|
+
rules,
|
|
107
|
+
}
|
package/lib/path.mjs
ADDED