@mui/internal-code-infra 0.0.4-canary.62 → 0.0.4-canary.64
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/utils/pnpm.d.mts
CHANGED
|
@@ -135,6 +135,19 @@ export declare function readPackageJson(packagePath: string): Promise<import('..
|
|
|
135
135
|
* @returns {Promise<void>}
|
|
136
136
|
*/
|
|
137
137
|
export declare function writePackageJson(packagePath: string, packageJson: Object): Promise<void>;
|
|
138
|
+
/**
|
|
139
|
+
* Write the computed overrides into whichever manifest already defines
|
|
140
|
+
* overrides — preferring pnpm-workspace.yaml, falling back to package.json
|
|
141
|
+
* `pnpm.overrides`, defaulting to pnpm-workspace.yaml — and persist the result.
|
|
142
|
+
* A missing pnpm-workspace.yaml is treated as empty, so a fresh file is created
|
|
143
|
+
* with just the `overrides:` block. Rejects a `resolutions` field in
|
|
144
|
+
* package.json because pnpm 11 silently ignores it.
|
|
145
|
+
*
|
|
146
|
+
* @param {string} workspaceDir - Workspace root directory
|
|
147
|
+
* @param {Record<string, string>} overrides - Overrides to apply
|
|
148
|
+
* @returns {Promise<void>}
|
|
149
|
+
*/
|
|
150
|
+
export declare function writeOverridesToWorkspace(workspaceDir: string, overrides: Record<string, string>): Promise<void>;
|
|
138
151
|
/**
|
|
139
152
|
* Resolve a package@version specifier to an exact version
|
|
140
153
|
* @param {string} packageSpec - Package specifier in format "package@version"
|
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.64",
|
|
4
4
|
"author": "MUI Team",
|
|
5
5
|
"description": "Infra scripts and configs to be used across MUI repos.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -138,10 +138,11 @@
|
|
|
138
138
|
"unified": "^11.0.5",
|
|
139
139
|
"unified-lint-rule": "^3.0.1",
|
|
140
140
|
"unist-util-visit": "^5.1.0",
|
|
141
|
+
"yaml": "^2.9.0",
|
|
141
142
|
"yargs": "^18.0.0",
|
|
142
|
-
"@mui/internal-babel-plugin-
|
|
143
|
+
"@mui/internal-babel-plugin-display-name": "1.0.4-canary.20",
|
|
143
144
|
"@mui/internal-babel-plugin-minify-errors": "2.0.8-canary.27",
|
|
144
|
-
"@mui/internal-babel-plugin-
|
|
145
|
+
"@mui/internal-babel-plugin-resolve-imports": "2.0.7-canary.36"
|
|
145
146
|
},
|
|
146
147
|
"peerDependencies": {
|
|
147
148
|
"@next/eslint-plugin-next": "*",
|
|
@@ -191,7 +192,7 @@
|
|
|
191
192
|
"publishConfig": {
|
|
192
193
|
"access": "public"
|
|
193
194
|
},
|
|
194
|
-
"gitSha": "
|
|
195
|
+
"gitSha": "42ab800dc8926bfe1c6ea3020a013565143f1bd6",
|
|
195
196
|
"scripts": {
|
|
196
197
|
"build": "tsgo -p tsconfig.build.json",
|
|
197
198
|
"typescript": "tsgo -noEmit",
|
|
@@ -9,6 +9,7 @@ import { Transform } from 'node:stream';
|
|
|
9
9
|
import { Worker } from 'node:worker_threads';
|
|
10
10
|
|
|
11
11
|
const DEFAULT_CONCURRENCY = 4;
|
|
12
|
+
const SERVER_START_TIMEOUT = 10000;
|
|
12
13
|
|
|
13
14
|
const crawlWorkerUrl = new URL('./crawlWorker.mjs', import.meta.url);
|
|
14
15
|
|
|
@@ -620,30 +621,56 @@ export async function crawl(rawOptions) {
|
|
|
620
621
|
|
|
621
622
|
/** @type {AbortController | null} */
|
|
622
623
|
let controller = null;
|
|
623
|
-
if (options.startCommand) {
|
|
624
|
-
console.log(chalk.blue(`Starting server with "${options.startCommand}"...`));
|
|
625
|
-
controller = new AbortController();
|
|
626
|
-
const appProcess = execaCommand(options.startCommand, {
|
|
627
|
-
stdout: 'pipe',
|
|
628
|
-
stderr: 'pipe',
|
|
629
|
-
cancelSignal: controller.signal,
|
|
630
|
-
env: {
|
|
631
|
-
FORCE_COLOR: '1',
|
|
632
|
-
...process.env,
|
|
633
|
-
},
|
|
634
|
-
});
|
|
635
624
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
625
|
+
try {
|
|
626
|
+
if (options.startCommand) {
|
|
627
|
+
console.log(chalk.blue(`Starting server with "${options.startCommand}"...`));
|
|
628
|
+
controller = new AbortController();
|
|
629
|
+
const appProcess = execaCommand(options.startCommand, {
|
|
630
|
+
stdout: 'pipe',
|
|
631
|
+
stderr: 'pipe',
|
|
632
|
+
cancelSignal: controller.signal,
|
|
633
|
+
env: {
|
|
634
|
+
FORCE_COLOR: '1',
|
|
635
|
+
...process.env,
|
|
636
|
+
},
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
// Prefix server logs
|
|
640
|
+
const serverPrefix = chalk.gray('server: ');
|
|
641
|
+
appProcess.stdout.pipe(prefixLines(serverPrefix)).pipe(process.stdout);
|
|
642
|
+
appProcess.stderr.pipe(prefixLines(serverPrefix)).pipe(process.stderr);
|
|
643
|
+
appProcess.catch(() => {});
|
|
641
644
|
|
|
642
|
-
|
|
645
|
+
// Poll the first page we are about to crawl (resolved against host) so we
|
|
646
|
+
// wait for the actual entry point to be serveable rather than the
|
|
647
|
+
// homepage, which may be a different (slower) page.
|
|
648
|
+
const healthcheckUrl = new URL(options.seedUrls[0] ?? '/', options.host).href;
|
|
649
|
+
await pollUrl(healthcheckUrl, SERVER_START_TIMEOUT);
|
|
643
650
|
|
|
644
|
-
|
|
651
|
+
console.log(`Server started on ${chalk.underline(options.host)}`);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
return await runCrawl(options, startTime);
|
|
655
|
+
} finally {
|
|
656
|
+
// Always stop the server, even when startup or crawling throws. Without
|
|
657
|
+
// this, a failed healthcheck (or any error) would leave the dev server
|
|
658
|
+
// running, which on slow environments (e.g. Netlify) leads to orphaned
|
|
659
|
+
// servers piling up across retries.
|
|
660
|
+
if (controller) {
|
|
661
|
+
console.log(chalk.blue('Stopping server...'));
|
|
662
|
+
controller.abort();
|
|
663
|
+
}
|
|
645
664
|
}
|
|
665
|
+
}
|
|
646
666
|
|
|
667
|
+
/**
|
|
668
|
+
* Runs the crawl against an already-running server.
|
|
669
|
+
* @param {ResolvedCrawlOptions} options - Fully resolved crawl options
|
|
670
|
+
* @param {number} startTime - Timestamp (ms) when the crawl began, for duration reporting
|
|
671
|
+
* @returns {Promise<CrawlResult>} Crawl results including all links, pages, and issues found
|
|
672
|
+
*/
|
|
673
|
+
async function runCrawl(options, startTime) {
|
|
647
674
|
const knownTargets = await resolveKnownTargets(options);
|
|
648
675
|
|
|
649
676
|
/** @type {Map<string, Promise<PageData>>} */
|
|
@@ -733,11 +760,6 @@ export async function crawl(rawOptions) {
|
|
|
733
760
|
|
|
734
761
|
await queue.waitAll();
|
|
735
762
|
|
|
736
|
-
if (controller) {
|
|
737
|
-
console.log(chalk.blue('Stopping server...'));
|
|
738
|
-
controller.abort();
|
|
739
|
-
}
|
|
740
|
-
|
|
741
763
|
const results = new Map(
|
|
742
764
|
await Promise.all(
|
|
743
765
|
Array.from(crawledPages.entries(), async ([a, b]) => /** @type {const} */ ([a, await b])),
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import fs from 'node:fs/promises';
|
|
4
|
-
import os from 'node:os';
|
|
5
|
-
import path from 'node:path';
|
|
6
3
|
import * as semver from 'semver';
|
|
7
4
|
import { $ } from 'execa';
|
|
8
|
-
import {
|
|
5
|
+
import { findWorkspaceDir } from '@pnpm/find-workspace-dir';
|
|
6
|
+
import {
|
|
7
|
+
resolveVersion,
|
|
8
|
+
findDependencyVersionFromSpec,
|
|
9
|
+
writeOverridesToWorkspace,
|
|
10
|
+
} from '../utils/pnpm.mjs';
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* @typedef {Object} Args
|
|
@@ -103,11 +105,8 @@ async function handler(args) {
|
|
|
103
105
|
// eslint-disable-next-line no-console
|
|
104
106
|
console.log(`Using overrides: ${JSON.stringify(overrides, null, 2)}`);
|
|
105
107
|
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
packageJson.resolutions ??= {};
|
|
109
|
-
Object.assign(packageJson.resolutions, overrides);
|
|
110
|
-
await fs.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}${os.EOL}`);
|
|
108
|
+
const workspaceDir = (await findWorkspaceDir(process.cwd())) ?? process.cwd();
|
|
109
|
+
await writeOverridesToWorkspace(workspaceDir, overrides);
|
|
111
110
|
|
|
112
111
|
await $({ stdio: 'inherit' })`pnpm dedupe`;
|
|
113
112
|
}
|
package/src/utils/pnpm.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import { $ } from 'execa';
|
|
|
5
5
|
import * as fs from 'node:fs/promises';
|
|
6
6
|
import * as path from 'node:path';
|
|
7
7
|
import * as semver from 'semver';
|
|
8
|
+
import { parseDocument, isMap } from 'yaml';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* @typedef {Object} PrivatePackage
|
|
@@ -385,6 +386,68 @@ export async function writePackageJson(packagePath, packageJson) {
|
|
|
385
386
|
await fs.writeFile(path.join(packagePath, 'package.json'), content);
|
|
386
387
|
}
|
|
387
388
|
|
|
389
|
+
/**
|
|
390
|
+
* Write the computed overrides into whichever manifest already defines
|
|
391
|
+
* overrides — preferring pnpm-workspace.yaml, falling back to package.json
|
|
392
|
+
* `pnpm.overrides`, defaulting to pnpm-workspace.yaml — and persist the result.
|
|
393
|
+
* A missing pnpm-workspace.yaml is treated as empty, so a fresh file is created
|
|
394
|
+
* with just the `overrides:` block. Rejects a `resolutions` field in
|
|
395
|
+
* package.json because pnpm 11 silently ignores it.
|
|
396
|
+
*
|
|
397
|
+
* @param {string} workspaceDir - Workspace root directory
|
|
398
|
+
* @param {Record<string, string>} overrides - Overrides to apply
|
|
399
|
+
* @returns {Promise<void>}
|
|
400
|
+
*/
|
|
401
|
+
export async function writeOverridesToWorkspace(workspaceDir, overrides) {
|
|
402
|
+
const workspaceYamlPath = path.join(workspaceDir, 'pnpm-workspace.yaml');
|
|
403
|
+
const yamlPromise = fs.readFile(workspaceYamlPath, { encoding: 'utf8' }).catch((error) => {
|
|
404
|
+
if (/** @type {NodeJS.ErrnoException} */ (error).code !== 'ENOENT') {
|
|
405
|
+
throw error;
|
|
406
|
+
}
|
|
407
|
+
return '';
|
|
408
|
+
});
|
|
409
|
+
const [rootPackageJson, yamlSource] = await Promise.all([
|
|
410
|
+
readPackageJson(workspaceDir),
|
|
411
|
+
yamlPromise,
|
|
412
|
+
]);
|
|
413
|
+
|
|
414
|
+
const { resolutions } = rootPackageJson;
|
|
415
|
+
if (resolutions && Object.keys(resolutions).length > 0) {
|
|
416
|
+
throw new Error(
|
|
417
|
+
'Found a "resolutions" field in package.json. pnpm 11 ignores it silently. ' +
|
|
418
|
+
'Move those entries into the "overrides:" key of pnpm-workspace.yaml.',
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Parsed once, reused for both the read (does it have overrides?) and the write.
|
|
423
|
+
const doc = parseDocument(yamlSource);
|
|
424
|
+
const existing = doc.get('overrides');
|
|
425
|
+
const workspaceHasOverrides = isMap(existing) && existing.items.length > 0;
|
|
426
|
+
|
|
427
|
+
const pnpm = /** @type {{ overrides?: Record<string, string> } | undefined} */ (
|
|
428
|
+
rootPackageJson.pnpm
|
|
429
|
+
);
|
|
430
|
+
const packageJsonOverrides = pnpm?.overrides;
|
|
431
|
+
|
|
432
|
+
// Write where overrides already live; default to the workspace file.
|
|
433
|
+
if (
|
|
434
|
+
!workspaceHasOverrides &&
|
|
435
|
+
packageJsonOverrides &&
|
|
436
|
+
Object.keys(packageJsonOverrides).length > 0
|
|
437
|
+
) {
|
|
438
|
+
await writePackageJson(workspaceDir, {
|
|
439
|
+
...rootPackageJson,
|
|
440
|
+
pnpm: { ...pnpm, overrides: { ...packageJsonOverrides, ...overrides } },
|
|
441
|
+
});
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
for (const [name, version] of Object.entries(overrides)) {
|
|
446
|
+
doc.setIn(['overrides', name], version);
|
|
447
|
+
}
|
|
448
|
+
await fs.writeFile(workspaceYamlPath, doc.toString());
|
|
449
|
+
}
|
|
450
|
+
|
|
388
451
|
/**
|
|
389
452
|
* Resolve a package@version specifier to an exact version
|
|
390
453
|
* @param {string} packageSpec - Package specifier in format "package@version"
|
package/src/utils/pnpm.test.mjs
CHANGED
|
@@ -3,7 +3,12 @@ import * as path from 'node:path';
|
|
|
3
3
|
import { describe, it, expect } from 'vitest';
|
|
4
4
|
|
|
5
5
|
import { makeTempDir } from './testUtils.mjs';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
checkPublishDependencies,
|
|
8
|
+
readPackageJson,
|
|
9
|
+
writePackageJson,
|
|
10
|
+
writeOverridesToWorkspace,
|
|
11
|
+
} from './pnpm.mjs';
|
|
7
12
|
|
|
8
13
|
/**
|
|
9
14
|
* Write a package.json file to a temp subdirectory and return the directory path.
|
|
@@ -578,3 +583,149 @@ describe('checkPublishDependencies', () => {
|
|
|
578
583
|
});
|
|
579
584
|
});
|
|
580
585
|
});
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Set up a temp workspace with a package.json and optional pnpm-workspace.yaml.
|
|
589
|
+
* @param {object} packageJson - package.json contents
|
|
590
|
+
* @param {string} [workspaceYaml] - pnpm-workspace.yaml contents, omitted to skip the file
|
|
591
|
+
* @returns {Promise<string>} The workspace directory
|
|
592
|
+
*/
|
|
593
|
+
async function makeWorkspace(packageJson, workspaceYaml) {
|
|
594
|
+
const cwd = await makeTempDir();
|
|
595
|
+
const writes = [writePackageJson(cwd, packageJson)];
|
|
596
|
+
if (workspaceYaml !== undefined) {
|
|
597
|
+
writes.push(fs.writeFile(path.join(cwd, 'pnpm-workspace.yaml'), workspaceYaml));
|
|
598
|
+
}
|
|
599
|
+
await Promise.all(writes);
|
|
600
|
+
return cwd;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* @param {string} cwd
|
|
605
|
+
* @returns {Promise<string>}
|
|
606
|
+
*/
|
|
607
|
+
function readWorkspaceYaml(cwd) {
|
|
608
|
+
return fs.readFile(path.join(cwd, 'pnpm-workspace.yaml'), 'utf8');
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
describe('writeOverridesToWorkspace', () => {
|
|
612
|
+
describe('writing to pnpm-workspace.yaml', () => {
|
|
613
|
+
it('creates the file with an overrides block when none exists', async () => {
|
|
614
|
+
const cwd = await makeWorkspace({ name: 'root' });
|
|
615
|
+
|
|
616
|
+
await writeOverridesToWorkspace(cwd, { foo: '1.2.3' });
|
|
617
|
+
|
|
618
|
+
expect(await readWorkspaceYaml(cwd)).toMatchInlineSnapshot(`
|
|
619
|
+
"overrides:
|
|
620
|
+
foo: 1.2.3
|
|
621
|
+
"
|
|
622
|
+
`);
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
it('merges into an existing block, preserving comments and quoting scoped names', async () => {
|
|
626
|
+
const cwd = await makeWorkspace(
|
|
627
|
+
{ name: 'root' },
|
|
628
|
+
[
|
|
629
|
+
'packages:',
|
|
630
|
+
" - 'packages/*'",
|
|
631
|
+
'overrides:',
|
|
632
|
+
' # keep this pin',
|
|
633
|
+
" bar: '2.0.0'",
|
|
634
|
+
'',
|
|
635
|
+
].join('\n'),
|
|
636
|
+
);
|
|
637
|
+
|
|
638
|
+
await writeOverridesToWorkspace(cwd, { playwright: '1.49.1', '@playwright/test': '1.49.1' });
|
|
639
|
+
|
|
640
|
+
expect(await readWorkspaceYaml(cwd)).toMatchInlineSnapshot(`
|
|
641
|
+
"packages:
|
|
642
|
+
- 'packages/*'
|
|
643
|
+
overrides:
|
|
644
|
+
# keep this pin
|
|
645
|
+
bar: '2.0.0'
|
|
646
|
+
playwright: 1.49.1
|
|
647
|
+
"@playwright/test": 1.49.1
|
|
648
|
+
"
|
|
649
|
+
`);
|
|
650
|
+
// The package.json is left untouched.
|
|
651
|
+
expect(await readPackageJson(cwd)).toEqual({ name: 'root' });
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
it('overwrites a same-named override, keeping its quote style', async () => {
|
|
655
|
+
const cwd = await makeWorkspace(
|
|
656
|
+
{ name: 'root' },
|
|
657
|
+
['overrides:', " foo: '1.0.0'", ''].join('\n'),
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
await writeOverridesToWorkspace(cwd, { foo: '2.0.0' });
|
|
661
|
+
|
|
662
|
+
expect(await readWorkspaceYaml(cwd)).toMatchInlineSnapshot(`
|
|
663
|
+
"overrides:
|
|
664
|
+
foo: '2.0.0'
|
|
665
|
+
"
|
|
666
|
+
`);
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
it('prefers the workspace file when both manifests define overrides', async () => {
|
|
670
|
+
const cwd = await makeWorkspace(
|
|
671
|
+
{ name: 'root', pnpm: { overrides: { baz: '3.0.0' } } },
|
|
672
|
+
['overrides:', " bar: '2.0.0'", ''].join('\n'),
|
|
673
|
+
);
|
|
674
|
+
|
|
675
|
+
await writeOverridesToWorkspace(cwd, { foo: '1.2.3' });
|
|
676
|
+
|
|
677
|
+
expect(await readWorkspaceYaml(cwd)).toContain('foo: 1.2.3');
|
|
678
|
+
// package.json overrides are left where they were.
|
|
679
|
+
expect(await readPackageJson(cwd)).toEqual({
|
|
680
|
+
name: 'root',
|
|
681
|
+
pnpm: { overrides: { baz: '3.0.0' } },
|
|
682
|
+
});
|
|
683
|
+
});
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
describe('writing to package.json', () => {
|
|
687
|
+
it('honors the package.json location when no workspace overrides exist', async () => {
|
|
688
|
+
const cwd = await makeWorkspace({
|
|
689
|
+
name: 'root',
|
|
690
|
+
pnpm: { overrides: { foo: '1.0.0' }, packageExtensions: { thing: {} } },
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
await writeOverridesToWorkspace(cwd, { bar: '2.0.0' });
|
|
694
|
+
|
|
695
|
+
expect(await readPackageJson(cwd)).toEqual({
|
|
696
|
+
name: 'root',
|
|
697
|
+
pnpm: { overrides: { foo: '1.0.0', bar: '2.0.0' }, packageExtensions: { thing: {} } },
|
|
698
|
+
});
|
|
699
|
+
// No workspace file is created.
|
|
700
|
+
await expect(fs.access(path.join(cwd, 'pnpm-workspace.yaml'))).rejects.toThrow();
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
it('lets computed overrides win over an existing package.json override', async () => {
|
|
704
|
+
const cwd = await makeWorkspace({ name: 'root', pnpm: { overrides: { foo: '1.0.0' } } });
|
|
705
|
+
|
|
706
|
+
await writeOverridesToWorkspace(cwd, { foo: '2.0.0' });
|
|
707
|
+
|
|
708
|
+
expect(await readPackageJson(cwd)).toEqual({
|
|
709
|
+
name: 'root',
|
|
710
|
+
pnpm: { overrides: { foo: '2.0.0' } },
|
|
711
|
+
});
|
|
712
|
+
});
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
describe('rejecting resolutions', () => {
|
|
716
|
+
it('throws and writes nothing when package.json has a resolutions field', async () => {
|
|
717
|
+
const cwd = await makeWorkspace({ name: 'root', resolutions: { foo: '1.0.0' } });
|
|
718
|
+
|
|
719
|
+
await expect(writeOverridesToWorkspace(cwd, { bar: '2.0.0' })).rejects.toThrow(/resolutions/);
|
|
720
|
+
await expect(fs.access(path.join(cwd, 'pnpm-workspace.yaml'))).rejects.toThrow();
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
it('ignores an empty resolutions field', async () => {
|
|
724
|
+
const cwd = await makeWorkspace({ name: 'root', resolutions: {} });
|
|
725
|
+
|
|
726
|
+
await writeOverridesToWorkspace(cwd, { foo: '1.2.3' });
|
|
727
|
+
|
|
728
|
+
expect(await readWorkspaceYaml(cwd)).toContain('foo: 1.2.3');
|
|
729
|
+
});
|
|
730
|
+
});
|
|
731
|
+
});
|