@mui/internal-code-infra 0.0.4-canary.4 → 0.0.4-canary.40

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 (101) hide show
  1. package/README.md +19 -8
  2. package/build/babel-config.d.mts +11 -3
  3. package/build/brokenLinksChecker/crawlWorker.d.mts +1 -0
  4. package/build/brokenLinksChecker/index.d.mts +44 -2
  5. package/build/changelog/types.d.ts +1 -1
  6. package/build/cli/cmdArgosPush.d.mts +2 -2
  7. package/build/cli/cmdBuild.d.mts +2 -2
  8. package/build/cli/cmdCopyFiles.d.mts +2 -2
  9. package/build/cli/cmdExtractErrorCodes.d.mts +2 -2
  10. package/build/cli/cmdGenerateChangelog.d.mts +2 -2
  11. package/build/cli/cmdGithubAuth.d.mts +2 -2
  12. package/build/cli/cmdListWorkspaces.d.mts +4 -2
  13. package/build/cli/cmdNetlifyIgnore.d.mts +2 -2
  14. package/build/cli/cmdPublish.d.mts +4 -2
  15. package/build/cli/cmdPublishCanary.d.mts +3 -2
  16. package/build/cli/cmdPublishNewPackage.d.mts +4 -2
  17. package/build/cli/cmdSetVersionOverrides.d.mts +2 -2
  18. package/build/cli/cmdVale.d.mts +46 -0
  19. package/build/cli/cmdValidateBuiltTypes.d.mts +2 -2
  20. package/build/eslint/baseConfig.d.mts +3 -1
  21. package/build/eslint/mui/rules/disallow-react-api-in-server-components.d.mts +2 -2
  22. package/build/eslint/mui/rules/docgen-ignore-before-comment.d.mts +2 -2
  23. package/build/eslint/mui/rules/no-guarded-throw.d.mts +31 -0
  24. package/build/eslint/mui/rules/no-restricted-resolved-imports.d.mts +2 -2
  25. package/build/eslint/mui/rules/nodeEnvUtils.d.mts +18 -0
  26. package/build/markdownlint/duplicate-h1.d.mts +1 -1
  27. package/build/markdownlint/git-diff.d.mts +1 -1
  28. package/build/markdownlint/index.d.mts +1 -1
  29. package/build/markdownlint/straight-quotes.d.mts +1 -1
  30. package/build/markdownlint/table-alignment.d.mts +1 -1
  31. package/build/markdownlint/terminal-language.d.mts +1 -1
  32. package/build/remark/config.d.mts +43 -0
  33. package/build/remark/createLintTester.d.mts +10 -0
  34. package/build/remark/firstBlockHeading.d.mts +4 -0
  35. package/build/remark/gitDiff.d.mts +2 -0
  36. package/build/remark/noSpaceInLinks.d.mts +2 -0
  37. package/build/remark/straightQuotes.d.mts +2 -0
  38. package/build/remark/tableAlignment.d.mts +2 -0
  39. package/build/remark/terminalLanguage.d.mts +2 -0
  40. package/build/utils/build.d.mts +3 -3
  41. package/build/utils/github.d.mts +1 -1
  42. package/build/utils/pnpm.d.mts +68 -2
  43. package/build/utils/testUtils.d.mts +7 -0
  44. package/package.json +59 -32
  45. package/src/babel-config.mjs +9 -3
  46. package/src/brokenLinksChecker/__fixtures__/static-site/index.html +1 -0
  47. package/src/brokenLinksChecker/__fixtures__/static-site/invalid-html.html +15 -0
  48. package/src/brokenLinksChecker/crawlWorker.mjs +200 -0
  49. package/src/brokenLinksChecker/index.mjs +213 -164
  50. package/src/brokenLinksChecker/index.test.ts +63 -13
  51. package/src/changelog/categorizeCommits.test.ts +5 -5
  52. package/src/changelog/fetchChangelogs.mjs +6 -2
  53. package/src/changelog/parseCommitLabels.test.ts +5 -5
  54. package/src/changelog/renderChangelog.mjs +1 -1
  55. package/src/changelog/types.ts +1 -1
  56. package/src/cli/cmdListWorkspaces.mjs +9 -2
  57. package/src/cli/cmdNetlifyIgnore.mjs +4 -88
  58. package/src/cli/cmdPublish.mjs +51 -14
  59. package/src/cli/cmdPublishCanary.mjs +139 -107
  60. package/src/cli/cmdPublishNewPackage.mjs +27 -6
  61. package/src/cli/cmdVale.mjs +513 -0
  62. package/src/cli/cmdVale.test.mjs +644 -0
  63. package/src/cli/index.mjs +2 -0
  64. package/src/eslint/baseConfig.mjs +45 -20
  65. package/src/eslint/docsConfig.mjs +2 -1
  66. package/src/eslint/jsonConfig.mjs +2 -1
  67. package/src/eslint/mui/config.mjs +20 -1
  68. package/src/eslint/mui/index.mjs +2 -0
  69. package/src/eslint/mui/rules/no-guarded-throw.mjs +115 -0
  70. package/src/eslint/mui/rules/no-guarded-throw.test.mjs +206 -0
  71. package/src/eslint/mui/rules/nodeEnvUtils.mjs +52 -0
  72. package/src/eslint/mui/rules/require-dev-wrapper.mjs +25 -40
  73. package/src/eslint/testConfig.mjs +2 -1
  74. package/src/estree-typescript.d.ts +1 -1
  75. package/src/remark/config.mjs +157 -0
  76. package/src/remark/createLintTester.mjs +19 -0
  77. package/src/remark/firstBlockHeading.mjs +87 -0
  78. package/src/remark/firstBlockHeading.test.mjs +107 -0
  79. package/src/remark/gitDiff.mjs +43 -0
  80. package/src/remark/gitDiff.test.mjs +45 -0
  81. package/src/remark/noSpaceInLinks.mjs +42 -0
  82. package/src/remark/noSpaceInLinks.test.mjs +22 -0
  83. package/src/remark/straightQuotes.mjs +31 -0
  84. package/src/remark/straightQuotes.test.mjs +25 -0
  85. package/src/remark/tableAlignment.mjs +23 -0
  86. package/src/remark/tableAlignment.test.mjs +28 -0
  87. package/src/remark/terminalLanguage.mjs +19 -0
  88. package/src/remark/terminalLanguage.test.mjs +17 -0
  89. package/src/untyped-plugins.d.ts +11 -11
  90. package/src/utils/build.test.mjs +546 -575
  91. package/src/utils/pnpm.mjs +192 -3
  92. package/src/utils/pnpm.test.mjs +580 -0
  93. package/src/utils/testUtils.mjs +18 -0
  94. package/src/utils/typescript.test.mjs +249 -272
  95. package/vale/.vale.ini +1 -0
  96. package/vale/styles/MUI/CorrectReferenceAllCases.yml +43 -0
  97. package/vale/styles/MUI/CorrectRererenceCased.yml +14 -0
  98. package/vale/styles/MUI/GoogleLatin.yml +11 -0
  99. package/vale/styles/MUI/MuiBrandName.yml +22 -0
  100. package/vale/styles/MUI/NoBritish.yml +112 -0
  101. package/vale/styles/MUI/NoCompanyName.yml +17 -0
@@ -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,154 @@ 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 {{type: BundleType; dir: string}[]} */
122
+ const bundles = [{ type: 'esm', dir: '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
+ isFlat: false,
134
+ packageType: 'module',
158
135
  });
136
+
137
+ // Verify file exists in the correct location
138
+ const dtsFile = path.join(buildDir, 'esm', 'index.d.ts');
139
+ const stat = await fs.stat(dtsFile).catch(() => null);
140
+ expect(stat).not.toBeNull();
141
+ expect(stat?.isFile()).toBe(true);
159
142
  });
160
143
 
161
144
  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);
145
+ const cwd = await makeTempDir();
146
+ const inputDir = path.join(cwd, 'input');
147
+ const buildDir = path.join(cwd, 'build');
148
+
149
+ // Create a test .d.ts file
150
+ await Promise.all([
151
+ createFile(path.join(inputDir, 'index.d.ts'), 'export const test: string;'),
152
+ ]);
153
+
154
+ /** @type {{type: BundleType; dir: string}[]} */
155
+ const bundles = [{ type: 'esm', dir: 'esm' }];
156
+
157
+ await moveAndTransformDeclarations({
158
+ inputDir,
159
+ buildDir,
160
+ bundles,
161
+ isFlat: false,
162
+ packageType: 'module',
186
163
  });
164
+
165
+ // For single bundle non-flat builds, files are copied to bundle dir
166
+ const dtsFile = path.join(buildDir, 'esm', 'index.d.ts');
167
+ const stat = await fs.stat(dtsFile).catch(() => null);
168
+ expect(stat?.isFile()).toBe(true);
187
169
  });
188
170
 
189
171
  it('correctly compares resolved paths on all platforms', async () => {
@@ -200,94 +182,91 @@ describe('moveAndTransformDeclarations', () => {
200
182
  });
201
183
 
202
184
  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);
185
+ const cwd = await makeTempDir();
186
+ const inputDir = path.join(cwd, 'input');
187
+ const buildDir = path.join(cwd, 'build');
188
+
189
+ const content = 'export const normalized: boolean;';
190
+ await Promise.all([createFile(path.join(inputDir, 'test.d.ts'), content)]);
191
+
192
+ /** @type {{type: BundleType; dir: string}[]} */
193
+ const bundles = [{ type: 'esm', dir: 'esm' }];
194
+
195
+ // Mock babel transformAsync to capture filename
196
+ const transformMock = vi.fn(async (code) => ({ code }));
197
+ vi.doMock('@babel/core', () => ({
198
+ transformAsync: transformMock,
199
+ }));
200
+
201
+ await moveAndTransformDeclarations({
202
+ inputDir,
203
+ buildDir,
204
+ bundles,
205
+ isFlat: false,
206
+ packageType: 'module',
231
207
  });
208
+
209
+ // Verify the file was read correctly by checking it exists
210
+ const dtsFile = path.join(buildDir, 'esm', 'test.d.ts');
211
+ const stat = await fs.stat(dtsFile).catch(() => null);
212
+ expect(stat?.isFile()).toBe(true);
232
213
  });
233
214
 
234
215
  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);
216
+ const cwd = await makeTempDir();
217
+ const inputDir = path.join(cwd, 'input');
218
+ const buildDir = path.join(cwd, 'build');
219
+
220
+ const content = 'export const flat: string;';
221
+ await Promise.all([createFile(path.join(inputDir, 'index.d.ts'), content)]);
222
+
223
+ /** @type {{type: BundleType; dir: string}[]} */
224
+ // ESM + module packageType keeps .d.ts extension in flat builds
225
+ const bundles = [{ type: 'esm', dir: 'esm' }];
226
+
227
+ await moveAndTransformDeclarations({
228
+ inputDir,
229
+ buildDir,
230
+ bundles,
231
+ isFlat: true,
232
+ packageType: 'module',
258
233
  });
234
+
235
+ // Since extension doesn't change (.d.ts -> .d.ts), file should remain
236
+ const outputFile = path.join(buildDir, 'esm', 'index.d.ts');
237
+ const outputStat = await fs.stat(outputFile).catch(() => null);
238
+ expect(outputStat?.isFile()).toBe(true);
259
239
  });
260
240
 
261
241
  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();
242
+ const cwd = await makeTempDir();
243
+ const inputDir = path.join(cwd, 'input');
244
+ const buildDir = path.join(cwd, 'build');
245
+
246
+ const content = 'export const transformed: string;';
247
+ await Promise.all([createFile(path.join(inputDir, 'index.d.ts'), content)]);
248
+ /** @type {{type: BundleType; dir: string}[]} */
249
+
250
+ // CJS bundle with module packageType creates .d.cts
251
+ const bundles = [{ type: 'cjs', dir: 'cjs' }];
252
+
253
+ await moveAndTransformDeclarations({
254
+ inputDir,
255
+ buildDir,
256
+ bundles,
257
+ isFlat: true,
258
+ packageType: 'module',
290
259
  });
260
+
261
+ // Transformed file with new extension should exist
262
+ const outputFile = path.join(buildDir, 'cjs', 'index.d.cts');
263
+ const outputStat = await fs.stat(outputFile).catch(() => null);
264
+ expect(outputStat?.isFile()).toBe(true);
265
+
266
+ // Original .d.ts should be removed
267
+ const originalFile = path.join(buildDir, 'cjs', 'index.d.ts');
268
+ const originalStat = await fs.stat(originalFile).catch(() => null);
269
+ expect(originalStat).toBeNull();
291
270
  });
292
271
 
293
272
  it('handles mixed separator paths in comparisons on Windows', async () => {
@@ -306,75 +285,73 @@ describe('moveAndTransformDeclarations', () => {
306
285
  });
307
286
 
308
287
  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();
288
+ const cwd = await makeTempDir();
289
+ const inputDir = path.join(cwd, 'input');
290
+ const buildDir = path.join(cwd, 'build');
291
+
292
+ const content = 'export const component: string;';
293
+ await Promise.all([createFile(path.join(inputDir, 'component.d.ts'), content)]);
294
+ /** @type {{type: BundleType; dir: string}[]} */
295
+
296
+ // ESM + commonjs packageType creates .d.mts
297
+ const bundles = [{ type: 'esm', dir: 'esm' }];
298
+
299
+ await moveAndTransformDeclarations({
300
+ inputDir,
301
+ buildDir,
302
+ bundles,
303
+ isFlat: true,
304
+ packageType: 'commonjs',
337
305
  });
306
+
307
+ // The .d.mts file should exist
308
+ const transformedFile = path.join(buildDir, 'esm', 'component.d.mts');
309
+ const transformedStat = await fs.stat(transformedFile).catch(() => null);
310
+ expect(transformedStat?.isFile()).toBe(true);
311
+
312
+ // Original .d.ts should be removed because extension changed
313
+ const originalFile = path.join(buildDir, 'esm', 'component.d.ts');
314
+ const originalStat = await fs.stat(originalFile).catch(() => null);
315
+ expect(originalStat).toBeNull();
338
316
  });
339
317
 
340
318
  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();
319
+ const cwd = await makeTempDir();
320
+ const inputDir = path.join(cwd, 'input');
321
+ const buildDir = path.join(cwd, 'build');
322
+
323
+ const content = 'export const multi: string;';
324
+ await Promise.all([createFile(path.join(inputDir, 'index.d.ts'), content)]);
325
+
326
+ // Multiple bundles: files are copied to buildDir, not directly to bundle dirs
327
+ /** @type {{type: BundleType; dir: string}[]} */
328
+ const bundles = [
329
+ { type: 'esm', dir: 'esm' },
330
+ { type: 'cjs', dir: 'cjs' },
331
+ ];
332
+
333
+ await moveAndTransformDeclarations({
334
+ inputDir,
335
+ buildDir,
336
+ bundles,
337
+ isFlat: true,
338
+ packageType: 'module',
378
339
  });
340
+
341
+ // Each bundle gets its own transformed copy
342
+ // ESM with module packageType keeps .d.ts
343
+ const esmFile = path.join(buildDir, 'esm', 'index.d.ts');
344
+ const esmStat = await fs.stat(esmFile).catch(() => null);
345
+ expect(esmStat?.isFile()).toBe(true);
346
+
347
+ // CJS with module packageType gets .d.cts
348
+ const cjsFile = path.join(buildDir, 'cjs', 'index.d.cts');
349
+ const cjsStat = await fs.stat(cjsFile).catch(() => null);
350
+ expect(cjsStat?.isFile()).toBe(true);
351
+
352
+ // Original in buildDir should be removed in flat mode since writesToOriginalPath is false
353
+ const originalFile = path.join(buildDir, 'index.d.ts');
354
+ const originalStat = await fs.stat(originalFile).catch(() => null);
355
+ expect(originalStat).toBeNull();
379
356
  });
380
357
  });
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://twitter.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.