@adobe/helix-html-pipeline 3.9.0 → 3.10.1

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
+ ## [3.10.1](https://github.com/adobe/helix-html-pipeline/compare/v3.10.0...v3.10.1) (2023-04-11)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * read contentbus-id from helix-config ([#291](https://github.com/adobe/helix-html-pipeline/issues/291)) ([c3ff2a8](https://github.com/adobe/helix-html-pipeline/commit/c3ff2a85a33f34c81a8d99f9afcbe085691734e9))
7
+
8
+ # [3.10.0](https://github.com/adobe/helix-html-pipeline/compare/v3.9.0...v3.10.0) (2023-03-28)
9
+
10
+
11
+ ### Features
12
+
13
+ * **picture:** update mobile breakpoint to 600px ([#280](https://github.com/adobe/helix-html-pipeline/issues/280)) ([6c72cba](https://github.com/adobe/helix-html-pipeline/commit/6c72cbaead55fb69b1c7d4c102052cc09a330b50))
14
+
1
15
  # [3.9.0](https://github.com/adobe/helix-html-pipeline/compare/v3.8.12...v3.9.0) (2023-03-23)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-html-pipeline",
3
- "version": "3.9.0",
3
+ "version": "3.10.1",
4
4
  "description": "Helix HTML Pipeline",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -56,12 +56,12 @@
56
56
  "mdast-util-gfm-table": "1.0.7",
57
57
  "mdast-util-gfm-task-list-item": "1.0.2",
58
58
  "mdast-util-to-hast": "12.3.0",
59
- "mdast-util-to-string": "3.1.1",
60
- "micromark-extension-gfm-footnote": "1.0.4",
61
- "micromark-extension-gfm-strikethrough": "1.0.4",
59
+ "mdast-util-to-string": "3.2.0",
60
+ "micromark-extension-gfm-footnote": "1.1.0",
61
+ "micromark-extension-gfm-strikethrough": "1.0.5",
62
62
  "micromark-extension-gfm-table": "1.0.5",
63
- "micromark-extension-gfm-tagfilter": "1.0.1",
64
- "micromark-extension-gfm-task-list-item": "1.0.3",
63
+ "micromark-extension-gfm-tagfilter": "1.0.2",
64
+ "micromark-extension-gfm-task-list-item": "1.0.4",
65
65
  "micromark-util-combine-extensions": "1.0.0",
66
66
  "mime": "3.0.0",
67
67
  "rehype-format": "4.0.1",
@@ -79,24 +79,24 @@
79
79
  "devDependencies": {
80
80
  "@adobe/eslint-config-helix": "2.0.2",
81
81
  "@markedjs/html-differ": "4.0.2",
82
- "@semantic-release/changelog": "6.0.2",
82
+ "@semantic-release/changelog": "6.0.3",
83
83
  "@semantic-release/git": "10.0.1",
84
- "@semantic-release/npm": "9.0.2",
84
+ "@semantic-release/npm": "10.0.3",
85
85
  "c8": "7.13.0",
86
- "eslint": "8.36.0",
86
+ "eslint": "8.38.0",
87
87
  "eslint-import-resolver-exports": "1.0.0-beta.5",
88
88
  "eslint-plugin-header": "3.1.1",
89
89
  "eslint-plugin-import": "2.27.5",
90
- "esmock": "2.1.0",
90
+ "esmock": "2.2.1",
91
91
  "husky": "8.0.3",
92
92
  "js-yaml": "4.1.0",
93
93
  "jsdom": "21.1.1",
94
94
  "junit-report-builder": "3.0.1",
95
- "lint-staged": "13.2.0",
95
+ "lint-staged": "13.2.1",
96
96
  "mocha": "10.2.0",
97
97
  "mocha-multi-reporters": "1.5.1",
98
98
  "remark-gfm": "3.0.1",
99
- "semantic-release": "20.1.3"
99
+ "semantic-release": "21.0.1"
100
100
  },
101
101
  "lint-staged": {
102
102
  "*.js": "eslint",
package/src/forms-pipe.js CHANGED
@@ -14,6 +14,7 @@ import { PipelineResponse } from './PipelineResponse.js';
14
14
  import fetchConfigAll from './steps/fetch-config-all.js';
15
15
  import setCustomResponseHeaders from './steps/set-custom-response-headers.js';
16
16
  import { authenticate } from './steps/authenticate.js';
17
+ import fetchConfig from './steps/fetch-config.js';
17
18
 
18
19
  function error(log, msg, status, response) {
19
20
  log.error(msg);
@@ -83,25 +84,36 @@ export async function extractBodyData(request) {
83
84
  * Handle a pipeline POST request.
84
85
  * At this point POST's only apply to json files that are backed by a workbook.
85
86
  * @param {PipelineState} state pipeline options
86
- * @param {PipelineRequest} request
87
+ * @param {PipelineRequest} req
87
88
  * @returns {Promise<PipelineResponse>} a response
88
89
  */
89
- export async function formsPipe(state, request) {
90
+ export async function formsPipe(state, req) {
90
91
  const { log } = state;
91
92
  state.type = 'form';
92
93
 
93
94
  // todo: improve
94
- const response = new PipelineResponse('', {
95
+ const res = new PipelineResponse('', {
95
96
  headers: {
96
97
  'content-type': 'text/plain; charset=utf-8',
97
98
  },
98
99
  });
99
- await fetchConfigAll(state, request, response);
100
- await authenticate(state, request, response);
101
- if (response.error) {
102
- return response;
100
+ try {
101
+ await fetchConfig(state, req, res);
102
+ } catch (e) {
103
+ // ignore
104
+ }
105
+ if (!state.contentBusId) {
106
+ res.status = 400;
107
+ res.headers.set('x-error', 'contentBusId missing');
108
+ return res;
109
+ }
110
+
111
+ await fetchConfigAll(state, req, res);
112
+ await authenticate(state, req, res);
113
+ if (res.error) {
114
+ return res;
103
115
  }
104
- await setCustomResponseHeaders(state, request, response);
116
+ await setCustomResponseHeaders(state, req, res);
105
117
 
106
118
  const {
107
119
  owner, repo, ref, contentBusId, partition, s3Loader,
@@ -111,7 +123,7 @@ export async function formsPipe(state, request) {
111
123
 
112
124
  // block all POSTs to resources with extensions
113
125
  if (state.info.originalExtension !== '') {
114
- return error(log, 'POST to URL with extension not allowed', 405, response);
126
+ return error(log, 'POST to URL with extension not allowed', 405, res);
115
127
  }
116
128
 
117
129
  // head workbook in content bus
@@ -122,22 +134,22 @@ export async function formsPipe(state, request) {
122
134
 
123
135
  let body;
124
136
  try {
125
- body = await extractBodyData(request);
137
+ body = await extractBodyData(req);
126
138
  } catch (err) {
127
- return error(log, err.message, 400, response);
139
+ return error(log, err.message, 400, res);
128
140
  }
129
141
 
130
142
  const sheets = resourceFetchResponse.headers.get('x-amz-meta-x-sheet-names');
131
143
  if (!sheets) {
132
- return error(log, `Target workbook at ${resourcePath} missing x-sheet-names header.`, 403, response);
144
+ return error(log, `Target workbook at ${resourcePath} missing x-sheet-names header.`, 403, res);
133
145
  }
134
146
 
135
147
  const sourceLocation = resourceFetchResponse.headers.get('x-amz-meta-x-source-location');
136
- const referer = request.headers.get('referer') || 'unknown';
148
+ const referer = req.headers.get('referer') || 'unknown';
137
149
  const sheetNames = sheets.split(',').map((s) => s.trim());
138
150
 
139
151
  if (!sourceLocation || !sheetNames.includes('incoming')) {
140
- return error(log, `Target workbook at ${resourcePath} is not setup to intake data.`, 403, response);
152
+ return error(log, `Target workbook at ${resourcePath} is not setup to intake data.`, 403, res);
141
153
  }
142
154
 
143
155
  // Send message to SQS if workbook contains and incoming
@@ -159,11 +171,11 @@ export async function formsPipe(state, request) {
159
171
  try {
160
172
  // Send message to forms queue
161
173
  const { requestId, messageId } = await state.messageDispatcher.dispatch(message);
162
- response.status = 201;
163
- response.headers.set('x-request-id', requestId);
164
- response.headers.set('x-message-id', messageId);
165
- return response;
174
+ res.status = 201;
175
+ res.headers.set('x-request-id', requestId);
176
+ res.headers.set('x-message-id', messageId);
177
+ return res;
166
178
  } catch (err) {
167
- return error(log, `Failed to send message to forms queue: ${err}`, 500, response);
179
+ return error(log, `Failed to send message to forms queue: ${err}`, 500, res);
168
180
  }
169
181
  }
package/src/html-pipe.js CHANGED
@@ -71,15 +71,14 @@ export async function htmlPipe(state, req) {
71
71
  }
72
72
  }
73
73
 
74
- if (!state.contentBusId) {
75
- res.status = 400;
76
- res.headers.set('x-error', 'contentBusId missing');
77
- return res;
78
- }
79
-
80
74
  try { // fetch config first, since we need to compute the content-bus-id from the fstab ...
81
75
  state.timer?.update('config-fetch');
82
76
  await fetchConfig(state, req, res);
77
+ if (!state.contentBusId) {
78
+ res.status = 400;
79
+ res.headers.set('x-error', 'contentBusId missing');
80
+ return res;
81
+ }
83
82
 
84
83
  // ...and apply the folder mapping
85
84
  await folderMapping(state);
package/src/json-pipe.js CHANGED
@@ -102,6 +102,14 @@ export async function jsonPipe(state, req) {
102
102
  try {
103
103
  // fetch config and apply the folder mapping
104
104
  await fetchConfig(state, req);
105
+ if (!state.contentBusId) {
106
+ return new PipelineResponse('', {
107
+ status: 400,
108
+ headers: {
109
+ 'x-error': 'contentBusId missing',
110
+ },
111
+ });
112
+ }
105
113
  await folderMapping(state);
106
114
 
107
115
  /** @type PipelineResponse */
@@ -14,7 +14,7 @@ import { h } from 'hastscript';
14
14
  import { visitParents } from 'unist-util-visit-parents';
15
15
 
16
16
  const BREAK_POINTS = [
17
- { media: '(min-width: 400px)', width: '2000' },
17
+ { media: '(min-width: 600px)', width: '2000' },
18
18
  { width: '750' },
19
19
  ];
20
20
 
@@ -47,6 +47,21 @@ export default async function fetchConfig(state, req, res) {
47
47
  });
48
48
  }
49
49
 
50
+ // set contentbusid from header if missing in config
51
+ const cbid = ret.headers.get('x-contentbus-id');
52
+ if (!config.content && cbid) {
53
+ config.content = {
54
+ data: {
55
+ '/': {
56
+ contentBusId: cbid.substring(2),
57
+ },
58
+ },
59
+ };
60
+ }
61
+ if (!state.contentBusId) {
62
+ state.contentBusId = config.content?.data?.['/']?.contentBusId;
63
+ }
64
+
50
65
  if (res) {
51
66
  // also update last-modified
52
67
  const configLastModified = extractLastModified(ret.headers);
@@ -11,6 +11,8 @@
11
11
  */
12
12
  import mime from 'mime';
13
13
 
14
+ const CHARSET_RE = /charset=([^()<>@,;:"/[\]?.=\s]*)/i;
15
+
14
16
  /**
15
17
  * "Renders" the content from the code-bus as-is
16
18
  * @type PipelineStep
@@ -21,5 +23,13 @@ import mime from 'mime';
21
23
  */
22
24
  export default async function renderCode(state, req, res) {
23
25
  res.body = state.content.data;
24
- res.headers.set('content-type', mime.getType(state.info.resourcePath));
26
+ let contentType = mime.getType(state.info.resourcePath);
27
+ const originalType = res.headers.get('content-type');
28
+ if (originalType) {
29
+ const match = CHARSET_RE.exec(originalType);
30
+ if (match) {
31
+ contentType += `; charset=${match[1]}`;
32
+ }
33
+ }
34
+ res.headers.set('content-type', contentType);
25
35
  }