@adobe/helix-html-pipeline 6.24.2 → 6.25.0

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 CHANGED
@@ -1,3 +1,17 @@
1
+ # [6.25.0](https://github.com/adobe/helix-html-pipeline/compare/v6.24.3...v6.25.0) (2025-04-09)
2
+
3
+
4
+ ### Features
5
+
6
+ * read metadata directly from source if required ([#853](https://github.com/adobe/helix-html-pipeline/issues/853)) ([3160ce7](https://github.com/adobe/helix-html-pipeline/commit/3160ce7b4ce61204666026f4c4d46f295ef6b17f))
7
+
8
+ ## [6.24.3](https://github.com/adobe/helix-html-pipeline/compare/v6.24.2...v6.24.3) (2025-04-07)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **deps:** update dependency mime to v4.0.7 ([#851](https://github.com/adobe/helix-html-pipeline/issues/851)) ([e117c04](https://github.com/adobe/helix-html-pipeline/commit/e117c0463b132b10f8754a04acd06da5b613443b))
14
+
1
15
  ## [6.24.2](https://github.com/adobe/helix-html-pipeline/compare/v6.24.1...v6.24.2) (2025-04-02)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-html-pipeline",
3
- "version": "6.24.2",
3
+ "version": "6.25.0",
4
4
  "description": "Helix HTML Pipeline",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -55,7 +55,7 @@
55
55
  "lodash.escape": "4.0.1",
56
56
  "mdast-util-to-hast": "13.2.0",
57
57
  "mdast-util-to-string": "4.0.0",
58
- "mime": "4.0.6",
58
+ "mime": "4.0.7",
59
59
  "parse5": "7.2.1",
60
60
  "rehype-format": "5.0.1",
61
61
  "rehype-parse": "9.0.1",
package/src/html-pipe.js CHANGED
@@ -36,6 +36,7 @@ import { PipelineResponse } from './PipelineResponse.js';
36
36
  import { validatePathInfo } from './utils/path.js';
37
37
  import fetchMappedMetadata from './steps/fetch-mapped-metadata.js';
38
38
  import { applyMetaLastModified, setLastModified } from './utils/last-modified.js';
39
+ import fetchSourcedMetadata from './steps/fetch-sourced-metadata.js';
39
40
 
40
41
  /**
41
42
  * Fetches the content and if not found, fetches the 404.html
@@ -132,6 +133,7 @@ export async function htmlPipe(state, req) {
132
133
  state.timer?.update('metadata-fetch');
133
134
  await Promise.all([
134
135
  contentPromise,
136
+ fetchSourcedMetadata(state, res),
135
137
  fetchMappedMetadata(state, res),
136
138
  ]);
137
139
 
@@ -0,0 +1,71 @@
1
+ /*
2
+ * Copyright 2021 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { PipelineStatusError } from '../PipelineStatusError.js';
14
+ import { Modifiers } from '../utils/modifiers.js';
15
+ import { extractLastModified, recordLastModified } from '../utils/last-modified.js';
16
+
17
+ /**
18
+ * Loads metadata from the metadata sources if required. this happens when the amount of metadata
19
+ * was too large to include in the config response. the metadata is loaded if
20
+ * `state.metadata` is empty and `config.metadata.source` is not.
21
+ *
22
+ * @type PipelineStep
23
+ * @param {PipelineState} state
24
+ * @param {PipelineResponse} res
25
+ * @returns {Promise<void>}
26
+ */
27
+ // eslint-disable-next-line no-unused-vars
28
+ export default async function fetchSourcedMetadata(state, res) {
29
+ if (!state.metadata.isEmpty()) {
30
+ return;
31
+ }
32
+ const sources = state.config.metadata?.source || [];
33
+ if (sources.length === 0) {
34
+ return;
35
+ }
36
+
37
+ const { contentBusId, partition } = state;
38
+ const metadatas = {};
39
+ await Promise.all(sources.map(async (src) => {
40
+ metadatas[src] = [];
41
+ const key = `${contentBusId}/${partition}/${src}`;
42
+ const ret = await state.s3Loader.getObject('helix-content-bus', key);
43
+ if (ret.status === 200) {
44
+ let json;
45
+ try {
46
+ json = JSON.parse(ret.body);
47
+ } catch (e) {
48
+ throw new PipelineStatusError(500, `failed parsing of ${key}: ${e.message}`);
49
+ }
50
+ const { data } = json.default ?? json;
51
+ if (!data) {
52
+ state.log.info(`default sheet missing in ${key}`);
53
+ return;
54
+ }
55
+
56
+ if (!Array.isArray(data)) {
57
+ throw new PipelineStatusError(500, `failed loading of ${key}: data must be an array`);
58
+ }
59
+ metadatas[src] = data;
60
+ recordLastModified(state, res, 'content', extractLastModified(ret.headers));
61
+ } else if (ret.status !== 404) {
62
+ throw new PipelineStatusError(502, `failed to load ${key}: ${ret.status}`);
63
+ }
64
+ }));
65
+ // aggregate the metadata in the same order as specified
66
+ const metadata = [];
67
+ for (const src of sources) {
68
+ metadata.push(...metadatas[src]);
69
+ }
70
+ state.metadata = Modifiers.fromModifierSheet(metadata);
71
+ }
@@ -124,6 +124,14 @@ export class Modifiers {
124
124
  return new Modifiers(res);
125
125
  }
126
126
 
127
+ /**
128
+ * Returns true if there are no modifiers.
129
+ * @returns {boolean}
130
+ */
131
+ isEmpty() {
132
+ return this.modifiers.length === 0;
133
+ }
134
+
127
135
  constructor(config) {
128
136
  this.modifiers = Object.entries(config).map(([url, mods]) => {
129
137
  const pat = url.indexOf('*') >= 0 ? globToRegExp(url) : url;