@@ -7,6 +7,80 @@ import reactRefresh from 'eslint-plugin-react-refresh';
77import security from 'eslint-plugin-security' ;
88import tseslint from 'typescript-eslint' ;
99
10+ /** @type {import('eslint').ESLint.Plugin } */
11+ const partitionPlugin = {
12+ rules : {
13+ 'no-hardcoded-arn-partition' : {
14+ meta : {
15+ type : 'problem' ,
16+ docs : {
17+ description : 'Disallow hardcoded arn:aws: partition in ARN construction. Use arnPrefix(region) instead.' ,
18+ } ,
19+ schema : [ ] ,
20+ } ,
21+ create ( context ) {
22+ function checkForHardcodedArn ( node , value ) {
23+ if ( / a r n : a w s : / . test ( value ) ) {
24+ context . report ( {
25+ node,
26+ message :
27+ 'Hardcoded "arn:aws:" detected. Use arnPrefix(region) from src/cli/aws/partition.ts for multi-partition support.' ,
28+ } ) ;
29+ }
30+ }
31+ return {
32+ TemplateLiteral ( node ) {
33+ for ( const quasi of node . quasis ) {
34+ checkForHardcodedArn ( node , quasi . value . raw ) ;
35+ }
36+ } ,
37+ } ;
38+ } ,
39+ } ,
40+ 'no-hardcoded-endpoint-tld' : {
41+ meta : {
42+ type : 'problem' ,
43+ docs : {
44+ description :
45+ 'Disallow hardcoded amazonaws.com in endpoint URL construction. Use serviceEndpoint() or dnsSuffix() instead.' ,
46+ } ,
47+ schema : [ ] ,
48+ } ,
49+ create ( context ) {
50+ const REGION_PATTERN = / [ a - z ] { 2 } ( - [ a - z ] + - \d + ) / ;
51+ function hasHardcodedEndpoint ( value ) {
52+ return / \. a m a z o n a w s \. c o m / . test ( value ) ;
53+ }
54+ function hasHardcodedEndpointWithRegion ( value ) {
55+ return hasHardcodedEndpoint ( value ) && REGION_PATTERN . test ( value ) ;
56+ }
57+ return {
58+ TemplateLiteral ( node ) {
59+ for ( const quasi of node . quasis ) {
60+ if ( hasHardcodedEndpoint ( quasi . value . raw ) ) {
61+ context . report ( {
62+ node,
63+ message :
64+ 'Hardcoded ".amazonaws.com" in template literal. Use serviceEndpoint() or dnsSuffix() from src/cli/aws/partition.ts for multi-partition support.' ,
65+ } ) ;
66+ }
67+ }
68+ } ,
69+ Literal ( node ) {
70+ if ( typeof node . value === 'string' && hasHardcodedEndpointWithRegion ( node . value ) ) {
71+ context . report ( {
72+ node,
73+ message :
74+ 'Hardcoded endpoint with region detected. Use serviceEndpoint() or dnsSuffix() from src/cli/aws/partition.ts for multi-partition support.' ,
75+ } ) ;
76+ }
77+ } ,
78+ } ;
79+ } ,
80+ } ,
81+ } ,
82+ } ;
83+
1084export default tseslint . config (
1185 eslint . configs . recommended ,
1286 ...tseslint . configs . recommendedTypeChecked ,
@@ -30,8 +104,11 @@ export default tseslint.config(
30104 'react-hooks' : reactHooks ,
31105 'react-refresh' : reactRefresh ,
32106 security,
107+ partition : partitionPlugin ,
33108 } ,
34109 rules : {
110+ 'partition/no-hardcoded-arn-partition' : 'error' ,
111+ 'partition/no-hardcoded-endpoint-tld' : 'error' ,
35112 ...importPlugin . configs . recommended . rules ,
36113 ...react . configs . recommended . rules ,
37114 ...security . configs . recommended . rules ,
@@ -68,6 +145,8 @@ export default tseslint.config(
68145 {
69146 files : [ '**/*.test.ts' , '**/*.test.tsx' , '**/test-utils/**' , 'integ-tests/**' ] ,
70147 rules : {
148+ 'partition/no-hardcoded-arn-partition' : 'off' ,
149+ 'partition/no-hardcoded-endpoint-tld' : 'off' ,
71150 '@typescript-eslint/no-unsafe-assignment' : 'off' ,
72151 '@typescript-eslint/no-unsafe-member-access' : 'off' ,
73152 '@typescript-eslint/no-unsafe-call' : 'off' ,
0 commit comments