@mui/internal-code-infra 0.0.4-canary.9 → 0.0.4-canary.90

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 (140) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +19 -8
  3. package/build/babel-config.d.mts +5 -1
  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 +3 -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/git.d.mts +7 -0
  40. package/build/utils/github.d.mts +1 -1
  41. package/build/utils/pnpm.d.mts +81 -2
  42. package/build/utils/testUtils.d.mts +7 -0
  43. package/build/utils/typescript.d.mts +6 -16
  44. package/package.json +74 -50
  45. package/src/babel-config.mjs +3 -1
  46. package/src/brokenLinksChecker/crawlWorker.mjs +240 -0
  47. package/src/brokenLinksChecker/index.mjs +263 -188
  48. package/src/changelog/fetchChangelogs.mjs +8 -2
  49. package/src/changelog/renderChangelog.mjs +1 -1
  50. package/src/changelog/types.ts +3 -1
  51. package/src/cli/cmdBuild.mjs +51 -85
  52. package/src/cli/cmdListWorkspaces.mjs +12 -27
  53. package/src/cli/cmdNetlifyIgnore.mjs +34 -93
  54. package/src/cli/cmdPublish.mjs +95 -20
  55. package/src/cli/cmdPublishCanary.mjs +128 -132
  56. package/src/cli/cmdPublishNewPackage.mjs +27 -6
  57. package/src/cli/cmdSetVersionOverrides.mjs +8 -9
  58. package/src/cli/cmdVale.mjs +513 -0
  59. package/src/cli/index.mjs +2 -0
  60. package/src/cli/packageJson.d.ts +1 -1
  61. package/src/eslint/baseConfig.mjs +51 -19
  62. package/src/eslint/docsConfig.mjs +2 -1
  63. package/src/eslint/mui/config.mjs +24 -4
  64. package/src/eslint/mui/index.mjs +6 -0
  65. package/src/eslint/mui/rules/no-floating-cleanup.mjs +187 -0
  66. package/src/eslint/mui/rules/no-guarded-throw.mjs +115 -0
  67. package/src/eslint/mui/rules/no-presentation-role.mjs +60 -0
  68. package/src/eslint/mui/rules/nodeEnvUtils.mjs +52 -0
  69. package/src/eslint/mui/rules/require-dev-wrapper.mjs +25 -40
  70. package/src/estree-typescript.d.ts +1 -1
  71. package/src/remark/config.mjs +157 -0
  72. package/src/remark/createLintTester.mjs +19 -0
  73. package/src/remark/firstBlockHeading.mjs +87 -0
  74. package/src/remark/gitDiff.mjs +43 -0
  75. package/src/remark/noSpaceInLinks.mjs +42 -0
  76. package/src/remark/straightQuotes.mjs +31 -0
  77. package/src/remark/tableAlignment.mjs +23 -0
  78. package/src/remark/terminalLanguage.mjs +19 -0
  79. package/src/untyped-plugins.d.ts +11 -11
  80. package/src/utils/build.mjs +604 -270
  81. package/src/utils/git.mjs +27 -7
  82. package/src/utils/pnpm.mjs +277 -10
  83. package/src/utils/testUtils.mjs +18 -0
  84. package/src/utils/typescript.mjs +23 -42
  85. package/vale/.vale.ini +1 -0
  86. package/vale/styles/MUI/CorrectReferenceAllCases.yml +42 -0
  87. package/vale/styles/MUI/CorrectRererenceCased.yml +14 -0
  88. package/vale/styles/MUI/GoogleLatin.yml +11 -0
  89. package/vale/styles/MUI/MuiBrandName.yml +22 -0
  90. package/vale/styles/MUI/NoBritish.yml +112 -0
  91. package/vale/styles/MUI/NoCompanyName.yml +17 -0
  92. package/build/markdownlint/duplicate-h1.d.mts +0 -56
  93. package/build/markdownlint/git-diff.d.mts +0 -11
  94. package/build/markdownlint/index.d.mts +0 -52
  95. package/build/markdownlint/straight-quotes.d.mts +0 -11
  96. package/build/markdownlint/table-alignment.d.mts +0 -11
  97. package/build/markdownlint/terminal-language.d.mts +0 -11
  98. package/src/brokenLinksChecker/__fixtures__/static-site/broken-links.html +0 -20
  99. package/src/brokenLinksChecker/__fixtures__/static-site/broken-targets.html +0 -22
  100. package/src/brokenLinksChecker/__fixtures__/static-site/example.md +0 -20
  101. package/src/brokenLinksChecker/__fixtures__/static-site/external-links.html +0 -21
  102. package/src/brokenLinksChecker/__fixtures__/static-site/ignored-page.html +0 -17
  103. package/src/brokenLinksChecker/__fixtures__/static-site/index.html +0 -28
  104. package/src/brokenLinksChecker/__fixtures__/static-site/known-targets.json +0 -5
  105. package/src/brokenLinksChecker/__fixtures__/static-site/nested/page.html +0 -21
  106. package/src/brokenLinksChecker/__fixtures__/static-site/orphaned-page.html +0 -20
  107. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-api-links.html +0 -20
  108. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-custom-targets.html +0 -24
  109. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-ignored-content.html +0 -28
  110. package/src/brokenLinksChecker/__fixtures__/static-site/page-with-known-target-links.html +0 -19
  111. package/src/brokenLinksChecker/__fixtures__/static-site/unclosed-tags.html +0 -1
  112. package/src/brokenLinksChecker/__fixtures__/static-site/valid.html +0 -20
  113. package/src/brokenLinksChecker/__fixtures__/static-site/with-anchors.html +0 -31
  114. package/src/brokenLinksChecker/index.test.ts +0 -261
  115. package/src/changelog/categorizeCommits.test.ts +0 -319
  116. package/src/changelog/filterCommits.test.ts +0 -363
  117. package/src/changelog/parseCommitLabels.test.ts +0 -509
  118. package/src/changelog/renderChangelog.test.ts +0 -378
  119. package/src/changelog/sortSections.test.ts +0 -199
  120. package/src/eslint/mui/rules/add-undef-to-optional.test.mjs +0 -361
  121. package/src/eslint/mui/rules/consistent-production-guard.test.mjs +0 -162
  122. package/src/eslint/mui/rules/disallow-active-elements-as-key-event-target.test.mjs +0 -66
  123. package/src/eslint/mui/rules/disallow-react-api-in-server-components.test.mjs +0 -305
  124. package/src/eslint/mui/rules/docgen-ignore-before-comment.test.mjs +0 -52
  125. package/src/eslint/mui/rules/flatten-parentheses.test.mjs +0 -245
  126. package/src/eslint/mui/rules/mui-name-matches-component-name.test.mjs +0 -247
  127. package/src/eslint/mui/rules/no-empty-box.test.mjs +0 -40
  128. package/src/eslint/mui/rules/no-styled-box.test.mjs +0 -73
  129. package/src/eslint/mui/rules/require-dev-wrapper.test.mjs +0 -265
  130. package/src/eslint/mui/rules/rules-of-use-theme-variants.test.mjs +0 -149
  131. package/src/eslint/mui/rules/straight-quotes.test.mjs +0 -67
  132. package/src/markdownlint/duplicate-h1.mjs +0 -69
  133. package/src/markdownlint/git-diff.mjs +0 -31
  134. package/src/markdownlint/index.mjs +0 -62
  135. package/src/markdownlint/straight-quotes.mjs +0 -26
  136. package/src/markdownlint/table-alignment.mjs +0 -42
  137. package/src/markdownlint/terminal-language.mjs +0 -19
  138. package/src/utils/build.test.mjs +0 -705
  139. package/src/utils/template.test.mjs +0 -133
  140. package/src/utils/typescript.test.mjs +0 -380
@@ -1,133 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { templateString } from './template.mjs';
3
-
4
- describe('templateString', () => {
5
- it('replaces a single placeholder with a value', () => {
6
- const result = templateString('Hello {{ name }}', { name: 'Alice' });
7
- expect(result).toBe('Hello Alice');
8
- });
9
-
10
- it('replaces multiple placeholders', () => {
11
- const result = templateString('{{ greeting }}, {{ name }}!', {
12
- greeting: 'Hello',
13
- name: 'Bob',
14
- });
15
- expect(result).toBe('Hello, Bob!');
16
- });
17
-
18
- it('handles spacing variations in placeholders', () => {
19
- const result1 = templateString('{{version}}', { version: '1.0.0' });
20
- const result2 = templateString('{{ version}}', { version: '1.0.0' });
21
- const result3 = templateString('{{version }}', { version: '1.0.0' });
22
- const result4 = templateString('{{ version }}', { version: '1.0.0' });
23
-
24
- expect(result1).toBe('1.0.0');
25
- expect(result2).toBe('1.0.0');
26
- expect(result3).toBe('1.0.0');
27
- expect(result4).toBe('1.0.0');
28
- });
29
-
30
- it('removes placeholders with undefined values', () => {
31
- const result = templateString('Version {{ version }}, Author {{ author }}', {
32
- version: '2.0.0',
33
- });
34
- expect(result).toBe('Version 2.0.0, Author ');
35
- });
36
-
37
- it('removes placeholders for missing keys', () => {
38
- const result = templateString('Release {{ version }} by {{ author }}', {});
39
- expect(result).toBe('Release by ');
40
- });
41
-
42
- it('handles empty template', () => {
43
- const result = templateString('', { name: 'Alice' });
44
- expect(result).toBe('');
45
- });
46
-
47
- it('handles template with no placeholders', () => {
48
- const result = templateString('This is plain text', { name: 'Alice' });
49
- expect(result).toBe('This is plain text');
50
- });
51
-
52
- it('converts non-string values to strings', () => {
53
- const result = templateString('Version {{ major }}.{{ minor }}', {
54
- major: 1,
55
- minor: 5,
56
- });
57
- expect(result).toBe('Version 1.5');
58
- });
59
-
60
- it('handles null values as empty string', () => {
61
- const result = templateString('Hello {{ name }}', { name: null });
62
- expect(result).toBe('Hello null');
63
- });
64
-
65
- it('handles boolean values', () => {
66
- const result = templateString('Enabled: {{ enabled }}, Disabled: {{ disabled }}', {
67
- enabled: true,
68
- disabled: false,
69
- });
70
- expect(result).toBe('Enabled: true, Disabled: false');
71
- });
72
-
73
- it('does not replace text outside of placeholders', () => {
74
- const result = templateString('Literal braces { name } and placeholder {{ name }}', {
75
- name: 'Alice',
76
- });
77
- expect(result).toBe('Literal braces { name } and placeholder Alice');
78
- });
79
-
80
- it('handles consecutive placeholders', () => {
81
- const result = templateString('{{ first }}{{ second }}{{ third }}', {
82
- first: 'A',
83
- second: 'B',
84
- third: 'C',
85
- });
86
- expect(result).toBe('ABC');
87
- });
88
-
89
- it('handles placeholders with extra whitespace', () => {
90
- const result = templateString('{{ version }}', { version: '1.0.0' });
91
- expect(result).toBe('1.0.0');
92
- });
93
-
94
- it('handles complex template with mixed content', () => {
95
- const result = templateString(
96
- 'Release {{ version }} published on {{ date }} by {{ author }} for project {{ project }}',
97
- {
98
- version: 'v1.2.0',
99
- date: 'Jan 19, 2026',
100
- project: 'MUI X',
101
- },
102
- );
103
- expect(result).toBe('Release v1.2.0 published on Jan 19, 2026 by for project MUI X');
104
- });
105
-
106
- it('handles empty object', () => {
107
- const result = templateString('Hello {{ name }}, version {{ version }}', {});
108
- expect(result).toBe('Hello , version ');
109
- });
110
-
111
- it('ignores extra keys in values object', () => {
112
- const result = templateString('Hello {{ name }}', {
113
- name: 'Alice',
114
- extra: 'ignored',
115
- another: 'also ignored',
116
- });
117
- expect(result).toBe('Hello Alice');
118
- });
119
-
120
- it('handles object values (converts to string)', () => {
121
- const result = templateString('Object: {{ obj }}', {
122
- obj: { key: 'value' },
123
- });
124
- expect(result).toBe('Object: [object Object]');
125
- });
126
-
127
- it('handles array values (converts to string)', () => {
128
- const result = templateString('Array: {{ arr }}', {
129
- arr: [1, 2, 3],
130
- });
131
- expect(result).toBe('Array: 1,2,3');
132
- });
133
- });
@@ -1,380 +0,0 @@
1
- import * as fs from 'node:fs/promises';
2
- import * as os from 'node:os';
3
- import * as path from 'node:path';
4
- import { describe, expect, it, vi } from 'vitest';
5
-
6
- import { copyDeclarations, moveAndTransformDeclarations } from './typescript.mjs';
7
-
8
- /**
9
- * @typedef {'esm' | 'cjs'} BundleType
10
- */
11
-
12
- /**
13
- * @param {string} filePath
14
- * @param {string} [contents]
15
- */
16
- async function createFile(filePath, contents = '') {
17
- await fs.mkdir(path.dirname(filePath), { recursive: true });
18
- await fs.writeFile(filePath, contents, 'utf8');
19
- }
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
- describe('copyDeclarations', () => {
34
- 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');
38
-
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
- ]);
44
-
45
- await copyDeclarations(sourceDir, destDir);
46
-
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');
49
-
50
- expect(indexDts).toBe('export const foo: string;');
51
- expect(utilsDts).toBe('export const bar: number;');
52
-
53
- const jsExists = await fs.stat(path.join(destDir, 'index.js')).catch(() => null);
54
- expect(jsExists).toBeNull();
55
- });
56
- });
57
-
58
- 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');
62
-
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
- ]);
67
-
68
- await copyDeclarations(sourceDir, destDir);
69
-
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');
72
-
73
- expect(mtsDts).toBe('export const esm: string;');
74
- expect(ctsDts).toBe('export const cjs: string;');
75
- });
76
- });
77
-
78
- 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');
82
-
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
- ]);
88
-
89
- await copyDeclarations(sourceDir, destDir);
90
-
91
- const indexDts = await fs.readFile(path.join(destDir, 'index.d.ts'), 'utf8');
92
- expect(indexDts).toBe('export const foo: string;');
93
-
94
- const hiddenDts = await fs.stat(path.join(destDir, '.hidden.d.ts')).catch(() => null);
95
- expect(hiddenDts).toBeNull();
96
-
97
- const gitDir = await fs.stat(path.join(destDir, '.git')).catch(() => null);
98
- expect(gitDir).toBeNull();
99
- });
100
- });
101
-
102
- 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');
106
-
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
- ]);
114
-
115
- await copyDeclarations(sourceDir, destDir);
116
-
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');
119
-
120
- expect(indexDts).toBe('export type Foo = string;');
121
- expect(helpersDts).toBe('export type Helper = () => void;');
122
- });
123
- });
124
- });
125
-
126
- describe('moveAndTransformDeclarations', () => {
127
- 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);
158
- });
159
- });
160
-
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);
186
- });
187
- });
188
-
189
- it('correctly compares resolved paths on all platforms', async () => {
190
- // This test verifies that path.resolve() normalizes paths consistently
191
- // across Windows (backslashes) and Unix (forward slashes)
192
- const testPath1 = 'build/esm/index.d.ts';
193
- const testPath2 = path.normalize('build/esm/index.d.ts');
194
-
195
- const resolved1 = path.resolve(testPath1);
196
- const resolved2 = path.resolve(testPath2);
197
-
198
- // Even if separators differ in input, resolved paths should be identical
199
- expect(resolved1).toBe(resolved2);
200
- });
201
-
202
- 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);
231
- });
232
- });
233
-
234
- 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);
258
- });
259
- });
260
-
261
- 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();
290
- });
291
- });
292
-
293
- it('handles mixed separator paths in comparisons on Windows', async () => {
294
- // Simulate Windows-style path comparison scenario
295
- // where globby might return forward slashes but path.join uses backslashes
296
- const basePath = process.platform === 'win32' ? 'C:\\project\\build' : '/project/build';
297
- const forwardSlashPath = `${basePath.replace(/\\/g, '/')}/esm/index.d.ts`;
298
- const backslashPath =
299
- basePath + (process.platform === 'win32' ? '\\esm\\index.d.ts' : '/esm/index.d.ts');
300
-
301
- // After path.resolve(), both should be identical
302
- const resolved1 = path.resolve(forwardSlashPath);
303
- const resolved2 = path.resolve(backslashPath);
304
-
305
- expect(resolved1).toBe(resolved2);
306
- });
307
-
308
- 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();
337
- });
338
- });
339
-
340
- 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();
378
- });
379
- });
380
- });