@adobe/helix-html-pipeline 6.27.23 → 6.27.25
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/CHANGELOG.md +14 -0
- package/CLAUDE.md +75 -0
- package/package.json +4 -4
- package/src/steps/init-config.js +7 -2
- package/src/steps/utils.js +12 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [6.27.25](https://github.com/adobe/helix-html-pipeline/compare/v6.27.24...v6.27.25) (2026-03-10)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* better logging for xfh ([b09cf5d](https://github.com/adobe/helix-html-pipeline/commit/b09cf5de887f56aadebf6db37812910a9d45f7e2))
|
|
7
|
+
|
|
8
|
+
## [6.27.24](https://github.com/adobe/helix-html-pipeline/compare/v6.27.23...v6.27.24) (2026-03-10)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **init-config:** warn when cdn.prod.host is absent and x-forwarded-host fallback is used ([#1038](https://github.com/adobe/helix-html-pipeline/issues/1038)) ([ba213ab](https://github.com/adobe/helix-html-pipeline/commit/ba213ab6a989697927c85578d06af1e5afeae229))
|
|
14
|
+
|
|
1
15
|
## [6.27.23](https://github.com/adobe/helix-html-pipeline/compare/v6.27.22...v6.27.23) (2026-02-22)
|
|
2
16
|
|
|
3
17
|
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm test # Run tests with c8 code coverage
|
|
9
|
+
npm run lint # Run ESLint
|
|
10
|
+
npm ci # Install dependencies (CI-style)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Run a single test file:
|
|
14
|
+
```bash
|
|
15
|
+
npx mocha test/html-pipe.test.js
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Run a specific test by name (grep):
|
|
19
|
+
```bash
|
|
20
|
+
npx mocha --grep "test name" test/rendering.test.js
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Architecture
|
|
24
|
+
|
|
25
|
+
This is a platform-neutral (Node + Cloudflare Worker) library for rendering Helix3 HTML responses. It serves as shared code between `helix-pipeline-service` and `helix-cloudflare-page`.
|
|
26
|
+
|
|
27
|
+
### Entry Points (Pipe Functions)
|
|
28
|
+
|
|
29
|
+
Each HTTP response type has a dedicated "pipe" function:
|
|
30
|
+
- **`htmlPipe`** (`src/html-pipe.js`) — Markdown → HTML rendering pipeline (30+ steps)
|
|
31
|
+
- **`jsonPipe`** (`src/json-pipe.js`) — JSON response pipeline with folder mapping
|
|
32
|
+
- **`optionsPipe`** (`src/options-pipe.js`) — HTTP OPTIONS method handler
|
|
33
|
+
- **`robotsPipe`** (`src/robots-pipe.js`) — `robots.txt` generation
|
|
34
|
+
- **`sitemapPipe`** (`src/sitemap-pipe.js`) — XML sitemap generation
|
|
35
|
+
|
|
36
|
+
### Core Classes
|
|
37
|
+
|
|
38
|
+
- **`PipelineState`** — Execution context; holds org, site, repo, owner, ref, partition, metadata, headers, and content
|
|
39
|
+
- **`PipelineRequest`** / **`PipelineResponse`** — HTTP request/response wrappers
|
|
40
|
+
- **`PipelineContent`** — Content container (source markdown, parsed AST, rendered HTML)
|
|
41
|
+
- **`PipelineStatusError`** — Custom error for pipeline-specific HTTP status codes
|
|
42
|
+
|
|
43
|
+
### Pipeline Steps Pattern
|
|
44
|
+
|
|
45
|
+
Each step is an async function with signature `(state, req?, res?) => void`. Steps live in `src/steps/` and are composed in sequence within each pipe function. Categories:
|
|
46
|
+
- **Content fetching**: `fetch-content.js`, `fetch-404.js`, `fetch-sourced-metadata.js`
|
|
47
|
+
- **Markdown processing**: `parse-markdown.js`, `split-sections.js`
|
|
48
|
+
- **HTML transformation**: `make-html.js`, `create-page-blocks.js`, `create-pictures.js`, `extract-metadata.js`
|
|
49
|
+
- **URL rewriting**: `rewrite-urls.js`, `rewrite-icons.js`
|
|
50
|
+
- **Response formatting**: `stringify-response.js`, `render.js`, `render-code.js`
|
|
51
|
+
|
|
52
|
+
### AST Processing
|
|
53
|
+
|
|
54
|
+
Uses the `unified` ecosystem (remark for Markdown, rehype for HTML). The conversion path is: raw Markdown → mdast (via `remark-parse`) → hast (via custom `mdast-to-hast.js`) → serialized HTML (via `rehype-stringify`). Custom handling in `src/utils/mdast-to-hast.js` and `src/utils/hast-utils.js`.
|
|
55
|
+
|
|
56
|
+
### Platform Abstraction
|
|
57
|
+
|
|
58
|
+
Crypto operations use `src/utils/crypto.node.js` vs `src/utils/crypto.worker.js` to stay compatible with both Node.js and Cloudflare Worker runtimes. No Node-specific or browser-specific modules should be added as runtime dependencies.
|
|
59
|
+
|
|
60
|
+
### Content Sources
|
|
61
|
+
|
|
62
|
+
Content is fetched from two S3-backed sources:
|
|
63
|
+
- **Content bus** — Markdown and metadata (`.md`, `metadata.json`)
|
|
64
|
+
- **Code bus** — Templates, headers, footers, scripts
|
|
65
|
+
|
|
66
|
+
The S3 loader is injected into `PipelineState` and abstracted for testing via `test/FileS3Loader.js` and `test/StaticS3Loader.js`.
|
|
67
|
+
|
|
68
|
+
## Testing
|
|
69
|
+
|
|
70
|
+
Tests use Mocha + c8. Test fixtures live in `test/fixtures/` organized by type (`content/`, `code/`, `json/`, `mdasts/`, `sections/`). The `test/setup-env.js` file initializes the test environment.
|
|
71
|
+
|
|
72
|
+
Key test files:
|
|
73
|
+
- `test/rendering.test.js` — Large integration tests for HTML rendering (49KB)
|
|
74
|
+
- `test/html-pipe.test.js` / `test/json-pipe.test.js` — Pipe-level integration tests
|
|
75
|
+
- `test/steps/` and `test/utils/` — Unit tests for individual modules
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-html-pipeline",
|
|
3
|
-
"version": "6.27.
|
|
3
|
+
"version": "6.27.25",
|
|
4
4
|
"description": "Helix HTML Pipeline",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -70,12 +70,12 @@
|
|
|
70
70
|
"unist-util-visit-parents": "6.0.2"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@adobe/eslint-config-helix": "3.0.
|
|
73
|
+
"@adobe/eslint-config-helix": "3.0.21",
|
|
74
74
|
"@eslint/config-helpers": "0.5.2",
|
|
75
75
|
"@markedjs/html-differ": "5.0.4",
|
|
76
76
|
"@semantic-release/changelog": "6.0.3",
|
|
77
77
|
"@semantic-release/git": "10.0.1",
|
|
78
|
-
"@semantic-release/npm": "13.1.
|
|
78
|
+
"@semantic-release/npm": "13.1.4",
|
|
79
79
|
"c8": "10.1.3",
|
|
80
80
|
"eslint": "9.4.0",
|
|
81
81
|
"eslint-import-resolver-exports": "1.0.0-beta.5",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"esmock": "2.7.3",
|
|
85
85
|
"husky": "9.1.7",
|
|
86
86
|
"js-yaml": "4.1.1",
|
|
87
|
-
"jsdom": "28.
|
|
87
|
+
"jsdom": "28.1.0",
|
|
88
88
|
"junit-report-builder": "5.1.1",
|
|
89
89
|
"lint-staged": "16.2.7",
|
|
90
90
|
"mocha": "11.7.5",
|
package/src/steps/init-config.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
import { Modifiers } from '../utils/modifiers.js';
|
|
13
|
-
import { getOriginalHost } from './utils.js';
|
|
13
|
+
import { getOriginalHost, getXFH } from './utils.js';
|
|
14
14
|
import { recordLastModified } from '../utils/last-modified.js';
|
|
15
15
|
|
|
16
16
|
function replaceParams(str, info) {
|
|
@@ -43,6 +43,11 @@ export default function initConfig(state, req, res) {
|
|
|
43
43
|
// set custom preview and live hosts
|
|
44
44
|
state.previewHost = replaceParams(config.cdn?.preview?.host, state);
|
|
45
45
|
state.liveHost = replaceParams(config.cdn?.live?.host, state);
|
|
46
|
-
|
|
46
|
+
const configuredProdHost = config.cdn?.prod?.host;
|
|
47
|
+
const xfh = getXFH(req.headers);
|
|
48
|
+
if (!configuredProdHost && xfh && !xfh.endsWith('.aem.page') && !xfh.endsWith('.aem.live')) {
|
|
49
|
+
state.log.warn(`[${state.org}/${state.site}] cdn.prod.host is not configured, falling back to x-forwarded-host: ${xfh}`);
|
|
50
|
+
}
|
|
51
|
+
state.prodHost = configuredProdHost || getOriginalHost(req.headers);
|
|
47
52
|
recordLastModified(state, res, 'config', state.config.lastModified);
|
|
48
53
|
}
|
package/src/steps/utils.js
CHANGED
|
@@ -17,11 +17,11 @@ const MEDIA_BLOB_REGEXP = /^https:\/\/.*\.(aem|hlx3?)\.(live|page)\/media_.*/;
|
|
|
17
17
|
const HELIX_URL_REGEXP = /^https:\/\/.*\.(aem|hlx3?)\.(live|page)\/?.*/;
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* Returns the
|
|
20
|
+
* Returns the x-forwarded-host from the header
|
|
21
21
|
* @param {object} headers The request headers
|
|
22
22
|
* @returns {string} The original host
|
|
23
23
|
*/
|
|
24
|
-
export function
|
|
24
|
+
export function getXFH(headers) {
|
|
25
25
|
const xfh = headers.get('x-forwarded-host');
|
|
26
26
|
if (xfh) {
|
|
27
27
|
const segs = xfh.split(',');
|
|
@@ -32,7 +32,16 @@ export function getOriginalHost(headers) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
return
|
|
35
|
+
return '';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Returns the original host name from the request to the outer CDN.
|
|
40
|
+
* @param {object} headers The request headers
|
|
41
|
+
* @returns {string} The original host
|
|
42
|
+
*/
|
|
43
|
+
export function getOriginalHost(headers) {
|
|
44
|
+
return getXFH(headers) || headers.get('host');
|
|
36
45
|
}
|
|
37
46
|
|
|
38
47
|
/**
|