@mui/internal-code-infra 0.0.4-canary.8 → 0.0.4-canary.80

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 +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/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 +65 -41
  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 +6 -2
  49. package/src/changelog/renderChangelog.mjs +1 -1
  50. package/src/changelog/types.ts +1 -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,705 +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 } from 'vitest';
5
-
6
- import { createPackageBin, createPackageExports } from './build.mjs';
7
-
8
- /**
9
- * @param {string} filePath
10
- * @param {string} [contents]
11
- */
12
- async function createFile(filePath, contents = '') {
13
- await fs.mkdir(path.dirname(filePath), { recursive: true });
14
- await fs.writeFile(filePath, contents, 'utf8');
15
- }
16
-
17
- /**
18
- * @param {(cwd: string) => Promise<void>} fn
19
- */
20
- async function withTempDir(fn) {
21
- const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'code-infra-build-test-'));
22
- try {
23
- return await fn(tmpDir);
24
- } finally {
25
- await fs.rm(tmpDir, { recursive: true, force: true });
26
- }
27
- }
28
-
29
- describe('createPackageExports', () => {
30
- it('creates exports for a dual bundle module package', async () => {
31
- await withTempDir(async (cwd) => {
32
- const outputDir = path.join(cwd, 'build');
33
- /**
34
- * @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
35
- */
36
- const bundles = [
37
- { type: 'esm', dir: '.' },
38
- { type: 'cjs', dir: '.' },
39
- ];
40
-
41
- await Promise.all([
42
- createFile(path.join(cwd, 'src/index.ts')),
43
- createFile(path.join(cwd, 'src/feature.ts')),
44
-
45
- // Create output files for index
46
- createFile(path.join(outputDir, `index.js`)),
47
- createFile(path.join(outputDir, `index.cjs`)),
48
- createFile(path.join(outputDir, `index.d.ts`)),
49
- createFile(path.join(outputDir, `index.d.cts`)),
50
-
51
- // Create output files for feature
52
- createFile(path.join(outputDir, `feature.js`)),
53
- createFile(path.join(outputDir, `feature.cjs`)),
54
- createFile(path.join(outputDir, `feature.d.ts`)),
55
- createFile(path.join(outputDir, `feature.d.cts`)),
56
- ]);
57
-
58
- const {
59
- exports: packageExports,
60
- main,
61
- types,
62
- } = await createPackageExports({
63
- exports: {
64
- '.': './src/index.ts',
65
- './feature': './src/feature.ts',
66
- },
67
- bundles,
68
- outputDir,
69
- cwd,
70
- addTypes: true,
71
- isFlat: true,
72
- packageType: 'module',
73
- });
74
-
75
- expect(main).toBe('./index.cjs');
76
- expect(types).toBe('./index.d.cts');
77
-
78
- expect(packageExports['.']).toEqual({
79
- import: { types: './index.d.ts', default: './index.js' },
80
- require: { types: './index.d.cts', default: './index.cjs' },
81
- default: {
82
- types: './index.d.ts',
83
- default: './index.js',
84
- },
85
- });
86
- expect(packageExports['./feature']).toEqual({
87
- import: { types: './feature.d.ts', default: './feature.js' },
88
- require: { types: './feature.d.cts', default: './feature.cjs' },
89
- default: {
90
- types: './feature.d.ts',
91
- default: './feature.js',
92
- },
93
- });
94
-
95
- const {
96
- exports: packageExports2,
97
- main: main2,
98
- types: types2,
99
- } = await createPackageExports({
100
- exports: {
101
- '.': './src/index.ts',
102
- './feature': './src/feature.ts',
103
- },
104
- bundles: [bundles[1]], // only CJS bundle
105
- outputDir,
106
- cwd,
107
- addTypes: true,
108
- isFlat: true,
109
- });
110
-
111
- expect(main2).toBe('./index.js');
112
- expect(types2).toBe('./index.d.ts');
113
-
114
- expect(packageExports2['.']).toEqual({
115
- require: { types: './index.d.ts', default: './index.js' },
116
- default: {
117
- types: './index.d.ts',
118
- default: './index.js',
119
- },
120
- });
121
- expect(packageExports2['./feature']).toEqual({
122
- require: { types: './feature.d.ts', default: './feature.js' },
123
- default: {
124
- types: './feature.d.ts',
125
- default: './feature.js',
126
- },
127
- });
128
- });
129
- });
130
-
131
- describe('glob expansion', () => {
132
- it('expands glob patterns in export keys and values', async () => {
133
- await withTempDir(async (cwd) => {
134
- const outputDir = path.join(cwd, 'build');
135
- /**
136
- * @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
137
- */
138
- const bundles = [
139
- { type: 'esm', dir: '.' },
140
- { type: 'cjs', dir: '.' },
141
- ];
142
-
143
- await Promise.all([
144
- createFile(path.join(cwd, 'src/Button.ts')),
145
- createFile(path.join(cwd, 'src/TextField.ts')),
146
-
147
- // Output files
148
- createFile(path.join(outputDir, 'Button.js')),
149
- createFile(path.join(outputDir, 'Button.cjs')),
150
- createFile(path.join(outputDir, 'Button.d.ts')),
151
- createFile(path.join(outputDir, 'Button.d.cts')),
152
- createFile(path.join(outputDir, 'TextField.js')),
153
- createFile(path.join(outputDir, 'TextField.cjs')),
154
- createFile(path.join(outputDir, 'TextField.d.ts')),
155
- createFile(path.join(outputDir, 'TextField.d.cts')),
156
- ]);
157
-
158
- const { exports: packageExports } = await createPackageExports({
159
- exports: {
160
- './*': './src/*.ts',
161
- },
162
- bundles,
163
- outputDir,
164
- cwd,
165
- addTypes: true,
166
- isFlat: true,
167
- packageType: 'module',
168
- });
169
-
170
- expect(packageExports['./Button']).toEqual({
171
- import: { types: './Button.d.ts', default: './Button.js' },
172
- require: { types: './Button.d.cts', default: './Button.cjs' },
173
- default: { types: './Button.d.ts', default: './Button.js' },
174
- });
175
- expect(packageExports['./TextField']).toEqual({
176
- import: { types: './TextField.d.ts', default: './TextField.js' },
177
- require: { types: './TextField.d.cts', default: './TextField.cjs' },
178
- default: { types: './TextField.d.ts', default: './TextField.js' },
179
- });
180
- // glob key should not appear in the output
181
- expect(packageExports['./*']).toBeUndefined();
182
- });
183
- });
184
-
185
- it('expands glob with commonjs package type', async () => {
186
- await withTempDir(async (cwd) => {
187
- const outputDir = path.join(cwd, 'build');
188
- /**
189
- * @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
190
- */
191
- const bundles = [
192
- { type: 'esm', dir: '.' },
193
- { type: 'cjs', dir: '.' },
194
- ];
195
-
196
- await Promise.all([
197
- createFile(path.join(cwd, 'src/Button.ts')),
198
-
199
- createFile(path.join(outputDir, 'Button.js')),
200
- createFile(path.join(outputDir, 'Button.mjs')),
201
- createFile(path.join(outputDir, 'Button.d.ts')),
202
- createFile(path.join(outputDir, 'Button.d.mts')),
203
- ]);
204
-
205
- const { exports: packageExports } = await createPackageExports({
206
- exports: {
207
- './*': './src/*.ts',
208
- },
209
- bundles,
210
- outputDir,
211
- cwd,
212
- addTypes: true,
213
- isFlat: true,
214
- packageType: 'commonjs',
215
- });
216
-
217
- expect(packageExports['./Button']).toEqual({
218
- import: { types: './Button.d.mts', default: './Button.mjs' },
219
- require: { types: './Button.d.ts', default: './Button.js' },
220
- default: { types: './Button.d.mts', default: './Button.mjs' },
221
- });
222
- });
223
- });
224
-
225
- it('expands glob with single CJS bundle', async () => {
226
- await withTempDir(async (cwd) => {
227
- const outputDir = path.join(cwd, 'build');
228
-
229
- await Promise.all([
230
- createFile(path.join(cwd, 'src/Button.ts')),
231
-
232
- createFile(path.join(outputDir, 'Button.js')),
233
- createFile(path.join(outputDir, 'Button.d.ts')),
234
- ]);
235
-
236
- const { exports: packageExports } = await createPackageExports({
237
- exports: {
238
- './*': './src/*.ts',
239
- },
240
- bundles: [{ type: 'cjs', dir: '.' }],
241
- outputDir,
242
- cwd,
243
- addTypes: true,
244
- isFlat: true,
245
- packageType: 'commonjs',
246
- });
247
-
248
- expect(packageExports['./Button']).toEqual({
249
- require: { types: './Button.d.ts', default: './Button.js' },
250
- default: { types: './Button.d.ts', default: './Button.js' },
251
- });
252
- });
253
- });
254
-
255
- it('expands glob patterns with mui-src object values', async () => {
256
- await withTempDir(async (cwd) => {
257
- const outputDir = path.join(cwd, 'build');
258
- /**
259
- * @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
260
- */
261
- const bundles = [
262
- { type: 'esm', dir: '.' },
263
- { type: 'cjs', dir: '.' },
264
- ];
265
-
266
- await Promise.all([
267
- createFile(path.join(cwd, 'src/Alert.ts')),
268
-
269
- createFile(path.join(outputDir, 'Alert.js')),
270
- createFile(path.join(outputDir, 'Alert.cjs')),
271
- ]);
272
-
273
- const { exports: packageExports } = await createPackageExports({
274
- exports: {
275
- './*': { 'mui-src': './src/*.ts' },
276
- },
277
- bundles,
278
- outputDir,
279
- cwd,
280
- isFlat: true,
281
- packageType: 'module',
282
- });
283
-
284
- expect(packageExports['./Alert']).toEqual({
285
- import: './Alert.js',
286
- require: './Alert.cjs',
287
- default: './Alert.js',
288
- });
289
- });
290
- });
291
-
292
- it('preserves extra conditions from mui-src object values', async () => {
293
- await withTempDir(async (cwd) => {
294
- const outputDir = path.join(cwd, 'build');
295
- /**
296
- * @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
297
- */
298
- const bundles = [
299
- { type: 'esm', dir: '.' },
300
- { type: 'cjs', dir: '.' },
301
- ];
302
-
303
- await Promise.all([
304
- createFile(path.join(cwd, 'src/Alert.ts')),
305
-
306
- createFile(path.join(outputDir, 'Alert.js')),
307
- createFile(path.join(outputDir, 'Alert.cjs')),
308
- ]);
309
-
310
- const { exports: packageExports } = await createPackageExports({
311
- exports: {
312
- './*': { 'mui-src': './src/*.ts', node: './src/node/*.ts' },
313
- },
314
- bundles,
315
- outputDir,
316
- cwd,
317
- isFlat: true,
318
- packageType: 'module',
319
- });
320
-
321
- expect(packageExports['./Alert']).toEqual({
322
- import: { node: './src/node/*.ts', default: './Alert.js' },
323
- require: { node: './src/node/*.ts', default: './Alert.cjs' },
324
- default: './Alert.js',
325
- });
326
- });
327
- });
328
-
329
- it('mixes glob and non-glob exports', async () => {
330
- await withTempDir(async (cwd) => {
331
- const outputDir = path.join(cwd, 'build');
332
- /**
333
- * @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
334
- */
335
- const bundles = [
336
- { type: 'esm', dir: '.' },
337
- { type: 'cjs', dir: '.' },
338
- ];
339
-
340
- await Promise.all([
341
- createFile(path.join(cwd, 'src/index.ts')),
342
- createFile(path.join(cwd, 'src/Chip.ts')),
343
-
344
- createFile(path.join(outputDir, 'index.js')),
345
- createFile(path.join(outputDir, 'index.cjs')),
346
- createFile(path.join(outputDir, 'Chip.js')),
347
- createFile(path.join(outputDir, 'Chip.cjs')),
348
- ]);
349
-
350
- const { exports: packageExports } = await createPackageExports({
351
- exports: {
352
- '.': './src/index.ts',
353
- './*': './src/*.ts',
354
- },
355
- bundles,
356
- outputDir,
357
- cwd,
358
- isFlat: true,
359
- packageType: 'module',
360
- });
361
-
362
- // Explicit export still works
363
- expect(packageExports['.']).toBeDefined();
364
- // Glob-expanded export
365
- expect(packageExports['./Chip']).toEqual({
366
- import: './Chip.js',
367
- require: './Chip.cjs',
368
- default: './Chip.js',
369
- });
370
- });
371
- });
372
-
373
- it('expands glob with subdirectory pattern', async () => {
374
- await withTempDir(async (cwd) => {
375
- const outputDir = path.join(cwd, 'build');
376
- /**
377
- * @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
378
- */
379
- const bundles = [
380
- { type: 'esm', dir: '.' },
381
- { type: 'cjs', dir: '.' },
382
- ];
383
-
384
- await Promise.all([
385
- createFile(path.join(cwd, 'src/utils/color.ts')),
386
- createFile(path.join(cwd, 'src/utils/size.ts')),
387
-
388
- createFile(path.join(outputDir, 'utils/color.js')),
389
- createFile(path.join(outputDir, 'utils/color.cjs')),
390
- createFile(path.join(outputDir, 'utils/size.js')),
391
- createFile(path.join(outputDir, 'utils/size.cjs')),
392
- ]);
393
-
394
- const { exports: packageExports } = await createPackageExports({
395
- exports: {
396
- './utils/*': './src/utils/*.ts',
397
- },
398
- bundles,
399
- outputDir,
400
- cwd,
401
- isFlat: true,
402
- packageType: 'module',
403
- });
404
-
405
- expect(packageExports['./utils/color']).toEqual({
406
- import: './utils/color.js',
407
- require: './utils/color.cjs',
408
- default: './utils/color.js',
409
- });
410
- expect(packageExports['./utils/size']).toEqual({
411
- import: './utils/size.js',
412
- require: './utils/size.cjs',
413
- default: './utils/size.js',
414
- });
415
- });
416
- });
417
-
418
- it('produces no entries when glob matches nothing', async () => {
419
- await withTempDir(async (cwd) => {
420
- const outputDir = path.join(cwd, 'build');
421
-
422
- // Create the src directory but no .ts files in it
423
- createFile(path.join(cwd, 'src/.gitkeep'));
424
-
425
- const { exports: packageExports } = await createPackageExports({
426
- exports: {
427
- './*': './src/*.ts',
428
- },
429
- bundles: [{ type: 'cjs', dir: '.' }],
430
- outputDir,
431
- cwd,
432
- isFlat: true,
433
- });
434
-
435
- // Only the default ./package.json entry should be present
436
- expect(Object.keys(packageExports)).toEqual(['./package.json']);
437
- });
438
- });
439
-
440
- it('expands globs in sorted order', async () => {
441
- await withTempDir(async (cwd) => {
442
- const outputDir = path.join(cwd, 'build');
443
-
444
- await Promise.all([
445
- createFile(path.join(cwd, 'src/Zebra.ts')),
446
- createFile(path.join(cwd, 'src/Apple.ts')),
447
- createFile(path.join(cwd, 'src/Mango.ts')),
448
-
449
- createFile(path.join(outputDir, 'Zebra.js')),
450
- createFile(path.join(outputDir, 'Apple.js')),
451
- createFile(path.join(outputDir, 'Mango.js')),
452
- ]);
453
-
454
- const { exports: packageExports } = await createPackageExports({
455
- exports: {
456
- './*': './src/*.ts',
457
- },
458
- bundles: [{ type: 'cjs', dir: '.' }],
459
- outputDir,
460
- cwd,
461
- isFlat: true,
462
- });
463
-
464
- const exportKeys = Object.keys(packageExports).filter((k) => k !== './package.json');
465
- expect(exportKeys).toEqual(['./Apple', './Mango', './Zebra']);
466
- });
467
- });
468
-
469
- it('removes expanded entries matching a null-valued glob (negation)', async () => {
470
- await withTempDir(async (cwd) => {
471
- const outputDir = path.join(cwd, 'build');
472
- /**
473
- * @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
474
- */
475
- const bundles = [
476
- { type: 'esm', dir: '.' },
477
- { type: 'cjs', dir: '.' },
478
- ];
479
-
480
- await Promise.all([
481
- createFile(path.join(cwd, 'src/Accordion.ts')),
482
- createFile(path.join(cwd, 'src/Button.ts')),
483
- createFile(path.join(cwd, 'src/ButtonBase.ts')),
484
-
485
- createFile(path.join(outputDir, 'Accordion.js')),
486
- createFile(path.join(outputDir, 'Accordion.cjs')),
487
- createFile(path.join(outputDir, 'Button.js')),
488
- createFile(path.join(outputDir, 'Button.cjs')),
489
- createFile(path.join(outputDir, 'ButtonBase.js')),
490
- createFile(path.join(outputDir, 'ButtonBase.cjs')),
491
- ]);
492
-
493
- const { exports: packageExports } = await createPackageExports({
494
- exports: {
495
- './*': './src/*.ts',
496
- './Button*': null,
497
- },
498
- bundles,
499
- outputDir,
500
- cwd,
501
- isFlat: true,
502
- packageType: 'module',
503
- });
504
-
505
- expect(packageExports['./Accordion']).toBeDefined();
506
- expect(packageExports['./Button']).toBeUndefined();
507
- expect(packageExports['./ButtonBase']).toBeUndefined();
508
- // The negation glob key itself should not appear
509
- expect(packageExports['./Button*']).toBeUndefined();
510
- });
511
- });
512
-
513
- it('negation with null removes only matching keys', async () => {
514
- await withTempDir(async (cwd) => {
515
- const outputDir = path.join(cwd, 'build');
516
-
517
- await Promise.all([
518
- createFile(path.join(cwd, 'src/Alert.ts')),
519
- createFile(path.join(cwd, 'src/AlertTitle.ts')),
520
- createFile(path.join(cwd, 'src/Button.ts')),
521
-
522
- createFile(path.join(outputDir, 'Alert.js')),
523
- createFile(path.join(outputDir, 'AlertTitle.js')),
524
- createFile(path.join(outputDir, 'Button.js')),
525
- ]);
526
-
527
- const { exports: packageExports } = await createPackageExports({
528
- exports: {
529
- './*': './src/*.ts',
530
- './Alert*': null,
531
- },
532
- bundles: [{ type: 'cjs', dir: '.' }],
533
- outputDir,
534
- cwd,
535
- isFlat: true,
536
- });
537
-
538
- const exportKeys = Object.keys(packageExports).filter((k) => k !== './package.json');
539
- expect(exportKeys).toEqual(['./Button']);
540
- });
541
- });
542
-
543
- it('preserves null glob pattern when no keys match', async () => {
544
- await withTempDir(async (cwd) => {
545
- const outputDir = path.join(cwd, 'build');
546
-
547
- await Promise.all([
548
- createFile(path.join(cwd, 'src/Button.ts')),
549
- createFile(path.join(outputDir, 'Button.js')),
550
- ]);
551
-
552
- const { exports: packageExports } = await createPackageExports({
553
- exports: {
554
- './*': './src/*.ts',
555
- './internal/*': null,
556
- },
557
- bundles: [{ type: 'cjs', dir: '.' }],
558
- outputDir,
559
- cwd,
560
- isFlat: true,
561
- });
562
-
563
- // Button is kept since it doesn't match the negation
564
- expect(packageExports['./Button']).toBeDefined();
565
- // The negation pattern is preserved as null since nothing matched it
566
- expect(packageExports['./internal/*']).toBeNull();
567
- });
568
- });
569
-
570
- it('does not expand glob patterns when isFlat is false', async () => {
571
- await withTempDir(async (cwd) => {
572
- const outputDir = path.join(cwd, 'build');
573
-
574
- await Promise.all([
575
- createFile(path.join(cwd, 'src/Button.ts')),
576
- createFile(path.join(cwd, 'src/TextField.ts')),
577
- ]);
578
-
579
- const { exports: packageExports } = await createPackageExports({
580
- exports: {
581
- './*': './src/*.ts',
582
- },
583
- bundles: [{ type: 'cjs', dir: '.' }],
584
- outputDir,
585
- cwd,
586
- isFlat: false,
587
- });
588
-
589
- // Glob should NOT be expanded to individual files
590
- expect(packageExports['./Button']).toBeUndefined();
591
- expect(packageExports['./TextField']).toBeUndefined();
592
- // The raw glob pattern is passed through as-is
593
- expect(packageExports['./*']).toEqual({
594
- require: './*.js',
595
- default: './*.js',
596
- });
597
- });
598
- });
599
-
600
- it('passes through glob key when value has no wildcard', async () => {
601
- await withTempDir(async (cwd) => {
602
- const outputDir = path.join(cwd, 'build');
603
-
604
- await Promise.all([
605
- createFile(path.join(cwd, 'src/index.ts')),
606
- createFile(path.join(outputDir, 'index.js')),
607
- ]);
608
-
609
- const { exports: packageExports } = await createPackageExports({
610
- exports: {
611
- './*': './src/index.ts',
612
- },
613
- bundles: [{ type: 'cjs', dir: '.' }],
614
- outputDir,
615
- cwd,
616
- isFlat: true,
617
- });
618
-
619
- // When the value has no *, the glob key is passed through as-is
620
- expect(packageExports['./*']).toBeDefined();
621
- });
622
- });
623
- });
624
-
625
- it('uses require/import and default for single bundle package', async () => {
626
- await withTempDir(async (cwd) => {
627
- const outputDir = path.join(cwd, 'build');
628
-
629
- await Promise.all([
630
- createFile(path.join(cwd, 'src/index.ts')),
631
- createFile(path.join(outputDir, 'index.js')),
632
- createFile(path.join(outputDir, 'index.d.ts')),
633
- ]);
634
-
635
- const { exports: packageExports } = await createPackageExports({
636
- exports: {
637
- '.': './src/index.ts',
638
- },
639
- bundles: [{ type: 'cjs', dir: '.' }],
640
- outputDir,
641
- cwd,
642
- addTypes: true,
643
- isFlat: true,
644
- packageType: 'commonjs',
645
- });
646
-
647
- // Single CJS bundle should have both require and default pointing to the same files
648
- expect(packageExports['.']).toEqual({
649
- require: {
650
- types: './index.d.ts',
651
- default: './index.js',
652
- },
653
- default: {
654
- types: './index.d.ts',
655
- default: './index.js',
656
- },
657
- });
658
- });
659
- });
660
- });
661
-
662
- describe('createPackageBin', () => {
663
- it('prefers the ESM bundle when available', async () => {
664
- await withTempDir(async (cwd) => {
665
- /**
666
- * @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
667
- */
668
- const bundles = [
669
- { type: 'esm', dir: '.' },
670
- { type: 'cjs', dir: '.' },
671
- ];
672
-
673
- await Promise.all([createFile(path.join(cwd, 'src/cli.ts'))]);
674
-
675
- let bin = await createPackageBin({
676
- bin: './src/cli.ts',
677
- bundles,
678
- cwd,
679
- isFlat: true,
680
- packageType: 'module',
681
- });
682
-
683
- expect(bin).toBe('./cli.js');
684
-
685
- bin = await createPackageBin({
686
- bin: './src/cli.ts',
687
- bundles: [bundles[1]], // only CJS bundle
688
- cwd,
689
- isFlat: true,
690
- });
691
-
692
- expect(bin).toBe('./cli.js');
693
-
694
- bin = await createPackageBin({
695
- bin: './src/cli.ts',
696
- bundles, // only CJS bundle
697
- cwd,
698
- isFlat: true,
699
- packageType: 'commonjs',
700
- });
701
-
702
- expect(bin).toBe('./cli.mjs');
703
- });
704
- });
705
- });