@quintype/framework 7.24.2 → 7.25.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,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.25.0](https://github.com/quintype/quintype-node-framework/compare/v7.24.2...v7.25.0) (2024-02-23)
6
+
7
+
8
+ ### Features
9
+
10
+ * **amp:** disable amp for a particular story ([#402](https://github.com/quintype/quintype-node-framework/issues/402)) ([8e99d24](https://github.com/quintype/quintype-node-framework/commit/8e99d24b38c6ff3eb452bc2362043910f3179e9b))
11
+
5
12
  ### [7.24.2](https://github.com/quintype/quintype-node-framework/compare/v7.24.1...v7.24.2) (2024-02-22)
6
13
 
7
14
  ### [7.24.1](https://github.com/quintype/quintype-node-framework/compare/v7.24.0...v7.24.1) (2024-02-22)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quintype/framework",
3
- "version": "7.24.2",
3
+ "version": "7.25.0",
4
4
  "description": "Libraries to help build Quintype Node.js apps",
5
5
  "main": "index.js",
6
6
  "engines": {
@@ -9,6 +9,7 @@ const { optimize, getDomainSpecificOpts } = require("../helpers");
9
9
  const { storyToCacheKey } = require("../../caching");
10
10
  const { addCacheHeadersToResult } = require("../../handlers/cdn-caching");
11
11
  const { getRedirectUrl } = require("../../../server/redirect-url-helper");
12
+ const { getAmpPageBasePath } = require("../helpers/get-amp-page-base-path");
12
13
 
13
14
  /**
14
15
  * ampStoryPageHandler gets all the things needed and calls "ampifyStory" function (which comes from ampLib)
@@ -40,6 +41,10 @@ async function ampStoryPageHandler(
40
41
  ) {
41
42
  try {
42
43
  const opts = cloneDeep(rest);
44
+ const isCorrectAmpPath = req.path.startsWith(`${getAmpPageBasePath(opts, config)}/`);
45
+ if (!isCorrectAmpPath) {
46
+ return next();
47
+ }
43
48
  const redirectUrls = opts && opts.redirectUrls;
44
49
  const getEnableAmp = get(opts, ["enableAmp"], true);
45
50
  const enableAmp = typeof getEnableAmp === "function" ? opts.enableAmp(config) : getEnableAmp;
@@ -47,9 +52,16 @@ async function ampStoryPageHandler(
47
52
  if (typeof redirectUrls === "function" || (redirectUrls && Object.keys(redirectUrls).length > 0)) {
48
53
  await getRedirectUrl(req, res, next, { redirectUrls, config });
49
54
  }
55
+ const story = await Story.getStoryBySlug(client, req.params["0"]);
56
+ const isAmpDisabled = get(story, ["metadata", "story-attributes", "disable-amp-for-single-story", "0"], "false");
50
57
 
51
- if (!isVisualStory && !enableAmp) {
52
- return res.redirect(301, `/${req.params[0]}`);
58
+ if ((!isVisualStory && !enableAmp) || isAmpDisabled === "true") {
59
+ const ampPageBasePath = getAmpPageBasePath(opts, config);
60
+ const redirectUrl = `/${req.params[0]}`.startsWith(ampPageBasePath)
61
+ ? `/${req.params[0]}`.replace(ampPageBasePath, "")
62
+ : `/${req.params[0]}`;
63
+
64
+ return res.redirect(301, redirectUrl);
53
65
  }
54
66
 
55
67
  const domainSpecificOpts = getDomainSpecificOpts(opts, domainSlug);
@@ -57,7 +69,6 @@ async function ampStoryPageHandler(
57
69
  const { ampifyStory, unsupportedStoryElementsPresent } = ampLibrary;
58
70
  // eslint-disable-next-line no-return-await
59
71
  const ampConfig = await config.memoizeAsync("amp-config", async () => await AmpConfig.getAmpConfig(client));
60
- const story = await Story.getStoryBySlug(client, req.params["0"]);
61
72
  let relatedStoriesCollection;
62
73
  let relatedStories = [];
63
74
 
package/server/routes.js CHANGED
@@ -657,6 +657,9 @@ exports.mountQuintypeAt = function (app, mountAt) {
657
657
  * GET - "/amp/:slug"* returns amp story page
658
658
  * GET - "/amp/api/v1/amp-infinite-scroll" returns the infinite scroll config JSON. Passed to <amp-next-page> component's `src` attribute
659
659
  *
660
+ * To disable amp version for a specific story, you need to create a story attribute in bold with the slug {disable-amp-for-single-story} and values {true} and {false}. Set its value to "true" in the story which you want to disable amp. Please make sure to name the attributes and values in the exact same way as mentioned
661
+ * attribute slug: "disable-amp-for-single-story" values: "true" , "false". This will redirect '<amp-page-base-path>/:slug' to the non-amp page
662
+ *
660
663
  * @param {Express} app Express app to add the routes to
661
664
  * @param {Object} opts Options object used to configure amp. Passing this is optional
662
665
  * @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
@@ -672,6 +675,6 @@ exports.ampRoutes = (app, opts = {}) => {
672
675
  const { ampStoryPageHandler, storyPageInfiniteScrollHandler } = require("./amp/handlers");
673
676
 
674
677
  getWithConfig(app, "/amp/api/v1/amp-infinite-scroll", storyPageInfiniteScrollHandler, opts);
675
- getWithConfig(app, "/amp/*", ampStoryPageHandler, opts);
676
678
  getWithConfig(app, "/ampstories/*", ampStoryPageHandler, { ...opts, isVisualStory: true });
679
+ getWithConfig(app, "/*", ampStoryPageHandler, opts);
677
680
  };
@@ -239,12 +239,148 @@ describe("ampStoryPageHandler integration tests", () => {
239
239
  return done();
240
240
  });
241
241
  });
242
+ it("should redirect to non-amp page if isAmpDisabled is true", (done) => {
243
+ const clientStubWithRedirectToWebVersion = () =>
244
+ getClientStub({
245
+ getStoryBySlug: (slug, params) =>
246
+ Promise.resolve({
247
+ story: {
248
+ id: "1",
249
+ url: "https://www.foo.com/cricket/ipl-2021",
250
+ "hero-image-metadata": {
251
+ width: 5472,
252
+ height: 3648,
253
+ "mime-type": "image/jpeg",
254
+ "file-size": 6127839,
255
+ "file-name": "Sample file",
256
+ "focus-point": [2609, 1102],
257
+ },
258
+ "hero-image-s3-key": "barandbench/2020-01/sample.jpg",
259
+ "story-content-id": "987c0480-41c8-41d2-ad35-36b5f92be73e",
260
+ metadata: {
261
+ "story-attributes": {
262
+ "disable-amp-for-single-story": ["true"],
263
+ },
264
+ },
265
+ cards: [
266
+ {
267
+ "story-elements": [
268
+ {
269
+ description: "",
270
+ "page-url":
271
+ "/story/7f3d5bdb-ec52-4047-ac0d-df4036ec974b/element/9eb8f5cc-6ebe-4fb0-88b8-eca79efde210",
272
+ type: "text",
273
+ "family-id": "e9e12f9f-8b9f-4b93-a8c8-83c7b278000f",
274
+ title: "",
275
+ id: "9eb8f5cc-6ebe-4fb0-88b8-eca79efde210",
276
+ metadata: {},
277
+ subtype: null,
278
+ 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>",
279
+ },
280
+ ],
281
+ "card-updated-at": 1581327522163,
282
+ "content-version-id": "efaf78de-c90b-4d15-b040-c84ebb29cabf",
283
+ "card-added-at": 1581327522163,
284
+ status: "draft",
285
+ id: "bf486412-1e8b-45d1-a5fd-51939cfe1ce1",
286
+ "content-id": "bf486412-1e8b-45d1-a5fd-51939cfe1ce1",
287
+ version: 1,
288
+ metadata: {},
289
+ },
290
+ ],
291
+ sections: [{ id: 1, name: "Sports" }],
292
+ "story-template": "text",
293
+ "is-amp-supported": true,
294
+ },
295
+ }),
296
+ });
297
+ const app = createApp({
298
+ clientStub: clientStubWithRedirectToWebVersion,
299
+ enableAmp: true,
300
+ });
301
+ supertest(app)
302
+ .get("/amp/story/cricket/ipl-2021")
303
+ .expect(301)
304
+ .expect("Location", "/cricket/ipl-2021")
305
+ .end((err) => {
306
+ if (err) return done(err);
307
+ return done();
308
+ });
309
+ });
310
+ it("should show amp page if isAmpDisabled is false", (done) => {
311
+ const clientStubWithRedirectToWebVersion = () =>
312
+ getClientStub({
313
+ getStoryBySlug: (slug, params) =>
314
+ Promise.resolve({
315
+ story: {
316
+ id: "1",
317
+ url: "https://www.foo.com/cricket/ipl-2021",
318
+ "hero-image-metadata": {
319
+ width: 5472,
320
+ height: 3648,
321
+ "mime-type": "image/jpeg",
322
+ "file-size": 6127839,
323
+ "file-name": "Sample file",
324
+ "focus-point": [2609, 1102],
325
+ },
326
+ "hero-image-s3-key": "barandbench/2020-01/sample.jpg",
327
+ "story-content-id": "987c0480-41c8-41d2-ad35-36b5f92be73e",
328
+ metadata: {
329
+ "story-attributes": {
330
+ "disable-amp-for-single-story": ["false"],
331
+ },
332
+ },
333
+ cards: [
334
+ {
335
+ "story-elements": [
336
+ {
337
+ description: "",
338
+ "page-url":
339
+ "/story/7f3d5bdb-ec52-4047-ac0d-df4036ec974b/element/9eb8f5cc-6ebe-4fb0-88b8-eca79efde210",
340
+ type: "text",
341
+ "family-id": "e9e12f9f-8b9f-4b93-a8c8-83c7b278000f",
342
+ title: "",
343
+ id: "9eb8f5cc-6ebe-4fb0-88b8-eca79efde210",
344
+ metadata: {},
345
+ subtype: null,
346
+ 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>",
347
+ },
348
+ ],
349
+ "card-updated-at": 1581327522163,
350
+ "content-version-id": "efaf78de-c90b-4d15-b040-c84ebb29cabf",
351
+ "card-added-at": 1581327522163,
352
+ status: "draft",
353
+ id: "bf486412-1e8b-45d1-a5fd-51939cfe1ce1",
354
+ "content-id": "bf486412-1e8b-45d1-a5fd-51939cfe1ce1",
355
+ version: 1,
356
+ metadata: {},
357
+ },
358
+ ],
359
+ sections: [{ id: 1, name: "Sports" }],
360
+ "story-template": "text",
361
+ "is-amp-supported": true,
362
+ },
363
+ }),
364
+ });
365
+ const app = createApp({
366
+ clientStub: clientStubWithRedirectToWebVersion,
367
+ enableAmp: true,
368
+ });
369
+ supertest(app)
370
+ .get("/amp/story/cricket/ipl-2021")
371
+ .expect("Content-Type", /html/)
372
+ .expect(200)
373
+ .end((err) => {
374
+ if (err) return done(err);
375
+ return done();
376
+ });
377
+ });
242
378
  it("should redirect to non-amp page if enableAmp is false", (done) => {
243
379
  const app = createApp({
244
380
  enableAmp: false,
245
381
  });
246
382
  supertest(app)
247
- .get("/amp/cricket/ipl-2021")
383
+ .get("/amp/story/cricket/ipl-2021")
248
384
  .expect(301)
249
385
  .expect("Location", "/cricket/ipl-2021")
250
386
  .end((err) => {
@@ -36,6 +36,7 @@ function getClientStub({
36
36
  const dummyReq = {
37
37
  url: "foo",
38
38
  params: "/story/slug",
39
+ path: "/amp/story/slug",
39
40
  };
40
41
  const dummyRes = {
41
42
  redirect: () => null,