declapract-typescript-ehmpathy 0.42.5 → 0.43.0

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 (30) hide show
  1. package/dist/practices/format/bad-practices/prettier/.declapract.readme.md +6 -0
  2. package/dist/practices/{prettier/best-practice → format/bad-practices/prettier}/.prettierignore +1 -0
  3. package/dist/practices/format/bad-practices/prettier/.prettierignore.declapract.ts +8 -0
  4. package/dist/practices/format/bad-practices/prettier/package.json.declapract.ts +35 -0
  5. package/dist/practices/format/bad-practices/prettier/prettier.config.js.declapract.ts +8 -0
  6. package/dist/practices/format/best-practice/package.json.declapract.ts +1 -1
  7. package/dist/practices/lint/bad-practices/depcheck-denylisted-ignores/.depcheckrc.yml.declapract.ts +2 -0
  8. package/dist/practices/lint/bad-practices/eslint/.eslintrc.js.declapract.ts +3 -0
  9. package/dist/practices/lint/bad-practices/eslint/package.json.declapract.ts +51 -0
  10. package/dist/practices/lint/best-practice/.declapract.readme.md +1 -1
  11. package/dist/practices/lint/best-practice/.depcheckrc.yml +7 -5
  12. package/dist/practices/lint/best-practice/package.json +7 -12
  13. package/dist/practices/package-json-order/best-practice/package.json.declapract.ts +2 -0
  14. package/dist/practices/serverless/best-practice/serverless.yml +5 -0
  15. package/dist/practices/serverless/best-practice/serverless.yml.declapract.ts +49 -34
  16. package/dist/practices/tests/best-practice/jest.acceptance.config.ts +3 -0
  17. package/dist/practices/tests/best-practice/jest.config.ts +3 -0
  18. package/dist/practices/tests/best-practice/jest.integration.config.ts +3 -0
  19. package/dist/practices/tests/best-practice/jest.unit.config.ts +3 -0
  20. package/dist/practices/tests/best-practice/package.json +3 -2
  21. package/dist/practices/typescript/best-practice/package.json +2 -1
  22. package/dist/practices/typescript/best-practice/tsconfig.json +4 -1
  23. package/dist/useCases.yml +0 -2
  24. package/package.json +1 -1
  25. package/dist/practices/lint/best-practice/.declapract.todo.md +0 -5
  26. package/dist/practices/prettier/best-practice/package.json.declapract.ts +0 -3
  27. /package/dist/practices/{prettier → format}/bad-practices/format-script/package.json.declapract.ts +0 -0
  28. /package/dist/practices/{prettier/best-practice → format/bad-practices/prettier}/package.json +0 -0
  29. /package/dist/practices/{prettier/best-practice → format/bad-practices/prettier}/prettier.config.js +0 -0
  30. /package/dist/practices/lint/{best-practice → bad-practices/eslint}/.eslintrc.js +0 -0
@@ -0,0 +1,6 @@
1
+ Prettier is no longer used - biome or other tools are preferred. This bad practice removes:
2
+
3
+ - prettier.config.js
4
+ - .prettierignore
5
+ - prettier and @trivago/prettier-plugin-sort-imports devDependencies
6
+ - fix:format:prettier and test:format:prettier scripts
@@ -0,0 +1,8 @@
1
+ import { FileCheckType, FileFixFunction } from 'declapract';
2
+
3
+ export const check = FileCheckType.EXISTS;
4
+
5
+ export const fix: FileFixFunction = () => {
6
+ // Remove the file by returning null contents
7
+ return { contents: null };
8
+ };
@@ -0,0 +1,35 @@
1
+ import { FileCheckType, FileFixFunction } from 'declapract';
2
+
3
+ export const check = FileCheckType.CONTAINS;
4
+
5
+ const depsToRemove = ['prettier', '@trivago/prettier-plugin-sort-imports'];
6
+
7
+ const scriptsToRemove = ['fix:format:prettier', 'test:format:prettier'];
8
+
9
+ export const fix: FileFixFunction = (contents) => {
10
+ if (!contents) return { contents };
11
+
12
+ const packageJSON = JSON.parse(contents);
13
+
14
+ // Remove prettier devDependencies
15
+ const updatedDevDeps = { ...packageJSON.devDependencies };
16
+ for (const dep of depsToRemove) {
17
+ delete updatedDevDeps[dep];
18
+ }
19
+
20
+ // Remove prettier scripts
21
+ const updatedScripts = { ...packageJSON.scripts };
22
+ for (const script of scriptsToRemove) {
23
+ delete updatedScripts[script];
24
+ }
25
+
26
+ const fixedPackageJSON = {
27
+ ...packageJSON,
28
+ devDependencies:
29
+ Object.keys(updatedDevDeps).length > 0 ? updatedDevDeps : undefined,
30
+ scripts:
31
+ Object.keys(updatedScripts).length > 0 ? updatedScripts : undefined,
32
+ };
33
+
34
+ return { contents: JSON.stringify(fixedPackageJSON, null, 2) };
35
+ };
@@ -0,0 +1,8 @@
1
+ import { FileCheckType, FileFixFunction } from 'declapract';
2
+
3
+ export const check = FileCheckType.EXISTS;
4
+
5
+ export const fix: FileFixFunction = () => {
6
+ // Remove the file by returning null contents
7
+ return { contents: null };
8
+ };
@@ -6,7 +6,7 @@ import { isPresent } from 'type-fns';
6
6
  */
7
7
  export const contents: FileContentsFunction = (context) => {
8
8
  const formatters = [
9
- 'prettier',
9
+ 'biome',
10
10
  context.projectPractices.includes('terraform') ? 'terraform' : null, // only include the terraform formatter if terraform practice is used
11
11
  ].filter(isPresent);
12
12
 
@@ -9,6 +9,8 @@ const denylist = [
9
9
  'ts-jest',
10
10
  'core-js',
11
11
  'babel-jest',
12
+ '@trivago/prettier-plugin-sort-imports',
13
+ '@tsconfig/node-lts-strictest',
12
14
  ];
13
15
 
14
16
  export const check: FileCheckFunction = (contents) => {
@@ -0,0 +1,3 @@
1
+ import { FileCheckType, FileFixFunction } from 'declapract';
2
+
3
+ export const check = FileCheckType.EXISTS;
@@ -0,0 +1,51 @@
1
+ import { FileCheckFunction, FileFixFunction } from 'declapract';
2
+
3
+ const depsBlocklist = [
4
+ '@typescript-eslint/eslint-plugin',
5
+ '@typescript-eslint/parser',
6
+ 'eslint',
7
+ 'eslint-config-airbnb-typescript',
8
+ 'eslint-config-prettier',
9
+ 'eslint-plugin-import',
10
+ 'eslint-plugin-prettier',
11
+ 'eslint-plugin-unused-imports',
12
+ ];
13
+
14
+ const scriptsBlocklist = ['test:lint:eslint'];
15
+
16
+ export const check: FileCheckFunction = (contents) => {
17
+ if (!contents) throw Error('does not match bad practice');
18
+ const packageJSONObject = JSON.parse(contents);
19
+ const devDepsFound = Object.keys(packageJSONObject.devDependencies ?? {});
20
+ const scriptsFound = Object.keys(packageJSONObject.scripts ?? {});
21
+ if (
22
+ depsBlocklist.some((dep) => devDepsFound.includes(dep)) ||
23
+ scriptsBlocklist.some((script) => scriptsFound.includes(script))
24
+ )
25
+ return; // matches bad practice
26
+ throw new Error('does not match bad practice');
27
+ };
28
+
29
+ export const fix: FileFixFunction = (contents) => {
30
+ if (!contents) return {}; // should not occur
31
+ const packageJSONObject = JSON.parse(contents);
32
+
33
+ // Remove blocklisted devDependencies
34
+ const updatedDevDeps = { ...packageJSONObject.devDependencies };
35
+ for (const dep of depsBlocklist) {
36
+ delete updatedDevDeps[dep];
37
+ }
38
+
39
+ // Remove blocklisted scripts
40
+ const updatedScripts = { ...packageJSONObject.scripts };
41
+ for (const script of scriptsBlocklist) {
42
+ delete updatedScripts[script];
43
+ }
44
+
45
+ const fixedPackageJSONObject = {
46
+ ...packageJSONObject,
47
+ devDependencies: updatedDevDeps,
48
+ scripts: packageJSONObject.scripts ? updatedScripts : undefined,
49
+ };
50
+ return { contents: JSON.stringify(fixedPackageJSONObject, null, 2) };
51
+ };
@@ -1,4 +1,4 @@
1
- # eslint
1
+ # biome
2
2
  prevents bad practices and improves code quality
3
3
 
4
4
  # depcheck
@@ -3,9 +3,11 @@ ignores:
3
3
  - declapract
4
4
  - declapract-typescript-ehmpathy
5
5
  - '@commitlint/config-conventional'
6
- - '@trivago/prettier-plugin-sort-imports'
7
- - '@tsconfig/node-lts-strictest'
8
- - tsx
6
+ - '@tsconfig/node20'
7
+ - '@tsconfig/strictest'
8
+ - '@biomejs/biome'
9
+ - esbuild-register
10
+ - "@swc/core"
11
+ - "@swc/jest"
9
12
  - husky
10
- - '@swc/core'
11
- - '@swc/jest'
13
+ - tsx
@@ -1,19 +1,14 @@
1
1
  {
2
2
  "devDependencies": {
3
- "@typescript-eslint/eslint-plugin": "7.8.0",
4
- "@typescript-eslint/parser": "7.8.0",
5
- "eslint": "8.56.0",
6
- "eslint-config-airbnb-typescript": "18.0.0",
7
- "eslint-config-prettier": "8.5.0",
8
- "eslint-plugin-import": "2.26.0",
9
- "eslint-plugin-prettier": "4.2.1",
10
- "eslint-plugin-unused-imports": "4.1.4",
11
- "depcheck": "1.4.3"
3
+ "depcheck": "1.4.3",
4
+ "@biomejs/biome": "2.3.8"
12
5
  },
13
6
  "scripts": {
14
- "fix:lint": "eslint -c ./.eslintrc.js src/**/*.ts --fix",
15
- "test:lint:eslint": "eslint -c ./.eslintrc.js src/**/*.ts",
7
+ "fix:format:biome": "biome check --write src",
8
+ "fix:lint": "biome check --write src",
9
+ "test:format:biome": "biome format src",
10
+ "test:lint:biome": "eslint -c ./.eslintrc.js src/**/*.ts",
16
11
  "test:lint:deps": "npx depcheck -c ./.depcheckrc.yml",
17
- "test:lint": "npm run test:lint:eslint && npm run test:lint:deps"
12
+ "test:lint": "npm run test:lint:biome && npm run test:lint:deps"
18
13
  }
19
14
  }
@@ -23,6 +23,7 @@ export const desiredRelativeKeyOrder = {
23
23
  ],
24
24
  scripts: [
25
25
  'commit:with-cli',
26
+ 'fix:format:biome',
26
27
  'fix:format:prettier',
27
28
  'fix:format:terraform',
28
29
  'fix:format',
@@ -55,6 +56,7 @@ export const desiredRelativeKeyOrder = {
55
56
  'test:format:terraform',
56
57
  'test:format',
57
58
  'test:lint:deps',
59
+ 'test:lint:biome',
58
60
  'test:lint:eslint',
59
61
  'test:lint',
60
62
  'test:unit',
@@ -110,3 +110,8 @@ provider:
110
110
  - athena:GetQueryExecution
111
111
  - athena:GetQueryResults
112
112
  Resource: '*'
113
+ # allow inferring access from account alias
114
+ - Effect: Allow
115
+ Action:
116
+ - iam:ListAccountAliases
117
+ Resource: '*'
@@ -3,40 +3,55 @@ import { FileFixFunction } from 'declapract/dist/domain';
3
3
 
4
4
  export const check = FileCheckType.CONTAINS; // i.e., check that the contents of the file contains what's declared (default is equals)
5
5
 
6
+ const listAccountAliasesPolicy = ` # allow inferring access from account alias
7
+ - Effect: Allow
8
+ Action:
9
+ - iam:ListAccountAliases
10
+ Resource: '*'`;
11
+
6
12
  export const fix: FileFixFunction = (contents) => {
7
13
  if (!contents) return { contents }; // do nothing if file dne; // TODO: update to provision file from declared contents
8
- return {
9
- // TODO: when we have special support for yml, do this better (i.e., instead of string replace, just add to the yml object after parsing it)
10
- contents: contents
11
- .replace(/runtime\: nodejs\d\d.x/, 'runtime: nodejs16.x')
12
- .replace(/ - serverless-offline .*\n/, '') // a plugin we no longer use (never used it, no need to have it)
13
- .replace(/ - serverless-pseudo-parameters .*\n/, '') // a plugin we no longer use (serverless supports variables natively now)
14
- .replace(/\#\{AWS\:\:Region\}/g, '${aws:region}') // use the serverless native variables, instead of the pseudo-parameters format
15
- .replace(/\#\{AWS\:\:AccountId\}/g, '${aws:accountId}') // use the serverless native variables, instead of the pseudo-parameters format
16
- .replace('## paramstore access', '# parameter store access')
17
- .replace(
18
- '## allow invocation of other lambdas',
19
- '# allow invocation of other lambdas',
20
- )
21
- .replace(
22
- 'environment:\n NODE_ENV:',
23
- 'environment:\n TZ: UTC # guarantee that utc timezone will be used explicitly, to facilitate a pit of success\n NODE_ENV:',
24
- )
25
- .replace(
26
- 'NODE_ENV: ${self:custom.stageToNodeEnvMapping.${self:provider.stage}}\n deploymentBucket',
27
- 'NODE_ENV: ${self:custom.stageToNodeEnvMapping.${self:provider.stage}}\n AWS_NODEJS_CONNECTION_REUSE_ENABLED: true # https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/node-reusing-connections.html\n deploymentBucket',
28
- ) // add this env flag
29
- .replace(
30
- /service: ([a-zA-Z0-9\-]+)\n\n?provider:/,
31
- 'service: $1\n\npackage:\n artifact: .artifact/contents.zip\n\nprovider:',
32
- )
33
- .replace(
34
- ' artifact: .artifact/contents.zip\n\nprovider:', // if no plugins at all
35
- ' artifact: .artifact/contents.zip\n\nplugins:\n - serverless-prune-plugin\n\nprovider:', // add the sls prune plugin
36
- )
37
- .replace(
38
- ' timeout: 10',
39
- ' timeout: 60 # default timeout to 1min, for resilience against increased cold start times; individual functions can override this', // bump the timeout
40
- ),
41
- };
14
+ let fixed = contents
15
+ .replace(/runtime\: nodejs\d\d.x/, 'runtime: nodejs16.x')
16
+ .replace(/ - serverless-offline .*\n/, '') // a plugin we no longer use (never used it, no need to have it)
17
+ .replace(/ - serverless-pseudo-parameters .*\n/, '') // a plugin we no longer use (serverless supports variables natively now)
18
+ .replace(/\#\{AWS\:\:Region\}/g, '${aws:region}') // use the serverless native variables, instead of the pseudo-parameters format
19
+ .replace(/\#\{AWS\:\:AccountId\}/g, '${aws:accountId}') // use the serverless native variables, instead of the pseudo-parameters format
20
+ .replace('## paramstore access', '# parameter store access')
21
+ .replace(
22
+ '## allow invocation of other lambdas',
23
+ '# allow invocation of other lambdas',
24
+ )
25
+ .replace(
26
+ 'environment:\n NODE_ENV:',
27
+ 'environment:\n TZ: UTC # guarantee that utc timezone will be used explicitly, to facilitate a pit of success\n NODE_ENV:',
28
+ )
29
+ .replace(
30
+ 'NODE_ENV: ${self:custom.stageToNodeEnvMapping.${self:provider.stage}}\n deploymentBucket',
31
+ 'NODE_ENV: ${self:custom.stageToNodeEnvMapping.${self:provider.stage}}\n AWS_NODEJS_CONNECTION_REUSE_ENABLED: true # https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/node-reusing-connections.html\n deploymentBucket',
32
+ ) // add this env flag
33
+ .replace(
34
+ /service: ([a-zA-Z0-9\-]+)\n\n?provider:/,
35
+ 'service: $1\n\npackage:\n artifact: .artifact/contents.zip\n\nprovider:',
36
+ )
37
+ .replace(
38
+ ' artifact: .artifact/contents.zip\n\nprovider:', // if no plugins at all
39
+ ' artifact: .artifact/contents.zip\n\nplugins:\n - serverless-prune-plugin\n\nprovider:', // add the sls prune plugin
40
+ )
41
+ .replace(
42
+ ' timeout: 10',
43
+ ' timeout: 60 # default timeout to 1min, for resilience against increased cold start times; individual functions can override this', // bump the timeout
44
+ );
45
+
46
+ // Append ListAccountAliases policy if not already present
47
+ if (!fixed.includes('iam:ListAccountAliases')) {
48
+ if (/iamRoleStatements:\s*\n/.test(fixed)) {
49
+ fixed = fixed.replace(
50
+ /iamRoleStatements:\s*\n/,
51
+ `iamRoleStatements:\n${listAccountAliasesPolicy}\n`,
52
+ );
53
+ }
54
+ }
55
+
56
+ return { contents: fixed };
42
57
  };
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @jest-config-loader esbuild-register
3
+ */
1
4
  import type { Config } from 'jest';
2
5
 
3
6
  // ensure tests run in utc, like they will on cicd and on server; https://stackoverflow.com/a/56277249/15593329
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @jest-config-loader esbuild-register
3
+ */
1
4
  import config from './jest.unit.config';
2
5
 
3
6
  // eslint-disable-next-line import/no-default-export
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @jest-config-loader esbuild-register
3
+ */
1
4
  import type { Config } from 'jest';
2
5
 
3
6
  // ensure tests run in utc, like they will on cicd and on server; https://stackoverflow.com/a/56277249/15593329
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @jest-config-loader esbuild-register
3
+ */
1
4
  import type { Config } from 'jest';
2
5
 
3
6
  // ensure tests run in utc, like they will on cicd and on server; https://stackoverflow.com/a/56277249/15593329
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "devDependencies": {
3
- "@types/jest": "@declapract{check.minVersion('29.2.4')}",
4
- "jest": "@declapract{check.minVersion('29.3.1')}",
3
+ "@types/jest": "@declapract{check.minVersion('30.2.0')}",
4
+ "jest": "@declapract{check.minVersion('30.2.0')}",
5
+ "esbuild-register": "@declapract{check.minVersion('3.6.0')}",
5
6
  "test-fns": "@declapract{check.minVersion('1.4.2')}",
6
7
  "tsx": "@declapract{check.minVersion('4.20.6')}",
7
8
  "@swc/core": "@declapract{check.minVersion('1.15.3')}",
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "devDependencies": {
3
3
  "typescript": "@declapract{check.minVersion('5.4.5')}",
4
- "@tsconfig/node-lts-strictest": "@declapract{check.minVersion('18.12.1')}"
4
+ "@tsconfig/node20": "@declapract{check.minVersion('20.1.5')}",
5
+ "@tsconfig/strictest": "@declapract{check.minVersion('2.0.5')}"
5
6
  },
6
7
  "scripts": {
7
8
  "build:clean": "rm dist/ -rf",
@@ -1,5 +1,8 @@
1
1
  {
2
- "extends": "@tsconfig/node-lts-strictest/tsconfig.json",
2
+ "extends": [
3
+ "@tsconfig/strictest/tsconfig.json",
4
+ "@tsconfig/node20/tsconfig.json"
5
+ ],
3
6
  "compilerOptions": {
4
7
  "importsNotUsedAsValues": "remove",
5
8
  "noPropertyAccessFromIndexSignature": false,
package/dist/useCases.yml CHANGED
@@ -14,7 +14,6 @@ use-cases:
14
14
  - node
15
15
  - nonpublished-modules
16
16
  - package-json-order
17
- - prettier
18
17
  - tests
19
18
  - typescript
20
19
  - pnpm
@@ -70,7 +69,6 @@ use-cases:
70
69
  - node
71
70
  - nonpublished-modules
72
71
  - package-json-order
73
- - prettier
74
72
  - terraform-common
75
73
  - provision-github
76
74
  - lint
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "declapract-typescript-ehmpathy",
3
3
  "author": "ehmpathy",
4
4
  "description": "declapract best practices declarations for typescript",
5
- "version": "0.42.5",
5
+ "version": "0.43.0",
6
6
  "license": "MIT",
7
7
  "main": "src/index.js",
8
8
  "repository": "ehmpathy/declapract-typescript-ehmpathy",
@@ -1,5 +0,0 @@
1
- # todo
2
-
3
- replace with biome
4
-
5
- its faster and requires less deps
@@ -1,3 +0,0 @@
1
- import { FileCheckType } from 'declapract';
2
-
3
- export const check = FileCheckType.CONTAINS;