@quintype/framework 7.30.2-update-amp-otp.0 → 7.30.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 +7 -0
- package/package.json +2 -2
- package/server/amp/handlers/story-page.js +84 -93
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [7.30.2](https://github.com/quintype/quintype-node-framework/compare/v7.30.1...v7.30.2) (2024-09-13)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **Amp story:** pass amp optimizer toggle to preload hero image ([#439](https://github.com/quintype/quintype-node-framework/issues/439)) ([c943095](https://github.com/quintype/quintype-node-framework/commit/c943095a25000377f94b709df1b75ccfed3983df))
|
|
11
|
+
|
|
5
12
|
### [7.30.1](https://github.com/quintype/quintype-node-framework/compare/v7.30.0...v7.30.1) (2024-08-14)
|
|
6
13
|
|
|
7
14
|
## [7.30.0](https://github.com/quintype/quintype-node-framework/compare/v7.29.1...v7.30.0) (2024-07-30)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quintype/framework",
|
|
3
|
-
"version": "7.30.2
|
|
3
|
+
"version": "7.30.2",
|
|
4
4
|
"description": "Libraries to help build Quintype Node.js apps",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"engines": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"homepage": "https://github.com/quintype/quintype-node-framework#readme",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@ampproject/toolbox-optimizer": "2.8.3",
|
|
34
|
-
"@quintype/amp": "^2.19.
|
|
34
|
+
"@quintype/amp": "^2.19.2",
|
|
35
35
|
"@quintype/backend": "2.5.1",
|
|
36
36
|
"@quintype/components": "^3.5.0",
|
|
37
37
|
"@quintype/prerender-node": "^3.2.26",
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
const urlLib = require(
|
|
2
|
-
const set = require(
|
|
3
|
-
const get = require(
|
|
4
|
-
const isEmpty = require(
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const {
|
|
9
|
-
const {
|
|
10
|
-
const {
|
|
11
|
-
const {
|
|
12
|
-
const {
|
|
13
|
-
const { getAmpPageBasePath } = require('../helpers/get-amp-page-base-path')
|
|
1
|
+
const urlLib = require("url");
|
|
2
|
+
const set = require("lodash/set");
|
|
3
|
+
const get = require("lodash/get");
|
|
4
|
+
const isEmpty = require("lodash/isEmpty");
|
|
5
|
+
const cloneDeep = require("lodash/cloneDeep");
|
|
6
|
+
const merge = require("lodash/merge");
|
|
7
|
+
const { Story, AmpConfig } = require("../../impl/api-client-impl");
|
|
8
|
+
const { optimize, getDomainSpecificOpts } = require("../helpers");
|
|
9
|
+
const { storyToCacheKey } = require("../../caching");
|
|
10
|
+
const { addCacheHeadersToResult } = require("../../handlers/cdn-caching");
|
|
11
|
+
const { getRedirectUrl } = require("../../../server/redirect-url-helper");
|
|
12
|
+
const { getAmpPageBasePath } = require("../helpers/get-amp-page-base-path");
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* ampStoryPageHandler gets all the things needed and calls "ampifyStory" function (which comes from ampLib)
|
|
@@ -23,7 +22,7 @@ const { getAmpPageBasePath } = require('../helpers/get-amp-page-base-path')
|
|
|
23
22
|
* @category AmpHandler
|
|
24
23
|
*/
|
|
25
24
|
|
|
26
|
-
async function ampStoryPageHandler
|
|
25
|
+
async function ampStoryPageHandler(
|
|
27
26
|
req,
|
|
28
27
|
res,
|
|
29
28
|
next,
|
|
@@ -31,86 +30,86 @@ async function ampStoryPageHandler (
|
|
|
31
30
|
client,
|
|
32
31
|
config,
|
|
33
32
|
domainSlug,
|
|
34
|
-
seo =
|
|
33
|
+
seo = "",
|
|
35
34
|
cdnProvider = null,
|
|
36
|
-
ampLibrary = require(
|
|
37
|
-
additionalConfig = require(
|
|
38
|
-
InfiniteScrollAmp = require(
|
|
35
|
+
ampLibrary = require("@quintype/amp"),
|
|
36
|
+
additionalConfig = require("../../publisher-config"),
|
|
37
|
+
InfiniteScrollAmp = require("../helpers/infinite-scroll"),
|
|
39
38
|
isVisualStory = false,
|
|
40
39
|
...rest
|
|
41
40
|
}
|
|
42
41
|
) {
|
|
43
42
|
try {
|
|
44
|
-
const opts = cloneDeep(rest)
|
|
43
|
+
const opts = cloneDeep(rest);
|
|
45
44
|
const isCorrectAmpPath = isVisualStory
|
|
46
45
|
? req.path.startsWith(`/ampstories`)
|
|
47
|
-
: req.path.startsWith(`${getAmpPageBasePath(opts, config)}/`)
|
|
46
|
+
: req.path.startsWith(`${getAmpPageBasePath(opts, config)}/`);
|
|
48
47
|
|
|
49
|
-
if (!isCorrectAmpPath) return next()
|
|
50
|
-
const redirectUrls = opts && opts.redirectUrls
|
|
51
|
-
const getEnableAmp = get(opts, [
|
|
52
|
-
const enableAmp = typeof getEnableAmp ===
|
|
48
|
+
if (!isCorrectAmpPath) return next();
|
|
49
|
+
const redirectUrls = opts && opts.redirectUrls;
|
|
50
|
+
const getEnableAmp = get(opts, ["enableAmp"], true);
|
|
51
|
+
const enableAmp = typeof getEnableAmp === "function" ? opts.enableAmp(config) : getEnableAmp;
|
|
53
52
|
|
|
54
|
-
if (typeof redirectUrls ===
|
|
55
|
-
await getRedirectUrl(req, res, next, { redirectUrls, config })
|
|
53
|
+
if (typeof redirectUrls === "function" || (redirectUrls && Object.keys(redirectUrls).length > 0)) {
|
|
54
|
+
await getRedirectUrl(req, res, next, { redirectUrls, config });
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
const story = await Story.getStoryBySlug(client, req.params[
|
|
59
|
-
const isAmpDisabled = get(story, [
|
|
57
|
+
const story = await Story.getStoryBySlug(client, req.params["0"]);
|
|
58
|
+
const isAmpDisabled = get(story, ["metadata", "story-attributes", "disable-amp-for-single-story", "0"], "false");
|
|
60
59
|
|
|
61
|
-
if (!isVisualStory && (!enableAmp || isAmpDisabled ===
|
|
62
|
-
const ampPageBasePath = getAmpPageBasePath(opts, config)
|
|
60
|
+
if (!isVisualStory && (!enableAmp || isAmpDisabled === "true")) {
|
|
61
|
+
const ampPageBasePath = getAmpPageBasePath(opts, config);
|
|
63
62
|
const redirectUrl = `/${req.params[0]}`.startsWith(ampPageBasePath)
|
|
64
|
-
? `/${req.params[0]}`.replace(ampPageBasePath,
|
|
65
|
-
: `/${req.params[0]}
|
|
63
|
+
? `/${req.params[0]}`.replace(ampPageBasePath, "")
|
|
64
|
+
: `/${req.params[0]}`;
|
|
66
65
|
|
|
67
|
-
return res.redirect(301, redirectUrl)
|
|
66
|
+
return res.redirect(301, redirectUrl);
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
const domainSpecificOpts = getDomainSpecificOpts(opts, domainSlug)
|
|
71
|
-
const url = urlLib.parse(req.url, true)
|
|
72
|
-
const { ampifyStory, unsupportedStoryElementsPresent } = ampLibrary
|
|
69
|
+
const domainSpecificOpts = getDomainSpecificOpts(opts, domainSlug);
|
|
70
|
+
const url = urlLib.parse(req.url, true);
|
|
71
|
+
const { ampifyStory, unsupportedStoryElementsPresent } = ampLibrary;
|
|
73
72
|
// eslint-disable-next-line no-return-await
|
|
74
|
-
const ampConfig = await config.memoizeAsync(
|
|
75
|
-
let relatedStoriesCollection
|
|
76
|
-
let relatedStories = []
|
|
73
|
+
const ampConfig = await config.memoizeAsync("amp-config", async () => await AmpConfig.getAmpConfig(client));
|
|
74
|
+
let relatedStoriesCollection;
|
|
75
|
+
let relatedStories = [];
|
|
77
76
|
|
|
78
|
-
if (!story) return next()
|
|
79
|
-
if (ampConfig[
|
|
80
|
-
relatedStoriesCollection = await client.getCollectionBySlug(ampConfig[
|
|
77
|
+
if (!story) return next();
|
|
78
|
+
if (ampConfig["related-collection-id"])
|
|
79
|
+
relatedStoriesCollection = await client.getCollectionBySlug(ampConfig["related-collection-id"]);
|
|
81
80
|
if (relatedStoriesCollection && relatedStoriesCollection.items) {
|
|
82
|
-
const storiesToTake = get(domainSpecificOpts, [
|
|
81
|
+
const storiesToTake = get(domainSpecificOpts, ["featureConfig", "relatedStories", "storiesToTake"], 5);
|
|
83
82
|
relatedStories = relatedStoriesCollection.items
|
|
84
|
-
.filter(item => item.type ===
|
|
83
|
+
.filter((item) => item.type === "story" && item.id !== story["story-content-id"])
|
|
85
84
|
.slice(0, storiesToTake)
|
|
86
|
-
.map(item => item.story)
|
|
85
|
+
.map((item) => item.story);
|
|
87
86
|
}
|
|
88
87
|
if (relatedStories.length) {
|
|
89
|
-
set(domainSpecificOpts, [
|
|
88
|
+
set(domainSpecificOpts, ["featureConfig", "relatedStories", "stories"], relatedStories);
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
if (
|
|
93
92
|
unsupportedStoryElementsPresent(story) &&
|
|
94
|
-
ampConfig.ampConfig[
|
|
93
|
+
ampConfig.ampConfig["invalid-elements-strategy"] === "redirect-to-web-version"
|
|
95
94
|
)
|
|
96
|
-
return res.redirect(story.url)
|
|
95
|
+
return res.redirect(story.url);
|
|
97
96
|
|
|
98
|
-
const timezone = get(additionalConfig, [
|
|
99
|
-
const seoInstance = typeof seo ===
|
|
97
|
+
const timezone = get(additionalConfig, ["publisher", "timezone"], null);
|
|
98
|
+
const seoInstance = typeof seo === "function" ? seo(config, "story-page-amp") : seo;
|
|
100
99
|
const seoTags =
|
|
101
|
-
seoInstance && seoInstance.getMetaTags(config,
|
|
100
|
+
seoInstance && seoInstance.getMetaTags(config, "story-page-amp", { data: { story, timezone }, config }, { url });
|
|
102
101
|
|
|
103
|
-
const infiniteScrollConfig = get(opts, [
|
|
104
|
-
const infiniteScrollSource = get(infiniteScrollConfig, [
|
|
105
|
-
const inlineConfig = get(infiniteScrollConfig, [
|
|
106
|
-
const remoteConfigEndpoint = get(infiniteScrollConfig, [
|
|
102
|
+
const infiniteScrollConfig = get(opts, ["featureConfig", "infiniteScroll"], "");
|
|
103
|
+
const infiniteScrollSource = get(infiniteScrollConfig, ["source"], "collection");
|
|
104
|
+
const inlineConfig = get(infiniteScrollConfig, ["inlineConfig"], "");
|
|
105
|
+
const remoteConfigEndpoint = get(infiniteScrollConfig, ["remoteConfigEndpoint"], "");
|
|
107
106
|
|
|
108
|
-
let infiniteScrollInlineConfig = []
|
|
107
|
+
let infiniteScrollInlineConfig = [];
|
|
109
108
|
|
|
110
|
-
if (infiniteScrollSource ===
|
|
109
|
+
if (infiniteScrollSource === "custom") {
|
|
111
110
|
if (!inlineConfig || !remoteConfigEndpoint)
|
|
112
|
-
throw new Error("Required params of 'custom' source (inlineConfig /remoteConfigEndpoint) is missing!!")
|
|
113
|
-
infiniteScrollInlineConfig = await inlineConfig()
|
|
111
|
+
throw new Error("Required params of 'custom' source (inlineConfig /remoteConfigEndpoint) is missing!!");
|
|
112
|
+
infiniteScrollInlineConfig = await inlineConfig();
|
|
114
113
|
} else {
|
|
115
114
|
const infiniteScrollAmp = new InfiniteScrollAmp({
|
|
116
115
|
opts,
|
|
@@ -118,64 +117,56 @@ async function ampStoryPageHandler (
|
|
|
118
117
|
ampConfig,
|
|
119
118
|
publisherConfig: config,
|
|
120
119
|
client,
|
|
121
|
-
infiniteScrollSource
|
|
122
|
-
})
|
|
120
|
+
infiniteScrollSource,
|
|
121
|
+
});
|
|
123
122
|
infiniteScrollInlineConfig = await infiniteScrollAmp.getInitialInlineConfig({
|
|
124
|
-
storyId: story[
|
|
125
|
-
})
|
|
123
|
+
storyId: story["story-content-id"],
|
|
124
|
+
});
|
|
126
125
|
}
|
|
127
|
-
if (infiniteScrollInlineConfig instanceof Error) return next(infiniteScrollInlineConfig)
|
|
126
|
+
if (infiniteScrollInlineConfig instanceof Error) return next(infiniteScrollInlineConfig);
|
|
128
127
|
if (infiniteScrollInlineConfig) {
|
|
129
128
|
set(
|
|
130
129
|
domainSpecificOpts,
|
|
131
|
-
[
|
|
130
|
+
["featureConfig", "infiniteScroll", "infiniteScrollInlineConfig"],
|
|
132
131
|
infiniteScrollInlineConfig
|
|
133
|
-
)
|
|
132
|
+
);
|
|
134
133
|
}
|
|
135
|
-
const mergedAdditionalConfig = {}
|
|
134
|
+
const mergedAdditionalConfig = {};
|
|
136
135
|
if (opts.getAdditionalConfig && opts.getAdditionalConfig instanceof Function) {
|
|
137
136
|
const fetchedAdditionalConfig = await opts.getAdditionalConfig({
|
|
138
137
|
story,
|
|
139
138
|
apiConfig: config.config,
|
|
140
139
|
ampApiConfig: ampConfig.ampConfig,
|
|
141
|
-
publisherConfig: additionalConfig
|
|
142
|
-
})
|
|
143
|
-
merge(mergedAdditionalConfig, additionalConfig, fetchedAdditionalConfig)
|
|
140
|
+
publisherConfig: additionalConfig,
|
|
141
|
+
});
|
|
142
|
+
merge(mergedAdditionalConfig, additionalConfig, fetchedAdditionalConfig);
|
|
144
143
|
}
|
|
145
|
-
|
|
144
|
+
const optimizeAmpHtml = get(domainSpecificOpts, ["featureConfig", "optimizeAmpHtml"], true);
|
|
146
145
|
const ampHtml = ampifyStory({
|
|
147
146
|
story,
|
|
148
147
|
publisherConfig: config.config,
|
|
149
148
|
ampConfig: ampConfig.ampConfig,
|
|
150
149
|
additionalConfig: isEmpty(mergedAdditionalConfig) ? additionalConfig : mergedAdditionalConfig,
|
|
151
|
-
opts: { ...domainSpecificOpts, domainSlug },
|
|
152
|
-
seo: seoTags ? seoTags.toString() :
|
|
153
|
-
})
|
|
154
|
-
if (ampHtml instanceof Error) return next(ampHtml)
|
|
150
|
+
opts: { ...domainSpecificOpts, domainSlug, optimizeAmpHtml },
|
|
151
|
+
seo: seoTags ? seoTags.toString() : "",
|
|
152
|
+
});
|
|
153
|
+
if (ampHtml instanceof Error) return next(ampHtml);
|
|
155
154
|
|
|
156
|
-
res.set(
|
|
155
|
+
res.set("Content-Type", "text/html");
|
|
157
156
|
addCacheHeadersToResult({
|
|
158
157
|
res,
|
|
159
|
-
cacheKeys: storyToCacheKey(config[
|
|
158
|
+
cacheKeys: storyToCacheKey(config["publisher-id"], story),
|
|
160
159
|
cdnProvider,
|
|
161
|
-
config
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (optimizeAmpHtml) {
|
|
167
|
-
const startTime = performance.now()
|
|
168
|
-
finalResponse = await optimize(ampHtml)
|
|
169
|
-
const endTime = performance.now()
|
|
170
|
-
console.log(`aa--Time taken: ${endTime - startTime} milliseconds`)
|
|
171
|
-
} else {
|
|
172
|
-
finalResponse = ampHtml
|
|
173
|
-
}
|
|
160
|
+
config,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
const finalResponse = optimizeAmpHtml ? await optimize(ampHtml) : ampHtml;
|
|
174
165
|
|
|
175
|
-
return res.send(finalResponse)
|
|
166
|
+
return res.send(finalResponse);
|
|
176
167
|
} catch (e) {
|
|
177
|
-
return next(e)
|
|
168
|
+
return next(e);
|
|
178
169
|
}
|
|
179
170
|
}
|
|
180
171
|
|
|
181
|
-
module.exports = { ampStoryPageHandler }
|
|
172
|
+
module.exports = { ampStoryPageHandler };
|