@adobe/helix-html-pipeline 3.11.24 → 3.12.2

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,24 @@
1
+ ## [3.12.2](https://github.com/adobe/helix-html-pipeline/compare/v3.12.1...v3.12.2) (2023-08-02)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * remove legacy loading of metadata.json ([#373](https://github.com/adobe/helix-html-pipeline/issues/373)) ([59d9f99](https://github.com/adobe/helix-html-pipeline/commit/59d9f99f145b0795961d3cfc912b3c8929c628a1))
7
+
8
+ ## [3.12.1](https://github.com/adobe/helix-html-pipeline/compare/v3.12.0...v3.12.1) (2023-07-27)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **deps:** update dependency @adobe/helix-markdown-support to v6.3.0 ([04d0c6c](https://github.com/adobe/helix-html-pipeline/commit/04d0c6c50831f8cac4bd31fa0a33367fabb68563))
14
+
15
+ # [3.12.0](https://github.com/adobe/helix-html-pipeline/compare/v3.11.24...v3.12.0) (2023-07-25)
16
+
17
+
18
+ ### Features
19
+
20
+ * also rewrite custom preview and live host links ([#367](https://github.com/adobe/helix-html-pipeline/issues/367)) ([#368](https://github.com/adobe/helix-html-pipeline/issues/368)) ([0127e72](https://github.com/adobe/helix-html-pipeline/commit/0127e720f67fcbd41bc862b26f0e5c42e3979e57)), closes [#359](https://github.com/adobe/helix-html-pipeline/issues/359)
21
+
1
22
  ## [3.11.24](https://github.com/adobe/helix-html-pipeline/compare/v3.11.23...v3.11.24) (2023-07-23)
2
23
 
3
24
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-html-pipeline",
3
- "version": "3.11.24",
3
+ "version": "3.12.2",
4
4
  "description": "Helix HTML Pipeline",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -39,7 +39,7 @@
39
39
  "node": ">=16.x"
40
40
  },
41
41
  "dependencies": {
42
- "@adobe/helix-markdown-support": "6.2.1",
42
+ "@adobe/helix-markdown-support": "6.3.0",
43
43
  "@adobe/helix-shared-utils": "3.0.0",
44
44
  "@adobe/mdast-util-gridtables": "2.0.2",
45
45
  "@adobe/remark-gridtables": "1.0.4",
@@ -72,12 +72,12 @@
72
72
  "@semantic-release/changelog": "6.0.3",
73
73
  "@semantic-release/git": "10.0.1",
74
74
  "@semantic-release/npm": "10.0.4",
75
- "c8": "8.0.0",
76
- "eslint": "8.45.0",
75
+ "c8": "8.0.1",
76
+ "eslint": "8.46.0",
77
77
  "eslint-import-resolver-exports": "1.0.0-beta.5",
78
78
  "eslint-plugin-header": "3.1.1",
79
- "eslint-plugin-import": "2.27.5",
80
- "esmock": "2.3.2",
79
+ "eslint-plugin-import": "2.28.0",
80
+ "esmock": "2.3.5",
81
81
  "husky": "8.0.3",
82
82
  "js-yaml": "4.1.0",
83
83
  "jsdom": "22.1.0",
@@ -12,6 +12,7 @@
12
12
  import {PathInfo, S3Loader, FormsMessageDispatcher, PipelineTimer} from "./index";
13
13
  import {PipelineContent} from "./PipelineContent";
14
14
  import {Modifiers} from './utils/modifiers';
15
+ import {ProjectConfig} from "./project-config";
15
16
 
16
17
  declare enum PipelineType {
17
18
  html = 'html',
@@ -29,13 +30,6 @@ declare interface AccessConfig {
29
30
  };
30
31
  }
31
32
 
32
- declare interface HelixConfigAll {
33
- host:string;
34
- routes:RegExp[];
35
- access?:AccessConfig;
36
- [string]:any;
37
- }
38
-
39
33
  declare interface PipelineOptions {
40
34
  log: Console;
41
35
  s3Loader: S3Loader;
@@ -97,7 +91,7 @@ declare class PipelineState {
97
91
  /**
98
92
  * the /.helix/config.json in object form
99
93
  */
100
- config?: HelixConfigAll;
94
+ config?: ProjectConfig;
101
95
 
102
96
  /**
103
97
  * the metadata.json in modifier form.
@@ -123,5 +117,17 @@ declare class PipelineState {
123
117
  * Authentication information
124
118
  */
125
119
  authInfo?: AuthInfo;
120
+
121
+ /**
122
+ * the custom preview host if configured via config.cdn.preview.host
123
+ * this is initialized after the config is loaded.
124
+ */
125
+ previewHost?: string;
126
+
127
+ /**
128
+ * the custom live host if configured via config.cdn.live.host
129
+ * this is initialized after the config is loaded.
130
+ */
131
+ liveHost?: string;
126
132
  }
127
133
 
@@ -0,0 +1,157 @@
1
+ /*
2
+ * Copyright 2023 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
+ // NOTE: this file is autogenerated via 'npm run docs:types' in helix-admin-support
14
+
15
+ export interface ProjectConfig {
16
+ /**
17
+ * Name of the project used by the slack bot when reporting.
18
+ */
19
+ name?: string;
20
+ /**
21
+ * Name of the project used by the sidekick.
22
+ */
23
+ project?: string;
24
+ /**
25
+ * Timezone to be used by the slack bot when reporting times.
26
+ */
27
+ timezone?: string;
28
+ /**
29
+ * Production host use by the slack bot to display project information.
30
+ */
31
+ host?: string;
32
+ /**
33
+ * configuration blueprint repository in the owner/repo format.
34
+ */
35
+ blueprint?: string;
36
+ /**
37
+ * the slack teamId/channelID(s) where the slack bot is used.
38
+ */
39
+ slack?: string | string[];
40
+ cdn?: ProjectCDNConfig;
41
+ access?: SiteAccessConfig;
42
+ admin?: AdminConfig;
43
+ }
44
+ /**
45
+ * The CDN config
46
+ */
47
+ export interface ProjectCDNConfig {
48
+ prod: FastlyConfig | AkamaiConfig | CloudflareConfig | ManagedConfig;
49
+ live?: {
50
+ /**
51
+ * Sidekick config to override the default preview host. it supports parameters $owner and $repo
52
+ */
53
+ host: string;
54
+ };
55
+ preview?: {
56
+ /**
57
+ * Sidekick config to override the default live host. it supports parameters $owner and $repo
58
+ */
59
+ host: string;
60
+ };
61
+ }
62
+ /**
63
+ * Production CDN configuration for Fastly
64
+ */
65
+ export interface FastlyConfig {
66
+ type: 'fastly';
67
+ /**
68
+ * production host
69
+ */
70
+ host: string;
71
+ /**
72
+ * Route or routes on the CDN that are rendered with Franklin
73
+ */
74
+ route: string | string[];
75
+ /**
76
+ * The Fastly Service ID
77
+ */
78
+ serviceId: string;
79
+ /**
80
+ * A Fastly token for purging
81
+ */
82
+ authToken: string;
83
+ }
84
+ export interface AkamaiConfig {
85
+ type: 'akamai';
86
+ /**
87
+ * production host
88
+ */
89
+ host: string;
90
+ /**
91
+ * Route or routes on the CDN that are rendered with Franklin
92
+ */
93
+ route: string | string[];
94
+ endpoint: string;
95
+ clientSecret: string;
96
+ clientToken: string;
97
+ accessToken: string;
98
+ }
99
+ export interface CloudflareConfig {
100
+ type: 'cloudflare';
101
+ /**
102
+ * production host
103
+ */
104
+ host: string;
105
+ /**
106
+ * Route or routes on the CDN that are rendered with Franklin
107
+ */
108
+ route: string | string[];
109
+ origin: string;
110
+ plan: string;
111
+ zoneId: string;
112
+ apiToken: string;
113
+ }
114
+ export interface ManagedConfig {
115
+ type: 'managed';
116
+ /**
117
+ * production host
118
+ */
119
+ host: string;
120
+ /**
121
+ * Route or routes on the CDN that are rendered with Franklin
122
+ */
123
+ route: string | string[];
124
+ }
125
+ export interface SiteAccessConfig {
126
+ /**
127
+ * The email glob of the users that are allowed.
128
+ */
129
+ allow: string | string[];
130
+ /**
131
+ * the id of the API key(s). this is used to validate the API KEYS and allows to invalidate them.
132
+ */
133
+ apiKeyId?: string | string[];
134
+ require?: {
135
+ /**
136
+ * The list of owner/repo pointers to projects that are allowed to use this content.
137
+ */
138
+ repository: string | string[];
139
+ };
140
+ }
141
+ export interface AdminConfig {
142
+ role?: Role;
143
+ /**
144
+ * the id of the API key(s). this is used to validate the API KEYS and allows to invalidate them.
145
+ */
146
+ apiKeyId?: string | string[];
147
+ }
148
+ export interface Role {
149
+ /**
150
+ * The email glob of the users with author role.
151
+ */
152
+ author?: string | string[];
153
+ /**
154
+ * The email glob of the users with publish role.
155
+ */
156
+ publish?: string | string[];
157
+ }
@@ -12,60 +12,9 @@
12
12
 
13
13
  import { PipelineStatusError } from '../PipelineStatusError.js';
14
14
  import { extractLastModified, updateLastModified } from '../utils/last-modified.js';
15
- import { ALLOWED_RESPONSE_HEADERS, globToRegExp, Modifiers } from '../utils/modifiers.js';
15
+ import { globToRegExp, Modifiers } from '../utils/modifiers.js';
16
16
  import { getOriginalHost } from './utils.js';
17
17
 
18
- /**
19
- * Loads the metadata.json from the content-bus and stores it in `state.metadata` and
20
- * `state.headers` in modifier form.
21
- * this is to be backward compatible and can be removed in the future.
22
- *
23
- * @type PipelineStep
24
- * @param {PipelineState} state
25
- * @param {PipelineRequest} req
26
- * @param {PipelineResponse} res
27
- * @returns {Promise<void>}
28
- */
29
- async function fetchMetadata(state, req, res) {
30
- const { contentBusId, partition } = state;
31
- const key = `${contentBusId}/${partition}/metadata.json`;
32
- const ret = await state.s3Loader.getObject('helix-content-bus', key);
33
- if (ret.status === 200) {
34
- let json;
35
- try {
36
- json = JSON.parse(ret.body);
37
- } catch (e) {
38
- throw new PipelineStatusError(500, `failed parsing of /metadata.json: ${e.message}`);
39
- }
40
-
41
- const { data } = json.default ?? json;
42
- if (!Array.isArray(data)) {
43
- throw new PipelineStatusError(500, 'failed loading of /metadata.json: data must be an array');
44
- }
45
-
46
- state.metadata = Modifiers.fromModifierSheet(
47
- data,
48
- (name) => !ALLOWED_RESPONSE_HEADERS.includes(name),
49
- );
50
- state.headers = Modifiers.fromModifierSheet(
51
- data,
52
- (name) => ALLOWED_RESPONSE_HEADERS.includes(name),
53
- );
54
-
55
- if (state.type === 'html' && state.info.selector !== 'plain') {
56
- // also update last-modified (only for extensionless html pipeline)
57
- updateLastModified(state, res, extractLastModified(ret.headers));
58
- }
59
- return;
60
- }
61
-
62
- if (ret.status !== 404) {
63
- throw new PipelineStatusError(502, `failed to load /metadata.json: ${ret.status}`);
64
- }
65
-
66
- // ignore 404
67
- }
68
-
69
18
  /**
70
19
  * Computes the routes from the given config value.
71
20
  * @param {string|string[]|undefined} value
@@ -87,6 +36,15 @@ export function computeRoutes(value) {
87
36
  });
88
37
  }
89
38
 
39
+ function replaceParams(str, info) {
40
+ if (!str) {
41
+ return '';
42
+ }
43
+ return str
44
+ .replaceAll('$owner', info.owner)
45
+ .replaceAll('$repo', info.repo);
46
+ }
47
+
90
48
  /**
91
49
  * Loads the /.helix/config-all.json from the content-bus and stores it in the state. if no
92
50
  * such config exists, it will load the metadata.json as fallback and separate out the
@@ -117,11 +75,15 @@ export default async function fetchConfigAll(state, req, res) {
117
75
  // also update last-modified (only for extensionless html pipeline)
118
76
  updateLastModified(state, res, extractLastModified(ret.headers));
119
77
  }
120
- } else if (ret.status !== 404) {
121
- throw new PipelineStatusError(502, `failed to load /.helix/config-all.json: ${ret.status}`);
78
+ // set custom preview and live hosts
79
+ state.previewHost = replaceParams(state.config.cdn?.preview?.host, state);
80
+ state.liveHost = replaceParams(state.config.cdn?.live?.host, state);
81
+ } else if (ret.status === 404) {
82
+ state.config = {};
83
+ state.metadata = new Modifiers({});
84
+ state.headers = new Modifiers({});
122
85
  } else {
123
- // fallback to old metadata loading
124
- await fetchMetadata(state, req, res);
86
+ throw new PipelineStatusError(502, `failed to load /.helix/config-all.json: ${ret.status}`);
125
87
  }
126
88
 
127
89
  // compute host and routes
@@ -186,7 +186,9 @@ export function rewriteUrl(state, url) {
186
186
  return url;
187
187
  }
188
188
  try {
189
- const { pathname, search, hash } = new URL(url);
189
+ const {
190
+ host, pathname, search, hash,
191
+ } = new URL(url);
190
192
 
191
193
  if (AZURE_BLOB_REGEXP.test(url)) {
192
194
  const filename = pathname.split('/').pop();
@@ -200,7 +202,9 @@ export function rewriteUrl(state, url) {
200
202
  return `.${pathname}${hash}`;
201
203
  }
202
204
 
203
- if (HELIX_URL_REGEXP.test(url)) {
205
+ if (HELIX_URL_REGEXP.test(url)
206
+ || host === state.previewHost
207
+ || host === state.liveHost) {
204
208
  if (hash && pathname === state.info?.path) {
205
209
  return hash;
206
210
  }