@astroscope/eslint-plugin-i18n 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +99 -11
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ var noModuleLevelT = {
16
16
  schema: []
17
17
  },
18
18
  create(context) {
19
+ if (context.filename.endsWith(".astro")) return {};
19
20
  return {
20
21
  CallExpression(node) {
21
22
  if (node.callee.type !== "Identifier" || node.callee.name !== "t") return;
@@ -40,14 +41,21 @@ var DEFAULT_IGNORE_PATTERNS = [
40
41
  // numbers
41
42
  /^\s*\|\s*$/,
42
43
  // pipe separators
43
- /^\s*[•·–—]\s*$/
44
+ /^\s*[•·–—]\s*$/,
44
45
  // bullets / dashes
46
+ /^[\s\p{P}\p{S}]+$/u,
47
+ // punctuation / symbols only (e.g. "(", ",", "/ —")
48
+ /^#[0-9a-fA-F]{3,8}$/,
49
+ // hex colors (e.g. "#003366", "#fff")
50
+ /^\d+x\d+$/
51
+ // dimensions (e.g. "180x180")
45
52
  ];
46
53
  var DEFAULT_IGNORE_ATTRIBUTES = [
47
- "className",
48
- "class",
54
+ // html attributes
49
55
  "id",
50
- "key",
56
+ "class",
57
+ "className",
58
+ "style",
51
59
  "href",
52
60
  "src",
53
61
  "type",
@@ -59,9 +67,70 @@ var DEFAULT_IGNORE_ATTRIBUTES = [
59
67
  "rel",
60
68
  "method",
61
69
  "action",
70
+ "loading",
71
+ "decoding",
72
+ "autoComplete",
73
+ "allow",
74
+ "as",
75
+ "sizes",
76
+ "color",
77
+ "crossorigin",
78
+ "referrerpolicy",
79
+ "charset",
80
+ "lang",
81
+ "form",
82
+ "key",
83
+ "slot",
84
+ // common component props
85
+ "variant",
86
+ "size",
87
+ "mode",
88
+ "orientation",
89
+ "align",
90
+ "icon",
91
+ "tag",
92
+ "tagName",
93
+ // html aria attributes (non-text)
94
+ "aria-hidden",
95
+ "aria-live",
96
+ "aria-atomic",
97
+ // astro attributes
98
+ "class:list",
99
+ // testing attributes
62
100
  "data-testid",
63
101
  "data-cy",
64
- "slot"
102
+ // svg attributes
103
+ "d",
104
+ "viewBox",
105
+ "xmlns",
106
+ "fill",
107
+ "stroke",
108
+ "strokeWidth",
109
+ "strokeLinecap",
110
+ "strokeLinejoin",
111
+ "clipPath",
112
+ "transform",
113
+ "points",
114
+ "pathLength",
115
+ "filter",
116
+ "filterUnits",
117
+ "colorInterpolationFilters",
118
+ "floodOpacity",
119
+ "in",
120
+ "in2",
121
+ "result",
122
+ "stroke-linecap",
123
+ "stroke-linejoin",
124
+ "clip-rule",
125
+ "fill-rule",
126
+ "path",
127
+ "values"
128
+ ];
129
+ var DEFAULT_IGNORE_ATTRIBUTE_PATTERNS = [
130
+ /className$/i,
131
+ // *ClassName, *classname (e.g. labelClassName, pictureClassName)
132
+ /^data-/
133
+ // data-* attributes
65
134
  ];
66
135
  var noRawStringsInJsx = {
67
136
  meta: {
@@ -91,21 +160,24 @@ var noRawStringsInJsx = {
91
160
  },
92
161
  create(context) {
93
162
  const options = context.options[0] ?? {};
94
- const userPatterns = (options.ignorePatterns ?? []).map((p) => new RegExp(p));
95
- const allPatterns = [...DEFAULT_IGNORE_PATTERNS, ...userPatterns];
96
- const ignoreAttributes = /* @__PURE__ */ new Set([...DEFAULT_IGNORE_ATTRIBUTES, ...options.ignoreAttributes ?? []]);
163
+ const allPatterns = options.ignorePatterns ? options.ignorePatterns.map((p) => new RegExp(p)) : DEFAULT_IGNORE_PATTERNS;
164
+ const ignoreAttributes = new Set(options.ignoreAttributes ?? DEFAULT_IGNORE_ATTRIBUTES);
97
165
  function shouldIgnore(text) {
98
166
  return allPatterns.some((p) => p.test(text));
99
167
  }
168
+ function shouldIgnoreAttribute(name) {
169
+ if (ignoreAttributes.has(name)) return true;
170
+ return DEFAULT_IGNORE_ATTRIBUTE_PATTERNS.some((p) => p.test(name));
171
+ }
100
172
  function isInsideIgnoredAttribute(node) {
101
173
  const parent = node.parent;
102
174
  if (parent?.type === "JSXAttribute") {
103
175
  const attrName = parent.name?.type === "JSXIdentifier" ? parent.name.name : parent.name?.type === "JSXNamespacedName" ? `${parent.name.namespace.name}:${parent.name.name.name}` : null;
104
- if (attrName && ignoreAttributes.has(attrName)) return true;
176
+ if (attrName && shouldIgnoreAttribute(attrName)) return true;
105
177
  }
106
178
  if (parent?.type === "JSXExpressionContainer" && parent.parent?.type === "JSXAttribute") {
107
179
  const attrName = parent.parent.name?.type === "JSXIdentifier" ? parent.parent.name.name : null;
108
- if (attrName && ignoreAttributes.has(attrName)) return true;
180
+ if (attrName && shouldIgnoreAttribute(attrName)) return true;
109
181
  }
110
182
  return false;
111
183
  }
@@ -129,12 +201,28 @@ var noRawStringsInJsx = {
129
201
  if (shouldIgnore(text)) return;
130
202
  if (isInsideIgnoredAttribute(node)) return;
131
203
  const attrName = node.name?.type === "JSXIdentifier" ? node.name.name : node.name?.type === "JSXNamespacedName" ? `${node.name.namespace.name}:${node.name.name.name}` : null;
132
- if (attrName && ignoreAttributes.has(attrName)) return;
204
+ if (attrName && shouldIgnoreAttribute(attrName)) return;
133
205
  context.report({
134
206
  node: node.value,
135
207
  messageId: "rawString",
136
208
  data: { text: text.length > 40 ? `${text.slice(0, 40)}...` : text }
137
209
  });
210
+ },
211
+ // string literals inside JSX expressions: <div title={value ?? 'fallback'} /> or <div>{'text'}</div>
212
+ Literal(node) {
213
+ if (typeof node.value !== "string") return;
214
+ const ancestors = context.sourceCode.getAncestors(node);
215
+ const inJsxExpression = ancestors.some((a) => a.type === "JSXExpressionContainer");
216
+ if (!inJsxExpression) return;
217
+ if (ancestors.some((a) => a.type === "CallExpression")) return;
218
+ const text = node.value;
219
+ if (shouldIgnore(text)) return;
220
+ if (isInsideIgnoredAttribute(node)) return;
221
+ context.report({
222
+ node,
223
+ messageId: "rawString",
224
+ data: { text: text.length > 40 ? `${text.slice(0, 40)}...` : text }
225
+ });
138
226
  }
139
227
  };
140
228
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astroscope/eslint-plugin-i18n",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "ESLint rules for @astroscope/i18n",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",