@brandlab-digital/eslint-plugin 0.1.0-alpha.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.
@@ -0,0 +1,42 @@
1
+ type ReportDescriptor = {
2
+ node: unknown;
3
+ messageId?: string;
4
+ message?: string;
5
+ };
6
+ type RuleContext = {
7
+ getFilename?: () => string;
8
+ report: (descriptor: ReportDescriptor) => void;
9
+ };
10
+ type Visitor = Record<string, (node: unknown) => void>;
11
+ type RuleModule = {
12
+ meta: {
13
+ type: 'problem';
14
+ docs: {
15
+ description: string;
16
+ recommended: boolean;
17
+ };
18
+ messages: Record<string, string>;
19
+ schema: [];
20
+ };
21
+ create: (context: RuleContext) => Visitor;
22
+ };
23
+ export declare const rules: {
24
+ 'no-legacy-analytics-events': RuleModule;
25
+ 'no-raw-json-ld': RuleModule;
26
+ 'no-allow-indexing-true': RuleModule;
27
+ 'no-unsafe-rich-text-sinks': RuleModule;
28
+ };
29
+ type BrandlabPlugin = {
30
+ rules: typeof rules;
31
+ configs: {
32
+ recommended: {
33
+ plugins: {
34
+ brandlab: unknown;
35
+ };
36
+ rules: Record<string, 'error'>;
37
+ };
38
+ };
39
+ };
40
+ declare const plugin: BrandlabPlugin;
41
+ export default plugin;
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,OAAO,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,KAAK,WAAW,GAAG;IACjB,WAAW,CAAC,EAAE,MAAM,MAAM,CAAA;IAC1B,MAAM,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAA;CAC/C,CAAA;AAED,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;AA+DD,eAAO,MAAM,KAAK;;;;;CA4BoB,CAAA;AAEtC,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,OAAO,EAAE;QACP,WAAW,EAAE;YACX,OAAO,EAAE;gBACP,QAAQ,EAAE,OAAO,CAAA;aAClB,CAAA;YACD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAC/B,CAAA;KACF,CAAA;CACF,CAAA;AAED,QAAA,MAAM,MAAM,EAAE,cAeb,CAAA;AAID,eAAe,MAAM,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,97 @@
1
+ function getNodeText(node) {
2
+ if (!node || typeof node !== 'object')
3
+ return null;
4
+ const record = node;
5
+ if (record.type === 'Literal' && typeof record.value === 'string') {
6
+ return record.value;
7
+ }
8
+ if (record.type === 'TemplateElement') {
9
+ const value = record.value;
10
+ if (value && typeof value === 'object') {
11
+ const raw = value.raw;
12
+ return typeof raw === 'string' ? raw : null;
13
+ }
14
+ }
15
+ return null;
16
+ }
17
+ function createTextRule(options) {
18
+ return {
19
+ meta: {
20
+ type: 'problem',
21
+ docs: {
22
+ description: options.description,
23
+ recommended: true,
24
+ },
25
+ messages: {
26
+ [options.messageId]: options.message,
27
+ },
28
+ schema: [],
29
+ },
30
+ create(context) {
31
+ function inspect(node) {
32
+ const text = getNodeText(node);
33
+ if (text && options.matcher(text, context)) {
34
+ context.report({ node, messageId: options.messageId });
35
+ }
36
+ }
37
+ return {
38
+ Literal: inspect,
39
+ TemplateElement: inspect,
40
+ };
41
+ },
42
+ };
43
+ }
44
+ const legacyAnalyticsEvents = new Set([
45
+ 'contact_form_submission',
46
+ 'phone_calls',
47
+ 'form_start',
48
+ 'cta_click',
49
+ ]);
50
+ export const rules = {
51
+ 'no-legacy-analytics-events': createTextRule({
52
+ description: 'Disallow retired Brandlab analytics event names.',
53
+ messageId: 'legacyAnalyticsEvent',
54
+ message: 'Use the canonical Brandlab lead events: phone_call or contact_form.',
55
+ matcher: (text) => legacyAnalyticsEvents.has(text),
56
+ }),
57
+ 'no-raw-json-ld': createTextRule({
58
+ description: 'Disallow raw JSON-LD scripts outside the shared schema adapter.',
59
+ messageId: 'rawJsonLd',
60
+ message: 'Render JSON-LD through the Brandlab SchemaScript adapter.',
61
+ matcher: (text, context) => {
62
+ const filename = context.getFilename?.() ?? '';
63
+ return text === 'application/ld+json' && !filename.endsWith('SchemaScript.tsx');
64
+ },
65
+ }),
66
+ 'no-allow-indexing-true': createTextRule({
67
+ description: 'Disallow ALLOW_INDEXING=true; only ALLOW_INDEXING=1 is supported.',
68
+ messageId: 'allowIndexingTrue',
69
+ message: 'Use ALLOW_INDEXING=1 as the only explicit indexing override.',
70
+ matcher: (text) => text.includes('ALLOW_INDEXING=true') || text === 'true',
71
+ }),
72
+ 'no-unsafe-rich-text-sinks': createTextRule({
73
+ description: 'Disallow visible rich text sinks that bypass a sanitizer.',
74
+ messageId: 'unsafeRichTextSink',
75
+ message: 'Visible rich text must be sanitizer-backed and tested.',
76
+ matcher: (text) => text.includes('dangerouslySetInnerHTML') && !text.includes('sanitize'),
77
+ }),
78
+ };
79
+ const plugin = {
80
+ rules,
81
+ configs: {
82
+ recommended: {
83
+ plugins: {
84
+ brandlab: undefined,
85
+ },
86
+ rules: {
87
+ 'brandlab/no-legacy-analytics-events': 'error',
88
+ 'brandlab/no-raw-json-ld': 'error',
89
+ 'brandlab/no-allow-indexing-true': 'error',
90
+ 'brandlab/no-unsafe-rich-text-sinks': 'error',
91
+ },
92
+ },
93
+ },
94
+ };
95
+ plugin.configs.recommended.plugins.brandlab = plugin;
96
+ export default plugin;
97
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@brandlab-digital/eslint-plugin",
3
+ "version": "0.1.0-alpha.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "files": ["dist"],
8
+ "scripts": {
9
+ "build": "tsc -p tsconfig.json",
10
+ "test": "vitest run",
11
+ "typecheck": "tsc --noEmit -p tsconfig.json"
12
+ },
13
+ "peerDependencies": {
14
+ "eslint": ">=9"
15
+ },
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
+ }
21
+ }
22
+ }