@futdevpro/dynamo-eslint 1.12.1

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 (97) hide show
  1. package/.eslintrc.json +16 -0
  2. package/.github/workflows/main.yml +393 -0
  3. package/INTEGRATION.md +74 -0
  4. package/POC-README.md +147 -0
  5. package/README.md +36 -0
  6. package/build/configs/base.d.ts +81 -0
  7. package/build/configs/base.d.ts.map +1 -0
  8. package/build/configs/base.js +51 -0
  9. package/build/configs/base.js.map +1 -0
  10. package/build/configs/fsm.d.ts +82 -0
  11. package/build/configs/fsm.d.ts.map +1 -0
  12. package/build/configs/fsm.js +7 -0
  13. package/build/configs/fsm.js.map +1 -0
  14. package/build/configs/ngx-package.d.ts +81 -0
  15. package/build/configs/ngx-package.d.ts.map +1 -0
  16. package/build/configs/ngx-package.js +7 -0
  17. package/build/configs/ngx-package.js.map +1 -0
  18. package/build/configs/ngx.d.ts +81 -0
  19. package/build/configs/ngx.d.ts.map +1 -0
  20. package/build/configs/ngx.js +12 -0
  21. package/build/configs/ngx.js.map +1 -0
  22. package/build/configs/nts-package.d.ts +83 -0
  23. package/build/configs/nts-package.d.ts.map +1 -0
  24. package/build/configs/nts-package.js +12 -0
  25. package/build/configs/nts-package.js.map +1 -0
  26. package/build/configs/nts.d.ts +82 -0
  27. package/build/configs/nts.d.ts.map +1 -0
  28. package/build/configs/nts.js +13 -0
  29. package/build/configs/nts.js.map +1 -0
  30. package/build/index.d.ts +2 -0
  31. package/build/index.d.ts.map +1 -0
  32. package/build/index.js +3 -0
  33. package/build/index.js.map +1 -0
  34. package/build/plugin/index.d.ts +16 -0
  35. package/build/plugin/index.d.ts.map +1 -0
  36. package/build/plugin/index.js +19 -0
  37. package/build/plugin/index.js.map +1 -0
  38. package/build/plugin/rules/import-order.d.ts +4 -0
  39. package/build/plugin/rules/import-order.d.ts.map +1 -0
  40. package/build/plugin/rules/import-order.js +134 -0
  41. package/build/plugin/rules/import-order.js.map +1 -0
  42. package/build/plugin/rules/import-order.spec.d.ts +2 -0
  43. package/build/plugin/rules/import-order.spec.d.ts.map +1 -0
  44. package/build/plugin/rules/import-order.spec.js +181 -0
  45. package/build/plugin/rules/import-order.spec.js.map +1 -0
  46. package/build/plugin/rules/naming-patterns.d.ts +4 -0
  47. package/build/plugin/rules/naming-patterns.d.ts.map +1 -0
  48. package/build/plugin/rules/naming-patterns.js +23 -0
  49. package/build/plugin/rules/naming-patterns.js.map +1 -0
  50. package/build/plugin/rules/naming-patterns.spec.d.ts +2 -0
  51. package/build/plugin/rules/naming-patterns.spec.d.ts.map +1 -0
  52. package/build/plugin/rules/naming-patterns.spec.js +36 -0
  53. package/build/plugin/rules/naming-patterns.spec.js.map +1 -0
  54. package/build/scripts/eslintrc-audit.d.ts +3 -0
  55. package/build/scripts/eslintrc-audit.d.ts.map +1 -0
  56. package/build/scripts/eslintrc-audit.js +36 -0
  57. package/build/scripts/eslintrc-audit.js.map +1 -0
  58. package/build/scripts/validate-imports.d.ts +3 -0
  59. package/build/scripts/validate-imports.d.ts.map +1 -0
  60. package/build/scripts/validate-imports.js +76 -0
  61. package/build/scripts/validate-imports.js.map +1 -0
  62. package/build/scripts/validate-naming.d.ts +3 -0
  63. package/build/scripts/validate-naming.d.ts.map +1 -0
  64. package/build/scripts/validate-naming.js +76 -0
  65. package/build/scripts/validate-naming.js.map +1 -0
  66. package/build-test/plugin/rules/import-order.d.ts +3 -0
  67. package/build-test/plugin/rules/import-order.js +23 -0
  68. package/build-test/plugin/rules/import-order.spec.d.ts +1 -0
  69. package/build-test/plugin/rules/import-order.spec.js +44 -0
  70. package/build-test/plugin/rules/naming-patterns.d.ts +3 -0
  71. package/build-test/plugin/rules/naming-patterns.js +22 -0
  72. package/build-test/plugin/rules/naming-patterns.spec.d.ts +1 -0
  73. package/build-test/plugin/rules/naming-patterns.spec.js +41 -0
  74. package/futdevpro-dynamo-eslint-01.12.01.tgz +0 -0
  75. package/package.json +95 -0
  76. package/samples/base/.eslintrc.json +6 -0
  77. package/samples/ngx/.eslintrc.json +6 -0
  78. package/samples/nts/.eslintrc.json +6 -0
  79. package/samples/poc-sample.ts +38 -0
  80. package/samples/poc-violations.ts +25 -0
  81. package/spec/support/jasmine.json +24 -0
  82. package/src/configs/base.ts +51 -0
  83. package/src/configs/fsm.ts +9 -0
  84. package/src/configs/ngx-package.ts +9 -0
  85. package/src/configs/ngx.ts +14 -0
  86. package/src/configs/nts-package.ts +14 -0
  87. package/src/configs/nts.ts +15 -0
  88. package/src/index.ts +4 -0
  89. package/src/plugin/index.ts +19 -0
  90. package/src/plugin/rules/import-order.spec.ts +197 -0
  91. package/src/plugin/rules/import-order.ts +167 -0
  92. package/src/plugin/rules/naming-patterns.spec.ts +39 -0
  93. package/src/plugin/rules/naming-patterns.ts +25 -0
  94. package/src/scripts/eslintrc-audit.ts +39 -0
  95. package/src/scripts/validate-imports.ts +98 -0
  96. package/src/scripts/validate-naming.ts +97 -0
  97. package/tsconfig.json +32 -0
package/.eslintrc.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "root": true,
3
+ "env": { "node": true, "es2021": true },
4
+ "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
5
+ "parser": "@typescript-eslint/parser",
6
+ "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" },
7
+ "plugins": ["@typescript-eslint"],
8
+ "ignorePatterns": ["build/**"],
9
+ "rules": {
10
+ "indent": ["warn", 2, { "SwitchCase": 1 }],
11
+ "quotes": ["warn", "single", { "allowTemplateLiterals": true }],
12
+ "semi": ["warn", "always"]
13
+ }
14
+ }
15
+
16
+
@@ -0,0 +1,393 @@
1
+ name: Test and Deploy
2
+ on:
3
+ push:
4
+ branches:
5
+ - '**'
6
+ permissions:
7
+ actions: read
8
+ id-token: write
9
+ contents: read
10
+ checks: write
11
+ issues: read
12
+ pull-requests: write
13
+ env:
14
+ PACKAGE_NAME: ''
15
+ THIS_VERSION: 0.0.0
16
+ LATEST_VERSION: 0.0.0
17
+ VERSION_PUBLISHED: true
18
+
19
+
20
+ jobs:
21
+ notification0:
22
+ name: 🏹 Discord start Notification
23
+ runs-on: ubuntu-latest
24
+ #runs-on: plo-koon
25
+ timeout-minutes: 20
26
+ outputs:
27
+ start: ${{ steps.mark_start.outputs.started }}
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - id: mark_start
31
+ run: echo "started=$(date +%s)" >> "$GITHUB_OUTPUT"
32
+ - name: Send Discord start notification
33
+ uses: futdevpro/fdp-github-actions/discord-start-notification@latest
34
+ with:
35
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
36
+ APPLICATION_NAME: "Dynamo-ESLint"
37
+ APPLICATION_EMOJI: "🔧"
38
+ COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
39
+ EVENT_DATETIME: ${{ github.event.head_commit.timestamp }}
40
+ DISCORD_WEBHOOK_ID: ${{ secrets.DISCORD_WEBHOOK_ID }}
41
+ DISCORD_WEBHOOK_TOKEN: ${{ secrets.DISCORD_WEBHOOK_TOKEN }}
42
+
43
+ notification0_fail_report:
44
+ name: 💣 Discord Start Notification Fail Report
45
+ runs-on: ubuntu-latest
46
+ #runs-on: plo-koon
47
+ timeout-minutes: 20
48
+ if: always() && needs.notification0.result == 'failure'
49
+ needs: [notification0]
50
+ steps:
51
+ - name: send custom message with args
52
+ uses: appleboy/discord-action@master
53
+ with:
54
+ webhook_id: ${{ secrets.DISCORD_WEBHOOK_ID }}
55
+ webhook_token: ${{ secrets.DISCORD_WEBHOOK_TOKEN }}
56
+ message: |
57
+ ❌❌❌🔧 Failed to send Discord start notification for ${{ github.repository }}! [🔗](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
58
+
59
+ check_secrets:
60
+ name: 🔍 Check Required Secrets and Variables
61
+ #runs-on: ubuntu-latest
62
+ runs-on: plo-koon
63
+ timeout-minutes: 20
64
+ steps:
65
+ - name: Check Required Secrets and Variables
66
+ uses: futdevpro/fdp-github-actions/check-secrets-and-variables@latest
67
+ with:
68
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
69
+ ITEMS_TO_CHECK: |
70
+ [
71
+ {
72
+ "valueName": "NPM_TOKEN",
73
+ "value": "${{ secrets.NPM_TOKEN }}",
74
+ "type": "SECRET"
75
+ },
76
+ {
77
+ "valueName": "DISCORD_WEBHOOK_ID",
78
+ "value": "${{ secrets.DISCORD_WEBHOOK_ID }}",
79
+ "type": "SECRET"
80
+ },
81
+ {
82
+ "valueName": "DISCORD_WEBHOOK_TOKEN",
83
+ "value": "${{ secrets.DISCORD_WEBHOOK_TOKEN }}",
84
+ "type": "SECRET"
85
+ },
86
+ {
87
+ "valueName": "OVERSEER_SECRET_KEY",
88
+ "value": "${{ secrets.OVERSEER_SECRET_KEY }}",
89
+ "type": "SECRET"
90
+ },
91
+
92
+ {
93
+ "valueName": "OVERSEER_URL",
94
+ "value": "${{ vars.OVERSEER_URL }}",
95
+ "type": "VARIABLE"
96
+ }
97
+ ]
98
+
99
+ check_dev_leftovers:
100
+ name: 🔍 Check Dev leftovers
101
+ #runs-on: ubuntu-latest
102
+ runs-on: plo-koon
103
+ timeout-minutes: 20
104
+ steps:
105
+ - name: Checkout code
106
+ uses: actions/checkout@v2
107
+
108
+ - name: Install Node.js
109
+ uses: actions/setup-node@v2
110
+ with:
111
+ node-version: '16'
112
+
113
+ # TODO: Check build version (to ALL packages)
114
+ - name: Check build folder
115
+ run: |
116
+ node -e "
117
+ const buildFolder = './build/';
118
+ const fs = require('fs');
119
+
120
+ fs.readdir(buildFolder, (err, files) => {
121
+ if (!files?.length) {
122
+ console.error(
123
+ 'FDPError: ./build folder is MISSING!' +
124
+ '\nbuild the project locally before push!'
125
+ );
126
+ process.exit(1);
127
+ }
128
+
129
+ if (files.includes('dynamo-eslint')) {
130
+ console.error(
131
+ 'FDPError: ./build contains dynamo-eslint folder which means this is a local dev build!' +
132
+ '\nrebuild the project locally before push!'
133
+ );
134
+ process.exit(1);
135
+ }
136
+ });
137
+ "
138
+
139
+ test:
140
+ name: 🧪 Test Build
141
+ runs-on: ubuntu-latest
142
+ needs: [ check_dev_leftovers ]
143
+ timeout-minutes: 20
144
+ steps:
145
+ - name: Checkout code
146
+ uses: actions/checkout@v2
147
+
148
+ - name: Set NPM RC
149
+ run: |
150
+ echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
151
+
152
+ - name: Install pnpm
153
+ run: |
154
+ npm i -g pnpm
155
+
156
+ - name: Install Packages
157
+ run: |
158
+ pnpm i
159
+
160
+ - name: Build
161
+ run: |
162
+ npx tsc
163
+
164
+ - name: Install Jasmine
165
+ run: |
166
+ npm i -g jasmine
167
+
168
+ - name: Test
169
+ run: |
170
+ jasmine
171
+
172
+ - name: Test Pack
173
+ run: |
174
+ pnpm pack
175
+
176
+
177
+ check_version:
178
+ name: 🔍 Check Version
179
+ needs: [ test ]
180
+ #runs-on: ubuntu-latest
181
+ runs-on: plo-koon
182
+ timeout-minutes: 20
183
+ outputs:
184
+ version_published: ${{ steps.version_check_results.outputs.version_published }}
185
+ steps:
186
+ - name: Checkout code
187
+ uses: actions/checkout@v2
188
+
189
+ - name: Set Package Name
190
+ run: |
191
+ echo "PACKAGE_NAME=$(node -p -e "require('./package.json').name")" >> $GITHUB_ENV
192
+
193
+ - name: Set RC
194
+ run: |
195
+ echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
196
+
197
+ - name: Get This Version
198
+ run: |
199
+ RAW_THIS_VERSION=$(node -p -e "require('./package.json').version")
200
+ # replace ALL: 'v0' with '', '01' with '1', '.0' with '.'
201
+ RAW_THIS_VERSION=$(echo $RAW_THIS_VERSION | sed 's:v0::g' | sed 's:01:1:g' | sed -e 's:\.0:\.:g')
202
+ echo "THIS_VERSION=$RAW_THIS_VERSION" >> $GITHUB_ENV
203
+
204
+ - name: Get Latest Version
205
+ run: |
206
+ echo "LATEST_VERSION=$(npm view ${{ env.PACKAGE_NAME }} version)" >> $GITHUB_ENV
207
+
208
+ - name: Check All Versions
209
+ run: |
210
+ ALL_VERSIONS=$(npm view ${{ env.PACKAGE_NAME }} versions)
211
+ if echo "$ALL_VERSIONS" | grep -q "${{ env.THIS_VERSION }}"; then
212
+ echo "VERSION_PUBLISHED=true" >> $GITHUB_ENV
213
+ else
214
+ echo "VERSION_PUBLISHED=false" >> $GITHUB_ENV
215
+ fi
216
+
217
+ - name: Version Check Results
218
+ id: version_check_results
219
+ run: |
220
+ echo package name: "${{ env.PACKAGE_NAME }}"
221
+ echo this: "${{ env.THIS_VERSION }}"
222
+ echo latest: "${{ env.LATEST_VERSION }}"
223
+ echo this is the latest: "${{ env.LATEST_VERSION == env.THIS_VERSION }}"
224
+ echo this version is published: "${{ env.VERSION_PUBLISHED }}"
225
+ echo all published versions: $(npm view ${{ env.PACKAGE_NAME }} versions)
226
+ echo "::set-output name=version_published::${{ env.VERSION_PUBLISHED }}"
227
+
228
+ deploy:
229
+ needs: [ check_version ]
230
+ name: 🚀 Deploy to NPM
231
+ runs-on: ubuntu-latest
232
+ timeout-minutes: 20
233
+ # if: ${{ needs.check_version.outputs.version_published != 'true' }}
234
+ if: always()
235
+ steps:
236
+ - name: Checkout code
237
+ uses: actions/checkout@v2
238
+
239
+ - name: Set RC
240
+ run: |
241
+ echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
242
+
243
+ - name: Install pnpm
244
+ run: |
245
+ npm i -g pnpm
246
+
247
+ - name: Install Packages
248
+ run: |
249
+ pnpm i
250
+
251
+ - name: Build
252
+ run: |
253
+ npx tsc
254
+
255
+ - name: Pack
256
+ run: |
257
+ pnpm pack
258
+
259
+ - name: Publish
260
+ run: |
261
+ npm publish
262
+
263
+ build_report:
264
+ name: 📊 Build Report
265
+ needs: [
266
+ notification0,
267
+ check_dev_leftovers,
268
+ test,
269
+ check_version,
270
+ deploy
271
+ ]
272
+ #runs-on: ubuntu-latest
273
+ runs-on: plo-koon
274
+ timeout-minutes: 20
275
+ if: always()
276
+ steps:
277
+
278
+ # NEW IMPLEMENTATION using futdevpro/fdp-github-actions/send-build-report@master:
279
+ - name: Checkout code
280
+ uses: actions/checkout@v2
281
+
282
+ - name: Send Build Report
283
+ uses: futdevpro/fdp-github-actions/send-build-report@master
284
+ with:
285
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
286
+ SETTINGS: |
287
+ {
288
+ "overseerUrl": "${{ vars.OVERSEER_URL }}",
289
+ "overseerSecret": "${{ secrets.OVERSEER_SECRET_KEY }}",
290
+ "branchName": "${{ github.ref_name }}",
291
+ "repository": "${{ github.repository }}",
292
+ "runId": "${{ github.run_id }}",
293
+ "linkToAction": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
294
+ "eventDateTime": "${{ needs.notification0.outputs.start }}",
295
+ "projects": [
296
+ {
297
+ "environment": "prod",
298
+ "stepResults": [
299
+ {
300
+ "stepName": "checkDevLeftovers",
301
+ "resultCode": "${{ needs.check_dev_leftovers.result }}",
302
+ "requirement": "optional"
303
+ },
304
+ {
305
+ "stepName": "tests",
306
+ "resultCode": "${{ needs.test.result }}",
307
+ "requirement": "required"
308
+ },
309
+ {
310
+ "stepName": "checkVersion",
311
+ "resultCode": "${{ needs.check_version.result }}",
312
+ "requirement": "required"
313
+ },
314
+ {
315
+ "stepName": "deploy",
316
+ "resultCode": "${{ needs.deploy.result }}",
317
+ "requirement": "optional"
318
+ }
319
+ ]
320
+ }
321
+ ]
322
+ }
323
+
324
+
325
+ end:
326
+ name: 🎯 Discord Results
327
+ needs: [
328
+ notification0,
329
+ check_secrets,
330
+ check_dev_leftovers,
331
+ test,
332
+ check_version,
333
+ deploy,
334
+ build_report
335
+ ]
336
+ #runs-on: ubuntu-latest
337
+ runs-on: plo-koon
338
+ timeout-minutes: 20
339
+ if: always()
340
+ steps:
341
+ - name: Checkout code
342
+ uses: actions/checkout@v4
343
+
344
+ - name: Send Discord result notification
345
+ uses: futdevpro/fdp-github-actions/discord-result-notification@latest
346
+ with:
347
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
348
+ APPLICATION_NAME: "Dynamo-ESLint"
349
+ APPLICATION_EMOJI: "🔧"
350
+ BRANCH: ${{ github.ref_name }}
351
+ RUN_NUMBER: ${{ github.run_number }}
352
+ RUN_ID: ${{ github.run_id }}
353
+ REPOSITORY: ${{ github.repository }}
354
+ START_TIME: ${{ needs.notification0.outputs.start }}
355
+ DISCORD_WEBHOOK_ID: ${{ secrets.DISCORD_WEBHOOK_ID }}
356
+ DISCORD_WEBHOOK_TOKEN: ${{ secrets.DISCORD_WEBHOOK_TOKEN }}
357
+ STEPS_CONFIG: |
358
+ [
359
+ {
360
+ "stepName": "Secrets Check",
361
+ "stepEmoji": "🔑",
362
+ "resultCode": "${{ needs.check_secrets.result }}"
363
+ },
364
+ {
365
+ "stepName": "Dev Leftovers Check",
366
+ "stepEmoji": "🔍",
367
+ "resultCode": "${{ needs.check_dev_leftovers.result }}"
368
+ },
369
+ {
370
+ "stepName": "Test Build",
371
+ "stepEmoji": "🧪",
372
+ "resultCode": "${{ needs.test.result }}"
373
+ },
374
+ {
375
+ "stepName": "Check Version",
376
+ "stepEmoji": "🔍",
377
+ "resultCode": "${{ needs.check_version.result }}"
378
+ },
379
+ {
380
+ "stepName": "Deploy",
381
+ "stepEmoji": "📦",
382
+ "resultCode": "${{ needs.deploy.result }}",
383
+ "specialSuccessEmoji": "🚀🚀🚀"
384
+ },
385
+ {
386
+ "stepName": "Build Report",
387
+ "stepEmoji": "📊",
388
+ "resultCode": "${{ needs.build_report.result }}"
389
+ }
390
+ ]
391
+
392
+
393
+
package/INTEGRATION.md ADDED
@@ -0,0 +1,74 @@
1
+ # Integration Guide
2
+
3
+ Use these steps in each repo to adopt `@futdevpro/dynamo-eslint` with on-save current-file linting.
4
+
5
+ ## 1) Install
6
+
7
+ ```bash
8
+ pnpm add -D @futdevpro/dynamo-eslint eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
9
+ # For Angular projects also install:
10
+ pnpm add -D @angular-eslint/eslint-plugin @angular-eslint/eslint-plugin-template @angular-eslint/template-parser
11
+ ```
12
+
13
+ Optional (enables deeper custom checks):
14
+ ```bash
15
+ pnpm add -D @futdevpro/fsm-dynamo
16
+ ```
17
+
18
+ ## 2) .eslintrc.json
19
+
20
+ Pick one preset per project type and keep project-specific overrides.
21
+
22
+ Node TS (service/lib):
23
+ ```json
24
+ {
25
+ "root": true,
26
+ "extends": ["@futdevpro/dynamo-eslint/nts"]
27
+ }
28
+ ```
29
+
30
+ Angular app/lib:
31
+ ```json
32
+ {
33
+ "root": true,
34
+ "extends": ["@futdevpro/dynamo-eslint/ngx"]
35
+ }
36
+ ```
37
+
38
+ Package flavors:
39
+ - `@futdevpro/dynamo-eslint/fsm`
40
+ - `@futdevpro/dynamo-eslint/nts-package`
41
+ - `@futdevpro/dynamo-eslint/ngx-package`
42
+
43
+ ## 3) VSCode settings (current file only)
44
+
45
+ Create or update `.vscode/settings.json`:
46
+ ```json
47
+ {
48
+ "eslint.run": "onSave",
49
+ "eslint.workingDirectories": [{ "mode": "auto" }],
50
+ "editor.codeActionsOnSave": { "source.fixAll.eslint": true }
51
+ }
52
+ ```
53
+
54
+ ## 4) NPM scripts
55
+
56
+ ```json
57
+ {
58
+ "scripts": {
59
+ "lint": "eslint .",
60
+ "lint:fix": "eslint . --fix",
61
+ "validate:imports": "dynamo-validate-imports",
62
+ "validate:naming": "dynamo-validate-naming"
63
+ }
64
+ }
65
+ ```
66
+
67
+ ## 5) CI
68
+ - Ensure your repo CI runs `npm run lint`.
69
+ - Heavy lint runs should be CLI-based (not editor) for performance when many repos are open.
70
+
71
+ ## Notes
72
+ - Presets derive from existing org configs; adjust local overrides sparingly.
73
+ - Custom validators are no-ops unless `@futdevpro/fsm-dynamo` is installed.
74
+
package/POC-README.md ADDED
@@ -0,0 +1,147 @@
1
+ # Dynamo ESLint POC - Import Ordering Rules
2
+
3
+ This POC demonstrates the implementation of comprehensive import ordering rules for the `@futdevpro/dynamo-eslint` package.
4
+
5
+ ## 🎯 Features Implemented
6
+
7
+ ### Import Grouping Rules
8
+ The linter enforces a specific import order with empty lines between groups:
9
+
10
+ 1. **Non-FutDevPro packages** (e.g., `@angular/core`, `rxjs`)
11
+ 2. **FutDevPro packages** (e.g., `@futdevpro/fsm-dynamo`, `@futdevpro/fdp-templates`)
12
+ 3. **Scripts from other modules** (3+ levels without underscore, or 3+ levels with underscore)
13
+ 4. **Scripts from same module** (up to 2 levels, or up to 3 levels with underscore)
14
+
15
+ ### Forbidden Import Patterns
16
+ - ❌ **NPM-packages imports**: `import { Something } from '../../../NPM-packages/some-package'`
17
+ - ❌ **JavaScript extensions**: `import { Something } from './some-file.js'`
18
+ - ❌ **Import type usage**: `import type { SomeType } from './some-file'`
19
+
20
+ ### Validation Features
21
+ - ✅ **Empty line enforcement**: Groups must be separated by empty lines
22
+ - ✅ **Order validation**: Imports must be in the correct group order
23
+ - ✅ **Same module detection**: Smart detection based on path depth and underscore patterns
24
+
25
+ ## 📁 File Structure
26
+
27
+ ```
28
+ src/
29
+ ├── plugin/
30
+ │ ├── rules/
31
+ │ │ ├── import-order.ts # Main import ordering rule
32
+ │ │ ├── import-order.spec.ts # Comprehensive test suite
33
+ │ │ ├── naming-patterns.ts # Naming patterns rule (placeholder)
34
+ │ │ └── naming-patterns.spec.ts # Naming patterns tests
35
+ │ └── index.ts # Plugin exports
36
+ ├── scripts/
37
+ │ ├── validate-imports.ts # CLI script for import validation
38
+ │ ├── validate-naming.ts # CLI script for naming validation
39
+ │ └── eslintrc-audit.ts # ESLint config audit script
40
+ └── configs/ # ESLint configuration presets
41
+ ```
42
+
43
+ ## 🧪 Testing
44
+
45
+ ### Sample Files
46
+ - `samples/poc-sample.ts` - Demonstrates correct import ordering
47
+ - `samples/poc-violations.ts` - Shows various violations for testing
48
+
49
+ ### Test Results
50
+ The POC successfully detects and reports:
51
+ - ✅ Forbidden NPM-packages imports
52
+ - ✅ Forbidden .js extension imports
53
+ - ✅ Forbidden import type usage
54
+ - ✅ Misordered import groups
55
+ - ✅ Missing empty lines between groups
56
+
57
+ ## 🚀 Usage
58
+
59
+ ### As ESLint Rule
60
+ ```json
61
+ {
62
+ "plugins": ["@futdevpro/dynamo"],
63
+ "rules": {
64
+ "@futdevpro/dynamo/import-order": "error"
65
+ }
66
+ }
67
+ ```
68
+
69
+ ### CLI Validation
70
+ ```bash
71
+ # Validate imports
72
+ npx dynamo-validate-imports
73
+
74
+ # Validate naming
75
+ npx dynamo-validate-naming
76
+
77
+ # Audit ESLint configs
78
+ npx dynamo-eslintrc-audit
79
+ ```
80
+
81
+ ## 📋 Example Output
82
+
83
+ ```
84
+ ❌ Violation: forbiddenNpmPackages
85
+ Line: 3
86
+ Message: Import from "*/../NPM-packages/*" is forbidden. Use "@futdevpro/*" instead.
87
+
88
+ ❌ Violation: forbiddenJsExtension
89
+ Line: 4
90
+ Message: Import with ".js" extension is forbidden. Use ".ts" or no extension.
91
+
92
+ ❌ Violation: forbiddenImportType
93
+ Line: 5
94
+ Message: Use of "import type" is forbidden.
95
+
96
+ ❌ Violation: misordered
97
+ Line: 2
98
+ Message: Import statements should be grouped and ordered by convention.
99
+
100
+ ❌ Violation: missingEmptyLine
101
+ Line: 1
102
+ Message: Missing empty line between import groups.
103
+ ```
104
+
105
+ ## 🔧 Implementation Details
106
+
107
+ ### Import Group Detection Logic
108
+ ```typescript
109
+ function getImportGroup(importNode: any): ImportGroup['type'] {
110
+ const source = importNode.source.value as string;
111
+
112
+ // Check for forbidden patterns first
113
+ if (source.includes('/NPM-packages/')) return 'non-futdevpro';
114
+ if (source.endsWith('.js')) return 'non-futdevpro';
115
+
116
+ // FutDevPro packages
117
+ if (source.startsWith('@futdevpro/')) return 'futdevpro';
118
+
119
+ // Same module detection
120
+ if (source.startsWith('./') || source.startsWith('../')) {
121
+ const pathParts = source.split('/');
122
+ const upLevels = pathParts.filter(part => part === '..').length;
123
+
124
+ // Same module: up to 3 ".." and starts with "_", or less than 2 ".."
125
+ if (upLevels <= 2 || (upLevels <= 3 && pathParts.some(part => part.startsWith('_')))) {
126
+ return 'same-module';
127
+ }
128
+
129
+ return 'other-modules';
130
+ }
131
+
132
+ return 'non-futdevpro';
133
+ }
134
+ ```
135
+
136
+ ## ✅ POC Status
137
+
138
+ - [x] Import grouping logic implemented
139
+ - [x] Forbidden pattern detection
140
+ - [x] Empty line validation
141
+ - [x] Order validation
142
+ - [x] Comprehensive test suite
143
+ - [x] CLI validation scripts
144
+ - [x] Sample files for demonstration
145
+ - [x] Documentation and examples
146
+
147
+ The POC successfully demonstrates all requested import ordering rules and is ready for integration into the main package.
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # @futdevpro/dynamo-eslint
2
+
3
+ Shared ESLint presets and Dynamo validators for Node TS and Angular.
4
+
5
+ ## Usage
6
+
7
+ - Install peers then extend one preset:
8
+
9
+ ```json
10
+ {
11
+ "root": true,
12
+ "extends": ["@futdevpro/dynamo-eslint/nts"]
13
+ }
14
+ ```
15
+
16
+ - VSCode settings for current-file on save:
17
+
18
+ ```json
19
+ {
20
+ "eslint.run": "onSave",
21
+ "eslint.workingDirectories": [{ "mode": "auto" }],
22
+ "editor.codeActionsOnSave": { "source.fixAll.eslint": true }
23
+ }
24
+ ```
25
+
26
+ ## Presets
27
+ - base
28
+ - nts
29
+ - ngx
30
+ - fsm
31
+ - nts-package
32
+ - ngx-package
33
+
34
+ ## Audit
35
+
36
+ Run `dynamo-eslintrc-audit` in a workspace to analyze duplicated rules.