@jterrazz/typescript 9.2.1 → 10.0.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 (71) hide show
  1. package/README.md +20 -16
  2. package/bin/commands/check.sh +348 -117
  3. package/bin/typescript.sh +55 -0
  4. package/lib/check-architecture.js +89 -0
  5. package/lib/check-baseline.js +144 -0
  6. package/lib/check-docs.js +4 -3
  7. package/lib/check-drift.js +209 -0
  8. package/lib/check-gitignore.js +4 -4
  9. package/lib/check-markdown.js +279 -0
  10. package/lib/check-names.js +125 -0
  11. package/lib/check-publish.js +150 -0
  12. package/lib/check-secrets.js +115 -0
  13. package/lib/check-suppressions.js +355 -0
  14. package/lib/doctor.js +185 -0
  15. package/lib/merge-knip-config.js +57 -25
  16. package/lib/tracked-files.js +165 -0
  17. package/lib/workspace-members.js +5 -6
  18. package/package.json +19 -8
  19. package/presets/oxfmt/index.js +49 -5
  20. package/presets/oxlint/profiles/astro.js +10 -0
  21. package/presets/oxlint/profiles/bun.js +7 -0
  22. package/presets/oxlint/profiles/expo.js +7 -0
  23. package/presets/oxlint/profiles/library.js +16 -0
  24. package/presets/oxlint/profiles/next.js +7 -0
  25. package/presets/oxlint/profiles/node.js +7 -0
  26. package/presets/prettier/astro.json +6 -0
  27. package/presets/tsconfig/expo.json +16 -6
  28. package/presets/tsconfig/library.json +18 -0
  29. package/presets/tsconfig/next.json +12 -2
  30. package/presets/tsconfig/node.json +18 -4
  31. package/rules/README.md +23 -0
  32. package/rules/_contract.js +191 -0
  33. package/rules/_contract.test.ts +81 -0
  34. package/rules/a11y.js +51 -0
  35. package/rules/architecture/hexagonal.js +56 -0
  36. package/rules/architecture/layers.js +75 -0
  37. package/rules/astro.js +49 -0
  38. package/rules/catalog.js +134 -0
  39. package/rules/catalog.test.ts +84 -0
  40. package/rules/compile.js +125 -0
  41. package/rules/core/eslint.js +234 -0
  42. package/rules/core/import.js +107 -0
  43. package/rules/core/jsdoc.js +52 -0
  44. package/rules/core/node.js +36 -0
  45. package/rules/core/oxc.js +54 -0
  46. package/rules/core/promise.js +39 -0
  47. package/rules/core/typescript.js +204 -0
  48. package/rules/core/unicorn.js +200 -0
  49. package/rules/next.js +53 -0
  50. package/rules/profiles.js +89 -0
  51. package/rules/react-native.js +48 -0
  52. package/rules/react.js +148 -0
  53. package/rules/sorted.js +41 -0
  54. package/rules/vitest.js +153 -0
  55. package/src/docs.d.ts +4 -4
  56. package/src/docs.js +75 -47
  57. package/src/docs.test.ts +136 -29
  58. package/src/index.d.ts +13 -9
  59. package/src/index.js +15 -8
  60. package/src/oxfmt.d.ts +15 -2
  61. package/src/oxfmt.test.ts +10 -0
  62. package/src/oxlint.d.ts +57 -10
  63. package/src/oxlint.js +35 -50
  64. package/src/oxlint.test.ts +82 -28
  65. package/presets/oxlint/architectures/hexagonal-rules.js +0 -39
  66. package/presets/oxlint/architectures/hexagonal.js +0 -13
  67. package/presets/oxlint/base.js +0 -145
  68. package/presets/oxlint/expo.js +0 -36
  69. package/presets/oxlint/next.js +0 -43
  70. package/presets/oxlint/node.js +0 -14
  71. package/presets/oxlint/plugins/codestyle.js +0 -231
@@ -1,231 +0,0 @@
1
- // Codestyle plugin - custom rules for code quality
2
- // Contains: architecture boundaries, import extensions
3
-
4
- import defaultHexagonalRules from '../architectures/hexagonal-rules.js';
5
-
6
- // ============================================
7
- // Hexagonal - Architecture boundary rules
8
- // ============================================
9
-
10
- function createHexagonalRule() {
11
- return {
12
- meta: {
13
- type: 'problem',
14
- docs: {
15
- description: 'Enforce hexagonal architecture layer boundaries',
16
- category: 'Best Practices',
17
- },
18
- schema: [
19
- {
20
- type: 'object',
21
- properties: {
22
- rules: {
23
- type: 'array',
24
- items: {
25
- type: 'object',
26
- properties: {
27
- from: { type: 'string' },
28
- disallow: { type: 'array', items: { type: 'string' } },
29
- message: { type: 'string' },
30
- },
31
- required: ['from', 'disallow'],
32
- },
33
- },
34
- },
35
- },
36
- ],
37
- },
38
- create(context) {
39
- const options = context.options[0];
40
- const rules = options && options.rules ? options.rules : defaultHexagonalRules;
41
- const filename = context.getFilename();
42
-
43
- function checkNode(node) {
44
- if (!node.source || !node.source.value) {
45
- return;
46
- }
47
-
48
- const importPath = node.source.value;
49
-
50
- for (const rule of rules) {
51
- const fromPattern = new RegExp(rule.from);
52
- if (!fromPattern.test(filename)) {
53
- continue;
54
- }
55
-
56
- for (const disallowPattern of rule.disallow) {
57
- if (new RegExp(disallowPattern).test(importPath)) {
58
- context.report({
59
- node: node.source,
60
- message: rule.message || 'Import violates architecture boundaries',
61
- });
62
- break;
63
- }
64
- }
65
- }
66
- }
67
-
68
- return {
69
- ImportDeclaration: checkNode,
70
- ExportNamedDeclaration: checkNode,
71
- ExportAllDeclaration: checkNode,
72
- };
73
- },
74
- };
75
- }
76
-
77
- // ============================================
78
- // Imports-with-ext - Require .js extensions
79
- // ============================================
80
-
81
- // The extensions a bundler or Node actually resolves from an import specifier.
82
- // Anything else after a dot is part of the module NAME (`user.entity`,
83
- // `dashboard.post`, `article.repository`) and still needs its `.js`.
84
- const KNOWN_IMPORT_EXTENSIONS = [
85
- 'cjs',
86
- 'css',
87
- 'cts',
88
- 'graphql',
89
- 'gql',
90
- 'html',
91
- 'jpeg',
92
- 'jpg',
93
- 'js',
94
- 'json',
95
- 'jsx',
96
- 'less',
97
- 'md',
98
- 'mdx',
99
- 'mjs',
100
- 'mts',
101
- 'node',
102
- 'png',
103
- 'sass',
104
- 'scss',
105
- 'svg',
106
- 'toml',
107
- 'ts',
108
- 'tsx',
109
- 'txt',
110
- 'wasm',
111
- 'webp',
112
- 'yaml',
113
- 'yml',
114
- ];
115
-
116
- const importsWithExtRule = {
117
- meta: {
118
- type: 'problem',
119
- docs: {
120
- description: 'Require .js extension in imports for Node.js ESM compatibility',
121
- category: 'Best Practices',
122
- },
123
- fixable: 'code',
124
- schema: [],
125
- },
126
- create(context) {
127
- // Only a KNOWN extension counts as already-extended — "anything after the
128
- // Last dot" read `./entities/dashboard.post` as extended and skipped it.
129
- const hasExtension = new RegExp(`\\.(?:${KNOWN_IMPORT_EXTENSIONS.join('|')})$`, 'i');
130
-
131
- function checkNode(node) {
132
- if (!node.source || !node.source.value) {
133
- return;
134
- }
135
-
136
- const importPath = node.source.value;
137
-
138
- // Only check relative imports
139
- if (!importPath.startsWith('.')) {
140
- return;
141
- }
142
-
143
- // Skip if it already has an extension
144
- if (hasExtension.test(importPath)) {
145
- return;
146
- }
147
-
148
- // Skip type-only imports (they are erased at runtime)
149
- if (node.importKind === 'type') {
150
- return;
151
- }
152
-
153
- context.report({
154
- node: node.source,
155
- message: 'Missing .js extension in import (required for Node.js ESM)',
156
- fix(fixer) {
157
- const newPath = `${importPath}.js`;
158
- return fixer.replaceText(node.source, `'${newPath}'`);
159
- },
160
- });
161
- }
162
-
163
- return {
164
- ImportDeclaration: checkNode,
165
- ExportNamedDeclaration: checkNode,
166
- ExportAllDeclaration: checkNode,
167
- };
168
- },
169
- };
170
-
171
- // ============================================
172
- // Imports-without-ext - Remove extensions
173
- // ============================================
174
-
175
- const importsWithoutExtRule = {
176
- meta: {
177
- type: 'problem',
178
- docs: {
179
- description: 'Remove .js, .jsx, .ts, .tsx extensions from imports',
180
- category: 'Best Practices',
181
- },
182
- fixable: 'code',
183
- schema: [],
184
- },
185
- create(context) {
186
- const extensionsToRemove = /\.(?:js|jsx|ts|tsx)$/;
187
-
188
- function checkNode(node) {
189
- if (!node.source || !node.source.value) {
190
- return;
191
- }
192
-
193
- const importPath = node.source.value;
194
-
195
- // Check both relative imports and path alias imports
196
- if (!importPath.startsWith('.') && !importPath.startsWith('@/')) {
197
- return;
198
- }
199
-
200
- if (extensionsToRemove.test(importPath)) {
201
- const match = importPath.match(extensionsToRemove);
202
- context.report({
203
- node: node.source,
204
- message: `Remove "${match[0]}" extension from import`,
205
- fix(fixer) {
206
- const newPath = importPath.replace(extensionsToRemove, '');
207
- return fixer.replaceText(node.source, `'${newPath}'`);
208
- },
209
- });
210
- }
211
- }
212
-
213
- return {
214
- ImportDeclaration: checkNode,
215
- ExportNamedDeclaration: checkNode,
216
- ExportAllDeclaration: checkNode,
217
- };
218
- },
219
- };
220
-
221
- export default {
222
- meta: {
223
- name: 'codestyle',
224
- version: '1.0.0',
225
- },
226
- rules: {
227
- 'arch-hexagonal': createHexagonalRule(),
228
- 'imports-with-ext': importsWithExtRule,
229
- 'imports-without-ext': importsWithoutExtRule,
230
- },
231
- };