@mui/internal-code-infra 0.0.4-canary.7 → 0.0.4-canary.70

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 (120) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +19 -8
  3. package/build/babel-config.d.mts +11 -3
  4. package/build/brokenLinksChecker/crawlWorker.d.mts +1 -0
  5. package/build/brokenLinksChecker/index.d.mts +45 -2
  6. package/build/changelog/types.d.ts +1 -1
  7. package/build/cli/cmdArgosPush.d.mts +2 -2
  8. package/build/cli/cmdBuild.d.mts +3 -2
  9. package/build/cli/cmdCopyFiles.d.mts +2 -2
  10. package/build/cli/cmdExtractErrorCodes.d.mts +2 -2
  11. package/build/cli/cmdGenerateChangelog.d.mts +2 -2
  12. package/build/cli/cmdGithubAuth.d.mts +2 -2
  13. package/build/cli/cmdListWorkspaces.d.mts +6 -4
  14. package/build/cli/cmdNetlifyIgnore.d.mts +3 -2
  15. package/build/cli/cmdPublish.d.mts +4 -2
  16. package/build/cli/cmdPublishCanary.d.mts +3 -3
  17. package/build/cli/cmdPublishNewPackage.d.mts +4 -2
  18. package/build/cli/cmdSetVersionOverrides.d.mts +2 -2
  19. package/build/cli/cmdVale.d.mts +46 -0
  20. package/build/cli/cmdValidateBuiltTypes.d.mts +2 -2
  21. package/build/eslint/baseConfig.d.mts +3 -1
  22. package/build/eslint/mui/rules/disallow-react-api-in-server-components.d.mts +2 -2
  23. package/build/eslint/mui/rules/docgen-ignore-before-comment.d.mts +2 -2
  24. package/build/eslint/mui/rules/no-floating-cleanup.d.mts +5 -0
  25. package/build/eslint/mui/rules/no-guarded-throw.d.mts +31 -0
  26. package/build/eslint/mui/rules/no-presentation-role.d.mts +5 -0
  27. package/build/eslint/mui/rules/no-restricted-resolved-imports.d.mts +2 -2
  28. package/build/eslint/mui/rules/nodeEnvUtils.d.mts +18 -0
  29. package/build/remark/config.d.mts +43 -0
  30. package/build/remark/createLintTester.d.mts +10 -0
  31. package/build/remark/firstBlockHeading.d.mts +4 -0
  32. package/build/remark/gitDiff.d.mts +2 -0
  33. package/build/remark/noSpaceInLinks.d.mts +2 -0
  34. package/build/remark/straightQuotes.d.mts +2 -0
  35. package/build/remark/tableAlignment.d.mts +2 -0
  36. package/build/remark/terminalLanguage.d.mts +2 -0
  37. package/build/utils/babel.d.mts +1 -1
  38. package/build/utils/build.d.mts +56 -37
  39. package/build/utils/github.d.mts +1 -1
  40. package/build/utils/pnpm.d.mts +81 -2
  41. package/build/utils/testUtils.d.mts +7 -0
  42. package/build/utils/typescript.d.mts +6 -16
  43. package/package.json +60 -38
  44. package/src/babel-config.mjs +9 -3
  45. package/src/brokenLinksChecker/__fixtures__/static-site/index.html +1 -0
  46. package/src/brokenLinksChecker/__fixtures__/static-site/invalid-html.html +15 -0
  47. package/src/brokenLinksChecker/crawlWorker.mjs +217 -0
  48. package/src/brokenLinksChecker/index.mjs +263 -188
  49. package/src/brokenLinksChecker/index.test.ts +50 -13
  50. package/src/changelog/categorizeCommits.test.ts +5 -5
  51. package/src/changelog/fetchChangelogs.mjs +6 -2
  52. package/src/changelog/parseCommitLabels.test.ts +5 -5
  53. package/src/changelog/renderChangelog.mjs +1 -1
  54. package/src/changelog/types.ts +1 -1
  55. package/src/cli/cmdBuild.mjs +51 -85
  56. package/src/cli/cmdListWorkspaces.mjs +12 -27
  57. package/src/cli/cmdNetlifyIgnore.mjs +34 -93
  58. package/src/cli/cmdPublish.mjs +55 -15
  59. package/src/cli/cmdPublishCanary.mjs +128 -132
  60. package/src/cli/cmdPublishNewPackage.mjs +27 -6
  61. package/src/cli/cmdSetVersionOverrides.mjs +8 -9
  62. package/src/cli/cmdVale.mjs +513 -0
  63. package/src/cli/cmdVale.test.mjs +644 -0
  64. package/src/cli/index.mjs +2 -0
  65. package/src/cli/packageJson.d.ts +1 -1
  66. package/src/eslint/baseConfig.mjs +51 -19
  67. package/src/eslint/docsConfig.mjs +2 -1
  68. package/src/eslint/mui/config.mjs +22 -3
  69. package/src/eslint/mui/index.mjs +6 -0
  70. package/src/eslint/mui/rules/no-floating-cleanup.mjs +187 -0
  71. package/src/eslint/mui/rules/no-floating-cleanup.test.mjs +141 -0
  72. package/src/eslint/mui/rules/no-guarded-throw.mjs +115 -0
  73. package/src/eslint/mui/rules/no-guarded-throw.test.mjs +206 -0
  74. package/src/eslint/mui/rules/no-presentation-role.mjs +60 -0
  75. package/src/eslint/mui/rules/no-presentation-role.test.mjs +33 -0
  76. package/src/eslint/mui/rules/nodeEnvUtils.mjs +52 -0
  77. package/src/eslint/mui/rules/require-dev-wrapper.mjs +25 -40
  78. package/src/estree-typescript.d.ts +1 -1
  79. package/src/remark/config.mjs +157 -0
  80. package/src/remark/createLintTester.mjs +19 -0
  81. package/src/remark/firstBlockHeading.mjs +87 -0
  82. package/src/remark/firstBlockHeading.test.mjs +107 -0
  83. package/src/remark/gitDiff.mjs +43 -0
  84. package/src/remark/gitDiff.test.mjs +45 -0
  85. package/src/remark/noSpaceInLinks.mjs +42 -0
  86. package/src/remark/noSpaceInLinks.test.mjs +22 -0
  87. package/src/remark/straightQuotes.mjs +31 -0
  88. package/src/remark/straightQuotes.test.mjs +25 -0
  89. package/src/remark/tableAlignment.mjs +23 -0
  90. package/src/remark/tableAlignment.test.mjs +28 -0
  91. package/src/remark/terminalLanguage.mjs +19 -0
  92. package/src/remark/terminalLanguage.test.mjs +17 -0
  93. package/src/untyped-plugins.d.ts +11 -11
  94. package/src/utils/build.mjs +604 -270
  95. package/src/utils/build.test.mjs +1079 -521
  96. package/src/utils/git.mjs +16 -7
  97. package/src/utils/pnpm.mjs +255 -3
  98. package/src/utils/pnpm.test.mjs +731 -0
  99. package/src/utils/testUtils.mjs +18 -0
  100. package/src/utils/typescript.mjs +23 -42
  101. package/src/utils/typescript.test.mjs +234 -273
  102. package/vale/.vale.ini +1 -0
  103. package/vale/styles/MUI/CorrectReferenceAllCases.yml +43 -0
  104. package/vale/styles/MUI/CorrectRererenceCased.yml +14 -0
  105. package/vale/styles/MUI/GoogleLatin.yml +11 -0
  106. package/vale/styles/MUI/MuiBrandName.yml +22 -0
  107. package/vale/styles/MUI/NoBritish.yml +112 -0
  108. package/vale/styles/MUI/NoCompanyName.yml +17 -0
  109. package/build/markdownlint/duplicate-h1.d.mts +0 -56
  110. package/build/markdownlint/git-diff.d.mts +0 -11
  111. package/build/markdownlint/index.d.mts +0 -52
  112. package/build/markdownlint/straight-quotes.d.mts +0 -11
  113. package/build/markdownlint/table-alignment.d.mts +0 -11
  114. package/build/markdownlint/terminal-language.d.mts +0 -11
  115. package/src/markdownlint/duplicate-h1.mjs +0 -69
  116. package/src/markdownlint/git-diff.mjs +0 -31
  117. package/src/markdownlint/index.mjs +0 -62
  118. package/src/markdownlint/straight-quotes.mjs +0 -26
  119. package/src/markdownlint/table-alignment.mjs +0 -42
  120. package/src/markdownlint/terminal-language.mjs +0 -19
@@ -1,8 +1,8 @@
1
1
  import * as fs from 'node:fs/promises';
2
- import * as os from 'node:os';
3
2
  import * as path from 'node:path';
4
3
  import { describe, expect, it, vi } from 'vitest';
5
4
 
5
+ import { makeTempDir } from './testUtils.mjs';
6
6
  import { copyDeclarations, moveAndTransformDeclarations } from './typescript.mjs';
7
7
 
8
8
  /**
@@ -18,172 +18,152 @@ async function createFile(filePath, contents = '') {
18
18
  await fs.writeFile(filePath, contents, 'utf8');
19
19
  }
20
20
 
21
- /**
22
- * @param {(cwd: string) => Promise<void>} fn
23
- */
24
- async function withTempDir(fn) {
25
- const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'code-infra-typescript-test-'));
26
- try {
27
- return await fn(tmpDir);
28
- } finally {
29
- await fs.rm(tmpDir, { recursive: true, force: true });
30
- }
31
- }
32
-
33
21
  describe('copyDeclarations', () => {
34
22
  it('copies .d.ts files from source to destination', async () => {
35
- await withTempDir(async (cwd) => {
36
- const sourceDir = path.join(cwd, 'source');
37
- const destDir = path.join(cwd, 'dest');
23
+ const cwd = await makeTempDir();
24
+ const sourceDir = path.join(cwd, 'source');
25
+ const destDir = path.join(cwd, 'dest');
38
26
 
39
- await Promise.all([
40
- createFile(path.join(sourceDir, 'index.d.ts'), 'export const foo: string;'),
41
- createFile(path.join(sourceDir, 'utils.d.ts'), 'export const bar: number;'),
42
- createFile(path.join(sourceDir, 'index.js'), 'export const foo = "test";'),
43
- ]);
27
+ await Promise.all([
28
+ createFile(path.join(sourceDir, 'index.d.ts'), 'export const foo: string;'),
29
+ createFile(path.join(sourceDir, 'utils.d.ts'), 'export const bar: number;'),
30
+ createFile(path.join(sourceDir, 'index.js'), 'export const foo = "test";'),
31
+ ]);
44
32
 
45
- await copyDeclarations(sourceDir, destDir);
33
+ await copyDeclarations(sourceDir, destDir);
46
34
 
47
- const indexDts = await fs.readFile(path.join(destDir, 'index.d.ts'), 'utf8');
48
- const utilsDts = await fs.readFile(path.join(destDir, 'utils.d.ts'), 'utf8');
35
+ const indexDts = await fs.readFile(path.join(destDir, 'index.d.ts'), 'utf8');
36
+ const utilsDts = await fs.readFile(path.join(destDir, 'utils.d.ts'), 'utf8');
49
37
 
50
- expect(indexDts).toBe('export const foo: string;');
51
- expect(utilsDts).toBe('export const bar: number;');
38
+ expect(indexDts).toBe('export const foo: string;');
39
+ expect(utilsDts).toBe('export const bar: number;');
52
40
 
53
- const jsExists = await fs.stat(path.join(destDir, 'index.js')).catch(() => null);
54
- expect(jsExists).toBeNull();
55
- });
41
+ const jsExists = await fs.stat(path.join(destDir, 'index.js')).catch(() => null);
42
+ expect(jsExists).toBeNull();
56
43
  });
57
44
 
58
45
  it('copies .d.mts and .d.cts files', async () => {
59
- await withTempDir(async (cwd) => {
60
- const sourceDir = path.join(cwd, 'source');
61
- const destDir = path.join(cwd, 'dest');
46
+ const cwd = await makeTempDir();
47
+ const sourceDir = path.join(cwd, 'source');
48
+ const destDir = path.join(cwd, 'dest');
62
49
 
63
- await Promise.all([
64
- createFile(path.join(sourceDir, 'index.d.mts'), 'export const esm: string;'),
65
- createFile(path.join(sourceDir, 'index.d.cts'), 'export const cjs: string;'),
66
- ]);
50
+ await Promise.all([
51
+ createFile(path.join(sourceDir, 'index.d.mts'), 'export const esm: string;'),
52
+ createFile(path.join(sourceDir, 'index.d.cts'), 'export const cjs: string;'),
53
+ ]);
67
54
 
68
- await copyDeclarations(sourceDir, destDir);
55
+ await copyDeclarations(sourceDir, destDir);
69
56
 
70
- const mtsDts = await fs.readFile(path.join(destDir, 'index.d.mts'), 'utf8');
71
- const ctsDts = await fs.readFile(path.join(destDir, 'index.d.cts'), 'utf8');
57
+ const mtsDts = await fs.readFile(path.join(destDir, 'index.d.mts'), 'utf8');
58
+ const ctsDts = await fs.readFile(path.join(destDir, 'index.d.cts'), 'utf8');
72
59
 
73
- expect(mtsDts).toBe('export const esm: string;');
74
- expect(ctsDts).toBe('export const cjs: string;');
75
- });
60
+ expect(mtsDts).toBe('export const esm: string;');
61
+ expect(ctsDts).toBe('export const cjs: string;');
76
62
  });
77
63
 
78
64
  it('ignores dotfiles and dot-directories', async () => {
79
- await withTempDir(async (cwd) => {
80
- const sourceDir = path.join(cwd, 'source');
81
- const destDir = path.join(cwd, 'dest');
65
+ const cwd = await makeTempDir();
66
+ const sourceDir = path.join(cwd, 'source');
67
+ const destDir = path.join(cwd, 'dest');
82
68
 
83
- await Promise.all([
84
- createFile(path.join(sourceDir, 'index.d.ts'), 'export const foo: string;'),
85
- createFile(path.join(sourceDir, '.hidden.d.ts'), 'export const hidden: string;'),
86
- createFile(path.join(sourceDir, '.git', 'config'), 'git config'),
87
- ]);
69
+ await Promise.all([
70
+ createFile(path.join(sourceDir, 'index.d.ts'), 'export const foo: string;'),
71
+ createFile(path.join(sourceDir, '.hidden.d.ts'), 'export const hidden: string;'),
72
+ createFile(path.join(sourceDir, '.git', 'config'), 'git config'),
73
+ ]);
88
74
 
89
- await copyDeclarations(sourceDir, destDir);
75
+ await copyDeclarations(sourceDir, destDir);
90
76
 
91
- const indexDts = await fs.readFile(path.join(destDir, 'index.d.ts'), 'utf8');
92
- expect(indexDts).toBe('export const foo: string;');
77
+ const indexDts = await fs.readFile(path.join(destDir, 'index.d.ts'), 'utf8');
78
+ expect(indexDts).toBe('export const foo: string;');
93
79
 
94
- const hiddenDts = await fs.stat(path.join(destDir, '.hidden.d.ts')).catch(() => null);
95
- expect(hiddenDts).toBeNull();
80
+ const hiddenDts = await fs.stat(path.join(destDir, '.hidden.d.ts')).catch(() => null);
81
+ expect(hiddenDts).toBeNull();
96
82
 
97
- const gitDir = await fs.stat(path.join(destDir, '.git')).catch(() => null);
98
- expect(gitDir).toBeNull();
99
- });
83
+ const gitDir = await fs.stat(path.join(destDir, '.git')).catch(() => null);
84
+ expect(gitDir).toBeNull();
100
85
  });
101
86
 
102
87
  it('preserves nested directory structure for .d.ts files', async () => {
103
- await withTempDir(async (cwd) => {
104
- const sourceDir = path.join(cwd, 'source');
105
- const destDir = path.join(cwd, 'dest');
88
+ const cwd = await makeTempDir();
89
+ const sourceDir = path.join(cwd, 'source');
90
+ const destDir = path.join(cwd, 'dest');
106
91
 
107
- await Promise.all([
108
- createFile(path.join(sourceDir, 'types/index.d.ts'), 'export type Foo = string;'),
109
- createFile(
110
- path.join(sourceDir, 'types/utils/helpers.d.ts'),
111
- 'export type Helper = () => void;',
112
- ),
113
- ]);
92
+ await Promise.all([
93
+ createFile(path.join(sourceDir, 'types/index.d.ts'), 'export type Foo = string;'),
94
+ createFile(
95
+ path.join(sourceDir, 'types/utils/helpers.d.ts'),
96
+ 'export type Helper = () => void;',
97
+ ),
98
+ ]);
114
99
 
115
- await copyDeclarations(sourceDir, destDir);
100
+ await copyDeclarations(sourceDir, destDir);
116
101
 
117
- const indexDts = await fs.readFile(path.join(destDir, 'types/index.d.ts'), 'utf8');
118
- const helpersDts = await fs.readFile(path.join(destDir, 'types/utils/helpers.d.ts'), 'utf8');
102
+ const indexDts = await fs.readFile(path.join(destDir, 'types/index.d.ts'), 'utf8');
103
+ const helpersDts = await fs.readFile(path.join(destDir, 'types/utils/helpers.d.ts'), 'utf8');
119
104
 
120
- expect(indexDts).toBe('export type Foo = string;');
121
- expect(helpersDts).toBe('export type Helper = () => void;');
122
- });
105
+ expect(indexDts).toBe('export type Foo = string;');
106
+ expect(helpersDts).toBe('export type Helper = () => void;');
123
107
  });
124
108
  });
125
109
 
126
110
  describe('moveAndTransformDeclarations', () => {
127
111
  it('handles path normalization correctly for Windows-style paths', async () => {
128
- await withTempDir(async (cwd) => {
129
- const inputDir = path.join(cwd, 'input');
130
- const buildDir = path.join(cwd, 'build');
131
-
132
- // Create a test .d.ts file
133
- await Promise.all([
134
- createFile(path.join(inputDir, 'index.d.ts'), 'export const test: string;'),
135
- ]);
136
-
137
- /** @type {{type: BundleType; dir: string}[]} */
138
- const bundles = [{ type: 'esm', dir: 'esm' }];
139
-
140
- // Mock babel transformAsync to avoid actual babel transformations
141
- vi.doMock('@babel/core', () => ({
142
- transformAsync: vi.fn(async (code) => ({ code })),
143
- }));
144
-
145
- await moveAndTransformDeclarations({
146
- inputDir,
147
- buildDir,
148
- bundles,
149
- isFlat: false,
150
- packageType: 'module',
151
- });
152
-
153
- // Verify file exists in the correct location
154
- const dtsFile = path.join(buildDir, 'esm', 'index.d.ts');
155
- const stat = await fs.stat(dtsFile).catch(() => null);
156
- expect(stat).not.toBeNull();
157
- expect(stat?.isFile()).toBe(true);
112
+ const cwd = await makeTempDir();
113
+ const inputDir = path.join(cwd, 'input');
114
+ const buildDir = path.join(cwd, 'build');
115
+
116
+ // Create a test .d.ts file
117
+ await Promise.all([
118
+ createFile(path.join(inputDir, 'index.d.ts'), 'export const test: string;'),
119
+ ]);
120
+
121
+ /** @type {BundleType[]} */
122
+ const bundles = ['esm'];
123
+
124
+ // Mock babel transformAsync to avoid actual babel transformations
125
+ vi.doMock('@babel/core', () => ({
126
+ transformAsync: vi.fn(async (code) => ({ code })),
127
+ }));
128
+
129
+ await moveAndTransformDeclarations({
130
+ inputDir,
131
+ buildDir,
132
+ bundles,
133
+ packageType: 'module',
158
134
  });
135
+
136
+ // Verify file exists in the correct location
137
+ const dtsFile = path.join(buildDir, 'index.d.ts');
138
+ const stat = await fs.stat(dtsFile).catch(() => null);
139
+ expect(stat).not.toBeNull();
140
+ expect(stat?.isFile()).toBe(true);
159
141
  });
160
142
 
161
- it('preserves original path file when not flat build', async () => {
162
- await withTempDir(async (cwd) => {
163
- const inputDir = path.join(cwd, 'input');
164
- const buildDir = path.join(cwd, 'build');
165
-
166
- // Create a test .d.ts file
167
- await Promise.all([
168
- createFile(path.join(inputDir, 'index.d.ts'), 'export const test: string;'),
169
- ]);
170
-
171
- /** @type {{type: BundleType; dir: string}[]} */
172
- const bundles = [{ type: 'esm', dir: 'esm' }];
173
-
174
- await moveAndTransformDeclarations({
175
- inputDir,
176
- buildDir,
177
- bundles,
178
- isFlat: false,
179
- packageType: 'module',
180
- });
181
-
182
- // For single bundle non-flat builds, files are copied to bundle dir
183
- const dtsFile = path.join(buildDir, 'esm', 'index.d.ts');
184
- const stat = await fs.stat(dtsFile).catch(() => null);
185
- expect(stat?.isFile()).toBe(true);
143
+ it('preserves original path file for a single esm bundle', async () => {
144
+ const cwd = await makeTempDir();
145
+ const inputDir = path.join(cwd, 'input');
146
+ const buildDir = path.join(cwd, 'build');
147
+
148
+ // Create a test .d.ts file
149
+ await Promise.all([
150
+ createFile(path.join(inputDir, 'index.d.ts'), 'export const test: string;'),
151
+ ]);
152
+
153
+ /** @type {BundleType[]} */
154
+ const bundles = ['esm'];
155
+
156
+ await moveAndTransformDeclarations({
157
+ inputDir,
158
+ buildDir,
159
+ bundles,
160
+ packageType: 'module',
186
161
  });
162
+
163
+ // Files are copied to the build root
164
+ const dtsFile = path.join(buildDir, 'index.d.ts');
165
+ const stat = await fs.stat(dtsFile).catch(() => null);
166
+ expect(stat?.isFile()).toBe(true);
187
167
  });
188
168
 
189
169
  it('correctly compares resolved paths on all platforms', async () => {
@@ -200,94 +180,88 @@ describe('moveAndTransformDeclarations', () => {
200
180
  });
201
181
 
202
182
  it('normalizes paths before reading files', async () => {
203
- await withTempDir(async (cwd) => {
204
- const inputDir = path.join(cwd, 'input');
205
- const buildDir = path.join(cwd, 'build');
206
-
207
- const content = 'export const normalized: boolean;';
208
- await Promise.all([createFile(path.join(inputDir, 'test.d.ts'), content)]);
209
-
210
- /** @type {{type: BundleType; dir: string}[]} */
211
- const bundles = [{ type: 'esm', dir: 'esm' }];
212
-
213
- // Mock babel transformAsync to capture filename
214
- const transformMock = vi.fn(async (code) => ({ code }));
215
- vi.doMock('@babel/core', () => ({
216
- transformAsync: transformMock,
217
- }));
218
-
219
- await moveAndTransformDeclarations({
220
- inputDir,
221
- buildDir,
222
- bundles,
223
- isFlat: false,
224
- packageType: 'module',
225
- });
226
-
227
- // Verify the file was read correctly by checking it exists
228
- const dtsFile = path.join(buildDir, 'esm', 'test.d.ts');
229
- const stat = await fs.stat(dtsFile).catch(() => null);
230
- expect(stat?.isFile()).toBe(true);
183
+ const cwd = await makeTempDir();
184
+ const inputDir = path.join(cwd, 'input');
185
+ const buildDir = path.join(cwd, 'build');
186
+
187
+ const content = 'export const normalized: boolean;';
188
+ await Promise.all([createFile(path.join(inputDir, 'test.d.ts'), content)]);
189
+
190
+ /** @type {BundleType[]} */
191
+ const bundles = ['esm'];
192
+
193
+ // Mock babel transformAsync to capture filename
194
+ const transformMock = vi.fn(async (code) => ({ code }));
195
+ vi.doMock('@babel/core', () => ({
196
+ transformAsync: transformMock,
197
+ }));
198
+
199
+ await moveAndTransformDeclarations({
200
+ inputDir,
201
+ buildDir,
202
+ bundles,
203
+ packageType: 'module',
231
204
  });
205
+
206
+ // Verify the file was read correctly by checking it exists
207
+ const dtsFile = path.join(buildDir, 'test.d.ts');
208
+ const stat = await fs.stat(dtsFile).catch(() => null);
209
+ expect(stat?.isFile()).toBe(true);
232
210
  });
233
211
 
234
212
  it('preserves file when output extension matches in flat builds', async () => {
235
- await withTempDir(async (cwd) => {
236
- const inputDir = path.join(cwd, 'input');
237
- const buildDir = path.join(cwd, 'build');
238
-
239
- const content = 'export const flat: string;';
240
- await Promise.all([createFile(path.join(inputDir, 'index.d.ts'), content)]);
241
-
242
- /** @type {{type: BundleType; dir: string}[]} */
243
- // ESM + module packageType keeps .d.ts extension in flat builds
244
- const bundles = [{ type: 'esm', dir: 'esm' }];
245
-
246
- await moveAndTransformDeclarations({
247
- inputDir,
248
- buildDir,
249
- bundles,
250
- isFlat: true,
251
- packageType: 'module',
252
- });
253
-
254
- // Since extension doesn't change (.d.ts -> .d.ts), file should remain
255
- const outputFile = path.join(buildDir, 'esm', 'index.d.ts');
256
- const outputStat = await fs.stat(outputFile).catch(() => null);
257
- expect(outputStat?.isFile()).toBe(true);
213
+ const cwd = await makeTempDir();
214
+ const inputDir = path.join(cwd, 'input');
215
+ const buildDir = path.join(cwd, 'build');
216
+
217
+ const content = 'export const flat: string;';
218
+ await Promise.all([createFile(path.join(inputDir, 'index.d.ts'), content)]);
219
+
220
+ /** @type {BundleType[]} */
221
+ // ESM + module packageType keeps .d.ts extension in flat builds
222
+ const bundles = ['esm'];
223
+
224
+ await moveAndTransformDeclarations({
225
+ inputDir,
226
+ buildDir,
227
+ bundles,
228
+ packageType: 'module',
258
229
  });
230
+
231
+ // Since extension doesn't change (.d.ts -> .d.ts), file should remain
232
+ const outputFile = path.join(buildDir, 'index.d.ts');
233
+ const outputStat = await fs.stat(outputFile).catch(() => null);
234
+ expect(outputStat?.isFile()).toBe(true);
259
235
  });
260
236
 
261
237
  it('removes original when output extension differs in flat builds', async () => {
262
- await withTempDir(async (cwd) => {
263
- const inputDir = path.join(cwd, 'input');
264
- const buildDir = path.join(cwd, 'build');
265
-
266
- const content = 'export const transformed: string;';
267
- await Promise.all([createFile(path.join(inputDir, 'index.d.ts'), content)]);
268
- /** @type {{type: BundleType; dir: string}[]} */
269
-
270
- // CJS bundle with module packageType creates .d.cts
271
- const bundles = [{ type: 'cjs', dir: 'cjs' }];
272
-
273
- await moveAndTransformDeclarations({
274
- inputDir,
275
- buildDir,
276
- bundles,
277
- isFlat: true,
278
- packageType: 'module',
279
- });
280
-
281
- // Transformed file with new extension should exist
282
- const outputFile = path.join(buildDir, 'cjs', 'index.d.cts');
283
- const outputStat = await fs.stat(outputFile).catch(() => null);
284
- expect(outputStat?.isFile()).toBe(true);
285
-
286
- // Original .d.ts should be removed
287
- const originalFile = path.join(buildDir, 'cjs', 'index.d.ts');
288
- const originalStat = await fs.stat(originalFile).catch(() => null);
289
- expect(originalStat).toBeNull();
238
+ const cwd = await makeTempDir();
239
+ const inputDir = path.join(cwd, 'input');
240
+ const buildDir = path.join(cwd, 'build');
241
+
242
+ const content = 'export const transformed: string;';
243
+ await Promise.all([createFile(path.join(inputDir, 'index.d.ts'), content)]);
244
+ /** @type {BundleType[]} */
245
+
246
+ // CJS bundle with module packageType creates .d.cts
247
+ const bundles = ['cjs'];
248
+
249
+ await moveAndTransformDeclarations({
250
+ inputDir,
251
+ buildDir,
252
+ bundles,
253
+ packageType: 'module',
290
254
  });
255
+
256
+ // Transformed file with new extension should exist
257
+ const outputFile = path.join(buildDir, 'index.d.cts');
258
+ const outputStat = await fs.stat(outputFile).catch(() => null);
259
+ expect(outputStat?.isFile()).toBe(true);
260
+
261
+ // Original .d.ts should be removed
262
+ const originalFile = path.join(buildDir, 'index.d.ts');
263
+ const originalStat = await fs.stat(originalFile).catch(() => null);
264
+ expect(originalStat).toBeNull();
291
265
  });
292
266
 
293
267
  it('handles mixed separator paths in comparisons on Windows', async () => {
@@ -306,75 +280,62 @@ describe('moveAndTransformDeclarations', () => {
306
280
  });
307
281
 
308
282
  it('uses normalized paths for writesToOriginalPath check', async () => {
309
- await withTempDir(async (cwd) => {
310
- const inputDir = path.join(cwd, 'input');
311
- const buildDir = path.join(cwd, 'build');
312
-
313
- const content = 'export const component: string;';
314
- await Promise.all([createFile(path.join(inputDir, 'component.d.ts'), content)]);
315
- /** @type {{type: BundleType; dir: string}[]} */
316
-
317
- // ESM + commonjs packageType creates .d.mts
318
- const bundles = [{ type: 'esm', dir: 'esm' }];
319
-
320
- await moveAndTransformDeclarations({
321
- inputDir,
322
- buildDir,
323
- bundles,
324
- isFlat: true,
325
- packageType: 'commonjs',
326
- });
327
-
328
- // The .d.mts file should exist
329
- const transformedFile = path.join(buildDir, 'esm', 'component.d.mts');
330
- const transformedStat = await fs.stat(transformedFile).catch(() => null);
331
- expect(transformedStat?.isFile()).toBe(true);
332
-
333
- // Original .d.ts should be removed because extension changed
334
- const originalFile = path.join(buildDir, 'esm', 'component.d.ts');
335
- const originalStat = await fs.stat(originalFile).catch(() => null);
336
- expect(originalStat).toBeNull();
283
+ const cwd = await makeTempDir();
284
+ const inputDir = path.join(cwd, 'input');
285
+ const buildDir = path.join(cwd, 'build');
286
+
287
+ const content = 'export const component: string;';
288
+ await Promise.all([createFile(path.join(inputDir, 'component.d.ts'), content)]);
289
+ /** @type {BundleType[]} */
290
+
291
+ // ESM + commonjs packageType creates .d.mts
292
+ const bundles = ['esm'];
293
+
294
+ await moveAndTransformDeclarations({
295
+ inputDir,
296
+ buildDir,
297
+ bundles,
298
+ packageType: 'commonjs',
337
299
  });
300
+
301
+ // The .d.mts file should exist
302
+ const transformedFile = path.join(buildDir, 'component.d.mts');
303
+ const transformedStat = await fs.stat(transformedFile).catch(() => null);
304
+ expect(transformedStat?.isFile()).toBe(true);
305
+
306
+ // Original .d.ts should be removed because extension changed
307
+ const originalFile = path.join(buildDir, 'component.d.ts');
308
+ const originalStat = await fs.stat(originalFile).catch(() => null);
309
+ expect(originalStat).toBeNull();
338
310
  });
339
311
 
340
312
  it('handles path normalization with multiple bundles in flat mode', async () => {
341
- await withTempDir(async (cwd) => {
342
- const inputDir = path.join(cwd, 'input');
343
- const buildDir = path.join(cwd, 'build');
344
-
345
- const content = 'export const multi: string;';
346
- await Promise.all([createFile(path.join(inputDir, 'index.d.ts'), content)]);
347
-
348
- // Multiple bundles: files are copied to buildDir, not directly to bundle dirs
349
- /** @type {{type: BundleType; dir: string}[]} */
350
- const bundles = [
351
- { type: 'esm', dir: 'esm' },
352
- { type: 'cjs', dir: 'cjs' },
353
- ];
354
-
355
- await moveAndTransformDeclarations({
356
- inputDir,
357
- buildDir,
358
- bundles,
359
- isFlat: true,
360
- packageType: 'module',
361
- });
362
-
363
- // Each bundle gets its own transformed copy
364
- // ESM with module packageType keeps .d.ts
365
- const esmFile = path.join(buildDir, 'esm', 'index.d.ts');
366
- const esmStat = await fs.stat(esmFile).catch(() => null);
367
- expect(esmStat?.isFile()).toBe(true);
368
-
369
- // CJS with module packageType gets .d.cts
370
- const cjsFile = path.join(buildDir, 'cjs', 'index.d.cts');
371
- const cjsStat = await fs.stat(cjsFile).catch(() => null);
372
- expect(cjsStat?.isFile()).toBe(true);
373
-
374
- // Original in buildDir should be removed in flat mode since writesToOriginalPath is false
375
- const originalFile = path.join(buildDir, 'index.d.ts');
376
- const originalStat = await fs.stat(originalFile).catch(() => null);
377
- expect(originalStat).toBeNull();
313
+ const cwd = await makeTempDir();
314
+ const inputDir = path.join(cwd, 'input');
315
+ const buildDir = path.join(cwd, 'build');
316
+
317
+ const content = 'export const multi: string;';
318
+ await Promise.all([createFile(path.join(inputDir, 'index.d.ts'), content)]);
319
+
320
+ /** @type {BundleType[]} */
321
+ const bundles = ['esm', 'cjs'];
322
+
323
+ await moveAndTransformDeclarations({
324
+ inputDir,
325
+ buildDir,
326
+ bundles,
327
+ packageType: 'module',
378
328
  });
329
+
330
+ // Each bundle writes its own transformed copy to the build root.
331
+ // ESM with module packageType keeps .d.ts (and is the original, so it stays)
332
+ const esmFile = path.join(buildDir, 'index.d.ts');
333
+ const esmStat = await fs.stat(esmFile).catch(() => null);
334
+ expect(esmStat?.isFile()).toBe(true);
335
+
336
+ // CJS with module packageType gets .d.cts
337
+ const cjsFile = path.join(buildDir, 'index.d.cts');
338
+ const cjsStat = await fs.stat(cjsFile).catch(() => null);
339
+ expect(cjsStat?.isFile()).toBe(true);
379
340
  });
380
341
  });
package/vale/.vale.ini ADDED
@@ -0,0 +1 @@
1
+ StylesPath = styles
@@ -0,0 +1,43 @@
1
+ # Enforce a single way to write specific terms or phrases.
2
+ extends: substitution
3
+ message: Use '%s' instead of '%s'
4
+ level: error
5
+ ignorecase: true # There is only one correct way to spell those, so we want to match inputs regardless of case.
6
+ # swap maps tokens in form of bad: good
7
+ # for more information: https://vale.sh/docs/topics/styles/#substitution
8
+ swap:
9
+ ' api': ' API'
10
+ 'typescript ': 'TypeScript '
11
+ ' ts': ' TypeScript'
12
+ javascript: JavaScript
13
+ ' js': ' JavaScript'
14
+ ' css ': ' CSS '
15
+ ' html ': ' HTML '
16
+ NPM: npm # https://css-tricks.com/start-sentence-npm/
17
+ Github: GitHub
18
+ StackOverflow: Stack Overflow
19
+ Stack Overflow: Stack Overflow
20
+ CSS modules: CSS Modules
21
+ Tailwind CSS: Tailwind CSS
22
+ Heat map: Heatmap
23
+ Tree map: Treemap
24
+ Sparkline Chart: Sparkline chart
25
+ Gauge Chart: Gauge chart
26
+ Treemap Chart: Treemap chart
27
+ sub-component: subcomponent
28
+ sub-components: subcomponents
29
+ use-case: use case
30
+ usecase: use case
31
+ Material 3: Material Design 3
32
+ VSCode: VS Code
33
+ VS Code: VS Code
34
+ 'Codesandbox ': 'CodeSandbox '
35
+ code sandbox: CodeSandbox
36
+ Stackblitz: StackBlitz
37
+ Webpack: webpack # https://x.com/wSokra/status/855800490713649152
38
+ app router: App Router # Next.js
39
+ pages router: Pages Router # Next.js
40
+ page router: Pages Router # Next.js
41
+ eslint: ESLint
42
+ ES modules: ES modules
43
+ JSDOM: jsdom
@@ -0,0 +1,14 @@
1
+ # Write things correctly, please no wrong references.
2
+ extends: substitution
3
+ message: Use '%s' instead of '%s'
4
+ level: error
5
+ ignorecase: false
6
+ # swap maps tokens in form of bad: good
7
+ # for more information: https://vale.sh/docs/topics/styles/#substitution
8
+ swap:
9
+ eg: e.g.
10
+ eg\.: e.g.
11
+ e\.g: e.g.
12
+ ie: i.e.
13
+ ie\.: i.e.
14
+ i\.e: i.e.
@@ -0,0 +1,11 @@
1
+ extends: substitution
2
+ message: Use '%s' instead of '%s'
3
+ link: https://developers.google.com/style/abbreviations
4
+ ignorecase: false
5
+ level: error
6
+ nonword: true
7
+ action:
8
+ name: replace
9
+ swap:
10
+ '\b(?:eg|e\.g\.)(?=[\s,;])': for example
11
+ '\b(?:ie|i\.e\.)(?=[\s,;])': that is