@mui/internal-code-infra 0.0.4-canary.6 → 0.0.4-canary.60
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.
- package/LICENSE +1 -1
- package/README.md +19 -8
- package/build/babel-config.d.mts +11 -3
- package/build/brokenLinksChecker/crawlWorker.d.mts +1 -0
- package/build/brokenLinksChecker/index.d.mts +45 -2
- package/build/changelog/types.d.ts +1 -1
- package/build/cli/cmdArgosPush.d.mts +2 -2
- package/build/cli/cmdBuild.d.mts +3 -2
- package/build/cli/cmdCopyFiles.d.mts +2 -2
- package/build/cli/cmdExtractErrorCodes.d.mts +2 -2
- package/build/cli/cmdGenerateChangelog.d.mts +2 -2
- package/build/cli/cmdGithubAuth.d.mts +2 -2
- package/build/cli/cmdListWorkspaces.d.mts +6 -4
- package/build/cli/cmdNetlifyIgnore.d.mts +3 -2
- package/build/cli/cmdPublish.d.mts +4 -2
- package/build/cli/cmdPublishCanary.d.mts +3 -3
- package/build/cli/cmdPublishNewPackage.d.mts +4 -2
- package/build/cli/cmdSetVersionOverrides.d.mts +2 -2
- package/build/cli/cmdVale.d.mts +46 -0
- package/build/cli/cmdValidateBuiltTypes.d.mts +2 -2
- package/build/eslint/baseConfig.d.mts +3 -1
- package/build/eslint/mui/rules/disallow-react-api-in-server-components.d.mts +2 -2
- package/build/eslint/mui/rules/docgen-ignore-before-comment.d.mts +2 -2
- package/build/eslint/mui/rules/no-guarded-throw.d.mts +31 -0
- package/build/eslint/mui/rules/no-presentation-role.d.mts +5 -0
- package/build/eslint/mui/rules/no-restricted-resolved-imports.d.mts +2 -2
- package/build/eslint/mui/rules/nodeEnvUtils.d.mts +18 -0
- package/build/markdownlint/duplicate-h1.d.mts +1 -1
- package/build/markdownlint/git-diff.d.mts +1 -1
- package/build/markdownlint/index.d.mts +1 -1
- package/build/markdownlint/straight-quotes.d.mts +1 -1
- package/build/markdownlint/table-alignment.d.mts +1 -1
- package/build/markdownlint/terminal-language.d.mts +1 -1
- package/build/remark/config.d.mts +43 -0
- package/build/remark/createLintTester.d.mts +10 -0
- package/build/remark/firstBlockHeading.d.mts +4 -0
- package/build/remark/gitDiff.d.mts +2 -0
- package/build/remark/noSpaceInLinks.d.mts +2 -0
- package/build/remark/straightQuotes.d.mts +2 -0
- package/build/remark/tableAlignment.d.mts +2 -0
- package/build/remark/terminalLanguage.d.mts +2 -0
- package/build/utils/babel.d.mts +1 -1
- package/build/utils/build.d.mts +61 -25
- package/build/utils/github.d.mts +1 -1
- package/build/utils/pnpm.d.mts +68 -2
- package/build/utils/testUtils.d.mts +7 -0
- package/build/utils/typescript.d.mts +2 -2
- package/package.json +61 -34
- package/src/babel-config.mjs +9 -3
- package/src/brokenLinksChecker/__fixtures__/static-site/index.html +1 -0
- package/src/brokenLinksChecker/__fixtures__/static-site/invalid-html.html +15 -0
- package/src/brokenLinksChecker/crawlWorker.mjs +217 -0
- package/src/brokenLinksChecker/index.mjs +217 -164
- package/src/brokenLinksChecker/index.test.ts +50 -13
- package/src/changelog/categorizeCommits.test.ts +5 -5
- package/src/changelog/fetchChangelogs.mjs +6 -2
- package/src/changelog/parseCommitLabels.test.ts +5 -5
- package/src/changelog/renderChangelog.mjs +1 -1
- package/src/changelog/types.ts +1 -1
- package/src/cli/cmdBuild.mjs +39 -16
- package/src/cli/cmdListWorkspaces.mjs +12 -27
- package/src/cli/cmdNetlifyIgnore.mjs +34 -93
- package/src/cli/cmdPublish.mjs +55 -15
- package/src/cli/cmdPublishCanary.mjs +128 -132
- package/src/cli/cmdPublishNewPackage.mjs +27 -6
- package/src/cli/cmdVale.mjs +513 -0
- package/src/cli/cmdVale.test.mjs +644 -0
- package/src/cli/index.mjs +2 -0
- package/src/cli/packageJson.d.ts +1 -1
- package/src/eslint/baseConfig.mjs +45 -20
- package/src/eslint/docsConfig.mjs +4 -2
- package/src/eslint/jsonConfig.mjs +2 -1
- package/src/eslint/mui/config.mjs +24 -4
- package/src/eslint/mui/index.mjs +4 -0
- package/src/eslint/mui/rules/no-guarded-throw.mjs +115 -0
- package/src/eslint/mui/rules/no-guarded-throw.test.mjs +206 -0
- package/src/eslint/mui/rules/no-presentation-role.mjs +60 -0
- package/src/eslint/mui/rules/no-presentation-role.test.mjs +33 -0
- package/src/eslint/mui/rules/nodeEnvUtils.mjs +52 -0
- package/src/eslint/mui/rules/require-dev-wrapper.mjs +25 -40
- package/src/eslint/testConfig.mjs +2 -1
- package/src/estree-typescript.d.ts +1 -1
- package/src/remark/config.mjs +157 -0
- package/src/remark/createLintTester.mjs +19 -0
- package/src/remark/firstBlockHeading.mjs +87 -0
- package/src/remark/firstBlockHeading.test.mjs +107 -0
- package/src/remark/gitDiff.mjs +43 -0
- package/src/remark/gitDiff.test.mjs +45 -0
- package/src/remark/noSpaceInLinks.mjs +42 -0
- package/src/remark/noSpaceInLinks.test.mjs +22 -0
- package/src/remark/straightQuotes.mjs +31 -0
- package/src/remark/straightQuotes.test.mjs +25 -0
- package/src/remark/tableAlignment.mjs +23 -0
- package/src/remark/tableAlignment.test.mjs +28 -0
- package/src/remark/terminalLanguage.mjs +19 -0
- package/src/remark/terminalLanguage.test.mjs +17 -0
- package/src/untyped-plugins.d.ts +11 -11
- package/src/utils/build.mjs +621 -256
- package/src/utils/build.test.mjs +1064 -485
- package/src/utils/git.mjs +16 -7
- package/src/utils/pnpm.mjs +192 -3
- package/src/utils/pnpm.test.mjs +580 -0
- package/src/utils/testUtils.mjs +18 -0
- package/src/utils/typescript.test.mjs +249 -272
- package/vale/.vale.ini +1 -0
- package/vale/styles/MUI/CorrectReferenceAllCases.yml +43 -0
- package/vale/styles/MUI/CorrectRererenceCased.yml +14 -0
- package/vale/styles/MUI/GoogleLatin.yml +11 -0
- package/vale/styles/MUI/MuiBrandName.yml +22 -0
- package/vale/styles/MUI/NoBritish.yml +112 -0
- package/vale/styles/MUI/NoCompanyName.yml +17 -0
package/src/utils/build.test.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
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
|
-
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
5
4
|
|
|
6
|
-
import {
|
|
5
|
+
import { makeTempDir } from './testUtils.mjs';
|
|
6
|
+
import { createPackageBin, createPackageExports, createPackageImports } from './build.mjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @param {string} filePath
|
|
@@ -14,692 +14,1271 @@ async function createFile(filePath, contents = '') {
|
|
|
14
14
|
await fs.writeFile(filePath, contents, 'utf8');
|
|
15
15
|
}
|
|
16
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
17
|
describe('createPackageExports', () => {
|
|
30
|
-
it('
|
|
31
|
-
await
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
18
|
+
it('always puts import before require regardless of bundle array order', async () => {
|
|
19
|
+
const cwd = await makeTempDir();
|
|
20
|
+
const outputDir = path.join(cwd, 'build');
|
|
21
|
+
|
|
22
|
+
await Promise.all([
|
|
23
|
+
createFile(path.join(cwd, 'src/index.ts')),
|
|
24
|
+
createFile(path.join(cwd, 'src/feature.ts')),
|
|
25
|
+
createFile(path.join(outputDir, 'index.js')),
|
|
26
|
+
createFile(path.join(outputDir, 'index.cjs')),
|
|
27
|
+
createFile(path.join(outputDir, 'feature.js')),
|
|
28
|
+
createFile(path.join(outputDir, 'feature.cjs')),
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
// Pass cjs before esm to verify the key order is still 'import' then 'require'
|
|
32
|
+
const { exports: packageExports } = await createPackageExports(
|
|
33
|
+
{
|
|
34
|
+
'.': './src/index.ts',
|
|
35
|
+
'./feature': './src/feature.ts',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
bundles: [
|
|
39
|
+
{ type: 'cjs', dir: '.' },
|
|
40
|
+
{ type: 'esm', dir: '.' },
|
|
41
|
+
],
|
|
42
|
+
outputDir,
|
|
43
|
+
cwd,
|
|
44
|
+
isFlat: true,
|
|
45
|
+
packageType: 'module',
|
|
46
|
+
},
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
expect(Object.keys(/** @type {Record<string, unknown>} */ (packageExports['.']))).toEqual([
|
|
50
|
+
'import',
|
|
51
|
+
'require',
|
|
52
|
+
'default',
|
|
53
|
+
]);
|
|
54
|
+
expect(
|
|
55
|
+
Object.keys(/** @type {Record<string, unknown>} */ (packageExports['./feature'])),
|
|
56
|
+
).toEqual(['import', 'require', 'default']);
|
|
57
|
+
});
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
it('creates exports for a dual bundle module package', async () => {
|
|
60
|
+
const cwd = await makeTempDir();
|
|
61
|
+
const outputDir = path.join(cwd, 'build');
|
|
62
|
+
/**
|
|
63
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
64
|
+
*/
|
|
65
|
+
const bundles = [
|
|
66
|
+
{ type: 'esm', dir: '.' },
|
|
67
|
+
{ type: 'cjs', dir: '.' },
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
await Promise.all([
|
|
71
|
+
createFile(path.join(cwd, 'src/index.ts')),
|
|
72
|
+
createFile(path.join(cwd, 'src/feature.ts')),
|
|
73
|
+
|
|
74
|
+
// Create output files for index
|
|
75
|
+
createFile(path.join(outputDir, `index.js`)),
|
|
76
|
+
createFile(path.join(outputDir, `index.cjs`)),
|
|
77
|
+
createFile(path.join(outputDir, `index.d.ts`)),
|
|
78
|
+
createFile(path.join(outputDir, `index.d.cts`)),
|
|
79
|
+
|
|
80
|
+
// Create output files for feature
|
|
81
|
+
createFile(path.join(outputDir, `feature.js`)),
|
|
82
|
+
createFile(path.join(outputDir, `feature.cjs`)),
|
|
83
|
+
createFile(path.join(outputDir, `feature.d.ts`)),
|
|
84
|
+
createFile(path.join(outputDir, `feature.d.cts`)),
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
const {
|
|
88
|
+
exports: packageExports,
|
|
89
|
+
main,
|
|
90
|
+
types,
|
|
91
|
+
} = await createPackageExports(
|
|
92
|
+
{
|
|
93
|
+
'.': './src/index.ts',
|
|
94
|
+
'./feature': './src/feature.ts',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
67
97
|
bundles,
|
|
68
98
|
outputDir,
|
|
69
99
|
cwd,
|
|
70
100
|
addTypes: true,
|
|
71
101
|
isFlat: true,
|
|
72
102
|
packageType: 'module',
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
103
|
+
},
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
expect(main).toBe('./index.cjs');
|
|
107
|
+
expect(types).toBe('./index.d.cts');
|
|
108
|
+
|
|
109
|
+
expect(packageExports['.']).toEqual({
|
|
110
|
+
import: { types: './index.d.ts', default: './index.js' },
|
|
111
|
+
require: { types: './index.d.cts', default: './index.cjs' },
|
|
112
|
+
default: {
|
|
113
|
+
types: './index.d.ts',
|
|
114
|
+
default: './index.js',
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
expect(packageExports['./feature']).toEqual({
|
|
118
|
+
import: { types: './feature.d.ts', default: './feature.js' },
|
|
119
|
+
require: { types: './feature.d.cts', default: './feature.cjs' },
|
|
120
|
+
default: {
|
|
121
|
+
types: './feature.d.ts',
|
|
122
|
+
default: './feature.js',
|
|
123
|
+
},
|
|
124
|
+
});
|
|
94
125
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
126
|
+
const {
|
|
127
|
+
exports: packageExports2,
|
|
128
|
+
main: main2,
|
|
129
|
+
types: types2,
|
|
130
|
+
} = await createPackageExports(
|
|
131
|
+
{
|
|
132
|
+
'.': './src/index.ts',
|
|
133
|
+
'./feature': './src/feature.ts',
|
|
134
|
+
},
|
|
135
|
+
{
|
|
104
136
|
bundles: [bundles[1]], // only CJS bundle
|
|
105
137
|
outputDir,
|
|
106
138
|
cwd,
|
|
107
139
|
addTypes: true,
|
|
108
140
|
isFlat: true,
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
141
|
+
},
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
expect(main2).toBe('./index.js');
|
|
145
|
+
expect(types2).toBe('./index.d.ts');
|
|
146
|
+
|
|
147
|
+
expect(packageExports2['.']).toEqual({
|
|
148
|
+
require: { types: './index.d.ts', default: './index.js' },
|
|
149
|
+
default: {
|
|
150
|
+
types: './index.d.ts',
|
|
151
|
+
default: './index.js',
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
expect(packageExports2['./feature']).toEqual({
|
|
155
|
+
require: { types: './feature.d.ts', default: './feature.js' },
|
|
156
|
+
default: {
|
|
157
|
+
types: './feature.d.ts',
|
|
158
|
+
default: './feature.js',
|
|
159
|
+
},
|
|
128
160
|
});
|
|
129
161
|
});
|
|
130
162
|
|
|
131
163
|
describe('glob expansion', () => {
|
|
132
164
|
it('expands glob patterns in export keys and values', async () => {
|
|
133
|
-
await
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
165
|
+
const cwd = await makeTempDir();
|
|
166
|
+
const outputDir = path.join(cwd, 'build');
|
|
167
|
+
/**
|
|
168
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
169
|
+
*/
|
|
170
|
+
const bundles = [
|
|
171
|
+
{ type: 'esm', dir: '.' },
|
|
172
|
+
{ type: 'cjs', dir: '.' },
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
await Promise.all([
|
|
176
|
+
createFile(path.join(cwd, 'src/Button.ts')),
|
|
177
|
+
createFile(path.join(cwd, 'src/TextField.ts')),
|
|
178
|
+
|
|
179
|
+
// Output files
|
|
180
|
+
createFile(path.join(outputDir, 'Button.js')),
|
|
181
|
+
createFile(path.join(outputDir, 'Button.cjs')),
|
|
182
|
+
createFile(path.join(outputDir, 'Button.d.ts')),
|
|
183
|
+
createFile(path.join(outputDir, 'Button.d.cts')),
|
|
184
|
+
createFile(path.join(outputDir, 'TextField.js')),
|
|
185
|
+
createFile(path.join(outputDir, 'TextField.cjs')),
|
|
186
|
+
createFile(path.join(outputDir, 'TextField.d.ts')),
|
|
187
|
+
createFile(path.join(outputDir, 'TextField.d.cts')),
|
|
188
|
+
]);
|
|
189
|
+
|
|
190
|
+
const { exports: packageExports } = await createPackageExports(
|
|
191
|
+
{
|
|
192
|
+
'./*': './src/*.ts',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
162
195
|
bundles,
|
|
163
196
|
outputDir,
|
|
164
197
|
cwd,
|
|
165
198
|
addTypes: true,
|
|
166
199
|
isFlat: true,
|
|
167
200
|
packageType: 'module',
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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();
|
|
201
|
+
},
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
expect(packageExports['./Button']).toEqual({
|
|
205
|
+
import: { types: './Button.d.ts', default: './Button.js' },
|
|
206
|
+
require: { types: './Button.d.cts', default: './Button.cjs' },
|
|
207
|
+
default: { types: './Button.d.ts', default: './Button.js' },
|
|
182
208
|
});
|
|
209
|
+
expect(packageExports['./TextField']).toEqual({
|
|
210
|
+
import: { types: './TextField.d.ts', default: './TextField.js' },
|
|
211
|
+
require: { types: './TextField.d.cts', default: './TextField.cjs' },
|
|
212
|
+
default: { types: './TextField.d.ts', default: './TextField.js' },
|
|
213
|
+
});
|
|
214
|
+
// glob key should not appear in the output
|
|
215
|
+
expect(packageExports['./*']).toBeUndefined();
|
|
183
216
|
});
|
|
184
217
|
|
|
185
218
|
it('expands glob with commonjs package type', async () => {
|
|
186
|
-
await
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
219
|
+
const cwd = await makeTempDir();
|
|
220
|
+
const outputDir = path.join(cwd, 'build');
|
|
221
|
+
/**
|
|
222
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
223
|
+
*/
|
|
224
|
+
const bundles = [
|
|
225
|
+
{ type: 'esm', dir: '.' },
|
|
226
|
+
{ type: 'cjs', dir: '.' },
|
|
227
|
+
];
|
|
195
228
|
|
|
196
|
-
|
|
197
|
-
|
|
229
|
+
await Promise.all([
|
|
230
|
+
createFile(path.join(cwd, 'src/Button.ts')),
|
|
198
231
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
232
|
+
createFile(path.join(outputDir, 'Button.js')),
|
|
233
|
+
createFile(path.join(outputDir, 'Button.mjs')),
|
|
234
|
+
createFile(path.join(outputDir, 'Button.d.ts')),
|
|
235
|
+
createFile(path.join(outputDir, 'Button.d.mts')),
|
|
236
|
+
]);
|
|
204
237
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
238
|
+
const { exports: packageExports } = await createPackageExports(
|
|
239
|
+
{
|
|
240
|
+
'./*': './src/*.ts',
|
|
241
|
+
},
|
|
242
|
+
{
|
|
209
243
|
bundles,
|
|
210
244
|
outputDir,
|
|
211
245
|
cwd,
|
|
212
246
|
addTypes: true,
|
|
213
247
|
isFlat: true,
|
|
214
248
|
packageType: 'commonjs',
|
|
215
|
-
}
|
|
249
|
+
},
|
|
250
|
+
);
|
|
216
251
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
});
|
|
252
|
+
expect(packageExports['./Button']).toEqual({
|
|
253
|
+
import: { types: './Button.d.mts', default: './Button.mjs' },
|
|
254
|
+
require: { types: './Button.d.ts', default: './Button.js' },
|
|
255
|
+
default: { types: './Button.d.mts', default: './Button.mjs' },
|
|
222
256
|
});
|
|
223
257
|
});
|
|
224
258
|
|
|
225
259
|
it('expands glob with single CJS bundle', async () => {
|
|
226
|
-
await
|
|
227
|
-
|
|
260
|
+
const cwd = await makeTempDir();
|
|
261
|
+
const outputDir = path.join(cwd, 'build');
|
|
228
262
|
|
|
229
|
-
|
|
230
|
-
|
|
263
|
+
await Promise.all([
|
|
264
|
+
createFile(path.join(cwd, 'src/Button.ts')),
|
|
231
265
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
266
|
+
createFile(path.join(outputDir, 'Button.js')),
|
|
267
|
+
createFile(path.join(outputDir, 'Button.d.ts')),
|
|
268
|
+
]);
|
|
235
269
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
270
|
+
const { exports: packageExports } = await createPackageExports(
|
|
271
|
+
{
|
|
272
|
+
'./*': './src/*.ts',
|
|
273
|
+
},
|
|
274
|
+
{
|
|
240
275
|
bundles: [{ type: 'cjs', dir: '.' }],
|
|
241
276
|
outputDir,
|
|
242
277
|
cwd,
|
|
243
278
|
addTypes: true,
|
|
244
279
|
isFlat: true,
|
|
245
280
|
packageType: 'commonjs',
|
|
246
|
-
}
|
|
281
|
+
},
|
|
282
|
+
);
|
|
247
283
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
});
|
|
284
|
+
expect(packageExports['./Button']).toEqual({
|
|
285
|
+
require: { types: './Button.d.ts', default: './Button.js' },
|
|
286
|
+
default: { types: './Button.d.ts', default: './Button.js' },
|
|
252
287
|
});
|
|
253
288
|
});
|
|
254
289
|
|
|
255
|
-
it('
|
|
256
|
-
await
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
await Promise.all([
|
|
267
|
-
createFile(path.join(cwd, 'src/Alert.ts')),
|
|
290
|
+
it('rewrites source paths inside sibling conditions when expanding globs', async () => {
|
|
291
|
+
const cwd = await makeTempDir();
|
|
292
|
+
const outputDir = path.join(cwd, 'build');
|
|
293
|
+
/**
|
|
294
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
295
|
+
*/
|
|
296
|
+
const bundles = [
|
|
297
|
+
{ type: 'esm', dir: '.' },
|
|
298
|
+
{ type: 'cjs', dir: '.' },
|
|
299
|
+
];
|
|
268
300
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
301
|
+
await Promise.all([
|
|
302
|
+
createFile(path.join(cwd, 'src/Alert.ts')),
|
|
303
|
+
createFile(path.join(cwd, 'src/node/Alert.ts')),
|
|
304
|
+
]);
|
|
272
305
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
306
|
+
const { exports: packageExports } = await createPackageExports(
|
|
307
|
+
{
|
|
308
|
+
'./*': { node: './src/node/*.ts', default: './src/*.ts' },
|
|
309
|
+
},
|
|
310
|
+
{
|
|
277
311
|
bundles,
|
|
278
312
|
outputDir,
|
|
279
313
|
cwd,
|
|
280
314
|
isFlat: true,
|
|
281
315
|
packageType: 'module',
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
|
|
316
|
+
},
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
// Every condition's source path is rewritten (no verbatim `./src/...`),
|
|
320
|
+
// and conditions stay outer with the import/require split at the leaves.
|
|
321
|
+
expect(packageExports['./Alert']).toEqual({
|
|
322
|
+
node: {
|
|
323
|
+
import: './node/Alert.js',
|
|
324
|
+
require: './node/Alert.cjs',
|
|
325
|
+
default: './node/Alert.js',
|
|
326
|
+
},
|
|
327
|
+
default: {
|
|
285
328
|
import: './Alert.js',
|
|
286
329
|
require: './Alert.cjs',
|
|
287
330
|
default: './Alert.js',
|
|
288
|
-
}
|
|
331
|
+
},
|
|
289
332
|
});
|
|
290
333
|
});
|
|
291
334
|
|
|
292
|
-
it('
|
|
293
|
-
await
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
await Promise.all([
|
|
304
|
-
createFile(path.join(cwd, 'src/Alert.ts')),
|
|
335
|
+
it('omits a sibling condition for stems its glob does not match', async () => {
|
|
336
|
+
const cwd = await makeTempDir();
|
|
337
|
+
const outputDir = path.join(cwd, 'build');
|
|
338
|
+
/**
|
|
339
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
340
|
+
*/
|
|
341
|
+
const bundles = [
|
|
342
|
+
{ type: 'esm', dir: '.' },
|
|
343
|
+
{ type: 'cjs', dir: '.' },
|
|
344
|
+
];
|
|
305
345
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
346
|
+
await Promise.all([
|
|
347
|
+
createFile(path.join(cwd, 'src/Alert.ts')),
|
|
348
|
+
createFile(path.join(cwd, 'src/Button.ts')),
|
|
349
|
+
// Only Alert has a node variant.
|
|
350
|
+
createFile(path.join(cwd, 'src/node/Alert.ts')),
|
|
351
|
+
]);
|
|
309
352
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
353
|
+
const { exports: packageExports } = await createPackageExports(
|
|
354
|
+
{
|
|
355
|
+
'./*': { node: './src/node/*.ts', default: './src/*.ts' },
|
|
356
|
+
},
|
|
357
|
+
{
|
|
314
358
|
bundles,
|
|
315
359
|
outputDir,
|
|
316
360
|
cwd,
|
|
317
361
|
isFlat: true,
|
|
318
362
|
packageType: 'module',
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
363
|
+
},
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
// Alert keeps its node condition.
|
|
367
|
+
expect(packageExports['./Alert']).toEqual({
|
|
368
|
+
node: {
|
|
369
|
+
import: './node/Alert.js',
|
|
370
|
+
require: './node/Alert.cjs',
|
|
371
|
+
default: './node/Alert.js',
|
|
372
|
+
},
|
|
373
|
+
default: { import: './Alert.js', require: './Alert.cjs', default: './Alert.js' },
|
|
374
|
+
});
|
|
375
|
+
// Button has no node variant, so the node condition is dropped rather than
|
|
376
|
+
// pointing at a non-existent source (which would fail the build).
|
|
377
|
+
expect(packageExports['./Button']).toEqual({
|
|
378
|
+
default: { import: './Button.js', require: './Button.cjs', default: './Button.js' },
|
|
326
379
|
});
|
|
327
380
|
});
|
|
328
381
|
|
|
329
|
-
it('
|
|
330
|
-
await
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
334
|
-
*/
|
|
335
|
-
const bundles = [
|
|
336
|
-
{ type: 'esm', dir: '.' },
|
|
337
|
-
{ type: 'cjs', dir: '.' },
|
|
338
|
-
];
|
|
382
|
+
it('enumerates a wildcard directory pattern', async () => {
|
|
383
|
+
const cwd = await makeTempDir();
|
|
384
|
+
const outputDir = path.join(cwd, 'build');
|
|
339
385
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
386
|
+
await Promise.all([
|
|
387
|
+
createFile(path.join(cwd, 'src/tabs/script.ts')),
|
|
388
|
+
createFile(path.join(cwd, 'src/menu/script.ts')),
|
|
389
|
+
]);
|
|
390
|
+
|
|
391
|
+
const { exports: packageExports } = await createPackageExports(
|
|
392
|
+
{
|
|
393
|
+
'./*': './src/*/script.ts',
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
bundles: [{ type: 'cjs', dir: '.' }],
|
|
397
|
+
outputDir,
|
|
398
|
+
cwd,
|
|
399
|
+
isFlat: true,
|
|
400
|
+
},
|
|
401
|
+
);
|
|
402
|
+
|
|
403
|
+
expect(packageExports['./tabs']).toEqual({
|
|
404
|
+
require: './tabs/script.js',
|
|
405
|
+
default: './tabs/script.js',
|
|
406
|
+
});
|
|
407
|
+
expect(packageExports['./menu']).toEqual({
|
|
408
|
+
require: './menu/script.js',
|
|
409
|
+
default: './menu/script.js',
|
|
410
|
+
});
|
|
411
|
+
});
|
|
343
412
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
]);
|
|
413
|
+
it('warns and produces nothing when a glob matches no files', async () => {
|
|
414
|
+
const cwd = await makeTempDir();
|
|
415
|
+
const outputDir = path.join(cwd, 'build');
|
|
416
|
+
createFile(path.join(cwd, 'src/.gitkeep'));
|
|
349
417
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
418
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
419
|
+
try {
|
|
420
|
+
const { exports: packageExports } = await createPackageExports(
|
|
421
|
+
{
|
|
353
422
|
'./*': './src/*.ts',
|
|
354
423
|
},
|
|
424
|
+
{
|
|
425
|
+
bundles: [{ type: 'cjs', dir: '.' }],
|
|
426
|
+
outputDir,
|
|
427
|
+
cwd,
|
|
428
|
+
isFlat: true,
|
|
429
|
+
},
|
|
430
|
+
);
|
|
431
|
+
|
|
432
|
+
expect(Object.keys(packageExports)).toEqual(['./package.json']);
|
|
433
|
+
expect(warn).toHaveBeenCalled();
|
|
434
|
+
} finally {
|
|
435
|
+
warn.mockRestore();
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
it('mixes glob and non-glob exports', async () => {
|
|
440
|
+
const cwd = await makeTempDir();
|
|
441
|
+
const outputDir = path.join(cwd, 'build');
|
|
442
|
+
/**
|
|
443
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
444
|
+
*/
|
|
445
|
+
const bundles = [
|
|
446
|
+
{ type: 'esm', dir: '.' },
|
|
447
|
+
{ type: 'cjs', dir: '.' },
|
|
448
|
+
];
|
|
449
|
+
|
|
450
|
+
await Promise.all([
|
|
451
|
+
createFile(path.join(cwd, 'src/index.ts')),
|
|
452
|
+
createFile(path.join(cwd, 'src/Chip.ts')),
|
|
453
|
+
|
|
454
|
+
createFile(path.join(outputDir, 'index.js')),
|
|
455
|
+
createFile(path.join(outputDir, 'index.cjs')),
|
|
456
|
+
createFile(path.join(outputDir, 'Chip.js')),
|
|
457
|
+
createFile(path.join(outputDir, 'Chip.cjs')),
|
|
458
|
+
]);
|
|
459
|
+
|
|
460
|
+
const { exports: packageExports } = await createPackageExports(
|
|
461
|
+
{
|
|
462
|
+
'.': './src/index.ts',
|
|
463
|
+
'./*': './src/*.ts',
|
|
464
|
+
},
|
|
465
|
+
{
|
|
355
466
|
bundles,
|
|
356
467
|
outputDir,
|
|
357
468
|
cwd,
|
|
358
469
|
isFlat: true,
|
|
359
470
|
packageType: 'module',
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
471
|
+
},
|
|
472
|
+
);
|
|
473
|
+
|
|
474
|
+
// Explicit export still works
|
|
475
|
+
expect(packageExports['.']).toBeDefined();
|
|
476
|
+
// Glob-expanded export
|
|
477
|
+
expect(packageExports['./Chip']).toEqual({
|
|
478
|
+
import: './Chip.js',
|
|
479
|
+
require: './Chip.cjs',
|
|
480
|
+
default: './Chip.js',
|
|
370
481
|
});
|
|
371
482
|
});
|
|
372
483
|
|
|
373
484
|
it('expands glob with subdirectory pattern', async () => {
|
|
374
|
-
await
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
485
|
+
const cwd = await makeTempDir();
|
|
486
|
+
const outputDir = path.join(cwd, 'build');
|
|
487
|
+
/**
|
|
488
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
489
|
+
*/
|
|
490
|
+
const bundles = [
|
|
491
|
+
{ type: 'esm', dir: '.' },
|
|
492
|
+
{ type: 'cjs', dir: '.' },
|
|
493
|
+
];
|
|
383
494
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
495
|
+
await Promise.all([
|
|
496
|
+
createFile(path.join(cwd, 'src/utils/color.ts')),
|
|
497
|
+
createFile(path.join(cwd, 'src/utils/size.ts')),
|
|
387
498
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
499
|
+
createFile(path.join(outputDir, 'utils/color.js')),
|
|
500
|
+
createFile(path.join(outputDir, 'utils/color.cjs')),
|
|
501
|
+
createFile(path.join(outputDir, 'utils/size.js')),
|
|
502
|
+
createFile(path.join(outputDir, 'utils/size.cjs')),
|
|
503
|
+
]);
|
|
393
504
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
505
|
+
const { exports: packageExports } = await createPackageExports(
|
|
506
|
+
{
|
|
507
|
+
'./utils/*': './src/utils/*.ts',
|
|
508
|
+
},
|
|
509
|
+
{
|
|
398
510
|
bundles,
|
|
399
511
|
outputDir,
|
|
400
512
|
cwd,
|
|
401
513
|
isFlat: true,
|
|
402
514
|
packageType: 'module',
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
515
|
+
},
|
|
516
|
+
);
|
|
517
|
+
|
|
518
|
+
expect(packageExports['./utils/color']).toEqual({
|
|
519
|
+
import: './utils/color.js',
|
|
520
|
+
require: './utils/color.cjs',
|
|
521
|
+
default: './utils/color.js',
|
|
522
|
+
});
|
|
523
|
+
expect(packageExports['./utils/size']).toEqual({
|
|
524
|
+
import: './utils/size.js',
|
|
525
|
+
require: './utils/size.cjs',
|
|
526
|
+
default: './utils/size.js',
|
|
415
527
|
});
|
|
416
528
|
});
|
|
417
529
|
|
|
418
530
|
it('produces no entries when glob matches nothing', async () => {
|
|
419
|
-
await
|
|
420
|
-
|
|
531
|
+
const cwd = await makeTempDir();
|
|
532
|
+
const outputDir = path.join(cwd, 'build');
|
|
421
533
|
|
|
422
|
-
|
|
423
|
-
|
|
534
|
+
// Create the src directory but no .ts files in it
|
|
535
|
+
createFile(path.join(cwd, 'src/.gitkeep'));
|
|
424
536
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
537
|
+
const { exports: packageExports } = await createPackageExports(
|
|
538
|
+
{
|
|
539
|
+
'./*': './src/*.ts',
|
|
540
|
+
},
|
|
541
|
+
{
|
|
429
542
|
bundles: [{ type: 'cjs', dir: '.' }],
|
|
430
543
|
outputDir,
|
|
431
544
|
cwd,
|
|
432
545
|
isFlat: true,
|
|
433
|
-
}
|
|
546
|
+
},
|
|
547
|
+
);
|
|
434
548
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
});
|
|
549
|
+
// Only the default ./package.json entry should be present
|
|
550
|
+
expect(Object.keys(packageExports)).toEqual(['./package.json']);
|
|
438
551
|
});
|
|
439
552
|
|
|
440
553
|
it('expands globs in sorted order', async () => {
|
|
441
|
-
await
|
|
442
|
-
|
|
554
|
+
const cwd = await makeTempDir();
|
|
555
|
+
const outputDir = path.join(cwd, 'build');
|
|
443
556
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
557
|
+
await Promise.all([
|
|
558
|
+
createFile(path.join(cwd, 'src/Zebra.ts')),
|
|
559
|
+
createFile(path.join(cwd, 'src/Apple.ts')),
|
|
560
|
+
createFile(path.join(cwd, 'src/Mango.ts')),
|
|
448
561
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
562
|
+
createFile(path.join(outputDir, 'Zebra.js')),
|
|
563
|
+
createFile(path.join(outputDir, 'Apple.js')),
|
|
564
|
+
createFile(path.join(outputDir, 'Mango.js')),
|
|
565
|
+
]);
|
|
453
566
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
567
|
+
const { exports: packageExports } = await createPackageExports(
|
|
568
|
+
{
|
|
569
|
+
'./*': './src/*.ts',
|
|
570
|
+
},
|
|
571
|
+
{
|
|
458
572
|
bundles: [{ type: 'cjs', dir: '.' }],
|
|
459
573
|
outputDir,
|
|
460
574
|
cwd,
|
|
461
575
|
isFlat: true,
|
|
462
|
-
}
|
|
576
|
+
},
|
|
577
|
+
);
|
|
463
578
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
});
|
|
579
|
+
const exportKeys = Object.keys(packageExports).filter((k) => k !== './package.json');
|
|
580
|
+
expect(exportKeys).toEqual(['./Apple', './Mango', './Zebra']);
|
|
467
581
|
});
|
|
468
582
|
|
|
469
583
|
it('removes expanded entries matching a null-valued glob (negation)', async () => {
|
|
470
|
-
await
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
584
|
+
const cwd = await makeTempDir();
|
|
585
|
+
const outputDir = path.join(cwd, 'build');
|
|
586
|
+
/**
|
|
587
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
588
|
+
*/
|
|
589
|
+
const bundles = [
|
|
590
|
+
{ type: 'esm', dir: '.' },
|
|
591
|
+
{ type: 'cjs', dir: '.' },
|
|
592
|
+
];
|
|
593
|
+
|
|
594
|
+
await Promise.all([
|
|
595
|
+
createFile(path.join(cwd, 'src/Accordion.ts')),
|
|
596
|
+
createFile(path.join(cwd, 'src/Button.ts')),
|
|
597
|
+
createFile(path.join(cwd, 'src/ButtonBase.ts')),
|
|
598
|
+
|
|
599
|
+
createFile(path.join(outputDir, 'Accordion.js')),
|
|
600
|
+
createFile(path.join(outputDir, 'Accordion.cjs')),
|
|
601
|
+
createFile(path.join(outputDir, 'Button.js')),
|
|
602
|
+
createFile(path.join(outputDir, 'Button.cjs')),
|
|
603
|
+
createFile(path.join(outputDir, 'ButtonBase.js')),
|
|
604
|
+
createFile(path.join(outputDir, 'ButtonBase.cjs')),
|
|
605
|
+
]);
|
|
606
|
+
|
|
607
|
+
const { exports: packageExports } = await createPackageExports(
|
|
608
|
+
{
|
|
609
|
+
'./*': './src/*.ts',
|
|
610
|
+
'./Button*': null,
|
|
611
|
+
},
|
|
612
|
+
{
|
|
498
613
|
bundles,
|
|
499
614
|
outputDir,
|
|
500
615
|
cwd,
|
|
501
616
|
isFlat: true,
|
|
502
617
|
packageType: 'module',
|
|
503
|
-
}
|
|
618
|
+
},
|
|
619
|
+
);
|
|
504
620
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
});
|
|
621
|
+
expect(packageExports['./Accordion']).toBeDefined();
|
|
622
|
+
expect(packageExports['./Button']).toBeUndefined();
|
|
623
|
+
expect(packageExports['./ButtonBase']).toBeUndefined();
|
|
624
|
+
// The negation glob key itself should not appear
|
|
625
|
+
expect(packageExports['./Button*']).toBeUndefined();
|
|
511
626
|
});
|
|
512
627
|
|
|
513
628
|
it('negation with null removes only matching keys', async () => {
|
|
514
|
-
await
|
|
515
|
-
|
|
629
|
+
const cwd = await makeTempDir();
|
|
630
|
+
const outputDir = path.join(cwd, 'build');
|
|
516
631
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
632
|
+
await Promise.all([
|
|
633
|
+
createFile(path.join(cwd, 'src/Alert.ts')),
|
|
634
|
+
createFile(path.join(cwd, 'src/AlertTitle.ts')),
|
|
635
|
+
createFile(path.join(cwd, 'src/Button.ts')),
|
|
521
636
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
637
|
+
createFile(path.join(outputDir, 'Alert.js')),
|
|
638
|
+
createFile(path.join(outputDir, 'AlertTitle.js')),
|
|
639
|
+
createFile(path.join(outputDir, 'Button.js')),
|
|
640
|
+
]);
|
|
526
641
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
642
|
+
const { exports: packageExports } = await createPackageExports(
|
|
643
|
+
{
|
|
644
|
+
'./*': './src/*.ts',
|
|
645
|
+
'./Alert*': null,
|
|
646
|
+
},
|
|
647
|
+
{
|
|
532
648
|
bundles: [{ type: 'cjs', dir: '.' }],
|
|
533
649
|
outputDir,
|
|
534
650
|
cwd,
|
|
535
651
|
isFlat: true,
|
|
536
|
-
}
|
|
652
|
+
},
|
|
653
|
+
);
|
|
537
654
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
});
|
|
655
|
+
const exportKeys = Object.keys(packageExports).filter((k) => k !== './package.json');
|
|
656
|
+
expect(exportKeys).toEqual(['./Button']);
|
|
541
657
|
});
|
|
542
658
|
|
|
543
659
|
it('preserves null glob pattern when no keys match', async () => {
|
|
544
|
-
await
|
|
545
|
-
|
|
660
|
+
const cwd = await makeTempDir();
|
|
661
|
+
const outputDir = path.join(cwd, 'build');
|
|
546
662
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
663
|
+
await Promise.all([
|
|
664
|
+
createFile(path.join(cwd, 'src/Button.ts')),
|
|
665
|
+
createFile(path.join(outputDir, 'Button.js')),
|
|
666
|
+
]);
|
|
551
667
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
668
|
+
const { exports: packageExports } = await createPackageExports(
|
|
669
|
+
{
|
|
670
|
+
'./*': './src/*.ts',
|
|
671
|
+
'./internal/*': null,
|
|
672
|
+
},
|
|
673
|
+
{
|
|
557
674
|
bundles: [{ type: 'cjs', dir: '.' }],
|
|
558
675
|
outputDir,
|
|
559
676
|
cwd,
|
|
560
677
|
isFlat: true,
|
|
561
|
-
}
|
|
678
|
+
},
|
|
679
|
+
);
|
|
562
680
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
});
|
|
681
|
+
// Button is kept since it doesn't match the negation
|
|
682
|
+
expect(packageExports['./Button']).toBeDefined();
|
|
683
|
+
// The negation pattern is preserved as null since nothing matched it
|
|
684
|
+
expect(packageExports['./internal/*']).toBeNull();
|
|
568
685
|
});
|
|
569
686
|
|
|
570
|
-
it('does not expand glob patterns when
|
|
571
|
-
await
|
|
572
|
-
|
|
687
|
+
it('does not expand glob patterns when expand is false', async () => {
|
|
688
|
+
const cwd = await makeTempDir();
|
|
689
|
+
const outputDir = path.join(cwd, 'build');
|
|
573
690
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
691
|
+
await Promise.all([
|
|
692
|
+
createFile(path.join(cwd, 'src/Button.ts')),
|
|
693
|
+
createFile(path.join(cwd, 'src/TextField.ts')),
|
|
694
|
+
]);
|
|
578
695
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
696
|
+
const { exports: packageExports } = await createPackageExports(
|
|
697
|
+
{
|
|
698
|
+
'./*': './src/*.ts',
|
|
699
|
+
},
|
|
700
|
+
{
|
|
583
701
|
bundles: [{ type: 'cjs', dir: '.' }],
|
|
584
702
|
outputDir,
|
|
585
703
|
cwd,
|
|
586
704
|
isFlat: false,
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
705
|
+
expand: false,
|
|
706
|
+
},
|
|
707
|
+
);
|
|
708
|
+
|
|
709
|
+
// Glob should NOT be expanded to individual files
|
|
710
|
+
expect(packageExports['./Button']).toBeUndefined();
|
|
711
|
+
expect(packageExports['./TextField']).toBeUndefined();
|
|
712
|
+
// The raw glob pattern is passed through as-is
|
|
713
|
+
expect(packageExports['./*']).toEqual({
|
|
714
|
+
require: './*.js',
|
|
715
|
+
default: './*.js',
|
|
597
716
|
});
|
|
598
717
|
});
|
|
599
718
|
|
|
600
719
|
it('passes through glob key when value has no wildcard', async () => {
|
|
601
|
-
await
|
|
602
|
-
|
|
720
|
+
const cwd = await makeTempDir();
|
|
721
|
+
const outputDir = path.join(cwd, 'build');
|
|
603
722
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
723
|
+
await Promise.all([
|
|
724
|
+
createFile(path.join(cwd, 'src/index.ts')),
|
|
725
|
+
createFile(path.join(outputDir, 'index.js')),
|
|
726
|
+
]);
|
|
608
727
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
728
|
+
const { exports: packageExports } = await createPackageExports(
|
|
729
|
+
{
|
|
730
|
+
'./*': './src/index.ts',
|
|
731
|
+
},
|
|
732
|
+
{
|
|
613
733
|
bundles: [{ type: 'cjs', dir: '.' }],
|
|
614
734
|
outputDir,
|
|
615
735
|
cwd,
|
|
616
736
|
isFlat: true,
|
|
617
|
-
}
|
|
737
|
+
},
|
|
738
|
+
);
|
|
618
739
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
});
|
|
740
|
+
// When the value has no *, the glob key is passed through as-is
|
|
741
|
+
expect(packageExports['./*']).toBeDefined();
|
|
622
742
|
});
|
|
623
743
|
});
|
|
624
744
|
|
|
625
745
|
it('uses require/import and default for single bundle package', async () => {
|
|
626
|
-
await
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
746
|
+
const cwd = await makeTempDir();
|
|
747
|
+
const outputDir = path.join(cwd, 'build');
|
|
748
|
+
|
|
749
|
+
await Promise.all([
|
|
750
|
+
createFile(path.join(cwd, 'src/index.ts')),
|
|
751
|
+
createFile(path.join(outputDir, 'index.js')),
|
|
752
|
+
createFile(path.join(outputDir, 'index.d.ts')),
|
|
753
|
+
]);
|
|
754
|
+
|
|
755
|
+
const { exports: packageExports } = await createPackageExports(
|
|
756
|
+
{
|
|
757
|
+
'.': './src/index.ts',
|
|
758
|
+
},
|
|
759
|
+
{
|
|
639
760
|
bundles: [{ type: 'cjs', dir: '.' }],
|
|
640
761
|
outputDir,
|
|
641
762
|
cwd,
|
|
642
763
|
addTypes: true,
|
|
643
764
|
isFlat: true,
|
|
644
765
|
packageType: 'commonjs',
|
|
645
|
-
}
|
|
766
|
+
},
|
|
767
|
+
);
|
|
768
|
+
|
|
769
|
+
// Single CJS bundle should have both require and default pointing to the same files
|
|
770
|
+
expect(packageExports['.']).toEqual({
|
|
771
|
+
require: {
|
|
772
|
+
types: './index.d.ts',
|
|
773
|
+
default: './index.js',
|
|
774
|
+
},
|
|
775
|
+
default: {
|
|
776
|
+
types: './index.d.ts',
|
|
777
|
+
default: './index.js',
|
|
778
|
+
},
|
|
779
|
+
});
|
|
780
|
+
});
|
|
781
|
+
});
|
|
646
782
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
783
|
+
describe('createPackageExports leaf rewriting', () => {
|
|
784
|
+
it('rewrites a standard conditions object (conditions-outer)', async () => {
|
|
785
|
+
const cwd = await makeTempDir();
|
|
786
|
+
const outputDir = path.join(cwd, 'build');
|
|
787
|
+
/**
|
|
788
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
789
|
+
*/
|
|
790
|
+
const bundles = [
|
|
791
|
+
{ type: 'esm', dir: '.' },
|
|
792
|
+
{ type: 'cjs', dir: '.' },
|
|
793
|
+
];
|
|
794
|
+
|
|
795
|
+
await Promise.all([
|
|
796
|
+
createFile(path.join(cwd, 'src/feature.ts')),
|
|
797
|
+
createFile(path.join(cwd, 'src/node/feature.ts')),
|
|
798
|
+
]);
|
|
799
|
+
|
|
800
|
+
const { exports: packageExports } = await createPackageExports(
|
|
801
|
+
{
|
|
802
|
+
'./feature': { node: './src/node/feature.ts', default: './src/feature.ts' },
|
|
803
|
+
},
|
|
804
|
+
{
|
|
805
|
+
bundles,
|
|
806
|
+
outputDir,
|
|
807
|
+
cwd,
|
|
808
|
+
isFlat: true,
|
|
809
|
+
packageType: 'module',
|
|
810
|
+
},
|
|
811
|
+
);
|
|
812
|
+
|
|
813
|
+
expect(packageExports['./feature']).toEqual({
|
|
814
|
+
node: {
|
|
815
|
+
import: './node/feature.js',
|
|
816
|
+
require: './node/feature.cjs',
|
|
817
|
+
default: './node/feature.js',
|
|
818
|
+
},
|
|
819
|
+
default: {
|
|
820
|
+
import: './feature.js',
|
|
821
|
+
require: './feature.cjs',
|
|
822
|
+
default: './feature.js',
|
|
823
|
+
},
|
|
824
|
+
});
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
it('passes through paths that are not under src/ verbatim', async () => {
|
|
828
|
+
const cwd = await makeTempDir();
|
|
829
|
+
const outputDir = path.join(cwd, 'build');
|
|
830
|
+
|
|
831
|
+
await Promise.all([
|
|
832
|
+
createFile(path.join(outputDir, 'assets/logo.svg')),
|
|
833
|
+
createFile(path.join(outputDir, 'vendor/legacy.js')),
|
|
834
|
+
]);
|
|
835
|
+
|
|
836
|
+
const { exports: packageExports } = await createPackageExports(
|
|
837
|
+
{
|
|
838
|
+
'./logo': './assets/logo.svg',
|
|
839
|
+
'./legacy': './vendor/legacy.js',
|
|
840
|
+
},
|
|
841
|
+
{
|
|
842
|
+
bundles: [{ type: 'cjs', dir: '.' }],
|
|
843
|
+
outputDir,
|
|
844
|
+
cwd,
|
|
845
|
+
isFlat: true,
|
|
846
|
+
},
|
|
847
|
+
);
|
|
848
|
+
|
|
849
|
+
// Already present in the published output: emitted unchanged.
|
|
850
|
+
expect(packageExports['./logo']).toBe('./assets/logo.svg');
|
|
851
|
+
expect(packageExports['./legacy']).toBe('./vendor/legacy.js');
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
it('treats src/ without a leading ./ as a source path', async () => {
|
|
855
|
+
const cwd = await makeTempDir();
|
|
856
|
+
const outputDir = path.join(cwd, 'build');
|
|
857
|
+
|
|
858
|
+
await createFile(path.join(cwd, 'src/index.ts'));
|
|
859
|
+
|
|
860
|
+
const { exports: packageExports } = await createPackageExports(
|
|
861
|
+
{
|
|
862
|
+
'./entry': 'src/index.ts',
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
bundles: [{ type: 'cjs', dir: '.' }],
|
|
866
|
+
outputDir,
|
|
867
|
+
cwd,
|
|
868
|
+
isFlat: true,
|
|
869
|
+
},
|
|
870
|
+
);
|
|
871
|
+
|
|
872
|
+
expect(packageExports['./entry']).toEqual({
|
|
873
|
+
require: './index.js',
|
|
874
|
+
default: './index.js',
|
|
875
|
+
});
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
it('rewrites the prefix of a non-JS asset under src/ without an extension swap', async () => {
|
|
879
|
+
const cwd = await makeTempDir();
|
|
880
|
+
const outputDir = path.join(cwd, 'build');
|
|
881
|
+
|
|
882
|
+
await createFile(path.join(cwd, 'src/theme.css'));
|
|
883
|
+
|
|
884
|
+
const { exports: packageExports } = await createPackageExports(
|
|
885
|
+
{
|
|
886
|
+
'./theme.css': './src/theme.css',
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
bundles: [{ type: 'cjs', dir: '.' }],
|
|
890
|
+
outputDir,
|
|
891
|
+
cwd,
|
|
892
|
+
isFlat: true,
|
|
893
|
+
},
|
|
894
|
+
);
|
|
895
|
+
|
|
896
|
+
expect(packageExports['./theme.css']).toBe('./theme.css');
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
it('preserves a user-authored default alongside import/require conditions', async () => {
|
|
900
|
+
const cwd = await makeTempDir();
|
|
901
|
+
const outputDir = path.join(cwd, 'build');
|
|
902
|
+
/**
|
|
903
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
904
|
+
*/
|
|
905
|
+
const bundles = [
|
|
906
|
+
{ type: 'esm', dir: '.' },
|
|
907
|
+
{ type: 'cjs', dir: '.' },
|
|
908
|
+
];
|
|
909
|
+
|
|
910
|
+
await Promise.all([
|
|
911
|
+
createFile(path.join(cwd, 'src/esm.ts')),
|
|
912
|
+
createFile(path.join(cwd, 'src/fallback.ts')),
|
|
913
|
+
]);
|
|
914
|
+
|
|
915
|
+
const { exports: packageExports } = await createPackageExports(
|
|
916
|
+
{
|
|
917
|
+
'./x': { import: './src/esm.ts', default: './src/fallback.ts' },
|
|
918
|
+
},
|
|
919
|
+
{
|
|
920
|
+
bundles,
|
|
921
|
+
outputDir,
|
|
922
|
+
cwd,
|
|
923
|
+
isFlat: true,
|
|
924
|
+
packageType: 'module',
|
|
925
|
+
},
|
|
926
|
+
);
|
|
927
|
+
|
|
928
|
+
// The synthesized default must not clobber the user's `default` branch.
|
|
929
|
+
expect(packageExports['./x']).toEqual({
|
|
930
|
+
import: { import: './esm.js', require: './esm.cjs', default: './esm.js' },
|
|
931
|
+
default: { import: './fallback.js', require: './fallback.cjs', default: './fallback.js' },
|
|
932
|
+
});
|
|
933
|
+
});
|
|
934
|
+
});
|
|
935
|
+
|
|
936
|
+
describe('createPackageExports resolution semantics', () => {
|
|
937
|
+
/**
|
|
938
|
+
* Seeds the worked example with files so the shallow and deep patterns match.
|
|
939
|
+
* @param {string} cwd
|
|
940
|
+
*/
|
|
941
|
+
async function seedWorkedExample(cwd) {
|
|
942
|
+
await Promise.all([
|
|
943
|
+
createFile(path.join(cwd, 'src/foo/x.ts')),
|
|
944
|
+
createFile(path.join(cwd, 'src/foo/bar/baz/z.ts')),
|
|
945
|
+
]);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
const workedExampleExports = {
|
|
949
|
+
'./foo/*': './src/foo/*.ts',
|
|
950
|
+
'./foo/bar/*': null,
|
|
951
|
+
'./foo/bar/baz/*': './src/foo/bar/baz/*.ts',
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
it('enumerates with Node-faithful, non-cascading negation (expand: true)', async () => {
|
|
955
|
+
const cwd = await makeTempDir();
|
|
956
|
+
const outputDir = path.join(cwd, 'build');
|
|
957
|
+
await seedWorkedExample(cwd);
|
|
958
|
+
|
|
959
|
+
const { exports: packageExports } = await createPackageExports(workedExampleExports, {
|
|
960
|
+
bundles: [{ type: 'cjs', dir: '.' }],
|
|
961
|
+
outputDir,
|
|
962
|
+
cwd,
|
|
963
|
+
isFlat: true,
|
|
964
|
+
});
|
|
965
|
+
|
|
966
|
+
// ./foo/x resolves (matched only by the shallow pattern)
|
|
967
|
+
expect(packageExports['./foo/x']).toEqual({
|
|
968
|
+
require: './foo/x.js',
|
|
969
|
+
default: './foo/x.js',
|
|
970
|
+
});
|
|
971
|
+
// ./foo/bar/baz/z resolves even though it sits under the null'd ./foo/bar/*
|
|
972
|
+
expect(packageExports['./foo/bar/baz/z']).toEqual({
|
|
973
|
+
require: './foo/bar/baz/z.js',
|
|
974
|
+
default: './foo/bar/baz/z.js',
|
|
975
|
+
});
|
|
976
|
+
// nothing whose most-specific match is the null is emitted as a concrete entry
|
|
977
|
+
expect(packageExports['./foo/bar/z']).toBeUndefined();
|
|
978
|
+
// the null pattern is carried through to keep blocking its subtree at runtime
|
|
979
|
+
expect(packageExports['./foo/bar/*']).toBeNull();
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
it('keeps patterns and the null verbatim (expand: false)', async () => {
|
|
983
|
+
const cwd = await makeTempDir();
|
|
984
|
+
const outputDir = path.join(cwd, 'build');
|
|
985
|
+
await seedWorkedExample(cwd);
|
|
986
|
+
|
|
987
|
+
const { exports: packageExports } = await createPackageExports(workedExampleExports, {
|
|
988
|
+
bundles: [{ type: 'cjs', dir: '.' }],
|
|
989
|
+
outputDir,
|
|
990
|
+
cwd,
|
|
991
|
+
isFlat: true,
|
|
992
|
+
expand: false,
|
|
993
|
+
});
|
|
994
|
+
|
|
995
|
+
expect(packageExports['./foo/*']).toEqual({
|
|
996
|
+
require: './foo/*.js',
|
|
997
|
+
default: './foo/*.js',
|
|
998
|
+
});
|
|
999
|
+
expect(packageExports['./foo/bar/baz/*']).toEqual({
|
|
1000
|
+
require: './foo/bar/baz/*.js',
|
|
1001
|
+
default: './foo/bar/baz/*.js',
|
|
1002
|
+
});
|
|
1003
|
+
expect(packageExports['./foo/bar/*']).toBeNull();
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
it('lets an exact key win over a matching pattern', async () => {
|
|
1007
|
+
const cwd = await makeTempDir();
|
|
1008
|
+
const outputDir = path.join(cwd, 'build');
|
|
1009
|
+
|
|
1010
|
+
await Promise.all([
|
|
1011
|
+
createFile(path.join(cwd, 'src/Other.ts')),
|
|
1012
|
+
createFile(path.join(cwd, 'src/override.ts')),
|
|
1013
|
+
]);
|
|
1014
|
+
|
|
1015
|
+
const { exports: packageExports } = await createPackageExports(
|
|
1016
|
+
{
|
|
1017
|
+
// Exact key collides with what `./*` would expand to, but points elsewhere.
|
|
1018
|
+
'./Other': './src/override.ts',
|
|
1019
|
+
'./*': './src/*.ts',
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
bundles: [{ type: 'cjs', dir: '.' }],
|
|
1023
|
+
outputDir,
|
|
1024
|
+
cwd,
|
|
1025
|
+
isFlat: true,
|
|
1026
|
+
},
|
|
1027
|
+
);
|
|
1028
|
+
|
|
1029
|
+
// The exact key keeps its own target rather than the pattern's stem.
|
|
1030
|
+
expect(packageExports['./Other']).toEqual({
|
|
1031
|
+
require: './override.js',
|
|
1032
|
+
default: './override.js',
|
|
1033
|
+
});
|
|
1034
|
+
// The pattern still expands its other matches.
|
|
1035
|
+
expect(packageExports['./override']).toEqual({
|
|
1036
|
+
require: './override.js',
|
|
1037
|
+
default: './override.js',
|
|
658
1038
|
});
|
|
659
1039
|
});
|
|
660
1040
|
});
|
|
661
1041
|
|
|
662
1042
|
describe('createPackageBin', () => {
|
|
663
1043
|
it('prefers the ESM bundle when available', async () => {
|
|
664
|
-
await
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
1044
|
+
const cwd = await makeTempDir();
|
|
1045
|
+
/**
|
|
1046
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
1047
|
+
*/
|
|
1048
|
+
const bundles = [
|
|
1049
|
+
{ type: 'esm', dir: '.' },
|
|
1050
|
+
{ type: 'cjs', dir: '.' },
|
|
1051
|
+
];
|
|
1052
|
+
|
|
1053
|
+
await Promise.all([createFile(path.join(cwd, 'src/cli.ts'))]);
|
|
1054
|
+
|
|
1055
|
+
let bin = await createPackageBin('./src/cli.ts', {
|
|
1056
|
+
bundles,
|
|
1057
|
+
cwd,
|
|
1058
|
+
isFlat: true,
|
|
1059
|
+
packageType: 'module',
|
|
1060
|
+
});
|
|
1061
|
+
|
|
1062
|
+
expect(bin).toBe('./cli.js');
|
|
1063
|
+
|
|
1064
|
+
bin = await createPackageBin('./src/cli.ts', {
|
|
1065
|
+
bundles: [bundles[1]], // only CJS bundle
|
|
1066
|
+
cwd,
|
|
1067
|
+
isFlat: true,
|
|
1068
|
+
});
|
|
672
1069
|
|
|
673
|
-
|
|
1070
|
+
expect(bin).toBe('./cli.js');
|
|
674
1071
|
|
|
675
|
-
|
|
676
|
-
|
|
1072
|
+
bin = await createPackageBin('./src/cli.ts', {
|
|
1073
|
+
bundles, // only CJS bundle
|
|
1074
|
+
cwd,
|
|
1075
|
+
isFlat: true,
|
|
1076
|
+
packageType: 'commonjs',
|
|
1077
|
+
});
|
|
1078
|
+
|
|
1079
|
+
expect(bin).toBe('./cli.mjs');
|
|
1080
|
+
});
|
|
1081
|
+
});
|
|
1082
|
+
|
|
1083
|
+
describe('createPackageImports', () => {
|
|
1084
|
+
it('returns undefined when there is no imports field', async () => {
|
|
1085
|
+
const cwd = await makeTempDir();
|
|
1086
|
+
|
|
1087
|
+
const imports = await createPackageImports(undefined, {
|
|
1088
|
+
bundles: [{ type: 'esm', dir: '.' }],
|
|
1089
|
+
cwd,
|
|
1090
|
+
isFlat: true,
|
|
1091
|
+
packageType: 'module',
|
|
1092
|
+
});
|
|
1093
|
+
|
|
1094
|
+
expect(imports).toBeUndefined();
|
|
1095
|
+
});
|
|
1096
|
+
|
|
1097
|
+
it('throws when an import key does not start with "#"', async () => {
|
|
1098
|
+
const cwd = await makeTempDir();
|
|
1099
|
+
|
|
1100
|
+
await expect(
|
|
1101
|
+
createPackageImports(
|
|
1102
|
+
/** @type {any} */ ({
|
|
1103
|
+
'internal/utils': './src/internal/utils.ts',
|
|
1104
|
+
}),
|
|
1105
|
+
{
|
|
1106
|
+
bundles: [{ type: 'esm', dir: '.' }],
|
|
1107
|
+
cwd,
|
|
1108
|
+
isFlat: true,
|
|
1109
|
+
packageType: 'module',
|
|
1110
|
+
},
|
|
1111
|
+
),
|
|
1112
|
+
).rejects.toThrow('must start with "#"');
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
it('rewrites internal subpath imports for a dual bundle module package', async () => {
|
|
1116
|
+
const cwd = await makeTempDir();
|
|
1117
|
+
const outputDir = path.join(cwd, 'build');
|
|
1118
|
+
/**
|
|
1119
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
1120
|
+
*/
|
|
1121
|
+
const bundles = [
|
|
1122
|
+
{ type: 'esm', dir: '.' },
|
|
1123
|
+
{ type: 'cjs', dir: '.' },
|
|
1124
|
+
];
|
|
1125
|
+
|
|
1126
|
+
await Promise.all([
|
|
1127
|
+
createFile(path.join(cwd, 'src/internal/utils.ts')),
|
|
1128
|
+
createFile(path.join(outputDir, 'internal/utils.js')),
|
|
1129
|
+
createFile(path.join(outputDir, 'internal/utils.cjs')),
|
|
1130
|
+
createFile(path.join(outputDir, 'internal/utils.d.ts')),
|
|
1131
|
+
createFile(path.join(outputDir, 'internal/utils.d.cts')),
|
|
1132
|
+
]);
|
|
1133
|
+
|
|
1134
|
+
const imports = await createPackageImports(
|
|
1135
|
+
{
|
|
1136
|
+
'#internal/utils': './src/internal/utils.ts',
|
|
1137
|
+
},
|
|
1138
|
+
{
|
|
677
1139
|
bundles,
|
|
678
1140
|
cwd,
|
|
1141
|
+
addTypes: true,
|
|
679
1142
|
isFlat: true,
|
|
680
1143
|
packageType: 'module',
|
|
681
|
-
}
|
|
1144
|
+
},
|
|
1145
|
+
);
|
|
1146
|
+
|
|
1147
|
+
expect(imports).toEqual({
|
|
1148
|
+
'#internal/utils': {
|
|
1149
|
+
import: { types: './internal/utils.d.ts', default: './internal/utils.js' },
|
|
1150
|
+
require: { types: './internal/utils.d.cts', default: './internal/utils.cjs' },
|
|
1151
|
+
default: { types: './internal/utils.d.ts', default: './internal/utils.js' },
|
|
1152
|
+
},
|
|
1153
|
+
});
|
|
1154
|
+
});
|
|
1155
|
+
|
|
1156
|
+
it('puts import before require regardless of bundle array order', async () => {
|
|
1157
|
+
const cwd = await makeTempDir();
|
|
1158
|
+
const outputDir = path.join(cwd, 'build');
|
|
1159
|
+
|
|
1160
|
+
await Promise.all([
|
|
1161
|
+
createFile(path.join(cwd, 'src/internal/utils.ts')),
|
|
1162
|
+
createFile(path.join(outputDir, 'internal/utils.js')),
|
|
1163
|
+
createFile(path.join(outputDir, 'internal/utils.cjs')),
|
|
1164
|
+
]);
|
|
1165
|
+
|
|
1166
|
+
const imports = await createPackageImports(
|
|
1167
|
+
{
|
|
1168
|
+
'#internal/utils': './src/internal/utils.ts',
|
|
1169
|
+
},
|
|
1170
|
+
{
|
|
1171
|
+
// Pass cjs before esm to verify the key order is still 'import' then 'require'
|
|
1172
|
+
bundles: [
|
|
1173
|
+
{ type: 'cjs', dir: '.' },
|
|
1174
|
+
{ type: 'esm', dir: '.' },
|
|
1175
|
+
],
|
|
1176
|
+
cwd,
|
|
1177
|
+
isFlat: true,
|
|
1178
|
+
packageType: 'module',
|
|
1179
|
+
},
|
|
1180
|
+
);
|
|
682
1181
|
|
|
683
|
-
|
|
1182
|
+
expect(
|
|
1183
|
+
Object.keys(/** @type {Record<string, unknown>} */ (imports?.['#internal/utils'])),
|
|
1184
|
+
).toEqual(['import', 'require', 'default']);
|
|
1185
|
+
});
|
|
684
1186
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
1187
|
+
it('passes bare specifiers through unchanged', async () => {
|
|
1188
|
+
const cwd = await makeTempDir();
|
|
1189
|
+
|
|
1190
|
+
const imports = await createPackageImports(
|
|
1191
|
+
{
|
|
1192
|
+
'#error-formatter': '@custom/error-formatter',
|
|
1193
|
+
},
|
|
1194
|
+
{
|
|
1195
|
+
bundles: [
|
|
1196
|
+
{ type: 'esm', dir: '.' },
|
|
1197
|
+
{ type: 'cjs', dir: '.' },
|
|
1198
|
+
],
|
|
688
1199
|
cwd,
|
|
689
1200
|
isFlat: true,
|
|
690
|
-
|
|
1201
|
+
packageType: 'module',
|
|
1202
|
+
},
|
|
1203
|
+
);
|
|
691
1204
|
|
|
692
|
-
|
|
1205
|
+
expect(imports).toEqual({
|
|
1206
|
+
'#error-formatter': '@custom/error-formatter',
|
|
1207
|
+
});
|
|
1208
|
+
});
|
|
693
1209
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
1210
|
+
it('expands glob patterns in import keys and values', async () => {
|
|
1211
|
+
const cwd = await makeTempDir();
|
|
1212
|
+
const outputDir = path.join(cwd, 'build');
|
|
1213
|
+
|
|
1214
|
+
await Promise.all([
|
|
1215
|
+
createFile(path.join(cwd, 'src/internal/foo.ts')),
|
|
1216
|
+
createFile(path.join(cwd, 'src/internal/bar.ts')),
|
|
1217
|
+
createFile(path.join(outputDir, 'internal/foo.js')),
|
|
1218
|
+
createFile(path.join(outputDir, 'internal/bar.js')),
|
|
1219
|
+
]);
|
|
1220
|
+
|
|
1221
|
+
const imports = await createPackageImports(
|
|
1222
|
+
{
|
|
1223
|
+
'#internal/*': './src/internal/*.ts',
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
bundles: [{ type: 'esm', dir: '.' }],
|
|
697
1227
|
cwd,
|
|
698
1228
|
isFlat: true,
|
|
699
|
-
packageType: '
|
|
700
|
-
}
|
|
1229
|
+
packageType: 'module',
|
|
1230
|
+
},
|
|
1231
|
+
);
|
|
1232
|
+
|
|
1233
|
+
expect(imports).toEqual({
|
|
1234
|
+
'#internal/bar': { import: './internal/bar.js', default: './internal/bar.js' },
|
|
1235
|
+
'#internal/foo': { import: './internal/foo.js', default: './internal/foo.js' },
|
|
1236
|
+
});
|
|
1237
|
+
});
|
|
701
1238
|
|
|
702
|
-
|
|
1239
|
+
it('rewrites every condition of a conditions object (conditions-outer)', async () => {
|
|
1240
|
+
const cwd = await makeTempDir();
|
|
1241
|
+
/**
|
|
1242
|
+
* @type {{ type: import('./build.mjs').BundleType; dir: string }[]}
|
|
1243
|
+
*/
|
|
1244
|
+
const bundles = [
|
|
1245
|
+
{ type: 'esm', dir: '.' },
|
|
1246
|
+
{ type: 'cjs', dir: '.' },
|
|
1247
|
+
];
|
|
1248
|
+
|
|
1249
|
+
await Promise.all([
|
|
1250
|
+
createFile(path.join(cwd, 'src/internal/utils.ts')),
|
|
1251
|
+
createFile(path.join(cwd, 'src/internal/node/utils.ts')),
|
|
1252
|
+
]);
|
|
1253
|
+
|
|
1254
|
+
const imports = await createPackageImports(
|
|
1255
|
+
{
|
|
1256
|
+
'#internal/utils': {
|
|
1257
|
+
node: './src/internal/node/utils.ts',
|
|
1258
|
+
default: './src/internal/utils.ts',
|
|
1259
|
+
},
|
|
1260
|
+
},
|
|
1261
|
+
{
|
|
1262
|
+
bundles,
|
|
1263
|
+
cwd,
|
|
1264
|
+
isFlat: true,
|
|
1265
|
+
packageType: 'module',
|
|
1266
|
+
},
|
|
1267
|
+
);
|
|
1268
|
+
|
|
1269
|
+
expect(imports).toEqual({
|
|
1270
|
+
'#internal/utils': {
|
|
1271
|
+
node: {
|
|
1272
|
+
import: './internal/node/utils.js',
|
|
1273
|
+
require: './internal/node/utils.cjs',
|
|
1274
|
+
default: './internal/node/utils.js',
|
|
1275
|
+
},
|
|
1276
|
+
default: {
|
|
1277
|
+
import: './internal/utils.js',
|
|
1278
|
+
require: './internal/utils.cjs',
|
|
1279
|
+
default: './internal/utils.js',
|
|
1280
|
+
},
|
|
1281
|
+
},
|
|
703
1282
|
});
|
|
704
1283
|
});
|
|
705
1284
|
});
|