@mui/internal-code-infra 0.0.4-canary.97 → 0.0.4-canary.99
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/build/brokenLinksChecker/index.d.mts +147 -0
- package/build/changelog/fetchChangelogs.d.mts +3 -0
- package/build/cli/cmdArgosPush.d.mts +6 -0
- package/build/cli/cmdBuild.d.mts +45 -0
- package/build/cli/cmdCopyFiles.d.mts +12 -0
- package/build/cli/cmdGenerateChangelog.d.mts +15 -0
- package/build/cli/cmdListWorkspaces.d.mts +12 -0
- package/build/cli/cmdNetlifyIgnore.d.mts +9 -0
- package/build/cli/cmdPublish.d.mts +20 -2
- package/build/cli/cmdPublishCanary.d.mts +18 -0
- package/build/cli/cmdPublishNewPackage.d.mts +6 -0
- package/build/cli/cmdRenameScope.d.mts +18 -0
- package/build/cli/cmdSetVersionOverrides.d.mts +3 -0
- package/build/eslint/mui/rules/no-restricted-resolved-imports.d.mts +6 -0
- package/build/utils/babel.d.mts +6 -0
- package/build/utils/build.d.mts +3 -0
- package/build/utils/extractErrorCodes.d.mts +9 -0
- package/build/utils/git.d.mts +9 -0
- package/build/utils/github.d.mts +12 -0
- package/build/utils/pnpm.d.mts +87 -6
- package/build/utils/testUtils.d.mts +21 -0
- package/package.json +10 -10
- package/src/cli/cmdRenameScope.mjs +76 -0
- package/src/cli/index.mjs +2 -0
- package/src/stylelint/index.mjs +2 -2
- package/src/untyped-plugins.d.ts +3 -3
- package/src/utils/pnpm.mjs +173 -9
- package/src/utils/testUtils.mjs +35 -0
|
@@ -1,40 +1,103 @@
|
|
|
1
1
|
export type LinkStructure = Map<string, Set<string>>;
|
|
2
2
|
export type SerializedLinkStructure = {
|
|
3
|
+
/**
|
|
4
|
+
* - Object mapping page URLs to arrays of target IDs
|
|
5
|
+
*/
|
|
3
6
|
targets: Record<string, string[]>;
|
|
4
7
|
};
|
|
5
8
|
export type CrawlWorkerInput = {
|
|
9
|
+
/**
|
|
10
|
+
* - The page URL to crawl
|
|
11
|
+
*/
|
|
6
12
|
pageUrl: string;
|
|
13
|
+
/**
|
|
14
|
+
* - Fully resolved crawl options
|
|
15
|
+
*/
|
|
7
16
|
options: ResolvedCrawlOptions;
|
|
8
17
|
};
|
|
9
18
|
export type CrawlWorkerPageData = {
|
|
19
|
+
/**
|
|
20
|
+
* - The normalized page URL
|
|
21
|
+
*/
|
|
10
22
|
url: string;
|
|
23
|
+
/**
|
|
24
|
+
* - HTTP status code
|
|
25
|
+
*/
|
|
11
26
|
status: number;
|
|
27
|
+
/**
|
|
28
|
+
* - Array of anchor targets (e.g., '#intro')
|
|
29
|
+
*/
|
|
12
30
|
targets: string[];
|
|
31
|
+
/**
|
|
32
|
+
* - Content-type of the page
|
|
33
|
+
*/
|
|
13
34
|
contentType: string;
|
|
14
35
|
};
|
|
15
36
|
export type CrawlWorkerOutput = {
|
|
37
|
+
/**
|
|
38
|
+
* - Serialized page data
|
|
39
|
+
*/
|
|
16
40
|
pageData: CrawlWorkerPageData;
|
|
41
|
+
/**
|
|
42
|
+
* - Links discovered on the page
|
|
43
|
+
*/
|
|
17
44
|
links: Link[];
|
|
45
|
+
/**
|
|
46
|
+
* - HTML validation results, or null if validation was skipped/passed
|
|
47
|
+
*/
|
|
18
48
|
htmlValidateResults: {
|
|
19
49
|
pageUrl: string;
|
|
20
50
|
results: import('html-validate').Result[];
|
|
21
51
|
} | null;
|
|
22
52
|
};
|
|
23
53
|
export type PageData = {
|
|
54
|
+
/**
|
|
55
|
+
* - The normalized page URL (without trailing slash unless root)
|
|
56
|
+
*/
|
|
24
57
|
url: string;
|
|
58
|
+
/**
|
|
59
|
+
* - HTTP status code from the response (e.g., 200, 404, 500)
|
|
60
|
+
*/
|
|
25
61
|
status: number;
|
|
62
|
+
/**
|
|
63
|
+
* - Set of available anchor targets on the page, keyed by hash (e.g., '#intro')
|
|
64
|
+
*/
|
|
26
65
|
targets: Set<string>;
|
|
66
|
+
/**
|
|
67
|
+
* - Content-type of the page (e.g., 'text/html', 'text/markdown')
|
|
68
|
+
*/
|
|
27
69
|
contentType: string;
|
|
28
70
|
};
|
|
29
71
|
export type Link = {
|
|
72
|
+
/**
|
|
73
|
+
* - URL of the page where this link was found, or null for seed URLs
|
|
74
|
+
*/
|
|
30
75
|
src: string | null;
|
|
76
|
+
/**
|
|
77
|
+
* - Accessible name/text content of the link element, or null for seed URLs
|
|
78
|
+
*/
|
|
31
79
|
text: string | null;
|
|
80
|
+
/**
|
|
81
|
+
* - The href attribute value (may be relative or absolute, with or without hash)
|
|
82
|
+
*/
|
|
32
83
|
href: string;
|
|
84
|
+
/**
|
|
85
|
+
* - Content-type of the source page (e.g., 'text/html', 'text/markdown')
|
|
86
|
+
*/
|
|
33
87
|
contentType?: string | null;
|
|
34
88
|
};
|
|
35
89
|
export type IgnoreRule = {
|
|
90
|
+
/**
|
|
91
|
+
* - Pattern(s) to match source page path
|
|
92
|
+
*/
|
|
36
93
|
path?: (string | RegExp) | (string | RegExp)[];
|
|
94
|
+
/**
|
|
95
|
+
* - Pattern(s) to match broken link href
|
|
96
|
+
*/
|
|
37
97
|
href?: (string | RegExp) | (string | RegExp)[];
|
|
98
|
+
/**
|
|
99
|
+
* - Pattern(s) to match source page content-type
|
|
100
|
+
*/
|
|
38
101
|
contentType?: (string | RegExp) | (string | RegExp)[];
|
|
39
102
|
};
|
|
40
103
|
export type NormalizedIgnoreRule = {
|
|
@@ -43,22 +106,67 @@ export type NormalizedIgnoreRule = {
|
|
|
43
106
|
contentType: (string | RegExp)[] | undefined;
|
|
44
107
|
};
|
|
45
108
|
export type CrawlOptions = {
|
|
109
|
+
/**
|
|
110
|
+
* - Shell command to start the dev server (e.g., 'npm run dev'). If null, assumes server is already running
|
|
111
|
+
*/
|
|
46
112
|
startCommand?: string | null;
|
|
113
|
+
/**
|
|
114
|
+
* - Base URL of the site to crawl (e.g., 'http://localhost:3000')
|
|
115
|
+
*/
|
|
47
116
|
host: string;
|
|
117
|
+
/**
|
|
118
|
+
* - File path to write discovered link targets to. If null, targets are not persisted
|
|
119
|
+
*/
|
|
48
120
|
outPath?: string | null;
|
|
121
|
+
/**
|
|
122
|
+
* - Array of regex patterns to exclude from crawling (e.g., [/^\/api\//] to skip /api/* routes)
|
|
123
|
+
*/
|
|
49
124
|
ignoredPaths?: RegExp[];
|
|
125
|
+
/**
|
|
126
|
+
* - CSS selectors for elements whose nested links should be ignored (e.g., ['.sidebar', 'footer'])
|
|
127
|
+
*/
|
|
50
128
|
ignoredContent?: string[];
|
|
129
|
+
/**
|
|
130
|
+
* - Set of element IDs to ignore as link targets (defaults to '__next', '__NEXT_DATA__')
|
|
131
|
+
*/
|
|
51
132
|
ignoredTargets?: Set<string>;
|
|
133
|
+
/**
|
|
134
|
+
* - Pre-populated map of known valid targets to skip crawling (useful for external pages)
|
|
135
|
+
*/
|
|
52
136
|
knownTargets?: Map<string, Set<string>>;
|
|
137
|
+
/**
|
|
138
|
+
* - URLs to fetch known targets from (fetched JSON will be merged with knownTargets)
|
|
139
|
+
*/
|
|
53
140
|
knownTargetsDownloadUrl?: string[];
|
|
141
|
+
/**
|
|
142
|
+
* - Number of concurrent page fetches (defaults to 4)
|
|
143
|
+
*/
|
|
54
144
|
concurrency?: number;
|
|
145
|
+
/**
|
|
146
|
+
* - Starting URLs for the crawl (defaults to ['/'])
|
|
147
|
+
*/
|
|
55
148
|
seedUrls?: string[];
|
|
149
|
+
/**
|
|
150
|
+
* - Rules to ignore broken links. Each rule can have path, href, contentType, and/or has properties. All specified properties must match (AND logic). Within a property, multiple values use OR logic.
|
|
151
|
+
*/
|
|
56
152
|
ignores?: IgnoreRule[];
|
|
153
|
+
/**
|
|
154
|
+
* - Enable HTML validation on crawled pages. `false` (default): disabled. `true`: validate with recommended rules. Object: use as html-validate config — `mui:recommended` is always applied as the baseline, so most callers only need to set `rules`. Array: per-path config overrides — `mui:recommended` is applied once as the baseline and every entry whose `path` matches the page URL is layered on top; later matching entries win on conflicting rule keys. If an entry omits `extends`, it behaves like a rule patch and typically only changes the rules it names. If an entry includes `extends` (for example, re-extending `mui:recommended`), it can re-introduce or reset baseline presets rather than acting as a pure patch. An entry without `path` matches every page. If no entry matches, the page is not validated.
|
|
155
|
+
*/
|
|
57
156
|
htmlValidate?: HtmlValidateOption;
|
|
157
|
+
/**
|
|
158
|
+
* - Log extra diagnostics during crawling (e.g. resolved html-validate config per page). Defaults to `false`.
|
|
159
|
+
*/
|
|
58
160
|
verbose?: boolean;
|
|
59
161
|
};
|
|
60
162
|
export type HtmlValidateOverride = {
|
|
163
|
+
/**
|
|
164
|
+
* - Pattern(s) to match the page URL. Strings use exact match. Omit to match every page.
|
|
165
|
+
*/
|
|
61
166
|
path?: (string | RegExp) | (string | RegExp)[];
|
|
167
|
+
/**
|
|
168
|
+
* - html-validate config (or `true` for `mui:recommended`).
|
|
169
|
+
*/
|
|
62
170
|
config: true | import('html-validate').ConfigData;
|
|
63
171
|
};
|
|
64
172
|
export type HtmlValidateOption = boolean | import('html-validate').ConfigData | HtmlValidateOverride[];
|
|
@@ -71,26 +179,65 @@ export type ResolvedCrawlOptions = Omit<Required<CrawlOptions>, 'ignores' | 'htm
|
|
|
71
179
|
htmlValidate: ResolvedHtmlValidateEntry[];
|
|
72
180
|
};
|
|
73
181
|
export type BrokenLinkIssue = {
|
|
182
|
+
/**
|
|
183
|
+
* - Type of issue: 'broken-link' for 404 pages, 'broken-target' for missing anchors
|
|
184
|
+
*/
|
|
74
185
|
type: 'broken-link' | 'broken-target';
|
|
186
|
+
/**
|
|
187
|
+
* - Human-readable description of the issue (e.g., 'Target not found', 'Page returned error 404')
|
|
188
|
+
*/
|
|
75
189
|
message: string;
|
|
190
|
+
/**
|
|
191
|
+
* - The link object that has the issue
|
|
192
|
+
*/
|
|
76
193
|
link: Link;
|
|
77
194
|
};
|
|
78
195
|
export type HtmlValidateIssue = {
|
|
196
|
+
/**
|
|
197
|
+
* - Issue type discriminator
|
|
198
|
+
*/
|
|
79
199
|
type: 'html-validate';
|
|
200
|
+
/**
|
|
201
|
+
* - Human-readable description of the issue
|
|
202
|
+
*/
|
|
80
203
|
message: string;
|
|
204
|
+
/**
|
|
205
|
+
* - The page URL where the issue was found
|
|
206
|
+
*/
|
|
81
207
|
pageUrl: string;
|
|
208
|
+
/**
|
|
209
|
+
* - The html-validate rule that triggered this issue (e.g., 'no-dup-id')
|
|
210
|
+
*/
|
|
82
211
|
ruleId: string;
|
|
212
|
+
/**
|
|
213
|
+
* - Severity level (1 = warning, 2 = error)
|
|
214
|
+
*/
|
|
83
215
|
severity: number;
|
|
216
|
+
/**
|
|
217
|
+
* - Source location of the issue
|
|
218
|
+
*/
|
|
84
219
|
location: {
|
|
85
220
|
line: number;
|
|
86
221
|
column: number;
|
|
87
222
|
};
|
|
223
|
+
/**
|
|
224
|
+
* - DOM selector for the element, or null
|
|
225
|
+
*/
|
|
88
226
|
selector: string | null;
|
|
89
227
|
};
|
|
90
228
|
export type Issue = BrokenLinkIssue | HtmlValidateIssue;
|
|
91
229
|
export type CrawlResult = {
|
|
230
|
+
/**
|
|
231
|
+
* - All links discovered during the crawl
|
|
232
|
+
*/
|
|
92
233
|
links: Set<Link>;
|
|
234
|
+
/**
|
|
235
|
+
* - All pages crawled, keyed by normalized URL
|
|
236
|
+
*/
|
|
93
237
|
pages: Map<string, PageData>;
|
|
238
|
+
/**
|
|
239
|
+
* - All issues found (broken links, broken targets, and HTML validation issues)
|
|
240
|
+
*/
|
|
94
241
|
issues: Issue[];
|
|
95
242
|
};
|
|
96
243
|
/**
|
package/build/cli/cmdBuild.d.mts
CHANGED
|
@@ -1,18 +1,63 @@
|
|
|
1
1
|
export type Args = {
|
|
2
|
+
/**
|
|
3
|
+
* - The bundles to build.
|
|
4
|
+
*/
|
|
2
5
|
bundle: import('../utils/build.mjs').BundleType[];
|
|
6
|
+
/**
|
|
7
|
+
* - The large files to build.
|
|
8
|
+
*/
|
|
3
9
|
hasLargeFiles: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* - Whether to skip generating a package.json file in the /esm folder.
|
|
12
|
+
*/
|
|
4
13
|
skipBundlePackageJson: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* - Whether to enable verbose logging.
|
|
16
|
+
*/
|
|
5
17
|
verbose: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* - Whether to build types for the package.
|
|
20
|
+
*/
|
|
6
21
|
buildTypes: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* - Whether to build types for the package.
|
|
24
|
+
*/
|
|
7
25
|
skipTsc: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* - Whether to skip checking for Babel runtime dependencies in the package.
|
|
28
|
+
*/
|
|
8
29
|
skipBabelRuntimeCheck: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* - Whether to skip generating the package.json file in the bundle output.
|
|
32
|
+
*/
|
|
9
33
|
skipPackageJson: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* - Whether to skip checking for main field in package.json.
|
|
36
|
+
*/
|
|
10
37
|
skipMainCheck: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* - Globs to be ignored by Babel.
|
|
40
|
+
*/
|
|
11
41
|
ignore: string[];
|
|
42
|
+
/**
|
|
43
|
+
* - Files/Directories to be copied. Can be a glob pattern.
|
|
44
|
+
*/
|
|
12
45
|
copy?: string[];
|
|
46
|
+
/**
|
|
47
|
+
* - Whether to use the React compiler.
|
|
48
|
+
*/
|
|
13
49
|
enableReactCompiler?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* - Whether to build types using typescript native (tsgo).
|
|
52
|
+
*/
|
|
14
53
|
tsgo?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* - Deprecated no-op; flat builds are always used.
|
|
56
|
+
*/
|
|
15
57
|
flat?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* - Whether to enumerate glob patterns in exports/imports into concrete entries.
|
|
60
|
+
*/
|
|
16
61
|
expand: boolean;
|
|
17
62
|
};
|
|
18
63
|
declare const _default: import('yargs').CommandModule<{}, Args>;
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
export type Args = {
|
|
2
|
+
/**
|
|
3
|
+
* Run in silent mode without logging
|
|
4
|
+
*/
|
|
2
5
|
silent?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Exclude default files from the copy operation
|
|
8
|
+
*/
|
|
3
9
|
excludeDefaults?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Glob patterns to copy
|
|
12
|
+
*/
|
|
4
13
|
glob?: string[];
|
|
14
|
+
/**
|
|
15
|
+
* Extra files to copy
|
|
16
|
+
*/
|
|
5
17
|
files?: string[];
|
|
6
18
|
};
|
|
7
19
|
declare const _default: import('yargs').CommandModule<{}, Args>;
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
export type Args = {
|
|
2
|
+
/**
|
|
3
|
+
* Path to the changelog configuration file
|
|
4
|
+
*/
|
|
2
5
|
config: string;
|
|
6
|
+
/**
|
|
7
|
+
* The git reference (tag/commit) of the last release
|
|
8
|
+
*/
|
|
3
9
|
lastRelease: string;
|
|
10
|
+
/**
|
|
11
|
+
* The git reference (tag/commit) of the new release
|
|
12
|
+
*/
|
|
4
13
|
release: string;
|
|
14
|
+
/**
|
|
15
|
+
* The version number for the new release
|
|
16
|
+
*/
|
|
5
17
|
releaseVersion: string;
|
|
18
|
+
/**
|
|
19
|
+
* The current working directory to run the command in
|
|
20
|
+
*/
|
|
6
21
|
cwd: string;
|
|
7
22
|
};
|
|
8
23
|
/**
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
export type PublicPackage = import('../utils/pnpm.mjs').PublicPackage;
|
|
3
3
|
export type Args = {
|
|
4
|
+
/**
|
|
5
|
+
* - Whether to filter to only public packages
|
|
6
|
+
*/
|
|
4
7
|
publicOnly?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* - Output format (name, path, or json)
|
|
10
|
+
*/
|
|
5
11
|
output?: 'json' | 'path' | 'name' | 'publish-dir';
|
|
12
|
+
/**
|
|
13
|
+
* - Git reference to filter changes since
|
|
14
|
+
*/
|
|
6
15
|
sinceRef?: string;
|
|
16
|
+
/**
|
|
17
|
+
* - Same as filtering packages with --filter in pnpm. Only include packages matching the filter. See https://pnpm.io/filtering.
|
|
18
|
+
*/
|
|
7
19
|
filter?: string[];
|
|
8
20
|
};
|
|
9
21
|
/**
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
export type Args = {
|
|
3
|
+
/**
|
|
4
|
+
* - List of workspace names to process
|
|
5
|
+
*/
|
|
3
6
|
workspaces: string[];
|
|
7
|
+
/**
|
|
8
|
+
* - Check mode - error if the generated content differs from current
|
|
9
|
+
*/
|
|
4
10
|
check?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* - Branch to compare PRs against (default: master)
|
|
13
|
+
*/
|
|
5
14
|
baseBranch?: string;
|
|
6
15
|
};
|
|
7
16
|
declare const _default: import('yargs').CommandModule<{}, Args>;
|
|
@@ -3,11 +3,29 @@ export type PublicPackage = import('../utils/pnpm.mjs').PublicPackage;
|
|
|
3
3
|
export type PublishOptions = import('../utils/pnpm.mjs').PublishOptions;
|
|
4
4
|
export type PublishSummaryEntry = import('../utils/pnpm.mjs').PublishSummaryEntry;
|
|
5
5
|
export type Args = {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Run in dry-run mode without publishing
|
|
8
|
+
*/
|
|
9
|
+
"dry-run": boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Create a GitHub draft release after publishing
|
|
12
|
+
*/
|
|
13
|
+
"github-release": boolean;
|
|
14
|
+
/**
|
|
15
|
+
* NPM dist tag to publish to
|
|
16
|
+
*/
|
|
8
17
|
tag: string;
|
|
18
|
+
/**
|
|
19
|
+
* Runs in CI environment
|
|
20
|
+
*/
|
|
9
21
|
ci: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Git SHA to use for the GitHub release workflow (local only)
|
|
24
|
+
*/
|
|
10
25
|
sha?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Same as filtering packages with --filter in pnpm. Only publish packages matching the filter. See https://pnpm.io/filtering.
|
|
28
|
+
*/
|
|
11
29
|
filter?: string[];
|
|
12
30
|
};
|
|
13
31
|
declare const _default: import('yargs').CommandModule<{}, Args>;
|
|
@@ -3,13 +3,31 @@ export type PublicPackage = import('../utils/pnpm.mjs').PublicPackage;
|
|
|
3
3
|
export type VersionInfo = import('../utils/pnpm.mjs').VersionInfo;
|
|
4
4
|
export type PublishOptions = import('../utils/pnpm.mjs').PublishOptions;
|
|
5
5
|
export type Args = {
|
|
6
|
+
/**
|
|
7
|
+
* - Whether to run in dry-run mode
|
|
8
|
+
*/
|
|
6
9
|
dryRun?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* - Whether to create GitHub releases for canary packages
|
|
12
|
+
*/
|
|
7
13
|
githubRelease?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* - Same as filtering packages with --filter in pnpm. Only publish packages matching the filter. See https://pnpm.io/filtering.
|
|
16
|
+
*/
|
|
8
17
|
filter?: string[];
|
|
9
18
|
};
|
|
10
19
|
export type Commit = {
|
|
20
|
+
/**
|
|
21
|
+
* - Commit SHA
|
|
22
|
+
*/
|
|
11
23
|
sha: string;
|
|
24
|
+
/**
|
|
25
|
+
* - Commit message
|
|
26
|
+
*/
|
|
12
27
|
message: string;
|
|
28
|
+
/**
|
|
29
|
+
* - Commit author
|
|
30
|
+
*/
|
|
13
31
|
author: string;
|
|
14
32
|
};
|
|
15
33
|
declare const _default: import('yargs').CommandModule<{}, Args>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export type Args = {
|
|
3
|
+
/**
|
|
4
|
+
* Source and target scope
|
|
5
|
+
*/
|
|
6
|
+
alias: [string, string];
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {Object} Args
|
|
10
|
+
* @property {[string, string]} alias Source and target scope
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* @param {string} alias
|
|
14
|
+
* @returns {[string, string]}
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseAlias(alias: string): [string, string];
|
|
17
|
+
declare const _default: import('yargs').CommandModule<{}, Args>;
|
|
18
|
+
export default _default;
|
package/build/utils/babel.d.mts
CHANGED
|
@@ -15,7 +15,13 @@ export declare function cjsCopy({ from, to }: {
|
|
|
15
15
|
to: string;
|
|
16
16
|
}): Promise<void>;
|
|
17
17
|
export type ErrorCodeMetadata = {
|
|
18
|
+
/**
|
|
19
|
+
* - The path where the error code file should be written.
|
|
20
|
+
*/
|
|
18
21
|
outputPath: string;
|
|
22
|
+
/**
|
|
23
|
+
* - The runtime module to replace the errors with.
|
|
24
|
+
*/
|
|
19
25
|
runtimeModule?: string;
|
|
20
26
|
};
|
|
21
27
|
/**
|
package/build/utils/build.d.mts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
export type Args = {
|
|
2
|
+
/**
|
|
3
|
+
* - The output path to write the extracted error codes.
|
|
4
|
+
*/
|
|
2
5
|
errorCodesPath: string;
|
|
6
|
+
/**
|
|
7
|
+
* - List of package names to skip. By default, all workspace packages are considered.
|
|
8
|
+
*/
|
|
3
9
|
skip?: string[];
|
|
10
|
+
/**
|
|
11
|
+
* - The detection strategy to use when extracting error codes.
|
|
12
|
+
*/
|
|
4
13
|
detection?: import('@mui/internal-babel-plugin-minify-errors').Options['detection'];
|
|
5
14
|
};
|
|
6
15
|
/**
|
package/build/utils/git.d.mts
CHANGED
package/build/utils/github.d.mts
CHANGED
|
@@ -7,9 +7,21 @@
|
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
9
9
|
export type GitHubAppAuthenticationWithRefreshToken = {
|
|
10
|
+
/**
|
|
11
|
+
* - The access token
|
|
12
|
+
*/
|
|
10
13
|
token: string;
|
|
14
|
+
/**
|
|
15
|
+
* - ISO string when the access token expires
|
|
16
|
+
*/
|
|
11
17
|
expiresAt?: string;
|
|
18
|
+
/**
|
|
19
|
+
* - The refresh token
|
|
20
|
+
*/
|
|
12
21
|
refreshToken?: string;
|
|
22
|
+
/**
|
|
23
|
+
* - ISO string when the refresh token expires
|
|
24
|
+
*/
|
|
13
25
|
refreshTokenExpiresAt?: string;
|
|
14
26
|
};
|
|
15
27
|
/**
|
package/build/utils/pnpm.d.mts
CHANGED
|
@@ -1,35 +1,98 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
export type PrivatePackage = {
|
|
3
|
+
/**
|
|
4
|
+
* - Package name
|
|
5
|
+
*/
|
|
3
6
|
name?: string;
|
|
7
|
+
/**
|
|
8
|
+
* - Package version
|
|
9
|
+
*/
|
|
4
10
|
version?: string;
|
|
11
|
+
/**
|
|
12
|
+
* - Package directory path
|
|
13
|
+
*/
|
|
5
14
|
path: string;
|
|
15
|
+
/**
|
|
16
|
+
* - Whether the package is private
|
|
17
|
+
*/
|
|
6
18
|
isPrivate: true;
|
|
7
19
|
};
|
|
8
20
|
export type PublicPackage = {
|
|
21
|
+
/**
|
|
22
|
+
* - Package name
|
|
23
|
+
*/
|
|
9
24
|
name: string;
|
|
25
|
+
/**
|
|
26
|
+
* - Package version
|
|
27
|
+
*/
|
|
10
28
|
version: string;
|
|
29
|
+
/**
|
|
30
|
+
* - Package directory path
|
|
31
|
+
*/
|
|
11
32
|
path: string;
|
|
33
|
+
/**
|
|
34
|
+
* - Whether the package is private
|
|
35
|
+
*/
|
|
12
36
|
isPrivate: false;
|
|
13
37
|
};
|
|
14
38
|
export type VersionInfo = {
|
|
39
|
+
/**
|
|
40
|
+
* - Whether current version exists on npm
|
|
41
|
+
*/
|
|
15
42
|
currentVersionExists: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* - Latest canary version if available
|
|
45
|
+
*/
|
|
16
46
|
latestCanaryVersion: string | null;
|
|
17
47
|
};
|
|
18
48
|
export type PublishOptions = {
|
|
49
|
+
/**
|
|
50
|
+
* - Whether to run in dry-run mode
|
|
51
|
+
*/
|
|
19
52
|
dryRun?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* - Whether to skip git checks
|
|
55
|
+
*/
|
|
20
56
|
noGitChecks?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* - NPM dist tag to publish to
|
|
59
|
+
*/
|
|
21
60
|
tag?: string;
|
|
22
61
|
};
|
|
23
62
|
export type PnpmListResultItem = {
|
|
63
|
+
/**
|
|
64
|
+
* - Package name
|
|
65
|
+
*/
|
|
24
66
|
name?: string;
|
|
67
|
+
/**
|
|
68
|
+
* - Package version
|
|
69
|
+
*/
|
|
25
70
|
version?: string;
|
|
71
|
+
/**
|
|
72
|
+
* - Package directory path
|
|
73
|
+
*/
|
|
26
74
|
path: string;
|
|
75
|
+
/**
|
|
76
|
+
* - Whether the package is private
|
|
77
|
+
*/
|
|
27
78
|
private: boolean;
|
|
28
79
|
};
|
|
29
80
|
export type GetWorkspacePackagesOptions = {
|
|
81
|
+
/**
|
|
82
|
+
* - Git reference to filter changes since
|
|
83
|
+
*/
|
|
30
84
|
sinceRef?: string | null;
|
|
85
|
+
/**
|
|
86
|
+
* - Whether to filter to only public packages
|
|
87
|
+
*/
|
|
31
88
|
publicOnly?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* - Current working directory to run pnpm command in
|
|
91
|
+
*/
|
|
32
92
|
cwd?: string;
|
|
93
|
+
/**
|
|
94
|
+
* - Same as filtering packages with --filter in pnpm. Only include packages matching the filter. See https://pnpm.io/filtering.
|
|
95
|
+
*/
|
|
33
96
|
filter?: string[];
|
|
34
97
|
};
|
|
35
98
|
export declare function getWorkspacePackages(options?: {
|
|
@@ -90,19 +153,22 @@ export type PublishSummaryEntry = {
|
|
|
90
153
|
*/
|
|
91
154
|
export declare function publishPackages(packages: PublicPackage[], options?: PublishOptions): Promise<PublishSummaryEntry[]>;
|
|
92
155
|
export type GetTransitiveDependenciesOptions = {
|
|
156
|
+
/**
|
|
157
|
+
* - Map of workspace package name to directory path
|
|
158
|
+
*/
|
|
93
159
|
workspacePathByName?: Map<string, string>;
|
|
160
|
+
/**
|
|
161
|
+
* - Whether to include devDependencies in the traversal
|
|
162
|
+
*/
|
|
94
163
|
includeDev?: boolean;
|
|
95
164
|
};
|
|
96
|
-
/**
|
|
97
|
-
* @typedef {Object} GetTransitiveDependenciesOptions
|
|
98
|
-
* @property {Map<string, string>} [workspacePathByName] - Map of workspace package name to directory path
|
|
99
|
-
* @property {boolean} [includeDev=true] - Whether to include devDependencies in the traversal
|
|
100
|
-
*/
|
|
101
165
|
/**
|
|
102
166
|
* Get all transitive workspace dependencies for a set of packages.
|
|
103
167
|
*
|
|
104
168
|
* Only follows deps whose version spec starts with `workspace:` (e.g. `workspace:*`
|
|
105
|
-
* or `workspace:^`), meaning they are sourced directly from the monorepo.
|
|
169
|
+
* or `workspace:^`), meaning they are sourced directly from the monorepo. An
|
|
170
|
+
* alias spec (`workspace:@scope/name@range`) is followed to the package it
|
|
171
|
+
* targets, which need not match the dependency key. Pinned
|
|
106
172
|
* external versions (e.g. `^1.0.0`) are ignored even when the package name exists
|
|
107
173
|
* in the workspace. Traverses `dependencies` and optionally `devDependencies`.
|
|
108
174
|
* Results are cached per package so each package is read from disk at most once
|
|
@@ -171,6 +237,21 @@ export declare function writePackageJson(packagePath: string, packageJson: Objec
|
|
|
171
237
|
* @returns {Promise<void>}
|
|
172
238
|
*/
|
|
173
239
|
export declare function writeOverridesToWorkspace(workspaceDir: string, overrides: Record<string, string>): Promise<void>;
|
|
240
|
+
/**
|
|
241
|
+
* Move the publishable workspace packages in one scope to another.
|
|
242
|
+
*
|
|
243
|
+
* Only packages that are part of the workspace are touched, so dependencies
|
|
244
|
+
* that merely share the scope but come from the registry (say `@base-ui/react`
|
|
245
|
+
* alongside a workspace `@base-ui/mosaic`) are left alone. Dependents keep the
|
|
246
|
+
* original dependency name and gain a `workspace:` alias, so imports in the
|
|
247
|
+
* repo resolve exactly as before.
|
|
248
|
+
*
|
|
249
|
+
* @param {(PublicPackage | PrivatePackage)[]} packages - All workspace packages
|
|
250
|
+
* @param {string} fromScope - Scope to move away from
|
|
251
|
+
* @param {string} toScope - Scope to move to
|
|
252
|
+
* @returns {Promise<Map<string, string>>} Old package name to new package name
|
|
253
|
+
*/
|
|
254
|
+
export declare function renameWorkspaceScope(packages: (PublicPackage | PrivatePackage)[], fromScope: string, toScope: string): Promise<Map<string, string>>;
|
|
174
255
|
/**
|
|
175
256
|
* Resolve a package@version specifier to an exact version
|
|
176
257
|
* @param {string} packageSpec - Package specifier in format "package@version"
|
|
@@ -5,3 +5,24 @@
|
|
|
5
5
|
* @returns {Promise<string>} The path of the created temporary directory.
|
|
6
6
|
*/
|
|
7
7
|
export declare function makeTempDir(): Promise<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Write a package.json into a subdirectory of a temp workspace.
|
|
10
|
+
*
|
|
11
|
+
* @param {string} root - Workspace root
|
|
12
|
+
* @param {string} dir - Subdirectory to create
|
|
13
|
+
* @param {object} pkgJson - Manifest contents
|
|
14
|
+
* @returns {Promise<string>} The package directory
|
|
15
|
+
*/
|
|
16
|
+
export declare function writePackage(root: string, dir: string, pkgJson: object): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* @param {string} name
|
|
19
|
+
* @param {string} pkgPath
|
|
20
|
+
* @returns {import('./pnpm.mjs').PublicPackage}
|
|
21
|
+
*/
|
|
22
|
+
export declare function publicPkg(name: string, pkgPath: string): import('./pnpm.mjs').PublicPackage;
|
|
23
|
+
/**
|
|
24
|
+
* @param {string} name
|
|
25
|
+
* @param {string} pkgPath
|
|
26
|
+
* @returns {import('./pnpm.mjs').PrivatePackage}
|
|
27
|
+
*/
|
|
28
|
+
export declare function privatePkg(name: string, pkgPath: string): import('./pnpm.mjs').PrivatePackage;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mui/internal-code-infra",
|
|
3
|
-
"version": "0.0.4-canary.
|
|
3
|
+
"version": "0.0.4-canary.99",
|
|
4
4
|
"author": "MUI Team",
|
|
5
5
|
"description": "Infra scripts and configs to be used across MUI repos.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -82,12 +82,12 @@
|
|
|
82
82
|
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
|
83
83
|
"babel-plugin-transform-remove-imports": "^1.8.1",
|
|
84
84
|
"chalk": "^5.6.2",
|
|
85
|
-
"clipboardy": "^5.3.
|
|
85
|
+
"clipboardy": "^5.3.2",
|
|
86
86
|
"content-type": "^2.0.0",
|
|
87
87
|
"env-ci": "^11.2.0",
|
|
88
88
|
"es-toolkit": "^1.49.0",
|
|
89
89
|
"eslint-config-prettier": "^10.1.8",
|
|
90
|
-
"eslint-import-resolver-typescript": "^4.4.
|
|
90
|
+
"eslint-import-resolver-typescript": "^4.4.5",
|
|
91
91
|
"eslint-module-utils": "^2.14.0",
|
|
92
92
|
"eslint-plugin-compat": "^7.0.2",
|
|
93
93
|
"eslint-plugin-import": "^2.32.0",
|
|
@@ -101,12 +101,12 @@
|
|
|
101
101
|
"execa": "^9.6.1",
|
|
102
102
|
"git-url-parse": "^16.1.0",
|
|
103
103
|
"globals": "^17.7.0",
|
|
104
|
-
"globby": "^16.2.
|
|
105
|
-
"html-validate": "^11.5.
|
|
104
|
+
"globby": "^16.2.2",
|
|
105
|
+
"html-validate": "^11.5.6",
|
|
106
106
|
"minimatch": "^10.2.5",
|
|
107
107
|
"node-html-parser": "^9.0.0",
|
|
108
108
|
"open": "^11.0.0",
|
|
109
|
-
"postcss-styled-syntax": "^0.7.
|
|
109
|
+
"postcss-styled-syntax": "^0.7.2",
|
|
110
110
|
"regexp.escape": "^2.0.1",
|
|
111
111
|
"rehype-slug": "^6.0.0",
|
|
112
112
|
"rehype-stringify": "^10.0.1",
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"remark-parse": "^11.0.0",
|
|
128
128
|
"remark-rehype": "^11.1.2",
|
|
129
129
|
"resolve-pkg-maps": "^1.0.0",
|
|
130
|
-
"semver": "^7.8.
|
|
130
|
+
"semver": "^7.8.5",
|
|
131
131
|
"stylelint-config-standard": "^40.0.0",
|
|
132
132
|
"typescript-eslint": "^8.64.0",
|
|
133
133
|
"unified": "^11.0.5",
|
|
@@ -136,8 +136,8 @@
|
|
|
136
136
|
"yaml": "^2.9.0",
|
|
137
137
|
"yargs": "^18.0.0",
|
|
138
138
|
"@mui/internal-babel-plugin-display-name": "1.0.4-canary.23",
|
|
139
|
-
"@mui/internal-babel-plugin-
|
|
140
|
-
"@mui/internal-babel-plugin-
|
|
139
|
+
"@mui/internal-babel-plugin-resolve-imports": "2.0.7-canary.41",
|
|
140
|
+
"@mui/internal-babel-plugin-minify-errors": "2.0.8-canary.30"
|
|
141
141
|
},
|
|
142
142
|
"peerDependencies": {
|
|
143
143
|
"@next/eslint-plugin-next": "*",
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
"publishConfig": {
|
|
189
189
|
"access": "public"
|
|
190
190
|
},
|
|
191
|
-
"gitSha": "
|
|
191
|
+
"gitSha": "327b1eabb817e566026fbeb46767736701766d0d",
|
|
192
192
|
"scripts": {
|
|
193
193
|
"build": "tsgo -p tsconfig.build.json",
|
|
194
194
|
"typescript": "tsgo -noEmit",
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/* eslint-disable no-console */
|
|
4
|
+
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
|
|
7
|
+
import { getWorkspacePackages, renameWorkspaceScope } from '../utils/pnpm.mjs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A scope is a single `@`-prefixed segment. Letting a `/` through would build
|
|
11
|
+
* names like `@acme/private/pkg`, which only npm rejects, long after every
|
|
12
|
+
* matching manifest has been rewritten.
|
|
13
|
+
*/
|
|
14
|
+
const SCOPE_PATTERN = /^@[a-z0-9-~][a-z0-9-._~]*$/;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {Object} Args
|
|
18
|
+
* @property {[string, string]} alias Source and target scope
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {string} alias
|
|
23
|
+
* @returns {[string, string]}
|
|
24
|
+
*/
|
|
25
|
+
export function parseAlias(alias) {
|
|
26
|
+
const parts = alias.split(':');
|
|
27
|
+
const [from, to] = parts;
|
|
28
|
+
if (parts.length !== 2 || !SCOPE_PATTERN.test(from) || !SCOPE_PATTERN.test(to)) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Invalid scope mapping "${alias}". Expected exactly two npm scopes separated by a colon, e.g. "@acme:@acme-private".`,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
if (from === to) {
|
|
34
|
+
throw new Error(`Invalid scope mapping "${alias}". The source and target scope are the same.`);
|
|
35
|
+
}
|
|
36
|
+
return [from, to];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
|
|
40
|
+
command: 'rename-scope <alias>',
|
|
41
|
+
describe: 'Move publishable workspace packages to a different npm scope',
|
|
42
|
+
builder: (yargs) =>
|
|
43
|
+
yargs
|
|
44
|
+
.positional('alias', {
|
|
45
|
+
type: 'string',
|
|
46
|
+
describe: 'Scope mapping written as "@from:@to"',
|
|
47
|
+
coerce: parseAlias,
|
|
48
|
+
})
|
|
49
|
+
.example(
|
|
50
|
+
'$0 rename-scope @acme:@acme-private',
|
|
51
|
+
'Publish the workspace @acme packages under @acme-private',
|
|
52
|
+
),
|
|
53
|
+
handler: async (argv) => {
|
|
54
|
+
const [from, to] = argv.alias;
|
|
55
|
+
const packages = await getWorkspacePackages();
|
|
56
|
+
const renamed = await renameWorkspaceScope(packages, from, to);
|
|
57
|
+
|
|
58
|
+
// Matching nothing means the mapping is wrong or stale. Carrying on would
|
|
59
|
+
// publish under the original scope, so fail instead of reporting success.
|
|
60
|
+
if (renamed.size === 0) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
`No publishable workspace packages found in ${from}. Check the scope mapping "${from}:${to}", or the workspace may already have been renamed.`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const [oldName, newName] of renamed) {
|
|
67
|
+
console.log(`📦 ${oldName} → ${chalk.bold(newName)}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log(
|
|
71
|
+
chalk.yellow(
|
|
72
|
+
'\n⚠️ Workspace manifests were rewritten in place and are not restored. Discard them before committing.',
|
|
73
|
+
),
|
|
74
|
+
);
|
|
75
|
+
},
|
|
76
|
+
});
|
package/src/cli/index.mjs
CHANGED
|
@@ -14,6 +14,7 @@ import cmdNetlifyIgnore from './cmdNetlifyIgnore.mjs';
|
|
|
14
14
|
import cmdPublish from './cmdPublish.mjs';
|
|
15
15
|
import cmdPublishCanary from './cmdPublishCanary.mjs';
|
|
16
16
|
import cmdPublishNewPackage from './cmdPublishNewPackage.mjs';
|
|
17
|
+
import cmdRenameScope from './cmdRenameScope.mjs';
|
|
17
18
|
import cmdSetVersionOverrides from './cmdSetVersionOverrides.mjs';
|
|
18
19
|
import cmdVale from './cmdVale.mjs';
|
|
19
20
|
import cmdValidateBuiltTypes from './cmdValidateBuiltTypes.mjs';
|
|
@@ -47,6 +48,7 @@ await yargs(hideBin(process.argv))
|
|
|
47
48
|
.command(cmdPublish)
|
|
48
49
|
.command(cmdPublishCanary)
|
|
49
50
|
.command(cmdPublishNewPackage)
|
|
51
|
+
.command(cmdRenameScope)
|
|
50
52
|
.command(cmdSetVersionOverrides)
|
|
51
53
|
.command(cmdVale)
|
|
52
54
|
.command(cmdValidateBuiltTypes)
|
package/src/stylelint/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as postcssStyledSyntax from 'postcss-styled-syntax';
|
|
2
2
|
|
|
3
3
|
/** @type {import('stylelint').Config} */
|
|
4
4
|
export default {
|
|
@@ -39,7 +39,7 @@ export default {
|
|
|
39
39
|
overrides: [
|
|
40
40
|
{
|
|
41
41
|
files: ['**/*.?(c|m)[jt]s?(x)'],
|
|
42
|
-
customSyntax:
|
|
42
|
+
customSyntax: postcssStyledSyntax,
|
|
43
43
|
},
|
|
44
44
|
],
|
|
45
45
|
};
|
package/src/untyped-plugins.d.ts
CHANGED
|
@@ -169,8 +169,8 @@ declare module 'stylelint-config-standard' {
|
|
|
169
169
|
export default configExtends;
|
|
170
170
|
}
|
|
171
171
|
declare module 'postcss-styled-syntax' {
|
|
172
|
-
import type {
|
|
172
|
+
import type { Parser, Stringifier } from 'postcss';
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
export
|
|
174
|
+
export const parse: Parser;
|
|
175
|
+
export const stringify: Stringifier;
|
|
176
176
|
}
|
package/src/utils/pnpm.mjs
CHANGED
|
@@ -303,11 +303,29 @@ export async function publishPackages(packages, options = {}) {
|
|
|
303
303
|
* @property {boolean} [includeDev=true] - Whether to include devDependencies in the traversal
|
|
304
304
|
*/
|
|
305
305
|
|
|
306
|
+
/**
|
|
307
|
+
* The package a `workspace:` alias spec resolves to, if it is one.
|
|
308
|
+
*
|
|
309
|
+
* @param {string} spec - Dependency spec
|
|
310
|
+
* @returns {string | null} The aliased package name, or null for a plain spec
|
|
311
|
+
*/
|
|
312
|
+
function aliasTarget(spec) {
|
|
313
|
+
if (!spec.startsWith('workspace:')) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
const range = spec.slice('workspace:'.length);
|
|
317
|
+
// Search from 1 so a scoped name's own leading `@` isn't read as the separator.
|
|
318
|
+
const separator = range.indexOf('@', 1);
|
|
319
|
+
return separator === -1 ? null : range.slice(0, separator);
|
|
320
|
+
}
|
|
321
|
+
|
|
306
322
|
/**
|
|
307
323
|
* Get all transitive workspace dependencies for a set of packages.
|
|
308
324
|
*
|
|
309
325
|
* Only follows deps whose version spec starts with `workspace:` (e.g. `workspace:*`
|
|
310
|
-
* or `workspace:^`), meaning they are sourced directly from the monorepo.
|
|
326
|
+
* or `workspace:^`), meaning they are sourced directly from the monorepo. An
|
|
327
|
+
* alias spec (`workspace:@scope/name@range`) is followed to the package it
|
|
328
|
+
* targets, which need not match the dependency key. Pinned
|
|
311
329
|
* external versions (e.g. `^1.0.0`) are ignored even when the package name exists
|
|
312
330
|
* in the workspace. Traverses `dependencies` and optionally `devDependencies`.
|
|
313
331
|
* Results are cached per package so each package is read from disk at most once
|
|
@@ -344,14 +362,15 @@ export async function getTransitiveDependencies(packageNames, options = {}) {
|
|
|
344
362
|
...Object.entries(pkgJson.dependencies ?? {}),
|
|
345
363
|
...(includeDev ? Object.entries(pkgJson.devDependencies ?? {}) : []),
|
|
346
364
|
];
|
|
347
|
-
const workspaceDeps = allDepEntries
|
|
348
|
-
.
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
)
|
|
354
|
-
.
|
|
365
|
+
const workspaceDeps = allDepEntries.flatMap(([dep, spec]) => {
|
|
366
|
+
if (typeof spec !== 'string' || !spec.startsWith('workspace:')) {
|
|
367
|
+
return [];
|
|
368
|
+
}
|
|
369
|
+
// An aliased spec (`workspace:@scope/name@range`) names the workspace
|
|
370
|
+
// package it resolves to, which need not match the dependency key.
|
|
371
|
+
const name = aliasTarget(spec) ?? dep;
|
|
372
|
+
return workspacePathByName.has(name) ? [name] : [];
|
|
373
|
+
});
|
|
355
374
|
|
|
356
375
|
const recursiveResults = await Promise.all(workspaceDeps.map(collectDeps));
|
|
357
376
|
return new Set([...workspaceDeps, ...recursiveResults.flatMap((s) => [...s])]);
|
|
@@ -540,6 +559,151 @@ export async function writeOverridesToWorkspace(workspaceDir, overrides) {
|
|
|
540
559
|
await fs.writeFile(workspaceYamlPath, doc.toString());
|
|
541
560
|
}
|
|
542
561
|
|
|
562
|
+
/**
|
|
563
|
+
* Map a package name onto a different npm scope.
|
|
564
|
+
* @param {string} name - Package name, e.g. `@base-ui/mosaic`
|
|
565
|
+
* @param {string} fromScope - Scope to replace, e.g. `@base-ui`
|
|
566
|
+
* @param {string} toScope - Replacement scope, e.g. `@base-ui-private`
|
|
567
|
+
* @returns {string | null} The renamed package, or null when the scope doesn't match
|
|
568
|
+
*/
|
|
569
|
+
function renameScope(name, fromScope, toScope) {
|
|
570
|
+
const prefix = `${fromScope}/`;
|
|
571
|
+
return name.startsWith(prefix) ? `${toScope}/${name.slice(prefix.length)}` : null;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Move the publishable workspace packages in one scope to another.
|
|
576
|
+
*
|
|
577
|
+
* Only packages that are part of the workspace are touched, so dependencies
|
|
578
|
+
* that merely share the scope but come from the registry (say `@base-ui/react`
|
|
579
|
+
* alongside a workspace `@base-ui/mosaic`) are left alone. Dependents keep the
|
|
580
|
+
* original dependency name and gain a `workspace:` alias, so imports in the
|
|
581
|
+
* repo resolve exactly as before.
|
|
582
|
+
*
|
|
583
|
+
* @param {(PublicPackage | PrivatePackage)[]} packages - All workspace packages
|
|
584
|
+
* @param {string} fromScope - Scope to move away from
|
|
585
|
+
* @param {string} toScope - Scope to move to
|
|
586
|
+
* @returns {Promise<Map<string, string>>} Old package name to new package name
|
|
587
|
+
*/
|
|
588
|
+
export async function renameWorkspaceScope(packages, fromScope, toScope) {
|
|
589
|
+
// Renaming a scope onto itself only rewrites every manifest to itself. The
|
|
590
|
+
// CLI rejects this earlier, but the guard belongs with the operation so a
|
|
591
|
+
// direct caller cannot trip the silent churn either.
|
|
592
|
+
if (fromScope === toScope) {
|
|
593
|
+
throw new Error(`Cannot rename ${fromScope} to itself.`);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/** @type {Map<string, string>} */
|
|
597
|
+
const renamed = new Map();
|
|
598
|
+
|
|
599
|
+
for (const pkg of packages) {
|
|
600
|
+
if (pkg.isPrivate) {
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
const newName = renameScope(pkg.name, fromScope, toScope);
|
|
604
|
+
if (newName) {
|
|
605
|
+
renamed.set(pkg.name, newName);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// A rename that lands on a name another package keeps would leave the
|
|
610
|
+
// workspace with two packages sharing a name. Catch it up front, before any
|
|
611
|
+
// manifest is written.
|
|
612
|
+
/** @type {Map<string, string>} */
|
|
613
|
+
const finalNames = new Map();
|
|
614
|
+
for (const pkg of packages) {
|
|
615
|
+
if (!pkg.name) {
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
const finalName = renamed.get(pkg.name) ?? pkg.name;
|
|
619
|
+
const owner = finalNames.get(finalName);
|
|
620
|
+
if (owner) {
|
|
621
|
+
throw new Error(
|
|
622
|
+
`Cannot rename ${fromScope} to ${toScope}: ${pkg.name} and ${owner} would both be named ${finalName}.`,
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
finalNames.set(finalName, pkg.name);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// Rewrite in memory first. A dependency that cannot be pointed at its renamed
|
|
629
|
+
// package has to fail before anything is written, or the workspace is left
|
|
630
|
+
// half renamed with nothing to restore it.
|
|
631
|
+
const rewritten = await Promise.all(
|
|
632
|
+
packages.map(async (pkg) => {
|
|
633
|
+
const packageJson = await readPackageJson(pkg.path);
|
|
634
|
+
const label = pkg.name ?? pkg.path;
|
|
635
|
+
/** @type {string[]} */
|
|
636
|
+
const problems = [];
|
|
637
|
+
let changed = false;
|
|
638
|
+
|
|
639
|
+
const newName = pkg.name ? renamed.get(pkg.name) : undefined;
|
|
640
|
+
if (newName) {
|
|
641
|
+
packageJson.name = newName;
|
|
642
|
+
changed = true;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// peerDependencies are deliberately absent: a peer is supplied by the
|
|
646
|
+
// consumer, who installs the package under its original name. An alias
|
|
647
|
+
// range would be unsatisfiable for them.
|
|
648
|
+
for (const deps of [
|
|
649
|
+
packageJson.dependencies,
|
|
650
|
+
packageJson.devDependencies,
|
|
651
|
+
packageJson.optionalDependencies,
|
|
652
|
+
]) {
|
|
653
|
+
if (!deps) {
|
|
654
|
+
continue;
|
|
655
|
+
}
|
|
656
|
+
for (const [depName, spec] of Object.entries(deps)) {
|
|
657
|
+
if (!spec) {
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
const existingTarget = aliasTarget(spec);
|
|
662
|
+
if (existingTarget) {
|
|
663
|
+
if (renamed.has(existingTarget)) {
|
|
664
|
+
problems.push(
|
|
665
|
+
`"${depName}" in ${label} already aliases ${existingTarget}, which is being renamed. Point it at the package directly so it can be rewritten.`,
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
// Otherwise it already aliases what it should, as a re-run does.
|
|
669
|
+
continue;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
const target = renamed.get(depName);
|
|
673
|
+
if (!target) {
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
if (!spec.startsWith('workspace:')) {
|
|
677
|
+
// Only `workspace:` specs can be aliased. Anything else would keep
|
|
678
|
+
// resolving the original name from the registry after the rename.
|
|
679
|
+
problems.push(
|
|
680
|
+
`"${depName}" in ${label} is required as "${spec}" rather than a workspace: dependency, so it cannot be pointed at ${target}.`,
|
|
681
|
+
);
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
684
|
+
deps[depName] = `workspace:${target}@${spec.slice('workspace:'.length)}`;
|
|
685
|
+
changed = true;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
return { path: pkg.path, packageJson, changed, problems };
|
|
690
|
+
}),
|
|
691
|
+
);
|
|
692
|
+
|
|
693
|
+
const problems = rewritten.flatMap((entry) => entry.problems);
|
|
694
|
+
if (problems.length > 0) {
|
|
695
|
+
throw new Error(`Cannot rename ${fromScope} to ${toScope}:\n ${problems.join('\n ')}`);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
await Promise.all(
|
|
699
|
+
rewritten
|
|
700
|
+
.filter((entry) => entry.changed)
|
|
701
|
+
.map((entry) => writePackageJson(entry.path, entry.packageJson)),
|
|
702
|
+
);
|
|
703
|
+
|
|
704
|
+
return renamed;
|
|
705
|
+
}
|
|
706
|
+
|
|
543
707
|
/**
|
|
544
708
|
* Resolve a package@version specifier to an exact version
|
|
545
709
|
* @param {string} packageSpec - Package specifier in format "package@version"
|
package/src/utils/testUtils.mjs
CHANGED
|
@@ -3,6 +3,8 @@ import * as os from 'node:os';
|
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import { onTestFinished } from 'vitest';
|
|
5
5
|
|
|
6
|
+
import { writePackageJson } from './pnpm.mjs';
|
|
7
|
+
|
|
6
8
|
/**
|
|
7
9
|
* Creates a temporary directory and registers an `onTestFinished` hook to
|
|
8
10
|
* remove it automatically when the current test ends — even if the test throws.
|
|
@@ -16,3 +18,36 @@ export async function makeTempDir() {
|
|
|
16
18
|
});
|
|
17
19
|
return tmpDir;
|
|
18
20
|
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Write a package.json into a subdirectory of a temp workspace.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} root - Workspace root
|
|
26
|
+
* @param {string} dir - Subdirectory to create
|
|
27
|
+
* @param {object} pkgJson - Manifest contents
|
|
28
|
+
* @returns {Promise<string>} The package directory
|
|
29
|
+
*/
|
|
30
|
+
export async function writePackage(root, dir, pkgJson) {
|
|
31
|
+
const pkgDir = path.join(root, dir);
|
|
32
|
+
await fs.mkdir(pkgDir, { recursive: true });
|
|
33
|
+
await writePackageJson(pkgDir, pkgJson);
|
|
34
|
+
return pkgDir;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param {string} name
|
|
39
|
+
* @param {string} pkgPath
|
|
40
|
+
* @returns {import('./pnpm.mjs').PublicPackage}
|
|
41
|
+
*/
|
|
42
|
+
export function publicPkg(name, pkgPath) {
|
|
43
|
+
return { name, version: '1.0.0', path: pkgPath, isPrivate: false };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {string} name
|
|
48
|
+
* @param {string} pkgPath
|
|
49
|
+
* @returns {import('./pnpm.mjs').PrivatePackage}
|
|
50
|
+
*/
|
|
51
|
+
export function privatePkg(name, pkgPath) {
|
|
52
|
+
return { name, version: '1.0.0', path: pkgPath, isPrivate: true };
|
|
53
|
+
}
|