@@ -7,6 +7,63 @@ 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 : { description : 'Disallow hardcoded arn:aws: partition in ARN construction. Use arnPrefix(region) instead.' } ,
17+ schema : [ ] ,
18+ } ,
19+ create ( context ) {
20+ function checkForHardcodedArn ( node , value ) {
21+ if ( / a r n : a w s : / . test ( value ) ) {
22+ context . report ( { node, message : 'Hardcoded "arn:aws:" detected. Use arnPrefix(region) from src/cli/aws/partition.ts for multi-partition support.' } ) ;
23+ }
24+ }
25+ return {
26+ TemplateLiteral ( node ) {
27+ for ( const quasi of node . quasis ) {
28+ checkForHardcodedArn ( node , quasi . value . raw ) ;
29+ }
30+ } ,
31+ } ;
32+ } ,
33+ } ,
34+ 'no-hardcoded-endpoint-tld' : {
35+ meta : {
36+ type : 'problem' ,
37+ docs : { description : 'Disallow hardcoded amazonaws.com in endpoint URL construction. Use serviceEndpoint() or dnsSuffix() instead.' } ,
38+ schema : [ ] ,
39+ } ,
40+ create ( context ) {
41+ const REGION_PATTERN = / [ a - z ] { 2 } ( - [ a - z ] + - \d + ) / ;
42+ function hasHardcodedEndpoint ( value ) {
43+ return / \. a m a z o n a w s \. c o m / . test ( value ) ;
44+ }
45+ function hasHardcodedEndpointWithRegion ( value ) {
46+ return hasHardcodedEndpoint ( value ) && REGION_PATTERN . test ( value ) ;
47+ }
48+ return {
49+ TemplateLiteral ( node ) {
50+ for ( const quasi of node . quasis ) {
51+ if ( hasHardcodedEndpoint ( quasi . value . raw ) ) {
52+ context . report ( { node, message : 'Hardcoded ".amazonaws.com" in template literal. Use serviceEndpoint() or dnsSuffix() from src/cli/aws/partition.ts for multi-partition support.' } ) ;
53+ }
54+ }
55+ } ,
56+ Literal ( node ) {
57+ if ( typeof node . value === 'string' && hasHardcodedEndpointWithRegion ( node . value ) ) {
58+ context . report ( { node, message : 'Hardcoded endpoint with region detected. Use serviceEndpoint() or dnsSuffix() from src/cli/aws/partition.ts for multi-partition support.' } ) ;
59+ }
60+ } ,
61+ } ;
62+ } ,
63+ } ,
64+ } ,
65+ } ;
66+
1067export default tseslint . config (
1168 eslint . configs . recommended ,
1269 ...tseslint . configs . recommendedTypeChecked ,
@@ -30,8 +87,11 @@ export default tseslint.config(
3087 'react-hooks' : reactHooks ,
3188 'react-refresh' : reactRefresh ,
3289 security,
90+ partition : partitionPlugin ,
3391 } ,
3492 rules : {
93+ 'partition/no-hardcoded-arn-partition' : 'error' ,
94+ 'partition/no-hardcoded-endpoint-tld' : 'error' ,
3595 ...importPlugin . configs . recommended . rules ,
3696 ...react . configs . recommended . rules ,
3797 ...security . configs . recommended . rules ,
@@ -68,6 +128,8 @@ export default tseslint.config(
68128 {
69129 files : [ '**/*.test.ts' , '**/*.test.tsx' , '**/test-utils/**' , 'integ-tests/**' ] ,
70130 rules : {
131+ 'partition/no-hardcoded-arn-partition' : 'off' ,
132+ 'partition/no-hardcoded-endpoint-tld' : 'off' ,
71133 '@typescript-eslint/no-unsafe-assignment' : 'off' ,
72134 '@typescript-eslint/no-unsafe-member-access' : 'off' ,
73135 '@typescript-eslint/no-unsafe-call' : 'off' ,
0 commit comments