@agilebot/eslint-plugin 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
package/lib/util/intl.js CHANGED
@@ -1,127 +1,127 @@
1
- /**
2
- * Finds an attribute in formatMessage using attribute name.
3
- *
4
- * @param {Object} node - parent formatMessage node
5
- * @param {string} attrName - attribute name.
6
- * @returns {Object} node - returns node if it finds the attribute.
7
- */
8
- function findFormatMessageAttrNode(node, attrName) {
9
- // Find formatMessage usages
10
- if (
11
- node.type === 'CallExpression' &&
12
- (node.callee.name === 'formatMessage' || node.callee.name === '$t') &&
13
- node.arguments.length > 0 &&
14
- node.arguments[0].properties
15
- ) {
16
- return node.arguments[0].properties.find(
17
- a => a.key && a.key.name === attrName
18
- );
19
- }
20
-
21
- // Find intl.formatMessage usages
22
- if (
23
- node.type === 'CallExpression' &&
24
- node.callee.type === 'MemberExpression' &&
25
- (node.callee.object.name === 'intl' ||
26
- (node.callee.object.name && node.callee.object.name.endsWith('Intl'))) &&
27
- (node.callee.property.name === 'formatMessage' ||
28
- node.callee.property.name === '$t')
29
- ) {
30
- return node.arguments[0].properties.find(
31
- a => a.key && a.key.name === attrName
32
- );
33
- }
34
- }
35
-
36
- /**
37
- * Finds an attribute in FormattedMessage using attribute name.
38
- *
39
- * @param {Object} node - parent FormattedMessage node
40
- * @param {string} attrName - attribute name.
41
- * @returns {Object} node - returns node if it finds the attribute.
42
- */
43
- function findFormattedMessageAttrNode(node, attrName) {
44
- if (
45
- node.type === 'JSXIdentifier' &&
46
- node.name === 'FormattedMessage' &&
47
- node.parent &&
48
- node.parent.type === 'JSXOpeningElement'
49
- ) {
50
- return node.parent.attributes.find(a => a.name && a.name.name === attrName);
51
- }
52
- }
53
-
54
- /**
55
- * Finds an attribute in defineMessages using attribute name.
56
- *
57
- * @param {Object} node - parent defineMessages node
58
- * @param {string} attrName - attribute name.
59
- * @returns {Object} node - returns node if it finds the attribute.
60
- */
61
- function findAttrNodeInDefineMessages(node, attrName) {
62
- if (
63
- node.type === 'Property' &&
64
- node.key.name === attrName &&
65
- node.parent &&
66
- node.parent.parent &&
67
- node.parent.parent.parent &&
68
- node.parent.parent.parent.parent &&
69
- node.parent.parent.parent.parent.type === 'CallExpression' &&
70
- node.parent.parent.parent.parent.callee.name === 'defineMessages'
71
- ) {
72
- return node;
73
- }
74
- }
75
-
76
- /**
77
- * Finds an attribute in defineMessages using attribute name.
78
- *
79
- * @param {Object} node - parent defineMessages node
80
- * @param {string} attrName - attribute name.
81
- * @returns {Object} node - returns node if it finds the attribute.
82
- */
83
- function findAttrNodeInDefineMessage(node, attrName) {
84
- if (
85
- node.type === 'Property' &&
86
- node.key.name === attrName &&
87
- node.parent &&
88
- node.parent.parent &&
89
- node.parent.parent.type === 'CallExpression' &&
90
- node.parent.parent.callee.name === 'defineMessage'
91
- ) {
92
- return node;
93
- }
94
- }
95
-
96
- /**
97
- * Returns a sorted array of nodes, based on their starting posting in the locale id.
98
- *
99
- * @param {Object} node - parent node containing the locale id.
100
- * @returns {Array} child nodes - sorted list.
101
- */
102
- function sortedTemplateElements(node) {
103
- return [...node.quasis, ...node.expressions].sort(
104
- (a, b) => a.range[0] - b.range[0]
105
- );
106
- }
107
-
108
- /**
109
- * Replaces place holders with asterisk and returns the resulting id.
110
- *
111
- * @param {Object} node - parent node containing the locale id.
112
- * @returns {string} id - fixed id.
113
- */
114
- function templateLiteralDisplayStr(node) {
115
- return sortedTemplateElements(node)
116
- .map(e => (!e.value ? '*' : e.value.raw))
117
- .join('');
118
- }
119
-
120
- module.exports = {
121
- findFormatMessageAttrNode,
122
- findFormattedMessageAttrNode,
123
- findAttrNodeInDefineMessages,
124
- findAttrNodeInDefineMessage,
125
- sortedTemplateElements,
126
- templateLiteralDisplayStr
127
- };
1
+ /**
2
+ * Finds an attribute in formatMessage using attribute name.
3
+ *
4
+ * @param {Object} node - parent formatMessage node
5
+ * @param {string} attrName - attribute name.
6
+ * @returns {Object} node - returns node if it finds the attribute.
7
+ */
8
+ function findFormatMessageAttrNode(node, attrName) {
9
+ // Find formatMessage usages
10
+ if (
11
+ node.type === 'CallExpression' &&
12
+ (node.callee.name === 'formatMessage' || node.callee.name === '$t') &&
13
+ node.arguments.length > 0 &&
14
+ node.arguments[0].properties
15
+ ) {
16
+ return node.arguments[0].properties.find(
17
+ a => a.key && a.key.name === attrName
18
+ );
19
+ }
20
+
21
+ // Find intl.formatMessage usages
22
+ if (
23
+ node.type === 'CallExpression' &&
24
+ node.callee.type === 'MemberExpression' &&
25
+ (node.callee.object.name === 'intl' ||
26
+ (node.callee.object.name && node.callee.object.name.endsWith('Intl'))) &&
27
+ (node.callee.property.name === 'formatMessage' ||
28
+ node.callee.property.name === '$t')
29
+ ) {
30
+ return node.arguments[0].properties.find(
31
+ a => a.key && a.key.name === attrName
32
+ );
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Finds an attribute in FormattedMessage using attribute name.
38
+ *
39
+ * @param {Object} node - parent FormattedMessage node
40
+ * @param {string} attrName - attribute name.
41
+ * @returns {Object} node - returns node if it finds the attribute.
42
+ */
43
+ function findFormattedMessageAttrNode(node, attrName) {
44
+ if (
45
+ node.type === 'JSXIdentifier' &&
46
+ node.name === 'FormattedMessage' &&
47
+ node.parent &&
48
+ node.parent.type === 'JSXOpeningElement'
49
+ ) {
50
+ return node.parent.attributes.find(a => a.name && a.name.name === attrName);
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Finds an attribute in defineMessages using attribute name.
56
+ *
57
+ * @param {Object} node - parent defineMessages node
58
+ * @param {string} attrName - attribute name.
59
+ * @returns {Object} node - returns node if it finds the attribute.
60
+ */
61
+ function findAttrNodeInDefineMessages(node, attrName) {
62
+ if (
63
+ node.type === 'Property' &&
64
+ node.key.name === attrName &&
65
+ node.parent &&
66
+ node.parent.parent &&
67
+ node.parent.parent.parent &&
68
+ node.parent.parent.parent.parent &&
69
+ node.parent.parent.parent.parent.type === 'CallExpression' &&
70
+ node.parent.parent.parent.parent.callee.name === 'defineMessages'
71
+ ) {
72
+ return node;
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Finds an attribute in defineMessages using attribute name.
78
+ *
79
+ * @param {Object} node - parent defineMessages node
80
+ * @param {string} attrName - attribute name.
81
+ * @returns {Object} node - returns node if it finds the attribute.
82
+ */
83
+ function findAttrNodeInDefineMessage(node, attrName) {
84
+ if (
85
+ node.type === 'Property' &&
86
+ node.key.name === attrName &&
87
+ node.parent &&
88
+ node.parent.parent &&
89
+ node.parent.parent.type === 'CallExpression' &&
90
+ node.parent.parent.callee.name === 'defineMessage'
91
+ ) {
92
+ return node;
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Returns a sorted array of nodes, based on their starting posting in the locale id.
98
+ *
99
+ * @param {Object} node - parent node containing the locale id.
100
+ * @returns {Array} child nodes - sorted list.
101
+ */
102
+ function sortedTemplateElements(node) {
103
+ return [...node.quasis, ...node.expressions].sort(
104
+ (a, b) => a.range[0] - b.range[0]
105
+ );
106
+ }
107
+
108
+ /**
109
+ * Replaces place holders with asterisk and returns the resulting id.
110
+ *
111
+ * @param {Object} node - parent node containing the locale id.
112
+ * @returns {string} id - fixed id.
113
+ */
114
+ function templateLiteralDisplayStr(node) {
115
+ return sortedTemplateElements(node)
116
+ .map(e => (!e.value ? '*' : e.value.raw))
117
+ .join('');
118
+ }
119
+
120
+ module.exports = {
121
+ findFormatMessageAttrNode,
122
+ findFormattedMessageAttrNode,
123
+ findAttrNodeInDefineMessages,
124
+ findAttrNodeInDefineMessage,
125
+ sortedTemplateElements,
126
+ templateLiteralDisplayStr
127
+ };
@@ -1,66 +1,66 @@
1
- const fs = require('node:fs');
2
- const path = require('node:path');
3
- const { tsImport } = require('./import');
4
- const { getSetting } = require('./settings');
5
-
6
- /**
7
- * Map of locale file paths to keys and modified time
8
- *
9
- * @type {{string: {keys: Array, mtime: number}}}
10
- */
11
- const localeFilesKeys = {};
12
-
13
- /**
14
- * Get a list of ids keys from reading locale files
15
- * Keeps track of modified times and reloads if changed,; useful for realtime eslint in-editor
16
- *
17
- * @param {object} context - Context
18
- * @returns {string[]} results - Array of ids
19
- */
20
- function getIntlIds(context) {
21
- const projectRoot = getSetting(context, 'project-root');
22
- const localeFiles = getSetting(context, 'locale-files');
23
-
24
- if (!localeFiles) {
25
- throw new Error('localeFiles not in settings');
26
- }
27
-
28
- const results = [];
29
- localeFiles.forEach(f => {
30
- const fullPath = projectRoot ? path.join(projectRoot, f) : f;
31
- const mtime = fs.lstatSync(fullPath).mtime.getTime();
32
- if (
33
- !localeFilesKeys[fullPath] ||
34
- mtime !== localeFilesKeys[fullPath].mtime
35
- ) {
36
- let json;
37
- if (fullPath.endsWith('.json')) {
38
- json = JSON.parse(fs.readFileSync(fullPath));
39
- } else if (fullPath.endsWith('.ts')) {
40
- json = tsImport(fullPath);
41
- if (typeof json === 'object' && json.default) {
42
- json = json.default;
43
- }
44
- } else if (fullPath.endsWith('.js')) {
45
- json = require(fullPath);
46
- if (typeof json === 'object' && json.default) {
47
- json = json.default;
48
- }
49
- } else {
50
- throw new Error('unsupported file extension');
51
- }
52
-
53
- localeFilesKeys[fullPath] = {
54
- keys: Object.keys(json),
55
- mtime: mtime
56
- };
57
- }
58
- results.push(...localeFilesKeys[fullPath].keys);
59
- });
60
-
61
- return results;
62
- }
63
-
64
- module.exports = {
65
- getIntlIds
66
- };
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+ const { tsImport } = require('@agilebot/eslint-utils');
4
+ const { getSetting } = require('./settings');
5
+
6
+ /**
7
+ * Map of locale file paths to keys and modified time
8
+ *
9
+ * @type {{string: {keys: Array, mtime: number}}}
10
+ */
11
+ const localeFilesKeys = {};
12
+
13
+ /**
14
+ * Get a list of ids keys from reading locale files
15
+ * Keeps track of modified times and reloads if changed,; useful for realtime eslint in-editor
16
+ *
17
+ * @param {object} context - Context
18
+ * @returns {string[]} results - Array of ids
19
+ */
20
+ function getIntlIds(context) {
21
+ const projectRoot = getSetting(context, 'project-root');
22
+ const localeFiles = getSetting(context, 'locale-files');
23
+
24
+ if (!localeFiles) {
25
+ throw new Error('localeFiles not in settings');
26
+ }
27
+
28
+ const results = [];
29
+ localeFiles.forEach(f => {
30
+ const fullPath = projectRoot ? path.join(projectRoot, f) : f;
31
+ const mtime = fs.lstatSync(fullPath).mtime.getTime();
32
+ if (
33
+ !localeFilesKeys[fullPath] ||
34
+ mtime !== localeFilesKeys[fullPath].mtime
35
+ ) {
36
+ let json;
37
+ if (fullPath.endsWith('.json')) {
38
+ json = JSON.parse(fs.readFileSync(fullPath));
39
+ } else if (fullPath.endsWith('.ts')) {
40
+ json = tsImport(fullPath);
41
+ if (typeof json === 'object' && json.default) {
42
+ json = json.default;
43
+ }
44
+ } else if (fullPath.endsWith('.js')) {
45
+ json = require(fullPath);
46
+ if (typeof json === 'object' && json.default) {
47
+ json = json.default;
48
+ }
49
+ } else {
50
+ throw new Error('unsupported file extension');
51
+ }
52
+
53
+ localeFilesKeys[fullPath] = {
54
+ keys: Object.keys(json),
55
+ mtime: mtime
56
+ };
57
+ }
58
+ results.push(...localeFilesKeys[fullPath].keys);
59
+ });
60
+
61
+ return results;
62
+ }
63
+
64
+ module.exports = {
65
+ getIntlIds
66
+ };
package/lib/util/tss.js CHANGED
@@ -1,109 +1,109 @@
1
- // Helper function to get the basic identifier from various node types
2
- function getBasicIdentifier(node) {
3
- if (node.type === 'Identifier') {
4
- // Return the identifier name for simple cases like classes.foo
5
- return node.name;
6
- }
7
-
8
- if (node.type === 'Literal') {
9
- // Return the literal value for cases like classes['foo']
10
- return node.value;
11
- }
12
-
13
- if (node.type === 'TemplateLiteral') {
14
- // Handle template literals, e.g., classes[`foo`]
15
- if (node.expressions.length > 0) {
16
- // Template literals with expressions, e.g., classes[`foo${bar}`]
17
- return null;
18
- }
19
- return node.quasis[0].value.raw;
20
- }
21
-
22
- // Handle other cases, e.g., classes['foo' + bar]
23
- return null;
24
- }
25
-
26
- // Helper function to recursively get the base identifier from a MemberExpression node
27
- function getBaseIdentifier(node) {
28
- switch (node.type) {
29
- case 'Identifier': {
30
- return node;
31
- }
32
- case 'CallExpression': {
33
- return getBaseIdentifier(node.callee);
34
- }
35
- case 'MemberExpression': {
36
- return getBaseIdentifier(node.object);
37
- }
38
- // No default
39
- }
40
- return null;
41
- }
42
-
43
- function getStyesObj(node) {
44
- const isMakeStyles = node.callee.name === 'makeStyles';
45
-
46
- const isModernApi =
47
- node.callee.type === 'MemberExpression' &&
48
- node.callee.property.name === 'create' &&
49
- getBaseIdentifier(node.callee.object) &&
50
- getBaseIdentifier(node.callee.object).name === 'tss';
51
-
52
- if (!isMakeStyles && !isModernApi) {
53
- return;
54
- }
55
-
56
- const styles = (() => {
57
- if (isMakeStyles) {
58
- return node.parent.arguments[0];
59
- }
60
-
61
- if (isModernApi) {
62
- return node.callee.parent.arguments[0];
63
- }
64
- })();
65
-
66
- if (!styles) {
67
- return;
68
- }
69
-
70
- switch (styles.type) {
71
- case 'ObjectExpression':
72
- return styles;
73
- case 'ArrowFunctionExpression':
74
- {
75
- const { body } = styles;
76
-
77
- switch (body.type) {
78
- case 'ObjectExpression':
79
- return body;
80
- case 'BlockStatement': {
81
- let stylesObj;
82
-
83
- body.body.forEach(bodyNode => {
84
- if (
85
- bodyNode.type === 'ReturnStatement' &&
86
- bodyNode.argument.type === 'ObjectExpression'
87
- ) {
88
- stylesObj = bodyNode.argument;
89
- }
90
- });
91
-
92
- return stylesObj;
93
- }
94
- }
95
- }
96
- break;
97
- }
98
- }
99
-
100
- function isCamelCase(value) {
101
- return /^[a-z][a-zA-Z0-9]*$/.test(value);
102
- }
103
-
104
- module.exports = {
105
- getBasicIdentifier: getBasicIdentifier,
106
- getBaseIdentifier: getBaseIdentifier,
107
- getStyesObj: getStyesObj,
108
- isCamelCase: isCamelCase
109
- };
1
+ // Helper function to get the basic identifier from various node types
2
+ function getBasicIdentifier(node) {
3
+ if (node.type === 'Identifier') {
4
+ // Return the identifier name for simple cases like classes.foo
5
+ return node.name;
6
+ }
7
+
8
+ if (node.type === 'Literal') {
9
+ // Return the literal value for cases like classes['foo']
10
+ return node.value;
11
+ }
12
+
13
+ if (node.type === 'TemplateLiteral') {
14
+ // Handle template literals, e.g., classes[`foo`]
15
+ if (node.expressions.length > 0) {
16
+ // Template literals with expressions, e.g., classes[`foo${bar}`]
17
+ return null;
18
+ }
19
+ return node.quasis[0].value.raw;
20
+ }
21
+
22
+ // Handle other cases, e.g., classes['foo' + bar]
23
+ return null;
24
+ }
25
+
26
+ // Helper function to recursively get the base identifier from a MemberExpression node
27
+ function getBaseIdentifier(node) {
28
+ switch (node.type) {
29
+ case 'Identifier': {
30
+ return node;
31
+ }
32
+ case 'CallExpression': {
33
+ return getBaseIdentifier(node.callee);
34
+ }
35
+ case 'MemberExpression': {
36
+ return getBaseIdentifier(node.object);
37
+ }
38
+ // No default
39
+ }
40
+ return null;
41
+ }
42
+
43
+ function getStyesObj(node) {
44
+ const isMakeStyles = node.callee.name === 'makeStyles';
45
+
46
+ const isModernApi =
47
+ node.callee.type === 'MemberExpression' &&
48
+ node.callee.property.name === 'create' &&
49
+ getBaseIdentifier(node.callee.object) &&
50
+ getBaseIdentifier(node.callee.object).name === 'tss';
51
+
52
+ if (!isMakeStyles && !isModernApi) {
53
+ return;
54
+ }
55
+
56
+ const styles = (() => {
57
+ if (isMakeStyles) {
58
+ return node.parent.arguments[0];
59
+ }
60
+
61
+ if (isModernApi) {
62
+ return node.callee.parent.arguments[0];
63
+ }
64
+ })();
65
+
66
+ if (!styles) {
67
+ return;
68
+ }
69
+
70
+ switch (styles.type) {
71
+ case 'ObjectExpression':
72
+ return styles;
73
+ case 'ArrowFunctionExpression':
74
+ {
75
+ const { body } = styles;
76
+
77
+ switch (body.type) {
78
+ case 'ObjectExpression':
79
+ return body;
80
+ case 'BlockStatement': {
81
+ let stylesObj;
82
+
83
+ body.body.forEach(bodyNode => {
84
+ if (
85
+ bodyNode.type === 'ReturnStatement' &&
86
+ bodyNode.argument.type === 'ObjectExpression'
87
+ ) {
88
+ stylesObj = bodyNode.argument;
89
+ }
90
+ });
91
+
92
+ return stylesObj;
93
+ }
94
+ }
95
+ }
96
+ break;
97
+ }
98
+ }
99
+
100
+ function isCamelCase(value) {
101
+ return /^[a-z][a-zA-Z0-9]*$/.test(value);
102
+ }
103
+
104
+ module.exports = {
105
+ getBasicIdentifier: getBasicIdentifier,
106
+ getBaseIdentifier: getBaseIdentifier,
107
+ getStyesObj: getStyesObj,
108
+ isCamelCase: isCamelCase
109
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agilebot/eslint-plugin",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Agilebot's ESLint plugin",
5
5
  "main": "lib",
6
6
  "license": "MIT",
@@ -18,10 +18,7 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@typescript-eslint/utils": "^7.1.1",
21
- "fast-glob": "^3.3.2",
22
- "get-tsconfig": "^4.7.3",
23
- "jiti": "^1.21.0",
24
- "sucrase": "^3.35.0"
21
+ "fast-glob": "^3.3.2"
25
22
  },
26
23
  "peerDependencies": {
27
24
  "eslint": "^7.0.0 || ^8.0.0"