@quintype/framework 7.4.0-update-build.0 → 7.4.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
@@ -2,6 +2,17 @@
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.4.0](https://github.com/quintype/quintype-node-framework/compare/v7.2.0...v7.4.0) (2022-05-23)
6
+
7
+
8
+ ### Features
9
+
10
+ * **request:** Implement request fallback for external calls ([#296](https://github.com/quintype/quintype-node-framework/issues/296)) ([44e1f7e](https://github.com/quintype/quintype-node-framework/commit/44e1f7eea9825225c0c300fb57a8178bd22c0630))
11
+
12
+ ### [7.3.4](https://github.com/quintype/quintype-node-framework/compare/v7.3.3...v7.3.4) (2022-05-20)
13
+
14
+ ### [7.3.3](https://github.com/quintype/quintype-node-framework/compare/v7.3.2...v7.3.3) (2022-05-20)
15
+
5
16
  ### [7.3.2](https://github.com/quintype/quintype-node-framework/compare/v7.3.1...v7.3.2) (2022-04-18)
6
17
 
7
18
  ### [7.3.1](https://github.com/quintype/quintype-node-framework/compare/v7.3.0...v7.3.1) (2022-03-03)
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@quintype/framework",
3
- "version": "7.4.0-update-build.0",
3
+ "version": "7.4.0",
4
4
  "description": "Libraries to help build Quintype Node.js apps",
5
5
  "main": "index.js",
6
+ "engines": {
7
+ "node": "^16.0.0",
8
+ "npm": "^8.5.0"
9
+ },
6
10
  "scripts": {
7
11
  "prepublishOnly": "npm test && ./bin-dev-scripts/standard-version-release.sh",
8
12
  "test": "NODE_ENV=test npx mocha --recursive --require ./test/babel",
@@ -27,7 +31,7 @@
27
31
  "homepage": "https://github.com/quintype/quintype-node-framework#readme",
28
32
  "dependencies": {
29
33
  "@ampproject/toolbox-optimizer": "2.8.3",
30
- "@quintype/amp": "^2.4.20",
34
+ "@quintype/amp": "^2.4.21",
31
35
  "@quintype/backend": "^2.3.1",
32
36
  "@quintype/components": "^3.0.0",
33
37
  "@quintype/prerender-node": "^3.2.24",
@@ -47,7 +51,7 @@
47
51
  "lodash": "^4.17.21",
48
52
  "mocha-snapshots": "^4.2.0",
49
53
  "morgan": "^1.10.0",
50
- "path-to-regexp": "^6.2.1",
54
+ "path-to-regexp": "^6.2.0",
51
55
  "react": "^16.14.0",
52
56
  "react-dom": "^16.14.0",
53
57
  "react-redux": "^7.2.5",
@@ -7,6 +7,7 @@ const { Story, AmpConfig } = require("../../impl/api-client-impl");
7
7
  const { optimize, getDomainSpecificOpts } = require("../helpers");
8
8
  const { storyToCacheKey } = require("../../caching");
9
9
  const { addCacheHeadersToResult } = require("../../handlers/cdn-caching");
10
+ const { getRedirectUrl } = require("../../../server/redirect-url-helper");
10
11
 
11
12
  /**
12
13
  * ampStoryPageHandler gets all the things needed and calls "ampifyStory" function (which comes from ampLib)
@@ -37,6 +38,20 @@ async function ampStoryPageHandler(
37
38
  ) {
38
39
  try {
39
40
  const opts = cloneDeep(rest);
41
+
42
+ const redirectUrls = opts && opts.redirectUrls;
43
+ const getEnableAmp = get(opts, ["enableAmp"], true);
44
+
45
+ const enableAmp = typeof getEnableAmp === "function" ? opts.enableAmp(config) : getEnableAmp;
46
+
47
+ if (typeof redirectUrls === "function" || (redirectUrls && Object.keys(redirectUrls).length > 0)) {
48
+ await getRedirectUrl(req, res, next, { redirectUrls, config });
49
+ }
50
+
51
+ if (!enableAmp) {
52
+ return res.redirect(301, `/${req.params[0]}`);
53
+ }
54
+
40
55
  const domainSpecificOpts = getDomainSpecificOpts(opts, domainSlug);
41
56
  const url = urlLib.parse(req.url, true);
42
57
  const { ampifyStory, unsupportedStoryElementsPresent } = ampLibrary;
package/server/routes.js CHANGED
@@ -232,12 +232,13 @@ function wrapLoadDataWithMultiDomain(publisherConfig, f, configPos) {
232
232
  * @param {Object} opts Options that will be passed to the handler. These options will be merged with a *config* and *client*
233
233
  */
234
234
  function getWithConfig(app, route, handler, opts = {}) {
235
+ const configWrapper = opts.configWrapper;
235
236
  const {
236
237
  getClient = require("./api-client").getClient,
237
238
  publisherConfig = require("./publisher-config"),
238
239
  logError = require("./logger").error,
239
240
  } = opts;
240
- const withConfig = withConfigPartial(getClient, logError, publisherConfig);
241
+ const withConfig = withConfigPartial(getClient, logError, publisherConfig, configWrapper);
241
242
  app.get(route, withConfig(handler, opts));
242
243
  }
243
244
 
@@ -608,6 +609,8 @@ exports.mountQuintypeAt = function (app, mountAt) {
608
609
  * @param {Object} opts.templates An object that's used to pass custom templates. Each key corresponds to the template name and corresponding value is the template
609
610
  * @param {Object} opts.slots An object used to pass slot data.
610
611
  * @param {SEO} opts.seo An SEO object that will generate html tags for each page. See [@quintype/seo](https://developers.quintype.com/malibu/isomorphic-rendering/server-side-architecture#quintypeseo)
612
+ * @param {boolean|function} opts.enableAmp 'amp/story/:slug' should redirect to non-amp page if enableAmp is false
613
+ * @param {object|function} opts.redirectUrls list of urls which is used to redirect URL(sourceUrl) to a different URL(destinationUrl). Eg: redirectUrls: { "/amp/story/sports/ipl-2021": {destinationUrl: "/amp/story/sports/cricket-2022", statusCode: 302,},}
611
614
  * @param {function} opts.headerCardRender Render prop for story headerCard. If passed, the headerCard in default stories will be replaced with this
612
615
  * @param {function} opts.relatedStoriesRender Render prop for relatedStories in a story page. If passed, this will replace the related stories
613
616
  *
@@ -70,16 +70,14 @@ function getClientStub({
70
70
  "story-elements": [
71
71
  {
72
72
  description: "",
73
- "page-url":
74
- "/story/7f3d5bdb-ec52-4047-ac0d-df4036ec974b/element/9eb8f5cc-6ebe-4fb0-88b8-eca79efde210",
73
+ "page-url": "/story/7f3d5bdb-ec52-4047-ac0d-df4036ec974b/element/9eb8f5cc-6ebe-4fb0-88b8-eca79efde210",
75
74
  type: "text",
76
75
  "family-id": "e9e12f9f-8b9f-4b93-a8c8-83c7b278000f",
77
76
  title: "",
78
77
  id: "9eb8f5cc-6ebe-4fb0-88b8-eca79efde210",
79
78
  metadata: {},
80
79
  subtype: null,
81
- text:
82
- "<p>In India today, the legal profession is growing in lockstep with one of the world’s most dynamic economies. It’s no surprise then— that in terms of absolute numbers— India’s legal profession is the world’s second largest, with over 1.4 million enrolled lawyers in legal practices nationwide.</p>",
80
+ text: "<p>In India today, the legal profession is growing in lockstep with one of the world’s most dynamic economies. It’s no surprise then— that in terms of absolute numbers— India’s legal profession is the world’s second largest, with over 1.4 million enrolled lawyers in legal practices nationwide.</p>",
83
81
  },
84
82
  ],
85
83
  "card-updated-at": 1581327522163,
@@ -195,20 +193,18 @@ const dummyAmpLib = {
195
193
 
196
194
  const getClientStubWithRelatedStories = (relatedStories) => () =>
197
195
  Object.assign({}, getClientStub(), {
198
- getRelatedStories: () =>
199
- Promise.resolve({ "related-stories": relatedStories }),
196
+ getRelatedStories: () => Promise.resolve({ "related-stories": relatedStories }),
200
197
  });
201
198
 
202
- function createApp({
203
- clientStub = getClientStub,
204
- ampLibrary = dummyAmpLib,
205
- } = {}) {
199
+ function createApp({ clientStub = getClientStub, ampLibrary = dummyAmpLib, enableAmp = true, redirectUrls = {} } = {}) {
206
200
  const app = express();
207
201
  ampRoutes(app, {
208
202
  getClient: clientStub,
209
203
  publisherConfig: {},
210
204
  ampLibrary,
211
205
  additionalConfig: {},
206
+ enableAmp,
207
+ redirectUrls,
212
208
  });
213
209
  return app;
214
210
  }
@@ -240,6 +236,38 @@ describe("ampStoryPageHandler integration tests", () => {
240
236
  return done();
241
237
  });
242
238
  });
239
+ it("should redirect to non-amp page if enableAmp is false", (done) => {
240
+ const app = createApp({
241
+ enableAmp: false,
242
+ });
243
+ supertest(app)
244
+ .get("/amp/story/cricket/ipl-2021")
245
+ .expect(301)
246
+ .expect("Location", "/cricket/ipl-2021")
247
+ .end((err) => {
248
+ if (err) return done(err);
249
+ return done();
250
+ });
251
+ });
252
+ it("Redirects the urls with status code to 302 if redirectUrls is present ", (done) => {
253
+ const app = createApp({
254
+ enableAmp: true,
255
+ redirectUrls: {
256
+ "/amp/story/sports/ipl-2021": {
257
+ destinationUrl: "/amp/story/sports/cricket-2022",
258
+ statusCode: 302,
259
+ },
260
+ },
261
+ });
262
+ supertest(app)
263
+ .get("/amp/story/sports/ipl-2021")
264
+ .expect(302)
265
+ .expect("Location", "/amp/story/sports/cricket-2022")
266
+ .end((err) => {
267
+ if (err) return done(err);
268
+ return done();
269
+ });
270
+ });
243
271
  it("should redirect to non-amp page if story contains unsuported elements and invalid-elements-strategy in /api/v1/amp/config is set to redirect-to-web-version", (done) => {
244
272
  const app = createApp({
245
273
  ampLibrary: {