@reticlehq/eslint-plugin 2.1.0 → 2.2.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.
- package/NOTICE +5 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/no-internal-tags.d.ts +25 -0
- package/dist/no-internal-tags.d.ts.map +1 -0
- package/dist/no-internal-tags.js +138 -0
- package/dist/no-internal-tags.js.map +1 -0
- package/package.json +6 -2
package/NOTICE
ADDED
package/dist/constants.d.ts
CHANGED
|
@@ -16,4 +16,6 @@ export declare const DEFAULT_MUTATORS: readonly string[];
|
|
|
16
16
|
export declare const PLUGIN_NAME = "reticle";
|
|
17
17
|
/** Docs URL builder root for ESLintUtils.RuleCreator. */
|
|
18
18
|
export declare const DOCS_URL_ROOT = "https://github.com/reticlehq/reticle/blob/main/packages/eslint-plugin/README.md";
|
|
19
|
+
/** Rule that keeps design-doc codes and internal version strings out of source comments. */
|
|
20
|
+
export declare const INTERNAL_TAGS_RULE_NAME = "no-internal-tags";
|
|
19
21
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,4CAA4C;AAC5C,eAAO,MAAM,SAAS,+BAA+B,CAAC;AAEtD,oDAAoD;AACpD,eAAO,MAAM,SAAS;;CAEZ,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAEnE,qFAAqF;AACrF,eAAO,MAAM,+BAA+B,mDAAmD,CAAC;AAEhG,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,sCAAuC,CAAC;AAE3E,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAAO,CAAC;AAEtD,mFAAmF;AACnF,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,yDAAyD;AACzD,eAAO,MAAM,aAAa,oFACyD,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,4CAA4C;AAC5C,eAAO,MAAM,SAAS,+BAA+B,CAAC;AAEtD,oDAAoD;AACpD,eAAO,MAAM,SAAS;;CAEZ,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAEnE,qFAAqF;AACrF,eAAO,MAAM,+BAA+B,mDAAmD,CAAC;AAEhG,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,sCAAuC,CAAC;AAE3E,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAAO,CAAC;AAEtD,mFAAmF;AACnF,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,yDAAyD;AACzD,eAAO,MAAM,aAAa,oFACyD,CAAC;AAEpF,4FAA4F;AAC5F,eAAO,MAAM,uBAAuB,qBAAqB,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -15,4 +15,6 @@ export const DEFAULT_MUTATORS = [];
|
|
|
15
15
|
export const PLUGIN_NAME = 'reticle';
|
|
16
16
|
/** Docs URL builder root for ESLintUtils.RuleCreator. */
|
|
17
17
|
export const DOCS_URL_ROOT = 'https://github.com/reticlehq/reticle/blob/main/packages/eslint-plugin/README.md';
|
|
18
|
+
/** Rule that keeps design-doc codes and internal version strings out of source comments. */
|
|
19
|
+
export const INTERNAL_TAGS_RULE_NAME = 'no-internal-tags';
|
|
18
20
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,4CAA4C;AAC5C,MAAM,CAAC,MAAM,SAAS,GAAG,4BAA4B,CAAC;AAEtD,oDAAoD;AACpD,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,uBAAuB,EAAE,uBAAuB;CACxC,CAAC;AAGX,qFAAqF;AACrF,MAAM,CAAC,MAAM,+BAA+B,GAAG,gDAAgD,CAAC;AAEhG,4EAA4E;AAC5E,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAU,CAAC;AAE3E,8FAA8F;AAC9F,MAAM,CAAC,MAAM,gBAAgB,GAAsB,EAAE,CAAC;AAEtD,mFAAmF;AACnF,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AAErC,yDAAyD;AACzD,MAAM,CAAC,MAAM,aAAa,GACxB,iFAAiF,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,4CAA4C;AAC5C,MAAM,CAAC,MAAM,SAAS,GAAG,4BAA4B,CAAC;AAEtD,oDAAoD;AACpD,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,uBAAuB,EAAE,uBAAuB;CACxC,CAAC;AAGX,qFAAqF;AACrF,MAAM,CAAC,MAAM,+BAA+B,GAAG,gDAAgD,CAAC;AAEhG,4EAA4E;AAC5E,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAU,CAAC;AAE3E,8FAA8F;AAC9F,MAAM,CAAC,MAAM,gBAAgB,GAAsB,EAAE,CAAC;AAEtD,mFAAmF;AACnF,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AAErC,yDAAyD;AACzD,MAAM,CAAC,MAAM,aAAa,GACxB,iFAAiF,CAAC;AAEpF,4FAA4F;AAC5F,MAAM,CAAC,MAAM,uBAAuB,GAAG,kBAAkB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
/** @reticlehq/eslint-plugin — flat-config plugin export. */
|
|
2
2
|
import { requireSignalOnMutation } from './require-signal-on-mutation.js';
|
|
3
|
+
import { noInternalTags } from './no-internal-tags.js';
|
|
3
4
|
export declare const rules: {
|
|
4
5
|
readonly "require-signal-on-mutation": import("@typescript-eslint/utils/ts-eslint").RuleModule<"mutationWithoutSignal", [import("./options.js").RawRuleOptions], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
5
6
|
name: string;
|
|
6
7
|
};
|
|
8
|
+
readonly "no-internal-tags": import("@typescript-eslint/utils/ts-eslint").RuleModule<"internalTag", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
7
11
|
};
|
|
8
12
|
declare const plugin: {
|
|
9
13
|
meta: {
|
|
@@ -13,9 +17,12 @@ declare const plugin: {
|
|
|
13
17
|
readonly "require-signal-on-mutation": import("@typescript-eslint/utils/ts-eslint").RuleModule<"mutationWithoutSignal", [import("./options.js").RawRuleOptions], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
14
18
|
name: string;
|
|
15
19
|
};
|
|
20
|
+
readonly "no-internal-tags": import("@typescript-eslint/utils/ts-eslint").RuleModule<"internalTag", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
21
|
+
name: string;
|
|
22
|
+
};
|
|
16
23
|
};
|
|
17
24
|
configs: Record<string, unknown>;
|
|
18
25
|
};
|
|
19
26
|
export default plugin;
|
|
20
|
-
export { requireSignalOnMutation };
|
|
27
|
+
export { requireSignalOnMutation, noInternalTags };
|
|
21
28
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,eAAO,MAAM,KAAK;;;;;;;CAGR,CAAC;AAEX,QAAA,MAAM,MAAM;;;;;;;;;;;;aAGK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CACvC,CAAC;AAWF,eAAe,MAAM,CAAC;AACtB,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/** @reticlehq/eslint-plugin — flat-config plugin export. */
|
|
2
2
|
import { requireSignalOnMutation } from './require-signal-on-mutation.js';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { noInternalTags } from './no-internal-tags.js';
|
|
4
|
+
import { PLUGIN_NAME, RULE_NAME, INTERNAL_TAGS_RULE_NAME } from './constants.js';
|
|
5
|
+
export const rules = {
|
|
6
|
+
[RULE_NAME]: requireSignalOnMutation,
|
|
7
|
+
[INTERNAL_TAGS_RULE_NAME]: noInternalTags,
|
|
8
|
+
};
|
|
5
9
|
const plugin = {
|
|
6
10
|
meta: { name: PLUGIN_NAME },
|
|
7
11
|
rules,
|
|
@@ -10,8 +14,11 @@ const plugin = {
|
|
|
10
14
|
// recommended flat config: turns the rule on with empty (no-op) defaults.
|
|
11
15
|
plugin.configs.recommended = {
|
|
12
16
|
plugins: { [PLUGIN_NAME]: plugin },
|
|
13
|
-
rules: {
|
|
17
|
+
rules: {
|
|
18
|
+
[`${PLUGIN_NAME}/${RULE_NAME}`]: 'warn',
|
|
19
|
+
[`${PLUGIN_NAME}/${INTERNAL_TAGS_RULE_NAME}`]: 'error',
|
|
20
|
+
},
|
|
14
21
|
};
|
|
15
22
|
export default plugin;
|
|
16
|
-
export { requireSignalOnMutation };
|
|
23
|
+
export { requireSignalOnMutation, noInternalTags };
|
|
17
24
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEjF,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,CAAC,SAAS,CAAC,EAAE,uBAAuB;IACpC,CAAC,uBAAuB,CAAC,EAAE,cAAc;CACjC,CAAC;AAEX,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;IAC3B,KAAK;IACL,OAAO,EAAE,EAA6B;CACvC,CAAC;AAEF,0EAA0E;AAC1E,MAAM,CAAC,OAAO,CAAC,WAAW,GAAG;IAC3B,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE;IAClC,KAAK,EAAE;QACL,CAAC,GAAG,WAAW,IAAI,SAAS,EAAE,CAAC,EAAE,MAAM;QACvC,CAAC,GAAG,WAAW,IAAI,uBAAuB,EAAE,CAAC,EAAE,OAAO;KACvD;CACF,CAAC;AAEF,eAAe,MAAM,CAAC;AACtB,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule: no-internal-tags.
|
|
3
|
+
*
|
|
4
|
+
* Bans design-doc reference codes and internal version strings from comments, so a reader of the source
|
|
5
|
+
* never meets a token that only means something in a document they cannot see.
|
|
6
|
+
*
|
|
7
|
+
* This rule exists because the prose version of it did not hold. An audit of the codebase found the
|
|
8
|
+
* machine-checked rules at ~100% compliance and every prose-only rule violated — 59 tracking codes
|
|
9
|
+
* across the library packages alone, including in the contract package and in test descriptions, plus
|
|
10
|
+
* codes that leaked into user-facing docs. The gap was enforcement, not intent, so the rule is now a
|
|
11
|
+
* lint error rather than a paragraph.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately narrow, to avoid punishing legitimate prose:
|
|
14
|
+
* - a bare `W11`, `B37`, `N5`, `M8` style token (one or two capitals + digits) standing alone;
|
|
15
|
+
* - a section reference like `§4.3`;
|
|
16
|
+
* - an internal version string like `v2.2.0`.
|
|
17
|
+
* Ordinary technical prose that happens to contain a letter and digits inside a larger word (`UTF-8`,
|
|
18
|
+
* `H2`, `Welford M2` when part of a sentence) is matched only when it stands alone as a tag.
|
|
19
|
+
*/
|
|
20
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
21
|
+
export declare const INTERNAL_TAG_MESSAGE = "Internal reference '{{tag}}' does not belong in source. It means nothing to a reader without the design doc \u2014 describe the behaviour instead.";
|
|
22
|
+
export declare const noInternalTags: ESLintUtils.RuleModule<"internalTag", [], unknown, ESLintUtils.RuleListener> & {
|
|
23
|
+
name: string;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=no-internal-tags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-internal-tags.d.ts","sourceRoot":"","sources":["../src/no-internal-tags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAkB,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAKvE,eAAO,MAAM,oBAAoB,uJACgH,CAAC;AAwDlJ,eAAO,MAAM,cAAc;;CA+DzB,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule: no-internal-tags.
|
|
3
|
+
*
|
|
4
|
+
* Bans design-doc reference codes and internal version strings from comments, so a reader of the source
|
|
5
|
+
* never meets a token that only means something in a document they cannot see.
|
|
6
|
+
*
|
|
7
|
+
* This rule exists because the prose version of it did not hold. An audit of the codebase found the
|
|
8
|
+
* machine-checked rules at ~100% compliance and every prose-only rule violated — 59 tracking codes
|
|
9
|
+
* across the library packages alone, including in the contract package and in test descriptions, plus
|
|
10
|
+
* codes that leaked into user-facing docs. The gap was enforcement, not intent, so the rule is now a
|
|
11
|
+
* lint error rather than a paragraph.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately narrow, to avoid punishing legitimate prose:
|
|
14
|
+
* - a bare `W11`, `B37`, `N5`, `M8` style token (one or two capitals + digits) standing alone;
|
|
15
|
+
* - a section reference like `§4.3`;
|
|
16
|
+
* - an internal version string like `v2.2.0`.
|
|
17
|
+
* Ordinary technical prose that happens to contain a letter and digits inside a larger word (`UTF-8`,
|
|
18
|
+
* `H2`, `Welford M2` when part of a sentence) is matched only when it stands alone as a tag.
|
|
19
|
+
*/
|
|
20
|
+
import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';
|
|
21
|
+
import { DOCS_URL_ROOT } from './constants.js';
|
|
22
|
+
const createRule = ESLintUtils.RuleCreator((name) => `${DOCS_URL_ROOT}#${name}`);
|
|
23
|
+
export const INTERNAL_TAG_MESSAGE = "Internal reference '{{tag}}' does not belong in source. It means nothing to a reader without the design doc — describe the behaviour instead.";
|
|
24
|
+
/** `(W11)`, `B37`, `W10.3`, `N5:` — a short capital-prefixed code used as a label. */
|
|
25
|
+
const TRACKING_CODE = /(?<![A-Za-z0-9])[A-Z]{1,2}\d{1,2}(?:\.\d{1,2})?(?![A-Za-z0-9])/g;
|
|
26
|
+
/**
|
|
27
|
+
* `§4.3` — a design-doc section reference.
|
|
28
|
+
*
|
|
29
|
+
* Defaults to FLAGGING and exempts only a citation of a NAMED EXTERNAL spec. The first version did the
|
|
30
|
+
* reverse — it exempted any § preceded by a word — which silently permitted `see PLAN §4.3`, the very
|
|
31
|
+
* shape being banned. For a ban rule the default must be "flag", or the exemption swallows the rule.
|
|
32
|
+
*/
|
|
33
|
+
const SECTION_REF = /§\s?\d+(?:\.\d+)*/g;
|
|
34
|
+
/** Specs whose section numbers are real references a reader can follow. */
|
|
35
|
+
const EXTERNAL_SPECS = /\b(RFC|WCAG|ECMA|ISO|IEEE|W3C|WHATWG|HTML|CSS|ARIA|HTTP|OAuth|JSON-LD)\b[^§]{0,20}$/i;
|
|
36
|
+
/**
|
|
37
|
+
* `v2.2.0` — an INTERNAL version string.
|
|
38
|
+
*
|
|
39
|
+
* Same inversion: flag by default, exempt only a version attributed to a NAMED third party. Exempting
|
|
40
|
+
* "any capitalised preceding word" permitted `new in Reticle v2.2.0` — our own product name made the
|
|
41
|
+
* banned string legal.
|
|
42
|
+
*/
|
|
43
|
+
const VERSION_STRING = /(?<![A-Za-z0-9])v\d+\.\d+\.\d+(?![A-Za-z0-9])/g;
|
|
44
|
+
/** Third-party names whose versions are legitimate prose. Reticle is deliberately NOT here. */
|
|
45
|
+
const THIRD_PARTY = /\b(React|Vite|Node|TypeScript|Playwright|Chrome|Chromium|Firefox|Safari|Zod|Vitest|ESLint|pnpm|MCP)\b[^v]{0,12}$/i;
|
|
46
|
+
/** Tokens that look like codes but are established technical terms. */
|
|
47
|
+
/** Test-block callees whose first argument is a human-readable description. */
|
|
48
|
+
const TEST_BLOCKS = new Set(['describe', 'it', 'test', 'suite', 'bench']);
|
|
49
|
+
/**
|
|
50
|
+
* Tokens matching the code shape that are established technical terms. Kept deliberately explicit: a
|
|
51
|
+
* rule that fires on ordinary technical writing gets disabled, and a disabled rule enforces nothing.
|
|
52
|
+
*/
|
|
53
|
+
const ALLOWED = new Set([
|
|
54
|
+
'M2', // Welford's streaming-variance accumulator
|
|
55
|
+
'H1',
|
|
56
|
+
'H2',
|
|
57
|
+
'H3', // heading levels
|
|
58
|
+
'P1',
|
|
59
|
+
'P2',
|
|
60
|
+
'P3', // priority labels
|
|
61
|
+
'S3',
|
|
62
|
+
'EC2', // AWS services
|
|
63
|
+
'ES5',
|
|
64
|
+
'ES6', // ECMAScript editions
|
|
65
|
+
'IE11', // browser
|
|
66
|
+
'Q1',
|
|
67
|
+
'Q2',
|
|
68
|
+
'Q3',
|
|
69
|
+
'Q4', // quarters
|
|
70
|
+
'L1',
|
|
71
|
+
'L2', // cache levels
|
|
72
|
+
]);
|
|
73
|
+
export const noInternalTags = createRule({
|
|
74
|
+
name: 'no-internal-tags',
|
|
75
|
+
meta: {
|
|
76
|
+
type: 'problem',
|
|
77
|
+
docs: { description: 'Ban design-doc codes and internal version strings from comments.' },
|
|
78
|
+
schema: [],
|
|
79
|
+
messages: { internalTag: INTERNAL_TAG_MESSAGE },
|
|
80
|
+
},
|
|
81
|
+
defaultOptions: [],
|
|
82
|
+
create(context) {
|
|
83
|
+
/** Every banned token in a piece of text. */
|
|
84
|
+
const tagsIn = (text) => {
|
|
85
|
+
const found = new Set();
|
|
86
|
+
for (const { pattern, exempt } of [
|
|
87
|
+
{ pattern: TRACKING_CODE, exempt: undefined },
|
|
88
|
+
{ pattern: SECTION_REF, exempt: EXTERNAL_SPECS },
|
|
89
|
+
{ pattern: VERSION_STRING, exempt: THIRD_PARTY },
|
|
90
|
+
]) {
|
|
91
|
+
pattern.lastIndex = 0;
|
|
92
|
+
for (const match of text.matchAll(pattern)) {
|
|
93
|
+
const tag = match[0].trim();
|
|
94
|
+
if (ALLOWED.has(tag.replace(/[^A-Za-z0-9]/g, '')))
|
|
95
|
+
continue;
|
|
96
|
+
// Attribution is judged from the text BEFORE the match, so "RFC 6265 §5.2" is a reference
|
|
97
|
+
// and "PLAN §4.3" is a design-doc pointer.
|
|
98
|
+
if (exempt !== undefined && exempt.test(text.slice(0, match.index ?? 0)))
|
|
99
|
+
continue;
|
|
100
|
+
found.add(tag);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return found;
|
|
104
|
+
};
|
|
105
|
+
return {
|
|
106
|
+
Program() {
|
|
107
|
+
for (const comment of context.sourceCode.getAllComments()) {
|
|
108
|
+
for (const tag of tagsIn(comment.value)) {
|
|
109
|
+
context.report({ node: comment, messageId: 'internalTag', data: { tag } });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
/**
|
|
114
|
+
* TEST DESCRIPTIONS are string literals, not comments, so a comment-only rule could not see them
|
|
115
|
+
* — and the project rule names them explicitly. Seven violations survived a repo-wide cleanup that
|
|
116
|
+
* claimed to have removed them, precisely because nothing mechanical was looking here.
|
|
117
|
+
*/
|
|
118
|
+
CallExpression(node) {
|
|
119
|
+
const callee = node.callee;
|
|
120
|
+
const name = callee.type === AST_NODE_TYPES.Identifier
|
|
121
|
+
? callee.name
|
|
122
|
+
: callee.type === AST_NODE_TYPES.MemberExpression &&
|
|
123
|
+
callee.object.type === AST_NODE_TYPES.Identifier
|
|
124
|
+
? callee.object.name
|
|
125
|
+
: undefined;
|
|
126
|
+
if (name === undefined || !TEST_BLOCKS.has(name))
|
|
127
|
+
return;
|
|
128
|
+
const first = node.arguments[0];
|
|
129
|
+
if (first?.type !== AST_NODE_TYPES.Literal || typeof first.value !== 'string')
|
|
130
|
+
return;
|
|
131
|
+
for (const tag of tagsIn(first.value)) {
|
|
132
|
+
context.report({ node: first, messageId: 'internalTag', data: { tag } });
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=no-internal-tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-internal-tags.js","sourceRoot":"","sources":["../src/no-internal-tags.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reticlehq/eslint-plugin",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Reticle ESLint plugin — keeps the signal layer self-enforcing (mutation-without-signal).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"bugs": "https://github.com/reticlehq/reticle/issues",
|
|
32
32
|
"files": [
|
|
33
33
|
"dist",
|
|
34
|
-
"README.md"
|
|
34
|
+
"README.md",
|
|
35
|
+
"NOTICE"
|
|
35
36
|
],
|
|
36
37
|
"sideEffects": false,
|
|
37
38
|
"keywords": [
|
|
@@ -44,6 +45,9 @@
|
|
|
44
45
|
"publishConfig": {
|
|
45
46
|
"access": "public"
|
|
46
47
|
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=20.0.0"
|
|
50
|
+
},
|
|
47
51
|
"scripts": {
|
|
48
52
|
"build": "tsc -b",
|
|
49
53
|
"typecheck": "tsc -b",
|