Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dev/test/proof-packaging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('proof packaging boundary', () => {
for (const [name, version] of Object.entries(proofTooling)) {
expect(packageJson.dependencies[name]).toBeUndefined();
expect(packageJson.devDependencies[name]).toBe(version);
expect(packageJson.peerDependencies[name]).toBe(version);
expect(packageJson.peerDependencies[name]).toBe(`^${version}`);
expect(packageJson.peerDependenciesMeta[name]).toEqual({ optional: true });
}
});
Expand Down
5 changes: 3 additions & 2 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ Library plus `convert`, `assemble`, `validate`, `fix`, `author`, `plugin`, `cont
and `skill` need only Block Runner's production dependencies. WP-CLI remains an
external requirement only when selected for context, token, or media resolution.

The browser-proof packages are exact optional peers, absent from a basic installation.
Install them only where real-WordPress proof will run.
The browser-proof packages are optional peers with compatible caret ranges, absent from a basic
installation. The proof setup below deliberately pins the known-good versions for reproducible
real-WordPress proof.

Set up the runtime/editor proof boundary before requesting `runtime` or `editor`:

Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@
"vitest": "4.1.11"
},
"peerDependencies": {
"@playwright/test": "1.61.1",
"@wordpress/e2e-test-utils-playwright": "1.51.0",
"@wordpress/env": "11.15.0",
"axe-core": "4.11.0",
"pixelmatch": "7.1.0",
"pngjs": "7.0.0"
"@playwright/test": "^1.61.1",
"@wordpress/e2e-test-utils-playwright": "^1.51.0",
"@wordpress/env": "^11.15.0",
"axe-core": "^4.11.0",
"pixelmatch": "^7.1.0",
"pngjs": "^7.0.0"
},
"peerDependenciesMeta": {
"@playwright/test": {
Expand Down
21 changes: 17 additions & 4 deletions scripts/package-boundary-check.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const basic = installPacked(tarball, 'basic');
const manifest = basic.require('block-runner/package.json');
await verifyBasicConsumer(basic);

const conflictingGutenberg = installPacked(tarball, 'conflicting-gutenberg', ['@wordpress/blocks@16.0.0']);
await verifyConflictingGutenbergConsumer(conflictingGutenberg);

const proof = installPacked(tarball, 'proof');
await verifyProofConsumer(proof);
const installedDependencyInventory = compareInstalledDependencyInventories(
Expand All @@ -58,7 +61,7 @@ async function verifyBasicConsumer({ consumer, packageRoot, cli, require }) {
const manifest = require('block-runner/package.json');
for (const name of PROOF_TOOLING) {
if (manifest.dependencies[name]) throw new Error(`Proof tooling remains a production dependency: ${name}`);
if (manifest.peerDependencies?.[name] !== manifest.devDependencies?.[name]) throw new Error(`Proof peer is not pinned to development tooling: ${name}`);
if (manifest.peerDependencies?.[name] !== `^${manifest.devDependencies?.[name]}`) throw new Error(`Proof peer is not a compatible range from development tooling: ${name}`);
if (manifest.peerDependenciesMeta?.[name]?.optional !== true) throw new Error(`Proof peer is not optional: ${name}`);
try {
require.resolve(`${name}/package.json`);
Expand Down Expand Up @@ -103,12 +106,22 @@ async function verifyBasicConsumer({ consumer, packageRoot, cli, require }) {
}
}

async function verifyConflictingGutenbergConsumer({ packageRoot }) {
const library = await import(pathToFileURL(path.join(packageRoot, 'dist', 'index.js')).href);
const report = await library.author('<section><p>Pinned runtime.</p><h2>Core blocks agree.</h2><p>Save hooks retain their attributes.</p></section>', {
author: { name: 'acme/conflicting-gutenberg-runtime', title: 'Conflicting Gutenberg runtime' },
});
if (!report.ok || !report.package?.canonicalPlan) {
throw new Error(`Packed authoring failed with a conflicting top-level @wordpress/blocks version: ${JSON.stringify(report.items)}`);
}
}

async function verifyProofConsumer({ consumer, packageRoot, cli, require }) {
const manifest = require('block-runner/package.json');
const pins = Object.entries(manifest.peerDependencies ?? {}).map(([name, version]) => `${name}@${version}`);
const pins = PROOF_TOOLING.map((name) => `${name}@${manifest.devDependencies[name]}`);
run('npm', ['install', '--ignore-scripts', '--no-audit', '--no-fund', '--save-dev', '--save-exact', ...pins], { cwd: consumer });
for (const name of PROOF_TOOLING) {
const expected = manifest.peerDependencies[name];
const expected = manifest.devDependencies[name];
const installed = require(`${name}/package.json`).version;
if (installed !== expected) throw new Error(`Proof tooling pin mismatch for ${name}: expected ${expected}, got ${installed}`);
}
Expand Down Expand Up @@ -194,7 +207,7 @@ function compareInstalledDependencyInventories(proofEnabled, basic) {

function proofToolingInstallCommand(manifest, profile) {
const required = profile === 'full' ? PROOF_TOOLING : PROOF_TOOLING.slice(0, 4);
return `npm install --save-dev --save-exact ${required.map((name) => `${name}@${manifest.peerDependencies?.[name]}`).join(' ')}`;
return `npm install --save-dev --save-exact ${required.map((name) => `${name}@${manifest.devDependencies?.[name]}`).join(' ')}`;
}

function run(command, args, { cwd = ROOT, expectedStatus = 0, env = process.env } = {}) {
Expand Down
9 changes: 8 additions & 1 deletion src/headless/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,18 @@ export function bootHeadlessWordPressSync(): WpModules {
installDomGlobals();

const require = createRequire(import.meta.url);
const blockLibraryEntry = require.resolve('@wordpress/block-library');
// Core block save functions call block-editor helpers. Resolve the registry from that same
// block-editor package rather than from this package: npm may otherwise nest an identical
// @wordpress/blocks version here when the consumer has a newer top-level copy.
const blockLibraryRequire = createRequire(blockLibraryEntry);
const blockEditorEntry = blockLibraryRequire.resolve('@wordpress/block-editor');
const blockEditorRequire = createRequire(blockEditorEntry);
const { blockLibrary, blocks } = withMutedWordPressConsole(() => ({
blockLibrary: require('@wordpress/block-library') as {
registerCoreBlocks: () => void;
},
blocks: require('@wordpress/blocks') as WpModules,
blocks: blockEditorRequire('@wordpress/blocks') as WpModules,
}));

withMutedWordPressConsole(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/proof/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1917,7 +1917,7 @@ function commandFailure(command: string, error: unknown): ProofCommandResult {
}

function proofToolingVersion(name: (typeof PROOF_TOOLING)[number]): string {
const version = packageJson.peerDependencies?.[name] ?? packageJson.devDependencies?.[name];
const version = packageJson.devDependencies?.[name];
if (!version) throw new Error(`Missing pinned proof tooling declaration for ${name}.`);
return version;
}
Expand Down
Loading