@atlaskit/eslint-plugin-design-system 13.26.0 → 13.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +73 -71
- package/dist/cjs/presets/all-flat.codegen.js +3 -1
- package/dist/cjs/presets/all.codegen.js +3 -1
- package/dist/cjs/presets/recommended-flat.codegen.js +1 -2
- package/dist/cjs/presets/recommended.codegen.js +1 -2
- package/dist/cjs/rules/index.codegen.js +5 -1
- package/dist/cjs/rules/lozenge-isBold-and-lozenge-badge-appearance-migration/index.js +1 -1
- package/dist/cjs/rules/no-to-match-snapshot/index.js +49 -0
- package/dist/cjs/rules/no-unsafe-inline-snapshot/index.js +139 -0
- package/dist/es2019/presets/all-flat.codegen.js +3 -1
- package/dist/es2019/presets/all.codegen.js +3 -1
- package/dist/es2019/presets/recommended-flat.codegen.js +1 -2
- package/dist/es2019/presets/recommended.codegen.js +1 -2
- package/dist/es2019/rules/index.codegen.js +5 -1
- package/dist/es2019/rules/lozenge-isBold-and-lozenge-badge-appearance-migration/index.js +1 -1
- package/dist/es2019/rules/no-to-match-snapshot/index.js +43 -0
- package/dist/es2019/rules/no-unsafe-inline-snapshot/index.js +134 -0
- package/dist/esm/presets/all-flat.codegen.js +3 -1
- package/dist/esm/presets/all.codegen.js +3 -1
- package/dist/esm/presets/recommended-flat.codegen.js +1 -2
- package/dist/esm/presets/recommended.codegen.js +1 -2
- package/dist/esm/rules/index.codegen.js +5 -1
- package/dist/esm/rules/lozenge-isBold-and-lozenge-badge-appearance-migration/index.js +1 -1
- package/dist/esm/rules/no-to-match-snapshot/index.js +43 -0
- package/dist/esm/rules/no-unsafe-inline-snapshot/index.js +133 -0
- package/dist/types/presets/all-flat.codegen.d.ts +1 -1
- package/dist/types/presets/all.codegen.d.ts +1 -1
- package/dist/types/presets/recommended-flat.codegen.d.ts +1 -1
- package/dist/types/presets/recommended.codegen.d.ts +1 -1
- package/dist/types/rules/index.codegen.d.ts +1 -1
- package/dist/types/rules/no-to-match-snapshot/index.d.ts +4 -0
- package/dist/types/rules/no-unsafe-inline-snapshot/index.d.ts +4 -0
- package/dist/types-ts4.5/presets/all-flat.codegen.d.ts +1 -1
- package/dist/types-ts4.5/presets/all.codegen.d.ts +1 -1
- package/dist/types-ts4.5/presets/recommended-flat.codegen.d.ts +1 -1
- package/dist/types-ts4.5/presets/recommended.codegen.d.ts +1 -1
- package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -1
- package/dist/types-ts4.5/rules/no-to-match-snapshot/index.d.ts +4 -0
- package/dist/types-ts4.5/rules/no-unsafe-inline-snapshot/index.d.ts +4 -0
- package/package.json +2 -2
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
+
import { getSourceCode } from '@atlaskit/eslint-utils/context-compat';
|
|
3
|
+
import { createLintRule } from '../utils/create-rule';
|
|
4
|
+
export var name = 'no-unsafe-inline-snapshot';
|
|
5
|
+
var MAX_LINES = 100;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Checks if a snapshot contains internal implementation details
|
|
9
|
+
*/
|
|
10
|
+
function containsInternalDetails(snapshotContent) {
|
|
11
|
+
var issues = [];
|
|
12
|
+
|
|
13
|
+
// Check for className attributes (unless they equal "REDACTED")
|
|
14
|
+
// Handles: className="value", className='value', and whitespace variations
|
|
15
|
+
var classNameRegex = /className\s*=\s*(["'])((?:(?!\1)[^\\]|\\.)*)\1/gi;
|
|
16
|
+
var match;
|
|
17
|
+
while ((match = classNameRegex.exec(snapshotContent)) !== null) {
|
|
18
|
+
var classNameValue = match[2];
|
|
19
|
+
if (classNameValue && classNameValue !== 'REDACTED') {
|
|
20
|
+
issues.push("className=\"".concat(classNameValue, "\""));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Check for style attributes (unless they equal "REDACTED")
|
|
25
|
+
// Handles: style="value", style='value', and whitespace variations
|
|
26
|
+
// Style values can contain colons, semicolons, etc., so we need to capture the full quoted value
|
|
27
|
+
var styleRegex = /style\s*=\s*(["'])((?:(?!\1)[^\\]|\\.)*)\1/gi;
|
|
28
|
+
while ((match = styleRegex.exec(snapshotContent)) !== null) {
|
|
29
|
+
var styleValue = match[2];
|
|
30
|
+
if (styleValue && styleValue !== 'REDACTED') {
|
|
31
|
+
issues.push("style=\"".concat(styleValue, "\""));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Check for style blocks (unless they contain "REDACTED")
|
|
36
|
+
var styleBlockRegex = /<style[^>]*>([\s\S]*?)<\/style>/gi;
|
|
37
|
+
while ((match = styleBlockRegex.exec(snapshotContent)) !== null) {
|
|
38
|
+
var styleContent = match[1];
|
|
39
|
+
if (styleContent && !styleContent.trim().includes('REDACTED')) {
|
|
40
|
+
issues.push('style block');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
hasIssues: issues.length > 0,
|
|
45
|
+
issues: issues
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Extracts the snapshot content from a template literal or string literal
|
|
51
|
+
*/
|
|
52
|
+
function extractSnapshotContent(node, sourceCode) {
|
|
53
|
+
if (isNodeOfType(node, 'TemplateLiteral')) {
|
|
54
|
+
// For template literals, get the raw text including the template parts
|
|
55
|
+
return sourceCode.getText(node);
|
|
56
|
+
}
|
|
57
|
+
if (isNodeOfType(node, 'Literal') && typeof node.value === 'string') {
|
|
58
|
+
return node.value;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
var rule = createLintRule({
|
|
63
|
+
meta: {
|
|
64
|
+
name: name,
|
|
65
|
+
type: 'problem',
|
|
66
|
+
docs: {
|
|
67
|
+
description: 'Enforce guardrails on toMatchInlineSnapshot usage: snapshots must not exceed 100 lines and must not contain internal implementation details like className or style attributes.',
|
|
68
|
+
recommended: false,
|
|
69
|
+
severity: 'error'
|
|
70
|
+
},
|
|
71
|
+
messages: {
|
|
72
|
+
exceedsMaxLines: "Inline snapshot exceeds ".concat(MAX_LINES, " lines. Consider breaking it into smaller snapshots or using a different testing approach."),
|
|
73
|
+
containsInternalDetails: 'Inline snapshot contains internal implementation details: {{details}}. Use "REDACTED" for className and style values, or remove these details from the snapshot.'
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
create: function create(context) {
|
|
77
|
+
var sourceCode = getSourceCode(context);
|
|
78
|
+
return {
|
|
79
|
+
MemberExpression: function MemberExpression(node) {
|
|
80
|
+
// Check if this is a call to toMatchInlineSnapshot
|
|
81
|
+
if (!isNodeOfType(node.property, 'Identifier') || node.property.name !== 'toMatchInlineSnapshot') {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Check if the object is an expect() call
|
|
86
|
+
if (!isNodeOfType(node.object, 'CallExpression') || !isNodeOfType(node.object.callee, 'Identifier') || node.object.callee.name !== 'expect') {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Only report if this is being called (i.e., it's part of a CallExpression)
|
|
91
|
+
if (!node.parent || !isNodeOfType(node.parent, 'CallExpression')) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Get the snapshot content from the first argument
|
|
96
|
+
var callExpression = node.parent;
|
|
97
|
+
if (callExpression.arguments.length === 0) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
var snapshotArg = callExpression.arguments[0];
|
|
101
|
+
var snapshotContent = extractSnapshotContent(snapshotArg, sourceCode);
|
|
102
|
+
if (!snapshotContent) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check line count
|
|
107
|
+
var lines = snapshotContent.split('\n');
|
|
108
|
+
if (lines.length > MAX_LINES) {
|
|
109
|
+
context.report({
|
|
110
|
+
node: snapshotArg,
|
|
111
|
+
messageId: 'exceedsMaxLines'
|
|
112
|
+
});
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Check for internal implementation details
|
|
117
|
+
var _containsInternalDeta = containsInternalDetails(snapshotContent),
|
|
118
|
+
hasIssues = _containsInternalDeta.hasIssues,
|
|
119
|
+
issues = _containsInternalDeta.issues;
|
|
120
|
+
if (hasIssues) {
|
|
121
|
+
context.report({
|
|
122
|
+
node: snapshotArg,
|
|
123
|
+
messageId: 'containsInternalDetails',
|
|
124
|
+
data: {
|
|
125
|
+
details: issues.slice(0, 3).join(', ') // Show first 3 issues
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
export default rule;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::d7a0407a6c6b10bfbba790523d06f97d>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import type { Linter } from 'eslint';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::e632a96e9bae920c23e25114f40e3c0d>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import type { ESLint } from 'eslint';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::e2157edd1fabfe25390d7c22a0b63f86>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import type { Linter } from 'eslint';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::b3fadf2e122fc30002c54a922fc55a1f>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import type { ESLint } from 'eslint';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::62347cf64e4ac99b927fce9d1a2bd894>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import type { Rule } from 'eslint';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::d7a0407a6c6b10bfbba790523d06f97d>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import type { Linter } from 'eslint';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::e632a96e9bae920c23e25114f40e3c0d>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import type { ESLint } from 'eslint';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::e2157edd1fabfe25390d7c22a0b63f86>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import type { Linter } from 'eslint';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::b3fadf2e122fc30002c54a922fc55a1f>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import type { ESLint } from 'eslint';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::62347cf64e4ac99b927fce9d1a2bd894>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import type { Rule } from 'eslint';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/eslint-plugin-design-system",
|
|
3
3
|
"description": "The essential plugin for use with the Atlassian Design System.",
|
|
4
|
-
"version": "13.
|
|
4
|
+
"version": "13.27.1",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"publishConfig": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@atlaskit/eslint-utils": "^2.0.0",
|
|
42
42
|
"@atlaskit/icon": "^29.0.0",
|
|
43
43
|
"@atlaskit/icon-lab": "^5.12.0",
|
|
44
|
-
"@atlaskit/tokens": "^8.
|
|
44
|
+
"@atlaskit/tokens": "^8.4.0",
|
|
45
45
|
"@babel/runtime": "^7.0.0",
|
|
46
46
|
"@typescript-eslint/utils": "^7.1.0",
|
|
47
47
|
"ajv": "^6.12.6",
|