@brandlab-digital/eslint-plugin 2.1.0 → 3.0.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/README.md +16 -3
- package/dist/index.d.ts +29 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +109 -59
- package/dist/index.js.map +1 -1
- package/package.json +12 -2
package/README.md
CHANGED
|
@@ -4,8 +4,22 @@ Fast, syntax-level safeguards for Brandlab Next.js consumers. The plugin gives i
|
|
|
4
4
|
|
|
5
5
|
It deliberately does not implement release support, migration policy, project health, rendered-output validation or portfolio scoring. Those decisions belong to `@brandlab-digital/conformance`.
|
|
6
6
|
|
|
7
|
+
## Client preset
|
|
8
|
+
|
|
9
|
+
Every Brandlab Next.js client uses the complete preset as its whole `eslint.config.mjs`:
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import brandlab from '@brandlab-digital/eslint-plugin'
|
|
13
|
+
|
|
14
|
+
export default brandlab.configs.next
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`configs.next` is Next's `core-web-vitals` and `typescript` configs, then `configs.recommended`, then `react/no-unescaped-entities` off (apostrophes are ordinary copy) and the standard ignores (`.next/`, `out/`, `build/`, `coverage/`, `playwright-report/`, `test-results/`, `.vercel/`, `public/`, `next-env.d.ts`). It loads `eslint-config-next` when first used, so install `eslint-config-next` at the exact version of `next`.
|
|
18
|
+
|
|
7
19
|
## Recommended flat config
|
|
8
20
|
|
|
21
|
+
For a non-Next consumer, or to compose a custom array:
|
|
22
|
+
|
|
9
23
|
```js
|
|
10
24
|
import brandlab from '@brandlab-digital/eslint-plugin'
|
|
11
25
|
|
|
@@ -20,14 +34,13 @@ The recommended config enables every published rule as an error.
|
|
|
20
34
|
|---|---|---|
|
|
21
35
|
| `brandlab/no-retired-analytics-events` | Rejects retired event names such as `contact_form_submission` and `phone_call`. | Use `contact_form` for accepted forms and `phone_link_click` for telephone-link diagnostics. |
|
|
22
36
|
| `brandlab/no-raw-json-ld` | Rejects raw JSON-LD `<script>` and `createElement` output in consumers. | Render typed graphs through `@brandlab-digital/site-next/schema`. |
|
|
23
|
-
| `brandlab/no-
|
|
24
|
-
| `brandlab/no-unsafe-rich-text-sinks` | Rejects statically visible unsanitized rich-text sinks. | Use a tested sanitizer-backed renderer. |
|
|
37
|
+
| `brandlab/no-unsafe-rich-text-sinks` | Rejects every project-owned raw HTML sink (`dangerouslySetInnerHTML` in JSX, props objects or assignments), whatever sanitiser it names. The conformance checker applies the same policy. | Render JSON-LD with `SchemaScript` and rich text with `SafeRichText` from `@brandlab-digital/site-next`. |
|
|
25
38
|
| `brandlab/no-protected-platform-reimplementation` | Rejects local declarations and direct calls that bypass protected contact, SEO or analytics surfaces. | Import the shared `site-core` or `site-next` API. |
|
|
26
39
|
| `brandlab/no-analytics-pii` | Rejects statically provable lead PII, message and attachment data in known analytics sinks. | Send only shared allowlisted event parameters. |
|
|
27
40
|
| `brandlab/no-unsafe-external-links` | Rejects script-bearing link schemes and external new-context links with opener access when the URL is static. | Use safe schemes and `rel="noopener"`; keep runtime URL validation at the trust boundary. |
|
|
28
41
|
| `brandlab/no-raw-image-elements` | Rejects raw website `<img>` and `createElement('img')` output. | Use `next/image`; the documented `getImageProps` art-direction pattern and email renderer files remain exempt. |
|
|
29
42
|
|
|
30
|
-
`RULE_IDS` is exported for tools that need the canonical IDs without duplicating strings.
|
|
43
|
+
`RULE_IDS` is exported for tools that need the canonical IDs without duplicating strings. The 3.0 release removed `brandlab/no-allow-indexing-true` together with the `ALLOW_INDEXING` path it guarded; indexing is decided by the deployment environment.
|
|
31
44
|
|
|
32
45
|
## Deliberate boundaries
|
|
33
46
|
|
package/dist/index.d.ts
CHANGED
|
@@ -7,14 +7,8 @@ type ReportDescriptor = {
|
|
|
7
7
|
type RuleContext = {
|
|
8
8
|
filename?: string;
|
|
9
9
|
getFilename?: () => string;
|
|
10
|
-
getSourceCode?: () => {
|
|
11
|
-
getText?: (node: unknown) => string;
|
|
12
|
-
};
|
|
13
10
|
physicalFilename?: string;
|
|
14
11
|
report: (descriptor: ReportDescriptor) => void;
|
|
15
|
-
sourceCode?: {
|
|
16
|
-
getText?: (node: unknown) => string;
|
|
17
|
-
};
|
|
18
12
|
};
|
|
19
13
|
type Visitor = Record<string, (node: unknown) => void>;
|
|
20
14
|
type RuleModule = {
|
|
@@ -32,7 +26,6 @@ type RuleModule = {
|
|
|
32
26
|
export declare const RULE_IDS: Readonly<{
|
|
33
27
|
readonly noRetiredAnalyticsEvents: "no-retired-analytics-events";
|
|
34
28
|
readonly noRawJsonLd: "no-raw-json-ld";
|
|
35
|
-
readonly noAllowIndexingTrue: "no-allow-indexing-true";
|
|
36
29
|
readonly noUnsafeRichTextSinks: "no-unsafe-rich-text-sinks";
|
|
37
30
|
readonly noProtectedPlatformReimplementation: "no-protected-platform-reimplementation";
|
|
38
31
|
readonly noAnalyticsPii: "no-analytics-pii";
|
|
@@ -42,24 +35,46 @@ export declare const RULE_IDS: Readonly<{
|
|
|
42
35
|
export declare const rules: {
|
|
43
36
|
"no-retired-analytics-events": RuleModule;
|
|
44
37
|
"no-raw-json-ld": RuleModule;
|
|
45
|
-
"no-allow-indexing-true": RuleModule;
|
|
46
38
|
"no-unsafe-rich-text-sinks": RuleModule;
|
|
47
39
|
"no-protected-platform-reimplementation": RuleModule;
|
|
48
40
|
"no-analytics-pii": RuleModule;
|
|
49
41
|
"no-unsafe-external-links": RuleModule;
|
|
50
42
|
"no-raw-image-elements": RuleModule;
|
|
51
43
|
};
|
|
44
|
+
/** A flat-config object; kept structural so ESLint stays a peer, not a type dependency. */
|
|
45
|
+
export type BrandlabFlatConfig = {
|
|
46
|
+
name?: string;
|
|
47
|
+
files?: readonly string[];
|
|
48
|
+
ignores?: readonly string[];
|
|
49
|
+
plugins?: Record<string, unknown>;
|
|
50
|
+
rules?: Record<string, unknown>;
|
|
51
|
+
[key: string]: unknown;
|
|
52
|
+
};
|
|
53
|
+
type BrandlabRecommendedConfig = {
|
|
54
|
+
name: 'brandlab/recommended';
|
|
55
|
+
plugins: {
|
|
56
|
+
brandlab: unknown;
|
|
57
|
+
};
|
|
58
|
+
rules: Record<string, 'error'>;
|
|
59
|
+
};
|
|
52
60
|
type BrandlabPlugin = {
|
|
53
61
|
rules: typeof rules;
|
|
54
62
|
configs: {
|
|
55
|
-
recommended:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
};
|
|
59
|
-
rules: Record<string, 'error'>;
|
|
60
|
-
};
|
|
63
|
+
recommended: BrandlabRecommendedConfig;
|
|
64
|
+
/** Next core-web-vitals + next/typescript + Brandlab recommended + standard ignores. */
|
|
65
|
+
readonly next: readonly BrandlabFlatConfig[];
|
|
61
66
|
};
|
|
62
67
|
};
|
|
68
|
+
/** Build and test output that is never project source. */
|
|
69
|
+
export declare const NEXT_CONFIG_IGNORES: readonly string[];
|
|
70
|
+
/**
|
|
71
|
+
* The complete client preset: `export default brandlab.configs.next`.
|
|
72
|
+
* eslint-config-next is an optional peer, so it loads only when this preset is used.
|
|
73
|
+
*/
|
|
74
|
+
export declare function createBrandlabNextConfig(presets: {
|
|
75
|
+
coreWebVitals: readonly BrandlabFlatConfig[];
|
|
76
|
+
typescript: readonly BrandlabFlatConfig[];
|
|
77
|
+
}): readonly BrandlabFlatConfig[];
|
|
63
78
|
declare const plugin: BrandlabPlugin;
|
|
64
79
|
export default plugin;
|
|
65
80
|
//# 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":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,OAAO,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9B,CAAA;AAED,KAAK,WAAW,GAAG;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,MAAM,CAAA;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,MAAM,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAA;CAC/C,CAAA;AAWD,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,CAAA;AAEtD,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS,CAAA;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,MAAM,CAAA;YACnB,WAAW,EAAE,OAAO,CAAA;SACrB,CAAA;QACD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAChC,MAAM,EAAE,EAAE,CAAA;KACX,CAAA;IACD,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAA;CAC1C,CAAA;AAED,eAAO,MAAM,QAAQ;;;;;;;;EAQV,CAAA;AAitBX,eAAO,MAAM,KAAK;;;;;;;;CAaoB,CAAA;AAEtC,2FAA2F;AAC3F,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACzB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,CAAA;AAED,KAAK,yBAAyB,GAAG;IAC/B,IAAI,EAAE,sBAAsB,CAAA;IAC5B,OAAO,EAAE;QACP,QAAQ,EAAE,OAAO,CAAA;KAClB,CAAA;IACD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,OAAO,EAAE;QACP,WAAW,EAAE,yBAAyB,CAAA;QACtC,wFAAwF;QACxF,QAAQ,CAAC,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAA;KAC7C,CAAA;CACF,CAAA;AAED,0DAA0D;AAC1D,eAAO,MAAM,mBAAmB,mBAU9B,CAAA;AAwBF;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,aAAa,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAC5C,UAAU,EAAE,SAAS,kBAAkB,EAAE,CAAA;CAC1C,GAAG,SAAS,kBAAkB,EAAE,CAchC;AAsBD,QAAA,MAAM,MAAM,EAAE,cASb,CAAA;AAID,eAAe,MAAM,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
1
2
|
function getContextFilename(context) {
|
|
2
3
|
return (context.filename ??
|
|
3
4
|
context.physicalFilename ??
|
|
@@ -7,7 +8,6 @@ function getContextFilename(context) {
|
|
|
7
8
|
export const RULE_IDS = Object.freeze({
|
|
8
9
|
noRetiredAnalyticsEvents: 'no-retired-analytics-events',
|
|
9
10
|
noRawJsonLd: 'no-raw-json-ld',
|
|
10
|
-
noAllowIndexingTrue: 'no-allow-indexing-true',
|
|
11
11
|
noUnsafeRichTextSinks: 'no-unsafe-rich-text-sinks',
|
|
12
12
|
noProtectedPlatformReimplementation: 'no-protected-platform-reimplementation',
|
|
13
13
|
noAnalyticsPii: 'no-analytics-pii',
|
|
@@ -54,10 +54,6 @@ function getIdentifierName(value) {
|
|
|
54
54
|
}
|
|
55
55
|
return null;
|
|
56
56
|
}
|
|
57
|
-
function getSourceText(context, node) {
|
|
58
|
-
const sourceCode = context.sourceCode ?? context.getSourceCode?.();
|
|
59
|
-
return sourceCode?.getText?.(node) ?? '';
|
|
60
|
-
}
|
|
61
57
|
function defineRule(options) {
|
|
62
58
|
return {
|
|
63
59
|
meta: {
|
|
@@ -90,41 +86,13 @@ function createTextRule(options) {
|
|
|
90
86
|
},
|
|
91
87
|
});
|
|
92
88
|
}
|
|
93
|
-
function containsAllowIndexingTrue(text) {
|
|
94
|
-
return (text.includes('ALLOW_INDEXING=true') ||
|
|
95
|
-
/ALLOW_INDEXING[\s\S]{0,80}['"]true['"]/.test(text));
|
|
96
|
-
}
|
|
97
|
-
const noAllowIndexingTrueRule = defineRule({
|
|
98
|
-
description: 'Disallow ALLOW_INDEXING=true; only ALLOW_INDEXING=1 is supported.',
|
|
99
|
-
messages: {
|
|
100
|
-
allowIndexingTrue: 'Use ALLOW_INDEXING=1 as the only explicit indexing override.',
|
|
101
|
-
},
|
|
102
|
-
create(context) {
|
|
103
|
-
function inspectStringNode(node) {
|
|
104
|
-
const text = getStaticString(node);
|
|
105
|
-
if (text && containsAllowIndexingTrue(text)) {
|
|
106
|
-
context.report({ node, messageId: 'allowIndexingTrue' });
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
function inspectSourceNode(node) {
|
|
110
|
-
const text = getSourceText(context, node);
|
|
111
|
-
if (text && containsAllowIndexingTrue(text)) {
|
|
112
|
-
context.report({ node, messageId: 'allowIndexingTrue' });
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return {
|
|
116
|
-
BinaryExpression: inspectSourceNode,
|
|
117
|
-
Literal: inspectStringNode,
|
|
118
|
-
Property: inspectSourceNode,
|
|
119
|
-
TemplateElement: inspectStringNode,
|
|
120
|
-
};
|
|
121
|
-
},
|
|
122
|
-
});
|
|
123
89
|
const retiredAnalyticsEvents = new Set([
|
|
124
90
|
'contact_form_submission',
|
|
125
91
|
'phone_call',
|
|
126
92
|
'phone_calls',
|
|
127
93
|
'form_start',
|
|
94
|
+
'form_submit',
|
|
95
|
+
'generate_lead',
|
|
128
96
|
'cta_click',
|
|
129
97
|
]);
|
|
130
98
|
const protectedPlatformNames = new Set([
|
|
@@ -372,11 +340,19 @@ function isAnalyticsSink(value) {
|
|
|
372
340
|
path === 'trackBrandlabEvent' ||
|
|
373
341
|
path === 'ReactGA.event');
|
|
374
342
|
}
|
|
343
|
+
/** Lead and phone events, current or retired, whose payloads must never carry contact details. */
|
|
344
|
+
const contactAnalyticsEvents = new Set([
|
|
345
|
+
'contact_form',
|
|
346
|
+
'phone_link_click',
|
|
347
|
+
'phone_call',
|
|
348
|
+
'generate_lead',
|
|
349
|
+
'form_submit',
|
|
350
|
+
]);
|
|
375
351
|
function isContactAnalyticsCall(node) {
|
|
376
352
|
const args = Array.isArray(node.arguments) ? node.arguments : [];
|
|
377
353
|
return args.some((argument) => {
|
|
378
354
|
const value = getStaticString(argument);
|
|
379
|
-
return value
|
|
355
|
+
return value !== null && contactAnalyticsEvents.has(value);
|
|
380
356
|
});
|
|
381
357
|
}
|
|
382
358
|
function looksLikeLiteralPii(value) {
|
|
@@ -643,31 +619,43 @@ const noRawImageElementsRule = defineRule({
|
|
|
643
619
|
};
|
|
644
620
|
},
|
|
645
621
|
});
|
|
622
|
+
const RAW_HTML_PROPERTY = 'dangerouslySetInnerHTML';
|
|
646
623
|
const noUnsafeRichTextSinksRule = defineRule({
|
|
647
|
-
description: 'Disallow
|
|
624
|
+
description: 'Disallow project-owned raw HTML; only the shared SchemaScript and SafeRichText renderers may inject markup.',
|
|
648
625
|
messages: {
|
|
649
|
-
unsafeRichTextSink: '
|
|
626
|
+
unsafeRichTextSink: 'Project-owned raw HTML is not permitted. Render JSON-LD with SchemaScript and rich text with SafeRichText from @brandlab-digital/site-next.',
|
|
650
627
|
},
|
|
651
628
|
create(context) {
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
629
|
+
if (isSharedPlatformImplementation(context))
|
|
630
|
+
return {};
|
|
631
|
+
function inspectJsxAttribute(nodeValue) {
|
|
632
|
+
const node = asNode(nodeValue);
|
|
633
|
+
if (getIdentifierName(node?.name) === RAW_HTML_PROPERTY) {
|
|
634
|
+
context.report({ node: nodeValue, messageId: 'unsafeRichTextSink' });
|
|
657
635
|
}
|
|
658
636
|
}
|
|
659
|
-
function
|
|
660
|
-
const
|
|
661
|
-
if (
|
|
662
|
-
|
|
663
|
-
|
|
637
|
+
function inspectProperty(nodeValue) {
|
|
638
|
+
const node = asNode(nodeValue);
|
|
639
|
+
if (node?.type === 'Property' && getPropertyName(node) === RAW_HTML_PROPERTY) {
|
|
640
|
+
context.report({ node: nodeValue, messageId: 'unsafeRichTextSink' });
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
function inspectAssignment(nodeValue) {
|
|
644
|
+
const node = asNode(nodeValue);
|
|
645
|
+
const target = asNode(node?.left);
|
|
646
|
+
if (target?.type !== 'MemberExpression')
|
|
647
|
+
return;
|
|
648
|
+
const propertyName = target.computed
|
|
649
|
+
? getStaticString(target.property)
|
|
650
|
+
: getIdentifierName(target.property);
|
|
651
|
+
if (propertyName === RAW_HTML_PROPERTY) {
|
|
652
|
+
context.report({ node: nodeValue, messageId: 'unsafeRichTextSink' });
|
|
664
653
|
}
|
|
665
654
|
}
|
|
666
655
|
return {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
Property:
|
|
670
|
-
TemplateElement: inspectStringNode,
|
|
656
|
+
AssignmentExpression: inspectAssignment,
|
|
657
|
+
JSXAttribute: inspectJsxAttribute,
|
|
658
|
+
Property: inspectProperty,
|
|
671
659
|
};
|
|
672
660
|
},
|
|
673
661
|
});
|
|
@@ -679,25 +667,87 @@ export const rules = {
|
|
|
679
667
|
matcher: (text) => retiredAnalyticsEvents.has(text),
|
|
680
668
|
}),
|
|
681
669
|
[RULE_IDS.noRawJsonLd]: noRawJsonLdRule,
|
|
682
|
-
[RULE_IDS.noAllowIndexingTrue]: noAllowIndexingTrueRule,
|
|
683
670
|
[RULE_IDS.noUnsafeRichTextSinks]: noUnsafeRichTextSinksRule,
|
|
684
671
|
[RULE_IDS.noProtectedPlatformReimplementation]: noProtectedPlatformReimplementationRule,
|
|
685
672
|
[RULE_IDS.noAnalyticsPii]: noAnalyticsPiiRule,
|
|
686
673
|
[RULE_IDS.noUnsafeExternalLinks]: noUnsafeExternalLinksRule,
|
|
687
674
|
[RULE_IDS.noRawImageElements]: noRawImageElementsRule,
|
|
688
675
|
};
|
|
676
|
+
/** Build and test output that is never project source. */
|
|
677
|
+
export const NEXT_CONFIG_IGNORES = Object.freeze([
|
|
678
|
+
'.next/**',
|
|
679
|
+
'out/**',
|
|
680
|
+
'build/**',
|
|
681
|
+
'coverage/**',
|
|
682
|
+
'playwright-report/**',
|
|
683
|
+
'test-results/**',
|
|
684
|
+
'.vercel/**',
|
|
685
|
+
'public/**',
|
|
686
|
+
'next-env.d.ts',
|
|
687
|
+
]);
|
|
689
688
|
const recommendedRules = Object.fromEntries(Object.keys(rules).map((ruleId) => [`brandlab/${ruleId}`, 'error']));
|
|
689
|
+
const recommended = {
|
|
690
|
+
name: 'brandlab/recommended',
|
|
691
|
+
plugins: {
|
|
692
|
+
brandlab: undefined,
|
|
693
|
+
},
|
|
694
|
+
rules: recommendedRules,
|
|
695
|
+
};
|
|
696
|
+
function toConfigArray(value, specifier) {
|
|
697
|
+
const exported = Array.isArray(value)
|
|
698
|
+
? value
|
|
699
|
+
: Array.isArray(asNode(value)?.default)
|
|
700
|
+
? asNode(value)?.default
|
|
701
|
+
: null;
|
|
702
|
+
if (!exported)
|
|
703
|
+
throw new Error(`${specifier} did not export a flat config array.`);
|
|
704
|
+
return exported;
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* The complete client preset: `export default brandlab.configs.next`.
|
|
708
|
+
* eslint-config-next is an optional peer, so it loads only when this preset is used.
|
|
709
|
+
*/
|
|
710
|
+
export function createBrandlabNextConfig(presets) {
|
|
711
|
+
return Object.freeze([
|
|
712
|
+
...presets.coreWebVitals,
|
|
713
|
+
...presets.typescript,
|
|
714
|
+
recommended,
|
|
715
|
+
{
|
|
716
|
+
name: 'brandlab/next',
|
|
717
|
+
rules: {
|
|
718
|
+
// Apostrophes and quotes are ordinary Australian English copy in JSX text.
|
|
719
|
+
'react/no-unescaped-entities': 'off',
|
|
720
|
+
},
|
|
721
|
+
},
|
|
722
|
+
{ name: 'brandlab/next-ignores', ignores: NEXT_CONFIG_IGNORES },
|
|
723
|
+
]);
|
|
724
|
+
}
|
|
725
|
+
function loadNextConfig() {
|
|
726
|
+
const require = createRequire(import.meta.url);
|
|
727
|
+
const load = (specifier) => {
|
|
728
|
+
try {
|
|
729
|
+
return toConfigArray(require(specifier), specifier);
|
|
730
|
+
}
|
|
731
|
+
catch (error) {
|
|
732
|
+
throw new Error(`brandlab.configs.next requires ${specifier}. Install eslint-config-next at the exact version of next.`, { cause: error });
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
return createBrandlabNextConfig({
|
|
736
|
+
coreWebVitals: load('eslint-config-next/core-web-vitals'),
|
|
737
|
+
typescript: load('eslint-config-next/typescript'),
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
let nextConfig;
|
|
690
741
|
const plugin = {
|
|
691
742
|
rules,
|
|
692
743
|
configs: {
|
|
693
|
-
recommended
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
rules: recommendedRules,
|
|
744
|
+
recommended,
|
|
745
|
+
get next() {
|
|
746
|
+
nextConfig ??= loadNextConfig();
|
|
747
|
+
return nextConfig;
|
|
698
748
|
},
|
|
699
749
|
},
|
|
700
750
|
};
|
|
701
|
-
|
|
751
|
+
recommended.plugins.brandlab = plugin;
|
|
702
752
|
export default plugin;
|
|
703
753
|
//# 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":"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","sourcesContent":["type AstNode = {\n type?: string\n [key: string]: unknown\n}\n\ntype ReportDescriptor = {\n node: unknown\n messageId?: string\n message?: string\n data?: Record<string, string>\n}\n\ntype RuleContext = {\n filename?: string\n getFilename?: () => string\n getSourceCode?: () => {\n getText?: (node: unknown) => string\n }\n physicalFilename?: string\n report: (descriptor: ReportDescriptor) => void\n sourceCode?: {\n getText?: (node: unknown) => string\n }\n}\n\nfunction getContextFilename(context: RuleContext): string {\n return (\n context.filename ??\n context.physicalFilename ??\n context.getFilename?.() ??\n ''\n ).replaceAll('\\\\', '/')\n}\n\ntype Visitor = Record<string, (node: unknown) => void>\n\ntype RuleModule = {\n meta: {\n type: 'problem'\n docs: {\n description: string\n recommended: boolean\n }\n messages: Record<string, string>\n schema: []\n }\n create: (context: RuleContext) => Visitor\n}\n\nexport const RULE_IDS = Object.freeze({\n noRetiredAnalyticsEvents: 'no-retired-analytics-events',\n noRawJsonLd: 'no-raw-json-ld',\n noAllowIndexingTrue: 'no-allow-indexing-true',\n noUnsafeRichTextSinks: 'no-unsafe-rich-text-sinks',\n noProtectedPlatformReimplementation: 'no-protected-platform-reimplementation',\n noAnalyticsPii: 'no-analytics-pii',\n noUnsafeExternalLinks: 'no-unsafe-external-links',\n noRawImageElements: 'no-raw-image-elements',\n} as const)\n\nfunction asNode(value: unknown): AstNode | null {\n return value && typeof value === 'object' ? (value as AstNode) : null\n}\n\nfunction getStaticString(value: unknown): string | null {\n const node = asNode(value)\n if (!node) return null\n\n if (node.type === 'Literal' && typeof node.value === 'string') return node.value\n if (node.type === 'Identifier' || node.type === 'JSXIdentifier') {\n return typeof node.name === 'string' ? node.name : null\n }\n if (node.type === 'TemplateElement') {\n const templateValue = asNode(node.value)\n return typeof templateValue?.raw === 'string' ? templateValue.raw : null\n }\n if (node.type === 'TemplateLiteral') {\n const expressions = Array.isArray(node.expressions) ? node.expressions : []\n const quasis = Array.isArray(node.quasis) ? node.quasis : []\n if (expressions.length > 0) return null\n return quasis.map(getStaticString).join('')\n }\n if (node.type === 'JSXExpressionContainer') return getStaticString(node.expression)\n if (node.type === 'JSXAttribute') return getStaticString(node.value)\n if (node.type === 'ChainExpression') return getStaticString(node.expression)\n\n return null\n}\n\nfunction getIdentifierName(value: unknown): string | null {\n const node = asNode(value)\n if (!node) return null\n if (node.type === 'Identifier' || node.type === 'JSXIdentifier') {\n return typeof node.name === 'string' ? node.name : null\n }\n return null\n}\n\nfunction getSourceText(context: RuleContext, node: unknown): string {\n const sourceCode = context.sourceCode ?? context.getSourceCode?.()\n return sourceCode?.getText?.(node) ?? ''\n}\n\nfunction defineRule(options: {\n description: string\n messages: Record<string, string>\n create: (context: RuleContext) => Visitor\n}): RuleModule {\n return {\n meta: {\n type: 'problem',\n docs: {\n description: options.description,\n recommended: true,\n },\n messages: options.messages,\n schema: [],\n },\n create: options.create,\n }\n}\n\nfunction createTextRule(options: {\n description: string\n messageId: string\n message: string\n matcher: (text: string, context: RuleContext) => boolean\n}): RuleModule {\n return defineRule({\n description: options.description,\n messages: { [options.messageId]: options.message },\n create(context) {\n function inspect(node: unknown) {\n const text = getStaticString(node)\n if (text && options.matcher(text, context)) {\n context.report({ node, messageId: options.messageId })\n }\n }\n\n return {\n Literal: inspect,\n TemplateElement: inspect,\n }\n },\n })\n}\n\nfunction containsAllowIndexingTrue(text: string): boolean {\n return (\n text.includes('ALLOW_INDEXING=true') ||\n /ALLOW_INDEXING[\\s\\S]{0,80}['\"]true['\"]/.test(text)\n )\n}\n\nconst noAllowIndexingTrueRule = defineRule({\n description: 'Disallow ALLOW_INDEXING=true; only ALLOW_INDEXING=1 is supported.',\n messages: {\n allowIndexingTrue: 'Use ALLOW_INDEXING=1 as the only explicit indexing override.',\n },\n create(context) {\n function inspectStringNode(node: unknown) {\n const text = getStaticString(node)\n if (text && containsAllowIndexingTrue(text)) {\n context.report({ node, messageId: 'allowIndexingTrue' })\n }\n }\n\n function inspectSourceNode(node: unknown) {\n const text = getSourceText(context, node)\n if (text && containsAllowIndexingTrue(text)) {\n context.report({ node, messageId: 'allowIndexingTrue' })\n }\n }\n\n return {\n BinaryExpression: inspectSourceNode,\n Literal: inspectStringNode,\n Property: inspectSourceNode,\n TemplateElement: inspectStringNode,\n }\n },\n})\n\nconst retiredAnalyticsEvents = new Set([\n 'contact_form_submission',\n 'phone_call',\n 'phone_calls',\n 'form_start',\n 'cta_click',\n])\n\nconst protectedPlatformNames = new Set([\n 'BrandlabBreadcrumbs',\n 'ContactFormEmail',\n 'SchemaScript',\n 'buildBrandlabMetadata',\n 'buildLocalBusinessSchema',\n 'buildNextMetadata',\n 'buildRobotsMetadata',\n 'buildSchemaGraph',\n 'buildSitemapEntries',\n 'createRouteAwareMdxBlogAdapter',\n 'createRouteAwareStructuredBlogAdapter',\n 'createBrandlabContactRuntime',\n 'createNextMetadataBuilder',\n 'defineAnalyticsContract',\n 'defineBrandlabBusiness',\n 'defineBrandlabContact',\n 'defineBrandlabProject',\n 'defineBreadcrumbTrail',\n 'defineContactContract',\n 'defineRouteCatalog',\n 'installPhoneClickListener',\n 'renderContactEmail',\n 'sitemapIndexXmlResponse',\n 'sitemapXmlResponse',\n 'trackBrandlabBrowserEvent',\n])\n\nconst protectedDirectCalls = new Set([\n 'dataLayer.push',\n 'globalThis.dataLayer.push',\n 'globalThis.gtag',\n 'gtag',\n 'window.dataLayer.push',\n 'window.gtag',\n])\n\nfunction isSharedPlatformImplementation(context: RuleContext): boolean {\n const filename = getContextFilename(context)\n return (\n filename.includes('/node_modules/@brandlab-digital/') ||\n /(?:^|\\/)standards\\/source\\/packages\\/(?:site-core|site-next)\\//.test(filename)\n )\n}\n\nfunction getMemberPath(value: unknown): string | null {\n const node = asNode(value)\n if (!node) return null\n if (node.type === 'ChainExpression') return getMemberPath(node.expression)\n if (node.type === 'Identifier') return getIdentifierName(node)\n if (node.type === 'ThisExpression') return 'this'\n if (node.type !== 'MemberExpression') return null\n\n const objectPath = getMemberPath(node.object)\n const propertyName = node.computed\n ? getStaticString(node.property)\n : getIdentifierName(node.property)\n return objectPath && propertyName ? `${objectPath}.${propertyName}` : null\n}\n\nfunction getDeclarationName(value: unknown): string | null {\n const node = asNode(value)\n if (!node) return null\n return getIdentifierName(node.id)\n}\n\nconst noProtectedPlatformReimplementationRule = defineRule({\n description: 'Disallow local reimplementation of protected Brandlab runtime surfaces.',\n messages: {\n protectedDeclaration:\n '{{name}} is a protected Brandlab platform surface. Import the shared implementation instead of declaring it locally.',\n protectedCall:\n '{{name}} bypasses protected Brandlab delivery or analytics behaviour. Use the shared platform adapter.',\n },\n create(context) {\n if (isSharedPlatformImplementation(context)) return {} as Visitor\n\n function inspectDeclaration(node: unknown) {\n const name = getDeclarationName(node)\n if (name && protectedPlatformNames.has(name)) {\n context.report({\n node,\n messageId: 'protectedDeclaration',\n data: { name },\n })\n }\n }\n\n function inspectCall(nodeValue: unknown) {\n const node = asNode(nodeValue)\n const callPath = getMemberPath(node?.callee)\n if (!callPath) return\n if (protectedDirectCalls.has(callPath) || callPath.endsWith('.emails.send')) {\n context.report({\n node: nodeValue,\n messageId: 'protectedCall',\n data: { name: callPath },\n })\n }\n }\n\n return {\n CallExpression: inspectCall,\n ClassDeclaration: inspectDeclaration,\n FunctionDeclaration: inspectDeclaration,\n VariableDeclarator: inspectDeclaration,\n }\n },\n})\n\nfunction getJsxElementName(value: unknown): string | null {\n const node = asNode(value)\n if (!node) return null\n const direct = getIdentifierName(node)\n if (direct) return direct\n if (node.type !== 'JSXMemberExpression') return null\n const objectName = getJsxElementName(node.object)\n const propertyName = getJsxElementName(node.property)\n return objectName && propertyName ? `${objectName}.${propertyName}` : null\n}\n\nfunction getJsxAttribute(openingElement: AstNode, name: string): AstNode | null {\n const attributes = Array.isArray(openingElement.attributes) ? openingElement.attributes : []\n return (\n attributes\n .map(asNode)\n .find(\n (attribute) =>\n attribute?.type === 'JSXAttribute' &&\n getIdentifierName(attribute.name)?.toLowerCase() === name.toLowerCase(),\n ) ?? null\n )\n}\n\nfunction getObjectProperty(value: unknown, key: string): AstNode | null {\n const node = asNode(value)\n if (node?.type !== 'ObjectExpression') return null\n const properties = Array.isArray(node.properties) ? node.properties : []\n return (\n properties\n .map(asNode)\n .find(\n (property) =>\n property?.type === 'Property' &&\n getPropertyName(property)?.toLowerCase() === key.toLowerCase(),\n ) ?? null\n )\n}\n\nfunction getPropertyName(property: AstNode): string | null {\n return property.computed\n ? getStaticString(property.key)\n : getIdentifierName(property.key) ?? getStaticString(property.key)\n}\n\nfunction isRawJsonLdCreateElement(value: unknown): boolean {\n const node = asNode(value)\n if (node?.type !== 'CallExpression') return false\n const callee = getMemberPath(node.callee)\n if (callee !== 'createElement' && callee !== 'React.createElement') return false\n const args = Array.isArray(node.arguments) ? node.arguments : []\n if (getStaticString(args[0])?.toLowerCase() !== 'script') return false\n const typeProperty = getObjectProperty(args[1], 'type')\n return getStaticString(typeProperty?.value)?.toLowerCase() === 'application/ld+json'\n}\n\nconst noRawJsonLdRule = defineRule({\n description: 'Disallow raw JSON-LD scripts outside the shared Brandlab schema adapter.',\n messages: {\n rawJsonLd: 'Render JSON-LD through @brandlab-digital/site-next/schema.',\n },\n create(context) {\n if (isSharedPlatformImplementation(context)) return {} as Visitor\n\n function inspectOpeningElement(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (!node || getJsxElementName(node.name)?.toLowerCase() !== 'script') return\n const typeAttribute = getJsxAttribute(node, 'type')\n if (getStaticString(typeAttribute)?.toLowerCase() === 'application/ld+json') {\n context.report({ node: nodeValue, messageId: 'rawJsonLd' })\n }\n }\n\n function inspectCall(node: unknown) {\n if (isRawJsonLdCreateElement(node)) {\n context.report({ node, messageId: 'rawJsonLd' })\n }\n }\n\n function inspectLiteral(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (getStaticString(node)?.toLowerCase() !== 'application/ld+json') return\n const parentType = asNode(node?.parent)?.type\n if (parentType !== 'JSXAttribute' && parentType !== 'Property') {\n context.report({ node: nodeValue, messageId: 'rawJsonLd' })\n }\n }\n\n return {\n CallExpression: inspectCall,\n JSXOpeningElement: inspectOpeningElement,\n Literal: inspectLiteral,\n TemplateElement: inspectLiteral,\n }\n },\n})\n\nconst strictPiiTokens = new Set([\n 'attachment',\n 'attachment_name',\n 'contact_email',\n 'contact_name',\n 'customer_name',\n 'email',\n 'email_address',\n 'enquiry_message',\n 'file_name',\n 'filename',\n 'first_name',\n 'form_message',\n 'full_name',\n 'last_name',\n 'message',\n 'mobile',\n 'mobile_number',\n 'phone',\n 'phone_number',\n 'residential_address',\n 'street_address',\n 'user_email',\n 'user_phone',\n])\n\nconst contactOnlyPiiTokens = new Set(['address', 'name'])\n\nfunction normalizeToken(value: string): string {\n return value\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+|_+$/g, '')\n}\n\nfunction isPiiToken(value: string | null, includeContactOnly: boolean): boolean {\n if (!value) return false\n const normalized = normalizeToken(value)\n return (\n strictPiiTokens.has(normalized) ||\n (includeContactOnly && contactOnlyPiiTokens.has(normalized))\n )\n}\n\nfunction isAnalyticsSink(value: unknown): boolean {\n const path = getMemberPath(value)\n return (\n path === 'gtag' ||\n path === 'window.gtag' ||\n path === 'globalThis.gtag' ||\n path === 'dataLayer.push' ||\n path === 'window.dataLayer.push' ||\n path === 'globalThis.dataLayer.push' ||\n path === 'sendGAEvent' ||\n path === 'sendGTMEvent' ||\n path === 'trackBrandlabBrowserEvent' ||\n path === 'trackBrandlabEvent' ||\n path === 'ReactGA.event'\n )\n}\n\nfunction isContactAnalyticsCall(node: AstNode): boolean {\n const args = Array.isArray(node.arguments) ? node.arguments : []\n return args.some((argument) => {\n const value = getStaticString(argument)\n return value === 'contact_form' || value === 'phone_link_click' || value === 'phone_call'\n })\n}\n\nfunction looksLikeLiteralPii(value: string): boolean {\n const normalized = value.trim()\n if (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(normalized)) return true\n const digits = normalized.replace(/[^0-9]/g, '')\n return /^\\+?[0-9 ()-]+$/.test(normalized) && digits.length >= 10 && digits.length <= 15\n}\n\nfunction containsPiiReference(value: unknown, includeContactOnly: boolean): boolean {\n const node = asNode(value)\n if (!node) return false\n if (node.type === 'Identifier') {\n return isPiiToken(getIdentifierName(node), includeContactOnly)\n }\n if (node.type === 'MemberExpression') {\n const path = getMemberPath(node)\n const finalSegment = path?.split('.').at(-1) ?? null\n return isPiiToken(finalSegment, includeContactOnly)\n }\n if (node.type === 'Literal') {\n return typeof node.value === 'string' && looksLikeLiteralPii(node.value)\n }\n if (node.type === 'TemplateLiteral') {\n const expressions = Array.isArray(node.expressions) ? node.expressions : []\n return (\n expressions.some((expression) => containsPiiReference(expression, includeContactOnly)) ||\n (getStaticString(node) ? looksLikeLiteralPii(getStaticString(node) ?? '') : false)\n )\n }\n if (node.type === 'CallExpression') {\n const args = Array.isArray(node.arguments) ? node.arguments : []\n return args.some((argument) => containsPiiReference(argument, includeContactOnly))\n }\n if (node.type === 'ConditionalExpression') {\n return (\n containsPiiReference(node.consequent, includeContactOnly) ||\n containsPiiReference(node.alternate, includeContactOnly)\n )\n }\n if (node.type === 'LogicalExpression' || node.type === 'BinaryExpression') {\n return (\n containsPiiReference(node.left, includeContactOnly) ||\n containsPiiReference(node.right, includeContactOnly)\n )\n }\n return false\n}\n\nfunction collectPiiNodes(value: unknown, includeContactOnly: boolean): AstNode[] {\n const node = asNode(value)\n if (!node) return []\n if (node.type === 'ObjectExpression') {\n const properties = Array.isArray(node.properties) ? node.properties : []\n return properties.flatMap((property) => collectPiiNodes(property, includeContactOnly))\n }\n if (node.type === 'Property') {\n const key = getPropertyName(node)\n if (\n isPiiToken(key, includeContactOnly) ||\n containsPiiReference(node.value, includeContactOnly)\n ) {\n return [node]\n }\n return collectPiiNodes(node.value, includeContactOnly)\n }\n if (node.type === 'SpreadElement' || node.type === 'ExperimentalSpreadProperty') {\n return containsPiiReference(node.argument, includeContactOnly) ? [node] : []\n }\n if (node.type === 'ArrayExpression') {\n const elements = Array.isArray(node.elements) ? node.elements : []\n return elements.flatMap((element) => collectPiiNodes(element, includeContactOnly))\n }\n if (containsPiiReference(node, includeContactOnly)) return [node]\n return []\n}\n\nconst noAnalyticsPiiRule = defineRule({\n description: 'Disallow statically provable lead PII in analytics event payloads.',\n messages: {\n analyticsPii:\n 'Do not send lead PII or attachment details to analytics. Use the shared Brandlab analytics allowlist.',\n },\n create(context) {\n function inspectCall(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (node?.type !== 'CallExpression' || !isAnalyticsSink(node.callee)) return\n const includeContactOnly = isContactAnalyticsCall(node)\n const args = Array.isArray(node.arguments) ? node.arguments : []\n const reported = new Set<AstNode>()\n for (const argument of args) {\n for (const piiNode of collectPiiNodes(argument, includeContactOnly)) {\n if (reported.has(piiNode)) continue\n reported.add(piiNode)\n context.report({ node: piiNode, messageId: 'analyticsPii' })\n }\n }\n }\n\n return { CallExpression: inspectCall }\n },\n})\n\nfunction normalizeStaticUrl(value: string): string {\n return value.trim().replace(/[\\u0000-\\u0020]+/g, '').toLowerCase()\n}\n\nfunction isDangerousStaticUrl(value: string): boolean {\n return /^(?:javascript|vbscript):/.test(normalizeStaticUrl(value)) ||\n /^data:text\\/html(?:;|,)/.test(normalizeStaticUrl(value))\n}\n\nfunction isExternalStaticUrl(value: string): boolean {\n return /^(?:https?:)?\\/\\//i.test(value.trim())\n}\n\nfunction relHasNoopener(value: string | null): boolean {\n return Boolean(value?.toLowerCase().split(/\\s+/).includes('noopener'))\n}\n\nconst noUnsafeExternalLinksRule = defineRule({\n description: 'Disallow statically provable unsafe link schemes and external opener access.',\n messages: {\n unsafeLinkScheme: 'Do not use javascript:, vbscript:, or HTML data URLs in links.',\n missingNoopener:\n 'External links opened in a new context must include rel=\"noopener\".',\n },\n create(context) {\n function inspectOpeningElement(nodeValue: unknown) {\n const node = asNode(nodeValue)\n const elementName = getJsxElementName(node?.name)?.toLowerCase()\n if (!node || (elementName !== 'a' && elementName !== 'link')) return\n const href = getStaticString(getJsxAttribute(node, 'href'))\n if (!href) return\n if (isDangerousStaticUrl(href)) {\n context.report({ node: nodeValue, messageId: 'unsafeLinkScheme' })\n return\n }\n const target = getStaticString(getJsxAttribute(node, 'target'))\n if (\n isExternalStaticUrl(href) &&\n target?.toLowerCase() === '_blank' &&\n !relHasNoopener(getStaticString(getJsxAttribute(node, 'rel')))\n ) {\n context.report({ node: nodeValue, messageId: 'missingNoopener' })\n }\n }\n\n function inspectCall(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (node?.type !== 'CallExpression' || getMemberPath(node.callee) !== 'window.open') return\n const args = Array.isArray(node.arguments) ? node.arguments : []\n const url = getStaticString(args[0])\n if (!url) return\n if (isDangerousStaticUrl(url)) {\n context.report({ node: nodeValue, messageId: 'unsafeLinkScheme' })\n return\n }\n const target = getStaticString(args[1]) ?? '_blank'\n const features = getStaticString(args[2])\n if (\n isExternalStaticUrl(url) &&\n target.toLowerCase() === '_blank' &&\n !features?.toLowerCase().split(/\\s*,\\s*/).includes('noopener') &&\n !features?.toLowerCase().split(/\\s*,\\s*/).includes('noreferrer')\n ) {\n context.report({ node: nodeValue, messageId: 'missingNoopener' })\n }\n }\n\n return {\n CallExpression: inspectCall,\n JSXOpeningElement: inspectOpeningElement,\n }\n },\n})\n\nfunction isEmailRenderingFile(context: RuleContext): boolean {\n const filename = getContextFilename(context)\n return (\n /\\/(?:email|emails|contact-email)\\//i.test(filename) ||\n /(?:Email|EmailTemplate|ContactFormEmail)\\.(?:jsx|tsx)$/i.test(filename)\n )\n}\n\nconst noRawImageElementsRule = defineRule({\n description: 'Require Next.js-owned image delivery for website UI.',\n messages: {\n rawImage:\n 'Use next/image for website UI images. Raw image markup is reserved for reviewed getImageProps art direction and non-Next renderers such as email.',\n },\n create(context) {\n if (isEmailRenderingFile(context)) return {} as Visitor\n\n const getImagePropsBindings = new Set<string>()\n const nextImagePropBindings = new Set<string>()\n\n function inspectImport(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (node?.type !== 'ImportDeclaration' || getStaticString(node.source) !== 'next/image') {\n return\n }\n const specifiers = Array.isArray(node.specifiers) ? node.specifiers : []\n for (const specifierValue of specifiers) {\n const specifier = asNode(specifierValue)\n if (\n specifier?.type === 'ImportSpecifier' &&\n getIdentifierName(specifier.imported) === 'getImageProps'\n ) {\n const localName = getIdentifierName(specifier.local)\n if (localName) getImagePropsBindings.add(localName)\n }\n }\n }\n\n function inspectVariable(nodeValue: unknown) {\n const node = asNode(nodeValue)\n const initializer = asNode(node?.init)\n if (node?.type !== 'VariableDeclarator' || initializer?.type !== 'CallExpression') {\n return\n }\n const calleeName = getIdentifierName(initializer.callee)\n if (!calleeName || !getImagePropsBindings.has(calleeName)) return\n\n const pattern = asNode(node.id)\n if (pattern?.type !== 'ObjectPattern') return\n const properties = Array.isArray(pattern.properties) ? pattern.properties : []\n const propsProperty = properties\n .map(asNode)\n .find(\n (property) =>\n property?.type === 'Property' &&\n getIdentifierName(property.key) === 'props',\n )\n const propsPattern = asNode(propsProperty?.value)\n const directBinding = getIdentifierName(propsPattern)\n if (directBinding) {\n nextImagePropBindings.add(directBinding)\n return\n }\n if (propsPattern?.type !== 'ObjectPattern') return\n const nestedProperties = Array.isArray(propsPattern.properties)\n ? propsPattern.properties\n : []\n for (const propertyValue of nestedProperties) {\n const property = asNode(propertyValue)\n if (property?.type !== 'RestElement') continue\n const binding = getIdentifierName(property.argument)\n if (binding) nextImagePropBindings.add(binding)\n }\n }\n\n function usesReviewedNextImageProps(node: AstNode) {\n if (getJsxAttribute(node, 'src') || getJsxAttribute(node, 'srcSet')) return false\n const attributes = Array.isArray(node.attributes) ? node.attributes : []\n return attributes.some((attributeValue) => {\n const attribute = asNode(attributeValue)\n return (\n attribute?.type === 'JSXSpreadAttribute' &&\n nextImagePropBindings.has(getIdentifierName(attribute.argument) ?? '')\n )\n })\n }\n\n function inspectOpeningElement(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (\n node &&\n getJsxElementName(node.name)?.toLowerCase() === 'img' &&\n !usesReviewedNextImageProps(node)\n ) {\n context.report({ node: nodeValue, messageId: 'rawImage' })\n }\n }\n\n function inspectCall(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (node?.type !== 'CallExpression') return\n const callee = getMemberPath(node.callee)\n const args = Array.isArray(node.arguments) ? node.arguments : []\n if (\n (callee === 'createElement' || callee === 'React.createElement') &&\n getStaticString(args[0])?.toLowerCase() === 'img'\n ) {\n context.report({ node: nodeValue, messageId: 'rawImage' })\n }\n }\n\n return {\n CallExpression: inspectCall,\n ImportDeclaration: inspectImport,\n JSXOpeningElement: inspectOpeningElement,\n VariableDeclarator: inspectVariable,\n }\n },\n})\n\nconst noUnsafeRichTextSinksRule = defineRule({\n description: 'Disallow visible rich text sinks that bypass a sanitizer.',\n messages: {\n unsafeRichTextSink: 'Visible rich text must be sanitizer-backed and tested.',\n },\n create(context) {\n function inspectSourceNode(node: unknown) {\n const text = getSourceText(context, node)\n if (\n text.includes('dangerouslySetInnerHTML') &&\n !/saniti[sz](?:e|ed|er)/i.test(text)\n ) {\n context.report({ node, messageId: 'unsafeRichTextSink' })\n }\n }\n\n function inspectStringNode(node: unknown) {\n const text = getStaticString(node)\n if (\n text?.includes('dangerouslySetInnerHTML') &&\n !/saniti[sz](?:e|ed|er)/i.test(text)\n ) {\n context.report({ node, messageId: 'unsafeRichTextSink' })\n }\n }\n\n return {\n JSXAttribute: inspectSourceNode,\n Literal: inspectStringNode,\n Property: inspectSourceNode,\n TemplateElement: inspectStringNode,\n }\n },\n})\n\nexport const rules = {\n [RULE_IDS.noRetiredAnalyticsEvents]: createTextRule({\n description: 'Disallow retired Brandlab analytics event names.',\n messageId: 'retiredAnalyticsEvent',\n message: 'Use contact_form for accepted forms and phone_link_click for telephone-link diagnostics.',\n matcher: (text) => retiredAnalyticsEvents.has(text),\n }),\n [RULE_IDS.noRawJsonLd]: noRawJsonLdRule,\n [RULE_IDS.noAllowIndexingTrue]: noAllowIndexingTrueRule,\n [RULE_IDS.noUnsafeRichTextSinks]: noUnsafeRichTextSinksRule,\n [RULE_IDS.noProtectedPlatformReimplementation]: noProtectedPlatformReimplementationRule,\n [RULE_IDS.noAnalyticsPii]: noAnalyticsPiiRule,\n [RULE_IDS.noUnsafeExternalLinks]: noUnsafeExternalLinksRule,\n [RULE_IDS.noRawImageElements]: noRawImageElementsRule,\n} satisfies Record<string, RuleModule>\n\ntype BrandlabPlugin = {\n rules: typeof rules\n configs: {\n recommended: {\n plugins: {\n brandlab: unknown\n }\n rules: Record<string, 'error'>\n }\n }\n}\n\nconst recommendedRules = Object.fromEntries(\n Object.keys(rules).map((ruleId) => [`brandlab/${ruleId}`, 'error' as const]),\n) as Record<string, 'error'>\n\nconst plugin: BrandlabPlugin = {\n rules,\n configs: {\n recommended: {\n plugins: {\n brandlab: undefined,\n },\n rules: recommendedRules,\n },\n },\n}\n\nplugin.configs.recommended.plugins.brandlab = plugin\n\nexport default plugin\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { createRequire } from 'node:module'\n\ntype AstNode = {\n type?: string\n [key: string]: unknown\n}\n\ntype ReportDescriptor = {\n node: unknown\n messageId?: string\n message?: string\n data?: Record<string, string>\n}\n\ntype RuleContext = {\n filename?: string\n getFilename?: () => string\n physicalFilename?: string\n report: (descriptor: ReportDescriptor) => void\n}\n\nfunction getContextFilename(context: RuleContext): string {\n return (\n context.filename ??\n context.physicalFilename ??\n context.getFilename?.() ??\n ''\n ).replaceAll('\\\\', '/')\n}\n\ntype Visitor = Record<string, (node: unknown) => void>\n\ntype RuleModule = {\n meta: {\n type: 'problem'\n docs: {\n description: string\n recommended: boolean\n }\n messages: Record<string, string>\n schema: []\n }\n create: (context: RuleContext) => Visitor\n}\n\nexport const RULE_IDS = Object.freeze({\n noRetiredAnalyticsEvents: 'no-retired-analytics-events',\n noRawJsonLd: 'no-raw-json-ld',\n noUnsafeRichTextSinks: 'no-unsafe-rich-text-sinks',\n noProtectedPlatformReimplementation: 'no-protected-platform-reimplementation',\n noAnalyticsPii: 'no-analytics-pii',\n noUnsafeExternalLinks: 'no-unsafe-external-links',\n noRawImageElements: 'no-raw-image-elements',\n} as const)\n\nfunction asNode(value: unknown): AstNode | null {\n return value && typeof value === 'object' ? (value as AstNode) : null\n}\n\nfunction getStaticString(value: unknown): string | null {\n const node = asNode(value)\n if (!node) return null\n\n if (node.type === 'Literal' && typeof node.value === 'string') return node.value\n if (node.type === 'Identifier' || node.type === 'JSXIdentifier') {\n return typeof node.name === 'string' ? node.name : null\n }\n if (node.type === 'TemplateElement') {\n const templateValue = asNode(node.value)\n return typeof templateValue?.raw === 'string' ? templateValue.raw : null\n }\n if (node.type === 'TemplateLiteral') {\n const expressions = Array.isArray(node.expressions) ? node.expressions : []\n const quasis = Array.isArray(node.quasis) ? node.quasis : []\n if (expressions.length > 0) return null\n return quasis.map(getStaticString).join('')\n }\n if (node.type === 'JSXExpressionContainer') return getStaticString(node.expression)\n if (node.type === 'JSXAttribute') return getStaticString(node.value)\n if (node.type === 'ChainExpression') return getStaticString(node.expression)\n\n return null\n}\n\nfunction getIdentifierName(value: unknown): string | null {\n const node = asNode(value)\n if (!node) return null\n if (node.type === 'Identifier' || node.type === 'JSXIdentifier') {\n return typeof node.name === 'string' ? node.name : null\n }\n return null\n}\n\nfunction defineRule(options: {\n description: string\n messages: Record<string, string>\n create: (context: RuleContext) => Visitor\n}): RuleModule {\n return {\n meta: {\n type: 'problem',\n docs: {\n description: options.description,\n recommended: true,\n },\n messages: options.messages,\n schema: [],\n },\n create: options.create,\n }\n}\n\nfunction createTextRule(options: {\n description: string\n messageId: string\n message: string\n matcher: (text: string, context: RuleContext) => boolean\n}): RuleModule {\n return defineRule({\n description: options.description,\n messages: { [options.messageId]: options.message },\n create(context) {\n function inspect(node: unknown) {\n const text = getStaticString(node)\n if (text && options.matcher(text, context)) {\n context.report({ node, messageId: options.messageId })\n }\n }\n\n return {\n Literal: inspect,\n TemplateElement: inspect,\n }\n },\n })\n}\n\nconst retiredAnalyticsEvents = new Set([\n 'contact_form_submission',\n 'phone_call',\n 'phone_calls',\n 'form_start',\n 'form_submit',\n 'generate_lead',\n 'cta_click',\n])\n\nconst protectedPlatformNames = new Set([\n 'BrandlabBreadcrumbs',\n 'ContactFormEmail',\n 'SchemaScript',\n 'buildBrandlabMetadata',\n 'buildLocalBusinessSchema',\n 'buildNextMetadata',\n 'buildRobotsMetadata',\n 'buildSchemaGraph',\n 'buildSitemapEntries',\n 'createRouteAwareMdxBlogAdapter',\n 'createRouteAwareStructuredBlogAdapter',\n 'createBrandlabContactRuntime',\n 'createNextMetadataBuilder',\n 'defineAnalyticsContract',\n 'defineBrandlabBusiness',\n 'defineBrandlabContact',\n 'defineBrandlabProject',\n 'defineBreadcrumbTrail',\n 'defineContactContract',\n 'defineRouteCatalog',\n 'installPhoneClickListener',\n 'renderContactEmail',\n 'sitemapIndexXmlResponse',\n 'sitemapXmlResponse',\n 'trackBrandlabBrowserEvent',\n])\n\nconst protectedDirectCalls = new Set([\n 'dataLayer.push',\n 'globalThis.dataLayer.push',\n 'globalThis.gtag',\n 'gtag',\n 'window.dataLayer.push',\n 'window.gtag',\n])\n\nfunction isSharedPlatformImplementation(context: RuleContext): boolean {\n const filename = getContextFilename(context)\n return (\n filename.includes('/node_modules/@brandlab-digital/') ||\n /(?:^|\\/)standards\\/source\\/packages\\/(?:site-core|site-next)\\//.test(filename)\n )\n}\n\nfunction getMemberPath(value: unknown): string | null {\n const node = asNode(value)\n if (!node) return null\n if (node.type === 'ChainExpression') return getMemberPath(node.expression)\n if (node.type === 'Identifier') return getIdentifierName(node)\n if (node.type === 'ThisExpression') return 'this'\n if (node.type !== 'MemberExpression') return null\n\n const objectPath = getMemberPath(node.object)\n const propertyName = node.computed\n ? getStaticString(node.property)\n : getIdentifierName(node.property)\n return objectPath && propertyName ? `${objectPath}.${propertyName}` : null\n}\n\nfunction getDeclarationName(value: unknown): string | null {\n const node = asNode(value)\n if (!node) return null\n return getIdentifierName(node.id)\n}\n\nconst noProtectedPlatformReimplementationRule = defineRule({\n description: 'Disallow local reimplementation of protected Brandlab runtime surfaces.',\n messages: {\n protectedDeclaration:\n '{{name}} is a protected Brandlab platform surface. Import the shared implementation instead of declaring it locally.',\n protectedCall:\n '{{name}} bypasses protected Brandlab delivery or analytics behaviour. Use the shared platform adapter.',\n },\n create(context) {\n if (isSharedPlatformImplementation(context)) return {} as Visitor\n\n function inspectDeclaration(node: unknown) {\n const name = getDeclarationName(node)\n if (name && protectedPlatformNames.has(name)) {\n context.report({\n node,\n messageId: 'protectedDeclaration',\n data: { name },\n })\n }\n }\n\n function inspectCall(nodeValue: unknown) {\n const node = asNode(nodeValue)\n const callPath = getMemberPath(node?.callee)\n if (!callPath) return\n if (protectedDirectCalls.has(callPath) || callPath.endsWith('.emails.send')) {\n context.report({\n node: nodeValue,\n messageId: 'protectedCall',\n data: { name: callPath },\n })\n }\n }\n\n return {\n CallExpression: inspectCall,\n ClassDeclaration: inspectDeclaration,\n FunctionDeclaration: inspectDeclaration,\n VariableDeclarator: inspectDeclaration,\n }\n },\n})\n\nfunction getJsxElementName(value: unknown): string | null {\n const node = asNode(value)\n if (!node) return null\n const direct = getIdentifierName(node)\n if (direct) return direct\n if (node.type !== 'JSXMemberExpression') return null\n const objectName = getJsxElementName(node.object)\n const propertyName = getJsxElementName(node.property)\n return objectName && propertyName ? `${objectName}.${propertyName}` : null\n}\n\nfunction getJsxAttribute(openingElement: AstNode, name: string): AstNode | null {\n const attributes = Array.isArray(openingElement.attributes) ? openingElement.attributes : []\n return (\n attributes\n .map(asNode)\n .find(\n (attribute) =>\n attribute?.type === 'JSXAttribute' &&\n getIdentifierName(attribute.name)?.toLowerCase() === name.toLowerCase(),\n ) ?? null\n )\n}\n\nfunction getObjectProperty(value: unknown, key: string): AstNode | null {\n const node = asNode(value)\n if (node?.type !== 'ObjectExpression') return null\n const properties = Array.isArray(node.properties) ? node.properties : []\n return (\n properties\n .map(asNode)\n .find(\n (property) =>\n property?.type === 'Property' &&\n getPropertyName(property)?.toLowerCase() === key.toLowerCase(),\n ) ?? null\n )\n}\n\nfunction getPropertyName(property: AstNode): string | null {\n return property.computed\n ? getStaticString(property.key)\n : getIdentifierName(property.key) ?? getStaticString(property.key)\n}\n\nfunction isRawJsonLdCreateElement(value: unknown): boolean {\n const node = asNode(value)\n if (node?.type !== 'CallExpression') return false\n const callee = getMemberPath(node.callee)\n if (callee !== 'createElement' && callee !== 'React.createElement') return false\n const args = Array.isArray(node.arguments) ? node.arguments : []\n if (getStaticString(args[0])?.toLowerCase() !== 'script') return false\n const typeProperty = getObjectProperty(args[1], 'type')\n return getStaticString(typeProperty?.value)?.toLowerCase() === 'application/ld+json'\n}\n\nconst noRawJsonLdRule = defineRule({\n description: 'Disallow raw JSON-LD scripts outside the shared Brandlab schema adapter.',\n messages: {\n rawJsonLd: 'Render JSON-LD through @brandlab-digital/site-next/schema.',\n },\n create(context) {\n if (isSharedPlatformImplementation(context)) return {} as Visitor\n\n function inspectOpeningElement(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (!node || getJsxElementName(node.name)?.toLowerCase() !== 'script') return\n const typeAttribute = getJsxAttribute(node, 'type')\n if (getStaticString(typeAttribute)?.toLowerCase() === 'application/ld+json') {\n context.report({ node: nodeValue, messageId: 'rawJsonLd' })\n }\n }\n\n function inspectCall(node: unknown) {\n if (isRawJsonLdCreateElement(node)) {\n context.report({ node, messageId: 'rawJsonLd' })\n }\n }\n\n function inspectLiteral(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (getStaticString(node)?.toLowerCase() !== 'application/ld+json') return\n const parentType = asNode(node?.parent)?.type\n if (parentType !== 'JSXAttribute' && parentType !== 'Property') {\n context.report({ node: nodeValue, messageId: 'rawJsonLd' })\n }\n }\n\n return {\n CallExpression: inspectCall,\n JSXOpeningElement: inspectOpeningElement,\n Literal: inspectLiteral,\n TemplateElement: inspectLiteral,\n }\n },\n})\n\nconst strictPiiTokens = new Set([\n 'attachment',\n 'attachment_name',\n 'contact_email',\n 'contact_name',\n 'customer_name',\n 'email',\n 'email_address',\n 'enquiry_message',\n 'file_name',\n 'filename',\n 'first_name',\n 'form_message',\n 'full_name',\n 'last_name',\n 'message',\n 'mobile',\n 'mobile_number',\n 'phone',\n 'phone_number',\n 'residential_address',\n 'street_address',\n 'user_email',\n 'user_phone',\n])\n\nconst contactOnlyPiiTokens = new Set(['address', 'name'])\n\nfunction normalizeToken(value: string): string {\n return value\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+|_+$/g, '')\n}\n\nfunction isPiiToken(value: string | null, includeContactOnly: boolean): boolean {\n if (!value) return false\n const normalized = normalizeToken(value)\n return (\n strictPiiTokens.has(normalized) ||\n (includeContactOnly && contactOnlyPiiTokens.has(normalized))\n )\n}\n\nfunction isAnalyticsSink(value: unknown): boolean {\n const path = getMemberPath(value)\n return (\n path === 'gtag' ||\n path === 'window.gtag' ||\n path === 'globalThis.gtag' ||\n path === 'dataLayer.push' ||\n path === 'window.dataLayer.push' ||\n path === 'globalThis.dataLayer.push' ||\n path === 'sendGAEvent' ||\n path === 'sendGTMEvent' ||\n path === 'trackBrandlabBrowserEvent' ||\n path === 'trackBrandlabEvent' ||\n path === 'ReactGA.event'\n )\n}\n\n/** Lead and phone events, current or retired, whose payloads must never carry contact details. */\nconst contactAnalyticsEvents = new Set([\n 'contact_form',\n 'phone_link_click',\n 'phone_call',\n 'generate_lead',\n 'form_submit',\n])\n\nfunction isContactAnalyticsCall(node: AstNode): boolean {\n const args = Array.isArray(node.arguments) ? node.arguments : []\n return args.some((argument) => {\n const value = getStaticString(argument)\n return value !== null && contactAnalyticsEvents.has(value)\n })\n}\n\nfunction looksLikeLiteralPii(value: string): boolean {\n const normalized = value.trim()\n if (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(normalized)) return true\n const digits = normalized.replace(/[^0-9]/g, '')\n return /^\\+?[0-9 ()-]+$/.test(normalized) && digits.length >= 10 && digits.length <= 15\n}\n\nfunction containsPiiReference(value: unknown, includeContactOnly: boolean): boolean {\n const node = asNode(value)\n if (!node) return false\n if (node.type === 'Identifier') {\n return isPiiToken(getIdentifierName(node), includeContactOnly)\n }\n if (node.type === 'MemberExpression') {\n const path = getMemberPath(node)\n const finalSegment = path?.split('.').at(-1) ?? null\n return isPiiToken(finalSegment, includeContactOnly)\n }\n if (node.type === 'Literal') {\n return typeof node.value === 'string' && looksLikeLiteralPii(node.value)\n }\n if (node.type === 'TemplateLiteral') {\n const expressions = Array.isArray(node.expressions) ? node.expressions : []\n return (\n expressions.some((expression) => containsPiiReference(expression, includeContactOnly)) ||\n (getStaticString(node) ? looksLikeLiteralPii(getStaticString(node) ?? '') : false)\n )\n }\n if (node.type === 'CallExpression') {\n const args = Array.isArray(node.arguments) ? node.arguments : []\n return args.some((argument) => containsPiiReference(argument, includeContactOnly))\n }\n if (node.type === 'ConditionalExpression') {\n return (\n containsPiiReference(node.consequent, includeContactOnly) ||\n containsPiiReference(node.alternate, includeContactOnly)\n )\n }\n if (node.type === 'LogicalExpression' || node.type === 'BinaryExpression') {\n return (\n containsPiiReference(node.left, includeContactOnly) ||\n containsPiiReference(node.right, includeContactOnly)\n )\n }\n return false\n}\n\nfunction collectPiiNodes(value: unknown, includeContactOnly: boolean): AstNode[] {\n const node = asNode(value)\n if (!node) return []\n if (node.type === 'ObjectExpression') {\n const properties = Array.isArray(node.properties) ? node.properties : []\n return properties.flatMap((property) => collectPiiNodes(property, includeContactOnly))\n }\n if (node.type === 'Property') {\n const key = getPropertyName(node)\n if (\n isPiiToken(key, includeContactOnly) ||\n containsPiiReference(node.value, includeContactOnly)\n ) {\n return [node]\n }\n return collectPiiNodes(node.value, includeContactOnly)\n }\n if (node.type === 'SpreadElement' || node.type === 'ExperimentalSpreadProperty') {\n return containsPiiReference(node.argument, includeContactOnly) ? [node] : []\n }\n if (node.type === 'ArrayExpression') {\n const elements = Array.isArray(node.elements) ? node.elements : []\n return elements.flatMap((element) => collectPiiNodes(element, includeContactOnly))\n }\n if (containsPiiReference(node, includeContactOnly)) return [node]\n return []\n}\n\nconst noAnalyticsPiiRule = defineRule({\n description: 'Disallow statically provable lead PII in analytics event payloads.',\n messages: {\n analyticsPii:\n 'Do not send lead PII or attachment details to analytics. Use the shared Brandlab analytics allowlist.',\n },\n create(context) {\n function inspectCall(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (node?.type !== 'CallExpression' || !isAnalyticsSink(node.callee)) return\n const includeContactOnly = isContactAnalyticsCall(node)\n const args = Array.isArray(node.arguments) ? node.arguments : []\n const reported = new Set<AstNode>()\n for (const argument of args) {\n for (const piiNode of collectPiiNodes(argument, includeContactOnly)) {\n if (reported.has(piiNode)) continue\n reported.add(piiNode)\n context.report({ node: piiNode, messageId: 'analyticsPii' })\n }\n }\n }\n\n return { CallExpression: inspectCall }\n },\n})\n\nfunction normalizeStaticUrl(value: string): string {\n return value.trim().replace(/[\\u0000-\\u0020]+/g, '').toLowerCase()\n}\n\nfunction isDangerousStaticUrl(value: string): boolean {\n return /^(?:javascript|vbscript):/.test(normalizeStaticUrl(value)) ||\n /^data:text\\/html(?:;|,)/.test(normalizeStaticUrl(value))\n}\n\nfunction isExternalStaticUrl(value: string): boolean {\n return /^(?:https?:)?\\/\\//i.test(value.trim())\n}\n\nfunction relHasNoopener(value: string | null): boolean {\n return Boolean(value?.toLowerCase().split(/\\s+/).includes('noopener'))\n}\n\nconst noUnsafeExternalLinksRule = defineRule({\n description: 'Disallow statically provable unsafe link schemes and external opener access.',\n messages: {\n unsafeLinkScheme: 'Do not use javascript:, vbscript:, or HTML data URLs in links.',\n missingNoopener:\n 'External links opened in a new context must include rel=\"noopener\".',\n },\n create(context) {\n function inspectOpeningElement(nodeValue: unknown) {\n const node = asNode(nodeValue)\n const elementName = getJsxElementName(node?.name)?.toLowerCase()\n if (!node || (elementName !== 'a' && elementName !== 'link')) return\n const href = getStaticString(getJsxAttribute(node, 'href'))\n if (!href) return\n if (isDangerousStaticUrl(href)) {\n context.report({ node: nodeValue, messageId: 'unsafeLinkScheme' })\n return\n }\n const target = getStaticString(getJsxAttribute(node, 'target'))\n if (\n isExternalStaticUrl(href) &&\n target?.toLowerCase() === '_blank' &&\n !relHasNoopener(getStaticString(getJsxAttribute(node, 'rel')))\n ) {\n context.report({ node: nodeValue, messageId: 'missingNoopener' })\n }\n }\n\n function inspectCall(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (node?.type !== 'CallExpression' || getMemberPath(node.callee) !== 'window.open') return\n const args = Array.isArray(node.arguments) ? node.arguments : []\n const url = getStaticString(args[0])\n if (!url) return\n if (isDangerousStaticUrl(url)) {\n context.report({ node: nodeValue, messageId: 'unsafeLinkScheme' })\n return\n }\n const target = getStaticString(args[1]) ?? '_blank'\n const features = getStaticString(args[2])\n if (\n isExternalStaticUrl(url) &&\n target.toLowerCase() === '_blank' &&\n !features?.toLowerCase().split(/\\s*,\\s*/).includes('noopener') &&\n !features?.toLowerCase().split(/\\s*,\\s*/).includes('noreferrer')\n ) {\n context.report({ node: nodeValue, messageId: 'missingNoopener' })\n }\n }\n\n return {\n CallExpression: inspectCall,\n JSXOpeningElement: inspectOpeningElement,\n }\n },\n})\n\nfunction isEmailRenderingFile(context: RuleContext): boolean {\n const filename = getContextFilename(context)\n return (\n /\\/(?:email|emails|contact-email)\\//i.test(filename) ||\n /(?:Email|EmailTemplate|ContactFormEmail)\\.(?:jsx|tsx)$/i.test(filename)\n )\n}\n\nconst noRawImageElementsRule = defineRule({\n description: 'Require Next.js-owned image delivery for website UI.',\n messages: {\n rawImage:\n 'Use next/image for website UI images. Raw image markup is reserved for reviewed getImageProps art direction and non-Next renderers such as email.',\n },\n create(context) {\n if (isEmailRenderingFile(context)) return {} as Visitor\n\n const getImagePropsBindings = new Set<string>()\n const nextImagePropBindings = new Set<string>()\n\n function inspectImport(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (node?.type !== 'ImportDeclaration' || getStaticString(node.source) !== 'next/image') {\n return\n }\n const specifiers = Array.isArray(node.specifiers) ? node.specifiers : []\n for (const specifierValue of specifiers) {\n const specifier = asNode(specifierValue)\n if (\n specifier?.type === 'ImportSpecifier' &&\n getIdentifierName(specifier.imported) === 'getImageProps'\n ) {\n const localName = getIdentifierName(specifier.local)\n if (localName) getImagePropsBindings.add(localName)\n }\n }\n }\n\n function inspectVariable(nodeValue: unknown) {\n const node = asNode(nodeValue)\n const initializer = asNode(node?.init)\n if (node?.type !== 'VariableDeclarator' || initializer?.type !== 'CallExpression') {\n return\n }\n const calleeName = getIdentifierName(initializer.callee)\n if (!calleeName || !getImagePropsBindings.has(calleeName)) return\n\n const pattern = asNode(node.id)\n if (pattern?.type !== 'ObjectPattern') return\n const properties = Array.isArray(pattern.properties) ? pattern.properties : []\n const propsProperty = properties\n .map(asNode)\n .find(\n (property) =>\n property?.type === 'Property' &&\n getIdentifierName(property.key) === 'props',\n )\n const propsPattern = asNode(propsProperty?.value)\n const directBinding = getIdentifierName(propsPattern)\n if (directBinding) {\n nextImagePropBindings.add(directBinding)\n return\n }\n if (propsPattern?.type !== 'ObjectPattern') return\n const nestedProperties = Array.isArray(propsPattern.properties)\n ? propsPattern.properties\n : []\n for (const propertyValue of nestedProperties) {\n const property = asNode(propertyValue)\n if (property?.type !== 'RestElement') continue\n const binding = getIdentifierName(property.argument)\n if (binding) nextImagePropBindings.add(binding)\n }\n }\n\n function usesReviewedNextImageProps(node: AstNode) {\n if (getJsxAttribute(node, 'src') || getJsxAttribute(node, 'srcSet')) return false\n const attributes = Array.isArray(node.attributes) ? node.attributes : []\n return attributes.some((attributeValue) => {\n const attribute = asNode(attributeValue)\n return (\n attribute?.type === 'JSXSpreadAttribute' &&\n nextImagePropBindings.has(getIdentifierName(attribute.argument) ?? '')\n )\n })\n }\n\n function inspectOpeningElement(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (\n node &&\n getJsxElementName(node.name)?.toLowerCase() === 'img' &&\n !usesReviewedNextImageProps(node)\n ) {\n context.report({ node: nodeValue, messageId: 'rawImage' })\n }\n }\n\n function inspectCall(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (node?.type !== 'CallExpression') return\n const callee = getMemberPath(node.callee)\n const args = Array.isArray(node.arguments) ? node.arguments : []\n if (\n (callee === 'createElement' || callee === 'React.createElement') &&\n getStaticString(args[0])?.toLowerCase() === 'img'\n ) {\n context.report({ node: nodeValue, messageId: 'rawImage' })\n }\n }\n\n return {\n CallExpression: inspectCall,\n ImportDeclaration: inspectImport,\n JSXOpeningElement: inspectOpeningElement,\n VariableDeclarator: inspectVariable,\n }\n },\n})\n\nconst RAW_HTML_PROPERTY = 'dangerouslySetInnerHTML'\n\nconst noUnsafeRichTextSinksRule = defineRule({\n description:\n 'Disallow project-owned raw HTML; only the shared SchemaScript and SafeRichText renderers may inject markup.',\n messages: {\n unsafeRichTextSink:\n 'Project-owned raw HTML is not permitted. Render JSON-LD with SchemaScript and rich text with SafeRichText from @brandlab-digital/site-next.',\n },\n create(context) {\n if (isSharedPlatformImplementation(context)) return {} as Visitor\n\n function inspectJsxAttribute(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (getIdentifierName(node?.name) === RAW_HTML_PROPERTY) {\n context.report({ node: nodeValue, messageId: 'unsafeRichTextSink' })\n }\n }\n\n function inspectProperty(nodeValue: unknown) {\n const node = asNode(nodeValue)\n if (node?.type === 'Property' && getPropertyName(node) === RAW_HTML_PROPERTY) {\n context.report({ node: nodeValue, messageId: 'unsafeRichTextSink' })\n }\n }\n\n function inspectAssignment(nodeValue: unknown) {\n const node = asNode(nodeValue)\n const target = asNode(node?.left)\n if (target?.type !== 'MemberExpression') return\n const propertyName = target.computed\n ? getStaticString(target.property)\n : getIdentifierName(target.property)\n if (propertyName === RAW_HTML_PROPERTY) {\n context.report({ node: nodeValue, messageId: 'unsafeRichTextSink' })\n }\n }\n\n return {\n AssignmentExpression: inspectAssignment,\n JSXAttribute: inspectJsxAttribute,\n Property: inspectProperty,\n }\n },\n})\n\nexport const rules = {\n [RULE_IDS.noRetiredAnalyticsEvents]: createTextRule({\n description: 'Disallow retired Brandlab analytics event names.',\n messageId: 'retiredAnalyticsEvent',\n message: 'Use contact_form for accepted forms and phone_link_click for telephone-link diagnostics.',\n matcher: (text) => retiredAnalyticsEvents.has(text),\n }),\n [RULE_IDS.noRawJsonLd]: noRawJsonLdRule,\n [RULE_IDS.noUnsafeRichTextSinks]: noUnsafeRichTextSinksRule,\n [RULE_IDS.noProtectedPlatformReimplementation]: noProtectedPlatformReimplementationRule,\n [RULE_IDS.noAnalyticsPii]: noAnalyticsPiiRule,\n [RULE_IDS.noUnsafeExternalLinks]: noUnsafeExternalLinksRule,\n [RULE_IDS.noRawImageElements]: noRawImageElementsRule,\n} satisfies Record<string, RuleModule>\n\n/** A flat-config object; kept structural so ESLint stays a peer, not a type dependency. */\nexport type BrandlabFlatConfig = {\n name?: string\n files?: readonly string[]\n ignores?: readonly string[]\n plugins?: Record<string, unknown>\n rules?: Record<string, unknown>\n [key: string]: unknown\n}\n\ntype BrandlabRecommendedConfig = {\n name: 'brandlab/recommended'\n plugins: {\n brandlab: unknown\n }\n rules: Record<string, 'error'>\n}\n\ntype BrandlabPlugin = {\n rules: typeof rules\n configs: {\n recommended: BrandlabRecommendedConfig\n /** Next core-web-vitals + next/typescript + Brandlab recommended + standard ignores. */\n readonly next: readonly BrandlabFlatConfig[]\n }\n}\n\n/** Build and test output that is never project source. */\nexport const NEXT_CONFIG_IGNORES = Object.freeze([\n '.next/**',\n 'out/**',\n 'build/**',\n 'coverage/**',\n 'playwright-report/**',\n 'test-results/**',\n '.vercel/**',\n 'public/**',\n 'next-env.d.ts',\n])\n\nconst recommendedRules = Object.fromEntries(\n Object.keys(rules).map((ruleId) => [`brandlab/${ruleId}`, 'error' as const]),\n) as Record<string, 'error'>\n\nconst recommended: BrandlabRecommendedConfig = {\n name: 'brandlab/recommended',\n plugins: {\n brandlab: undefined,\n },\n rules: recommendedRules,\n}\n\nfunction toConfigArray(value: unknown, specifier: string): BrandlabFlatConfig[] {\n const exported = Array.isArray(value)\n ? value\n : Array.isArray(asNode(value)?.default)\n ? (asNode(value)?.default as unknown[])\n : null\n if (!exported) throw new Error(`${specifier} did not export a flat config array.`)\n return exported as BrandlabFlatConfig[]\n}\n\n/**\n * The complete client preset: `export default brandlab.configs.next`.\n * eslint-config-next is an optional peer, so it loads only when this preset is used.\n */\nexport function createBrandlabNextConfig(presets: {\n coreWebVitals: readonly BrandlabFlatConfig[]\n typescript: readonly BrandlabFlatConfig[]\n}): readonly BrandlabFlatConfig[] {\n return Object.freeze([\n ...presets.coreWebVitals,\n ...presets.typescript,\n recommended,\n {\n name: 'brandlab/next',\n rules: {\n // Apostrophes and quotes are ordinary Australian English copy in JSX text.\n 'react/no-unescaped-entities': 'off',\n },\n },\n { name: 'brandlab/next-ignores', ignores: NEXT_CONFIG_IGNORES },\n ])\n}\n\nfunction loadNextConfig(): readonly BrandlabFlatConfig[] {\n const require = createRequire(import.meta.url)\n const load = (specifier: string) => {\n try {\n return toConfigArray(require(specifier), specifier)\n } catch (error) {\n throw new Error(\n `brandlab.configs.next requires ${specifier}. Install eslint-config-next at the exact version of next.`,\n { cause: error },\n )\n }\n }\n return createBrandlabNextConfig({\n coreWebVitals: load('eslint-config-next/core-web-vitals'),\n typescript: load('eslint-config-next/typescript'),\n })\n}\n\nlet nextConfig: readonly BrandlabFlatConfig[] | undefined\n\nconst plugin: BrandlabPlugin = {\n rules,\n configs: {\n recommended,\n get next() {\n nextConfig ??= loadNextConfig()\n return nextConfig\n },\n },\n}\n\nrecommended.plugins.brandlab = plugin\n\nexport default plugin\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brandlab-digital/eslint-plugin",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/RomieDandan/brandlab.git",
|
|
@@ -18,12 +18,22 @@
|
|
|
18
18
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
|
-
"eslint": ">=9"
|
|
21
|
+
"eslint": ">=9",
|
|
22
|
+
"eslint-config-next": ">=16"
|
|
23
|
+
},
|
|
24
|
+
"peerDependenciesMeta": {
|
|
25
|
+
"eslint-config-next": {
|
|
26
|
+
"optional": true
|
|
27
|
+
}
|
|
22
28
|
},
|
|
23
29
|
"exports": {
|
|
24
30
|
".": {
|
|
25
31
|
"types": "./dist/index.d.ts",
|
|
26
32
|
"import": "./dist/index.js"
|
|
27
33
|
}
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"eslint-config-next": "16.3.6",
|
|
37
|
+
"next": "16.3.6"
|
|
28
38
|
}
|
|
29
39
|
}
|