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