From 61a2efe5a2c735efd491d9844b4f13fa5c4a0c7d Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Mon, 22 Jun 2026 23:01:42 -0400 Subject: [PATCH] Compile artifact entry HTML by default --- php-transformer/README.md | 2 +- .../src/ArtifactCompiler/ArtifactCompiler.php | 21 +------------------ php-transformer/tests/contract/run.php | 5 +++-- .../parity/artifact-generated-html.json | 13 +++++++++--- 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/php-transformer/README.md b/php-transformer/README.md index 899bcf1..6055012 100644 --- a/php-transformer/README.md +++ b/php-transformer/README.md @@ -126,7 +126,7 @@ if ('failed' === $result['status']) { ## Artifact Compiler Fallbacks -The artifact compiler accepts loose generated-site bundles and normalizes them into an explicit result envelope. HTML entries are preserved as `core/html` serialized block markup, Markdown falls back to `core/html` when a Markdown adapter is not loaded, and MDX support is partial: source documents are preserved while imports and JSX component references are exposed as inspectable metadata and warnings. +The artifact compiler accepts loose generated-site bundles and normalizes them into an explicit result envelope. Safe HTML entries are compiled through `HtmlTransformer` into native serialized block markup, Markdown falls back to `core/html` when a Markdown adapter is not loaded, and MDX support is partial: source documents are preserved while imports and JSX component references are exposed as inspectable metadata and warnings. Unsupported or unsafe artifact inputs are reported through diagnostics instead of hidden best-effort behavior. Empty, absolute, or root-escaping paths are rejected; oversized files are ignored according to the source report limits; and a bundle with neither an HTML entry nor source documents fails with `missing_entry_html`. diff --git a/php-transformer/src/ArtifactCompiler/ArtifactCompiler.php b/php-transformer/src/ArtifactCompiler/ArtifactCompiler.php index 2b2fa2b..ba330fa 100644 --- a/php-transformer/src/ArtifactCompiler/ArtifactCompiler.php +++ b/php-transformer/src/ArtifactCompiler/ArtifactCompiler.php @@ -137,7 +137,7 @@ private function compileEntryBlocks(string $html, string $entryPath, array $file ); } - if ( '' === trim($html) || ! $this->entryHtmlReferencesImageAsset($html, $entryPath, $files) ) { + if ( '' === trim($html) ) { return array( 'blocks' => array(), 'serialized_blocks' => '', @@ -159,25 +159,6 @@ private function compileEntryBlocks(string $html, string $entryPath, array $file ); } - /** - * @param array> $files - */ - private function entryHtmlReferencesImageAsset(string $html, string $entryPath, array $files): bool - { - if ( ! preg_match_all('/]*src\s*=\s*(["\'])([^"\']+)\1/i', $html, $matches) ) { - return false; - } - - foreach ( $matches[2] as $src ) { - $asset = $this->findAssetByHtmlReference((string) $src, $entryPath, $files); - if ( is_array($asset) && str_starts_with((string) ($asset['mime_type'] ?? ''), 'image/') && $this->isSafeImageAsset($asset) ) { - return true; - } - } - - return false; - } - /** * @param array> $files */ diff --git a/php-transformer/tests/contract/run.php b/php-transformer/tests/contract/run.php index ba9e98c..8978116 100644 --- a/php-transformer/tests/contract/run.php +++ b/php-transformer/tests/contract/run.php @@ -154,12 +154,13 @@ function serialize_blocks(array $blocks): string $assert(ArtifactCompiler::INPUT_SCHEMA === ($simple['source_reports']['artifact']['schema'] ?? ''), 'artifact report exposes canonical site artifact schema'); $assert(ArtifactCompiler::INPUT_SCHEMA === ($simple['source_reports']['artifact']['original_schema'] ?? ''), 'canonical site artifact input schema is accepted and preserved'); $assert('index.html' === ($simple['source_reports']['artifact']['entry_path'] ?? ''), 'generated HTML becomes an index entry'); -$assert(str_contains((string) $simple['serialized_blocks'], ''), 'HTML is preserved as serialized block markup'); +$assert(str_contains((string) $simple['serialized_blocks'], ''), 'artifact HTML does not fall back to raw HTML when transformer-safe'); $assert('hero' === ($simple['components'][0]['name'] ?? ''), 'component candidates are exposed'); $assert(! array_key_exists('legacy_mapping', $simple), 'artifact result omits compatibility-only legacy mapping'); $assert(strlen('

Hello artifact

') === ($simple['metrics']['input_bytes'] ?? null), 'artifact metrics expose input bytes'); $assert(strlen((string) $simple['serialized_blocks']) === ($simple['metrics']['output_bytes'] ?? null), 'artifact metrics expose output bytes'); -$assert(0 === ($simple['metrics']['block_count'] ?? null), 'artifact metrics expose block count'); +$assert(2 === ($simple['metrics']['block_count'] ?? null), 'artifact metrics expose nested block count'); $assert(0 === ($simple['metrics']['fallback_count'] ?? null), 'artifact metrics expose fallback count'); $assert(0 === ($simple['metrics']['diagnostic_count'] ?? null), 'artifact metrics expose diagnostic count'); $assert(is_float($simple['metrics']['transform_duration_ms'] ?? null), 'artifact metrics expose transform duration'); diff --git a/php-transformer/tests/fixtures/parity/artifact-generated-html.json b/php-transformer/tests/fixtures/parity/artifact-generated-html.json index 214f49f..be816e7 100644 --- a/php-transformer/tests/fixtures/parity/artifact-generated-html.json +++ b/php-transformer/tests/fixtures/parity/artifact-generated-html.json @@ -1,11 +1,11 @@ { "schema": "blocks-engine/php-transformer/parity-fixture/v1", "name": "artifact-generated-html-entry", - "description": "Compiles generated HTML artifact input into the shared transformer result shape.", + "description": "Compiles generated static HTML artifact input without images into native block markup through the HTML transformer.", "source_reference": { "repo": "php-transformer", "path": "tests/fixtures/parity/artifact-generated-html.json", - "notes": "Covers the artifact compiler contract smoke path." + "notes": "Covers the artifact compiler default HTML transform path when entry markup has no local image references." }, "operation": "artifact_compiler.compile", "input": { @@ -13,13 +13,20 @@ "generated_html": "

Hello artifact

" } }, + "expected_blocks": [ + { "path": "blocks.0", "name": "core/group" }, + { "path": "blocks.0.innerBlocks.0", "name": "core/heading", "attrs": { "content": "Hello artifact", "level": 1 } } + ], + "expected_fallbacks": [], "expect": [ { "path": "schema", "assert": "equals", "value": "blocks-engine/php-transformer/result/v1" }, { "path": "status", "assert": "equals", "value": "success" }, { "path": "source_reports.artifact.entry_path", "assert": "equals", "value": "index.html" }, { "path": "components.0.name", "assert": "equals", "value": "hero" }, - { "path": "serialized_blocks", "assert": "contains", "value": "" }, + { "path": "serialized_blocks", "assert": "contains", "value": "" }, + { "path": "serialized_blocks", "assert": "contains", "value": "" }, { "path": "serialized_blocks", "assert": "contains", "value": "

Hello artifact

" }, + { "path": "serialized_blocks", "assert": "not_contains", "value": "" }, { "path": "source_reports.artifact.html.element_count", "assert": "equals", "value": 3 }, { "path": "source_reports.conversion_report.metrics.fallback_count", "assert": "equals", "value": 0 }, { "path": "provenance.0.source_format", "assert": "equals", "value": "artifact" }