@mui/internal-code-infra 0.1.1-canary.21 → 0.1.1-canary.23

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.
@@ -124,19 +124,15 @@ export declare function getPublishRegistry(packagePath: string): Promise<string>
124
124
  * @returns {Promise<string | null>} Version string, or null when absent/invalid
125
125
  */
126
126
  export declare function getReleaseVersion(cwd?: string): Promise<string | null>;
127
- /**
128
- * Filter to the packages that must be published by hand before CI can take over.
129
- *
130
- * A brand new package has to be pushed once manually (see
131
- * `code-infra publish-new-package`) before the OIDC-based workflow can publish
132
- * it, so the release fails with a clear message instead of a confusing 404
133
- * midway through. See {@link getPackageVersionInfo} for the version-level check.
134
- *
135
- * @param {PublicPackage[]} packages - Packages to check
136
- * @returns {Promise<PublicPackage[]>} The subset needing a manual first publish
137
- */
138
- export declare function getPackagesNeedingManualPublish(packages: PublicPackage[]): Promise<PublicPackage[]>;
139
127
  export type RegistryPackage = {
128
+ /**
129
+ * - Registry that the package publishes to
130
+ */
131
+ registry: string;
132
+ /**
133
+ * - Whether the package is on the registry
134
+ */
135
+ exists: boolean;
140
136
  /**
141
137
  * - Dist-tags of the package
142
138
  */
@@ -148,17 +144,36 @@ export type RegistryPackage = {
148
144
  };
149
145
  /**
150
146
  * @typedef {Object} RegistryPackage
147
+ * @property {string} registry - Registry that the package publishes to
148
+ * @property {boolean} exists - Whether the package is on the registry
151
149
  * @property {Record<string, string>} distTags - Dist-tags of the package
152
150
  * @property {string[]} versions - Published versions of the package
153
151
  */
154
152
  /**
155
- * Read the dist-tags and the published versions of each package with `pnpm view`, so
156
- * the lookup uses the same registry configuration and credentials as `pnpm publish`.
153
+ * Read each package from its publish registry with `pnpm view`, so the lookup uses the
154
+ * same registry configuration and credentials as `pnpm publish`.
157
155
  *
158
156
  * @param {PublicPackage[]} packages - Packages to read
159
- * @returns {Promise<Map<string, RegistryPackage | null>>} By package name, null for a package that is not on the registry
157
+ * @param {{ npmOnly?: boolean }} [options] - `npmOnly` reads only the packages that publish to npm.
158
+ * Checks that only concern npm use it, so a missing credential for another registry does not block them.
159
+ * @returns {Promise<Map<string, RegistryPackage>>} By package name
160
+ */
161
+ export declare function getRegistryPackages(packages: PublicPackage[], { npmOnly }?: {
162
+ npmOnly?: boolean;
163
+ }): Promise<Map<string, RegistryPackage>>;
164
+ /**
165
+ * Filter to the packages that must be published by hand before CI can take over.
166
+ *
167
+ * A brand new package has to be pushed once manually (see
168
+ * `code-infra publish-new-package`) before the OIDC-based workflow can publish
169
+ * it, so the release fails with a clear message instead of a confusing 404
170
+ * midway through. See {@link getPackageVersionInfo} for the version-level check.
171
+ *
172
+ * @param {PublicPackage[]} packages - Packages to check
173
+ * @param {Map<string, RegistryPackage>} registryPackages - Registry data from {@link getRegistryPackages}
174
+ * @returns {PublicPackage[]} The subset needing a manual first publish
160
175
  */
161
- export declare function getRegistryPackages(packages: PublicPackage[]): Promise<Map<string, RegistryPackage | null>>;
176
+ export declare function getPackagesNeedingManualPublish(packages: PublicPackage[], registryPackages: Map<string, RegistryPackage>): PublicPackage[];
162
177
  export type DistTagConflict = {
163
178
  /**
164
179
  * - Package to publish
@@ -179,15 +194,15 @@ export type DistTagConflict = {
179
194
  *
180
195
  * @param {PublicPackage[]} packages - Packages to publish
181
196
  * @param {string} tag - Dist-tag to publish with
182
- * @param {Map<string, RegistryPackage | null>} registryPackages - Registry data from {@link getRegistryPackages}
197
+ * @param {Map<string, RegistryPackage>} registryPackages - Registry data from {@link getRegistryPackages}
183
198
  * @returns {DistTagConflict[]}
184
199
  */
185
- export declare function getDistTagConflicts(packages: PublicPackage[], tag: string, registryPackages: Map<string, RegistryPackage | null>): DistTagConflict[];
200
+ export declare function getDistTagConflicts(packages: PublicPackage[], tag: string, registryPackages: Map<string, RegistryPackage>): DistTagConflict[];
186
201
  /**
187
202
  * Get package version info from registry.
188
203
  *
189
204
  * Resolves through `pnpm view`, which reports a lookup failure the same way it
190
- * reports a missing version. Use {@link getPackagesNeedingManualPublish} where
205
+ * reports a missing version. Use {@link getRegistryPackages} where
191
206
  * absence has to be told apart from an error.
192
207
  *
193
208
  * @param {string} packageName - Name of the package
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/internal-code-infra",
3
- "version": "0.1.1-canary.21",
3
+ "version": "0.1.1-canary.23",
4
4
  "author": "MUI Team",
5
5
  "description": "Infra scripts and configs to be used across MUI repos.",
6
6
  "license": "MIT",
@@ -67,23 +67,23 @@
67
67
  "@eslint/compat": "^2.1.1",
68
68
  "@eslint/js": "^10.0.1",
69
69
  "@eslint/json": "^2.1.1",
70
- "@inquirer/confirm": "^6.3.3",
71
- "@inquirer/select": "^5.2.6",
70
+ "@inquirer/confirm": "^6.3.4",
71
+ "@inquirer/select": "^5.2.7",
72
72
  "@mui/internal-babel-plugin-display-name": "2.0.1-canary.2",
73
73
  "@mui/internal-babel-plugin-minify-errors": "3.0.1-canary.2",
74
74
  "@mui/internal-babel-plugin-resolve-imports": "3.0.1-canary.3",
75
- "@napi-rs/keyring": "^2.1.1",
75
+ "@napi-rs/keyring": "^2.1.2",
76
76
  "@octokit/auth-action": "^6.0.3",
77
77
  "@octokit/oauth-methods": "^6.0.5",
78
78
  "@octokit/plugin-retry": "^8.1.1",
79
79
  "@octokit/plugin-throttling": "^11.0.5",
80
80
  "@octokit/rest": "^22.0.1",
81
- "@pnpm/config.version-policy": "^1100.2.8",
81
+ "@pnpm/config.version-policy": "^1100.2.9",
82
82
  "@pnpm/find-workspace-dir": "^1000.1.5",
83
83
  "@pnpm/parse-wanted-dependency": "^1001.0.0",
84
- "@typescript-eslint/types": "^8.71.2",
85
- "@typescript-eslint/utils": "^8.71.2",
86
- "@vitest/eslint-plugin": "^1.6.27",
84
+ "@typescript-eslint/types": "^8.72.0",
85
+ "@typescript-eslint/utils": "^8.72.0",
86
+ "@vitest/eslint-plugin": "^1.6.28",
87
87
  "babel-plugin-optimize-clsx": "^2.6.2",
88
88
  "babel-plugin-react-compiler": "^1.0.0",
89
89
  "babel-plugin-transform-import-meta": "^3.1.0",
@@ -100,19 +100,19 @@
100
100
  "eslint-plugin-compat": "^7.0.2",
101
101
  "eslint-plugin-import": "^2.32.0",
102
102
  "eslint-plugin-jsx-a11y": "^6.10.2",
103
- "eslint-plugin-mdx": "^3.8.1",
103
+ "eslint-plugin-mdx": "^3.8.2",
104
104
  "eslint-plugin-package-json": "^1.10.1",
105
105
  "eslint-plugin-react": "^7.37.5",
106
106
  "eslint-plugin-react-compiler": "^19.1.0-rc.2",
107
107
  "eslint-plugin-react-hooks": "^7.1.1",
108
108
  "eslint-plugin-testing-library": "^7.16.2",
109
- "execa": "^10.1.1",
109
+ "execa": "^10.2.0",
110
110
  "git-url-parse": "^16.1.0",
111
111
  "globals": "^17.13.0",
112
112
  "globby": "^16.2.4",
113
- "html-validate": "^11.16.2",
113
+ "html-validate": "^11.17.0",
114
114
  "minimatch": "^10.2.6",
115
- "node-html-parser": "^9.0.4",
115
+ "node-html-parser": "^9.0.5",
116
116
  "open": "^11.0.4",
117
117
  "postcss-styled-syntax": "^0.7.4",
118
118
  "regexp.escape": "^2.0.1",
@@ -137,7 +137,7 @@
137
137
  "resolve-pkg-maps": "^1.0.0",
138
138
  "semver": "^7.8.5",
139
139
  "stylelint-config-standard": "^40.0.0",
140
- "typescript-eslint": "^8.71.2",
140
+ "typescript-eslint": "^8.72.0",
141
141
  "unified": "^11.0.5",
142
142
  "unified-lint-rule": "^3.0.1",
143
143
  "unist-util-visit": "^5.1.0",
@@ -166,10 +166,10 @@
166
166
  "@types/mdast": "4.0.4",
167
167
  "@types/regexp.escape": "2.0.0",
168
168
  "@types/yargs": "17.0.35",
169
- "@typescript-eslint/parser": "8.71.2",
170
- "@typescript-eslint/rule-tester": "8.71.2",
169
+ "@typescript-eslint/parser": "8.72.0",
170
+ "@typescript-eslint/rule-tester": "8.72.0",
171
171
  "@typescript/native": "npm:typescript@7.0.2",
172
- "eslint": "10.12.0",
172
+ "eslint": "10.13.0",
173
173
  "get-port": "7.2.0",
174
174
  "prettier": "3.9.10",
175
175
  "remark": "15.0.1",
@@ -190,7 +190,7 @@
190
190
  "publishConfig": {
191
191
  "access": "public"
192
192
  },
193
- "gitSha": "e8aec3f286672d4639af7b385ef313c3d8ec74f3",
193
+ "gitSha": "8d779945c318e7e2dada1296b64de1e618a99942",
194
194
  "scripts": {
195
195
  "build": "tsc -p tsconfig.build.json",
196
196
  "typescript": "tsc -noEmit",
@@ -366,7 +366,8 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
366
366
  githubReleaseData = await validateGitHubRelease(version);
367
367
  }
368
368
 
369
- const newPackages = await getPackagesNeedingManualPublish(filteredPackages);
369
+ const registryPackages = await getRegistryPackages(filteredPackages);
370
+ const newPackages = getPackagesNeedingManualPublish(filteredPackages, registryPackages);
370
371
 
371
372
  if (newPackages.length > 0) {
372
373
  const newPackageNames = newPackages.map((pkg) => pkg.name).join(', ');
@@ -375,11 +376,7 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
375
376
  );
376
377
  }
377
378
 
378
- const distTagConflicts = getDistTagConflicts(
379
- filteredPackages,
380
- tag,
381
- await getRegistryPackages(filteredPackages),
382
- );
379
+ const distTagConflicts = getDistTagConflicts(filteredPackages, tag, registryPackages);
383
380
  if (distTagConflicts.length > 0) {
384
381
  throw new Error(
385
382
  `Publishing with the "${tag}" dist-tag would move it to the wrong release line:
@@ -441,8 +438,10 @@ const PUBLISH_WORKFLOW_ID = `.github/${WORKFLOW_PATH}`;
441
438
  */
442
439
  async function triggerLocalGithubPublishWorkflow(opts) {
443
440
  console.log(`🔍 Checking if there are new packages to publish in the workspace...`);
444
- const newPackages = await getPackagesNeedingManualPublish(
445
- await getWorkspacePackages({ publicOnly: true }),
441
+ const packages = await getWorkspacePackages({ publicOnly: true });
442
+ const newPackages = getPackagesNeedingManualPublish(
443
+ packages,
444
+ await getRegistryPackages(packages, { npmOnly: true }),
446
445
  );
447
446
  if (newPackages.length) {
448
447
  console.warn(
@@ -13,6 +13,7 @@ import { getRepositoryInfo } from '../utils/git.mjs';
13
13
  import { toPosixPath } from '../utils/path.mjs';
14
14
  import {
15
15
  getPackagesNeedingManualPublish,
16
+ getRegistryPackages,
16
17
  getWorkspacePackages,
17
18
  PLACEHOLDER_VERSION,
18
19
  } from '../utils/pnpm.mjs';
@@ -50,8 +51,10 @@ export default /** @type {import('yargs').CommandModule<{}, Args>} */ ({
50
51
  }),
51
52
  async handler(args) {
52
53
  console.log(`🔍 Detecting new packages to publish in workspace...`);
53
- const newPackages = await getPackagesNeedingManualPublish(
54
- await getWorkspacePackages({ publicOnly: true }),
54
+ const packages = await getWorkspacePackages({ publicOnly: true });
55
+ const newPackages = getPackagesNeedingManualPublish(
56
+ packages,
57
+ await getRegistryPackages(packages, { npmOnly: true }),
55
58
  );
56
59
 
57
60
  if (!newPackages.length) {
@@ -192,42 +192,82 @@ function requiresTrustedPublisherBootstrap(registry) {
192
192
  }
193
193
 
194
194
  /**
195
- * Filter to the packages that must be published by hand before CI can take over.
196
- *
197
- * A brand new package has to be pushed once manually (see
198
- * `code-infra publish-new-package`) before the OIDC-based workflow can publish
199
- * it, so the release fails with a clear message instead of a confusing 404
200
- * midway through. See {@link getPackageVersionInfo} for the version-level check.
195
+ * @typedef {Object} RegistryPackage
196
+ * @property {string} registry - Registry that the package publishes to
197
+ * @property {boolean} exists - Whether the package is on the registry
198
+ * @property {Record<string, string>} distTags - Dist-tags of the package
199
+ * @property {string[]} versions - Published versions of the package
200
+ */
201
+
202
+ /**
203
+ * Read each package from its publish registry with `pnpm view`, so the lookup uses the
204
+ * same registry configuration and credentials as `pnpm publish`.
201
205
  *
202
- * @param {PublicPackage[]} packages - Packages to check
203
- * @returns {Promise<PublicPackage[]>} The subset needing a manual first publish
206
+ * @param {PublicPackage[]} packages - Packages to read
207
+ * @param {{ npmOnly?: boolean }} [options] - `npmOnly` reads only the packages that publish to npm.
208
+ * Checks that only concern npm use it, so a missing credential for another registry does not block them.
209
+ * @returns {Promise<Map<string, RegistryPackage>>} By package name
204
210
  */
205
- export async function getPackagesNeedingManualPublish(packages) {
206
- const results = await Promise.all(
211
+ export async function getRegistryPackages(packages, { npmOnly = false } = {}) {
212
+ const entries = await Promise.all(
207
213
  packages.map(async (pkg) => {
208
214
  const registry = await getPublishRegistry(pkg.path);
209
- if (!requiresTrustedPublisherBootstrap(registry)) {
210
- return false;
215
+ if (npmOnly && registry !== NPMJS_REGISTRY) {
216
+ return null;
211
217
  }
212
-
213
- // HEAD, because only the status matters — a packument runs to megabytes.
214
- const res = await fetch(new URL(pkg.name, registry), { method: 'HEAD' });
215
- if (res.status === 404) {
216
- return true;
218
+ const { exitCode, stdout, stderr } = await $({
219
+ cwd: pkg.path,
220
+ reject: false,
221
+ // pnpm resolves its own `packageManager` version from `--registry`, which may not serve it.
222
+ env: { PNPM_CONFIG_PM_ON_FAIL: 'ignore' },
223
+ })`pnpm view ${pkg.name} dist-tags versions --json --registry ${registry}`;
224
+ let info;
225
+ try {
226
+ info = JSON.parse(stdout || '{}');
227
+ } catch {
228
+ info = {};
217
229
  }
218
- if (!res.ok) {
219
- // Anything else (401, 5xx, a proxy hiccup) tells us nothing about
220
- // whether the package exists. Treating it as "already published" would
221
- // silently disable the check, so fail loudly instead.
230
+ // Anything but a 404 tells nothing about whether the package exists. Treating it as
231
+ // "not published" would silently disable the checks, so fail loudly instead.
232
+ if (exitCode !== 0 && info.error?.code !== 'ERR_PNPM_FETCH_404') {
222
233
  throw new Error(
223
- `Failed to check whether ${pkg.name} exists on ${registry}: HTTP ${res.status}`,
234
+ `Failed to read ${pkg.name} from ${registry}: ${info.error?.message ?? stderr}`,
224
235
  );
225
236
  }
226
- return false;
237
+ /** @type {RegistryPackage} */
238
+ const registryPackage = {
239
+ registry,
240
+ exists: exitCode === 0,
241
+ distTags: info['dist-tags'] ?? {},
242
+ versions: [info.versions ?? []].flat(),
243
+ };
244
+ return /** @type {const} */ ([pkg.name, registryPackage]);
227
245
  }),
228
246
  );
247
+ return new Map(entries.filter((entry) => entry !== null));
248
+ }
229
249
 
230
- return packages.filter((_pkg, index) => results[index]);
250
+ /**
251
+ * Filter to the packages that must be published by hand before CI can take over.
252
+ *
253
+ * A brand new package has to be pushed once manually (see
254
+ * `code-infra publish-new-package`) before the OIDC-based workflow can publish
255
+ * it, so the release fails with a clear message instead of a confusing 404
256
+ * midway through. See {@link getPackageVersionInfo} for the version-level check.
257
+ *
258
+ * @param {PublicPackage[]} packages - Packages to check
259
+ * @param {Map<string, RegistryPackage>} registryPackages - Registry data from {@link getRegistryPackages}
260
+ * @returns {PublicPackage[]} The subset needing a manual first publish
261
+ */
262
+ export function getPackagesNeedingManualPublish(packages, registryPackages) {
263
+ return packages.filter((pkg) => {
264
+ const registryPackage = registryPackages.get(pkg.name);
265
+ return (
266
+ registryPackage !== undefined &&
267
+ !registryPackage.exists &&
268
+ requiresTrustedPublisherBootstrap(registryPackage.registry)
269
+ );
270
+ });
231
271
  }
232
272
 
233
273
  /**
@@ -256,54 +296,6 @@ function getDistTagConflict(tag, version, current) {
256
296
  return null;
257
297
  }
258
298
 
259
- /**
260
- * @typedef {Object} RegistryPackage
261
- * @property {Record<string, string>} distTags - Dist-tags of the package
262
- * @property {string[]} versions - Published versions of the package
263
- */
264
-
265
- /**
266
- * Read the dist-tags and the published versions of each package with `pnpm view`, so
267
- * the lookup uses the same registry configuration and credentials as `pnpm publish`.
268
- *
269
- * @param {PublicPackage[]} packages - Packages to read
270
- * @returns {Promise<Map<string, RegistryPackage | null>>} By package name, null for a package that is not on the registry
271
- */
272
- export async function getRegistryPackages(packages) {
273
- const entries = await Promise.all(
274
- packages.map(async (pkg) => {
275
- const registry = await getPublishRegistry(pkg.path);
276
- const { exitCode, stdout, stderr } = await $({
277
- cwd: pkg.path,
278
- reject: false,
279
- // pnpm resolves its own `packageManager` version from `--registry`, which may not serve it.
280
- env: { PNPM_CONFIG_PM_ON_FAIL: 'ignore' },
281
- })`pnpm view ${pkg.name} dist-tags versions --json --registry ${registry}`;
282
- let info;
283
- try {
284
- info = JSON.parse(stdout || '{}');
285
- } catch {
286
- info = {};
287
- }
288
- if (exitCode !== 0) {
289
- if (info.error?.code === 'ERR_PNPM_FETCH_404') {
290
- return /** @type {const} */ ([pkg.name, null]);
291
- }
292
- throw new Error(
293
- `Failed to read the dist-tags of ${pkg.name} from ${registry}: ${info.error?.message ?? stderr}`,
294
- );
295
- }
296
- /** @type {RegistryPackage} */
297
- const registryPackage = {
298
- distTags: info['dist-tags'] ?? {},
299
- versions: [info.versions ?? []].flat(),
300
- };
301
- return /** @type {const} */ ([pkg.name, registryPackage]);
302
- }),
303
- );
304
- return new Map(entries);
305
- }
306
-
307
299
  /**
308
300
  * @typedef {Object} DistTagConflict
309
301
  * @property {PublicPackage} pkg - Package to publish
@@ -315,19 +307,19 @@ export async function getRegistryPackages(packages) {
315
307
  *
316
308
  * @param {PublicPackage[]} packages - Packages to publish
317
309
  * @param {string} tag - Dist-tag to publish with
318
- * @param {Map<string, RegistryPackage | null>} registryPackages - Registry data from {@link getRegistryPackages}
310
+ * @param {Map<string, RegistryPackage>} registryPackages - Registry data from {@link getRegistryPackages}
319
311
  * @returns {DistTagConflict[]}
320
312
  */
321
313
  export function getDistTagConflicts(packages, tag, registryPackages) {
322
314
  return packages.flatMap((pkg) => {
323
315
  const registryPackage = registryPackages.get(pkg.name);
324
- // A package that is not on the registry yet has no dist-tags to protect. pnpm skips versions
325
- // that are already published, such as unchanged packages on a legacy branch.
316
+ // pnpm skips versions that are already published, such as unchanged packages on a legacy branch.
326
317
  if (!registryPackage || registryPackage.versions.includes(pkg.version)) {
327
318
  return [];
328
319
  }
320
+ // A package that is not on the registry yet has no dist-tags to protect, and npm points
321
+ // `latest` at the first version, which is the placeholder for a new package.
329
322
  const current = semver.valid(registryPackage.distTags[tag]);
330
- // npm points `latest` at the first version, which is the placeholder for a new package.
331
323
  if (!current || current === PLACEHOLDER_VERSION) {
332
324
  return [];
333
325
  }
@@ -340,7 +332,7 @@ export function getDistTagConflicts(packages, tag, registryPackages) {
340
332
  * Get package version info from registry.
341
333
  *
342
334
  * Resolves through `pnpm view`, which reports a lookup failure the same way it
343
- * reports a missing version. Use {@link getPackagesNeedingManualPublish} where
335
+ * reports a missing version. Use {@link getRegistryPackages} where
344
336
  * absence has to be told apart from an error.
345
337
  *
346
338
  * @param {string} packageName - Name of the package