@quintype/framework 7.4.2-ttl.0 → 7.5.0-internal-api.1

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/README.md CHANGED
@@ -286,7 +286,7 @@ Preloading app.js and /route-data.json can be triggered by passing preloadJS tru
286
286
 
287
287
  ### multiple publishers
288
288
 
289
- FIXME: Write notes on `host_to_api_host`, `host_to_automatic_api_host` and `skip_warm_config`
289
+ FIXME: Write notes on `host_to_api_host`, `host_to_automatic_api_host`, `wildcard_automatic_api_host` and `skip_warm_config`
290
290
 
291
291
  ### forwardFavicon
292
292
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quintype/framework",
3
- "version": "7.4.2-ttl.0",
3
+ "version": "7.5.0-internal-api.1",
4
4
  "description": "Libraries to help build Quintype Node.js apps",
5
5
  "main": "index.js",
6
6
  "engines": {
@@ -20,9 +20,7 @@ const {
20
20
  const _ = require("lodash");
21
21
 
22
22
  function getClientImpl(config, cachedSecondaryClients, hostname) {
23
- return (
24
- cachedSecondaryClients[hostname] || createTemporaryClient(config, hostname)
25
- );
23
+ return cachedSecondaryClients[hostname] || createTemporaryClient(config, hostname);
26
24
  }
27
25
 
28
26
  function createTemporaryClient(config, hostname) {
@@ -31,11 +29,13 @@ function createTemporaryClient(config, hostname) {
31
29
  return new Client(configuredHosts[hostname], true);
32
30
  }
33
31
 
34
- const matchedString = (config.host_to_automatic_api_host || []).find((str) =>
35
- hostname.includes(str)
36
- );
37
- if (matchedString)
38
- return new Client(`https://${hostname.replace(matchedString, "")}`, true);
32
+ const matchedMadridUrl = (config.wildcard_automatic_api_host || []).find((str) => hostname.includes(str));
33
+
34
+ if (matchedMadridUrl) return new Client(`http://${hostname.replace(matchedMadridUrl, ".internal")}`, true);
35
+
36
+ const matchedString = (config.host_to_automatic_api_host || []).find((str) => hostname.includes(str));
37
+
38
+ if (matchedString) return new Client(`https://${hostname.replace(matchedString, "")}`, true);
39
39
  }
40
40
 
41
41
  function itemToCacheKey(publisherId, item, depth) {
@@ -58,10 +58,7 @@ function getItemCacheKeys(publisherId, items, depth) {
58
58
  storyCacheKeys.push(storyToCacheKey(publisherId, item.story));
59
59
  break;
60
60
  case "collection":
61
- const collectionKeys = Collection.build(item).getCollectionCacheKeys(
62
- publisherId,
63
- depth - 1
64
- );
61
+ const collectionKeys = Collection.build(item).getCollectionCacheKeys(publisherId, depth - 1);
65
62
  storyCacheKeys.push(...collectionKeys.storyCacheKeys);
66
63
  collectionCacheKeys.push(...collectionKeys.collectionCacheKeys);
67
64
  break;
@@ -78,40 +75,36 @@ Collection.prototype.getCollectionCacheKeys = function (publisherId, depth) {
78
75
  collectionCacheKeys: [collectionToCacheKey(publisherId, this)],
79
76
  };
80
77
  }
81
- const { storyCacheKeys, collectionCacheKeys } = getItemCacheKeys(
82
- publisherId,
83
- this.items,
84
- depth
85
- );
78
+ const { storyCacheKeys, collectionCacheKeys } = getItemCacheKeys(publisherId, this.items, depth);
86
79
  collectionCacheKeys.unshift(collectionToCacheKey(publisherId, this));
87
80
  return { storyCacheKeys, collectionCacheKeys };
88
81
  };
89
82
 
90
- Collection.prototype.isAutomated = function() {
83
+ Collection.prototype.isAutomated = function () {
91
84
  return !!this.automated;
92
85
  };
93
86
 
94
- Collection.prototype.getChildCollections = function() {
87
+ Collection.prototype.getChildCollections = function () {
95
88
  return this.items && this.items.filter((i) => i.type === "collection");
96
89
  };
97
90
 
98
- Collection.prototype.getCacheableChildItems = function() {
91
+ Collection.prototype.getCacheableChildItems = function () {
99
92
  return this.isAutomated() ? this.getChildCollections() : this.items;
100
93
  };
101
94
 
102
- Collection.prototype.isLeafCollection = function() {
95
+ Collection.prototype.isLeafCollection = function () {
103
96
  return !this.getCacheableChildItems() && !this["collection-cache-keys"];
104
97
  };
105
98
 
106
99
  Collection.prototype.cacheKeys = function (publisherId, depth) {
107
100
  if (depth < 0 || this.isLeafCollection()) {
108
- return [collectionToCacheKey(publisherId,this)];
101
+ return [collectionToCacheKey(publisherId, this)];
109
102
  }
110
- const remainingDepth = _.isNumber(depth) ? (depth - 1) : depth;
111
- return ([
103
+ const remainingDepth = _.isNumber(depth) ? depth - 1 : depth;
104
+ return [
112
105
  ...(this["collection-cache-keys"] ? this["collection-cache-keys"] : []),
113
106
  ..._.flatMap(this.getCacheableChildItems(), (item) => itemToCacheKey(publisherId, item, remainingDepth)),
114
- ]);
107
+ ];
115
108
  };
116
109
 
117
110
  Story.prototype.cacheKeys = function (publisherId) {
package/server/routes.js CHANGED
@@ -87,13 +87,7 @@ exports.upstreamQuintypeRoutes = function upstreamQuintypeRoutes(
87
87
  });
88
88
 
89
89
  // Mention the routes which don't want to override the s-maxage value
90
- const excludeRoutes = [
91
- "/qlitics.js",
92
- "/api/v1/breaking-news",
93
- "/stories.rss",
94
- "/collection.rss",
95
- "/api/v1/advanced-search",
96
- ];
90
+ const excludeRoutes = ["/qlitics.js", "/api/v1/breaking-news"];
97
91
 
98
92
  app.all("/api/*", sketchesProxy);
99
93
  app.all("/login", sketchesProxy);
@@ -1,41 +1,22 @@
1
1
  const assert = require("assert");
2
2
 
3
- const {
4
- getClientImpl,
5
- Client,
6
- Story,
7
- Author,
8
- Collection,
9
- CustomPath,
10
- } = require("../../server/impl/api-client-impl");
3
+ const { getClientImpl, Client, Story, Author, Collection, CustomPath } = require("../../server/impl/api-client-impl");
11
4
 
12
5
  describe("ApiClient", function () {
13
6
  describe("getClient", function () {
14
7
  it("returns a cachedSecondaryClient if present", function () {
15
8
  const expectedClient = new Client("foo.staging.quintype.io", true);
16
- const client = getClientImpl(
17
- {},
18
- { "foo.com": expectedClient },
19
- "foo.com"
20
- );
9
+ const client = getClientImpl({}, { "foo.com": expectedClient }, "foo.com");
21
10
  assert.equal(expectedClient, client);
22
11
  });
23
12
 
24
13
  it("creates a temporary client if it matches a string", function () {
25
- const client = getClientImpl(
26
- { host_to_automatic_api_host: ["-web"] },
27
- {},
28
- "foo-web.staging.quintype.io"
29
- );
14
+ const client = getClientImpl({ host_to_automatic_api_host: ["-web"] }, {}, "foo-web.staging.quintype.io");
30
15
  assert.equal("https://foo.staging.quintype.io", client.baseUrl);
31
16
  });
32
17
 
33
18
  it("creates a temporary client if it matches a string with a .", function () {
34
- const client = getClientImpl(
35
- { host_to_automatic_api_host: [".madrid"] },
36
- {},
37
- "foo.madrid.quintype.io"
38
- );
19
+ const client = getClientImpl({ host_to_automatic_api_host: [".madrid"] }, {}, "foo.madrid.quintype.io");
39
20
  assert.equal("https://foo.quintype.io", client.baseUrl);
40
21
  });
41
22
 
@@ -52,6 +33,15 @@ describe("ApiClient", function () {
52
33
  assert.equal("https://foo.quintype.io", client.baseUrl);
53
34
  });
54
35
 
36
+ it("creates a wildcard temporary client if it matches a string", function () {
37
+ const client = getClientImpl(
38
+ { wildcard_automatic_api_host: [".madrid", "-madrid"] },
39
+ {},
40
+ "foo.madrid.quintype.io"
41
+ );
42
+ assert.equal("http://foo.internal.quintype.io", client.baseUrl);
43
+ });
44
+
55
45
  it("returns null if no client is found", function () {
56
46
  const client = getClientImpl({}, {}, "www.unknown.com");
57
47
  assert.equal(null, client);
@@ -147,13 +137,13 @@ describe("ApiClient", function () {
147
137
  it("should return as leaf collection when it has no items and has no collection cache keys", () => {
148
138
  const collection = Collection.build({
149
139
  id: 851,
150
- 'associated-metadata': {},
151
- type: 'collection',
152
- name: 'review-fashion',
153
- slug: 'review-fashion',
154
- template: 'default',
155
- metadata: { 'cover-image': null },
156
- 'collection-date': null
140
+ "associated-metadata": {},
141
+ type: "collection",
142
+ name: "review-fashion",
143
+ slug: "review-fashion",
144
+ template: "default",
145
+ metadata: { "cover-image": null },
146
+ "collection-date": null,
157
147
  });
158
148
 
159
149
  assert.strictEqual(collection.isLeafCollection(), true);
@@ -162,16 +152,16 @@ describe("ApiClient", function () {
162
152
  it("should not be a leaf collection when collection has items or collection cache keys", () => {
163
153
  const collectionWithCacheKeys = Collection.build({
164
154
  id: 851,
165
- 'associated-metadata': {},
166
- type: 'collection',
167
- slug: 'review-fashion',
155
+ "associated-metadata": {},
156
+ type: "collection",
157
+ slug: "review-fashion",
168
158
  "collection-cache-keys": ["c/1/851", "sc/1/1233"],
169
159
  });
170
160
  const collectionWithItems = Collection.build({
171
161
  id: 851,
172
- 'associated-metadata': {},
173
- type: 'collection',
174
- slug: 'review-fashion',
162
+ "associated-metadata": {},
163
+ type: "collection",
164
+ slug: "review-fashion",
175
165
  items: [{ type: "story", story: { id: "xyz1235" } }],
176
166
  });
177
167
 
@@ -208,10 +198,10 @@ describe("ApiClient", function () {
208
198
  ],
209
199
  });
210
200
 
211
- assert.strictEqual(collection.getCacheableChildItems(1).filter((c) => c.type === 'collection').length, 1);
201
+ assert.strictEqual(collection.getCacheableChildItems(1).filter((c) => c.type === "collection").length, 1);
212
202
  assert.strictEqual(collection.getCacheableChildItems(1)[0].id, "851");
213
203
 
214
- assert.strictEqual(collection.getCacheableChildItems().filter((c) => c.type === 'collection').length, 1);
204
+ assert.strictEqual(collection.getCacheableChildItems().filter((c) => c.type === "collection").length, 1);
215
205
  assert.strictEqual(collection.getCacheableChildItems()[0].id, "851");
216
206
  });
217
207
 
@@ -271,10 +261,7 @@ describe("ApiClient", function () {
271
261
  },
272
262
  ],
273
263
  });
274
- assert.deepEqual(
275
- ["c/1/42", "s/1/264f46f9", "s/1/1e5acfe4"],
276
- collection.cacheKeys(1)
277
- );
264
+ assert.deepEqual(["c/1/42", "s/1/264f46f9", "s/1/1e5acfe4"], collection.cacheKeys(1));
278
265
  });
279
266
 
280
267
  it("should include all nested stories and collection ids as cache tags for a manual collection", function () {
@@ -305,7 +292,7 @@ describe("ApiClient", function () {
305
292
  story: { id: "fd4fa2c4-5441-434a-bf76-7660bbf1a09d" },
306
293
  },
307
294
  ],
308
- }
295
+ },
309
296
  ],
310
297
  });
311
298
  assert.deepEqual(
@@ -330,10 +317,7 @@ describe("ApiClient", function () {
330
317
  },
331
318
  ],
332
319
  });
333
- assert.deepEqual(
334
- ["c/1/42", "sc/1/38586"],
335
- collection.cacheKeys(1)
336
- );
320
+ assert.deepEqual(["c/1/42", "sc/1/38586"], collection.cacheKeys(1));
337
321
  });
338
322
 
339
323
  it("should include all nested collection cache keys excluding story keys as cache keys for automated collection", function () {
@@ -365,13 +349,10 @@ describe("ApiClient", function () {
365
349
  story: { id: "fd4fa2c4-5441-434a-bf76-7660bbf1a09d" },
366
350
  },
367
351
  ],
368
- }
352
+ },
369
353
  ],
370
354
  });
371
- assert.deepEqual(
372
- ["c/1/42", "sc/1/38586", "c/1/43", "e/1/123"],
373
- collection.cacheKeys(1)
374
- );
355
+ assert.deepEqual(["c/1/42", "sc/1/38586", "c/1/43", "e/1/123"], collection.cacheKeys(1));
375
356
  });
376
357
 
377
358
  it("should return cache keys when an automated collection has a manual collection", function () {
@@ -403,13 +384,10 @@ describe("ApiClient", function () {
403
384
  story: { id: "fd4fa2c4-5441-434a-bf76-7660bbf1a09d" },
404
385
  },
405
386
  ],
406
- }
387
+ },
407
388
  ],
408
389
  });
409
- assert.deepEqual(
410
- ["c/1/42", "sc/1/38586", "c/1/43", "s/1/0c2809d8", "s/1/fd4fa2c4"],
411
- collection.cacheKeys(1)
412
- );
390
+ assert.deepEqual(["c/1/42", "sc/1/38586", "c/1/43", "s/1/0c2809d8", "s/1/fd4fa2c4"], collection.cacheKeys(1));
413
391
  });
414
392
 
415
393
  it("should return cache keys when a manual collection has an automated collection under it", function () {
@@ -440,13 +418,10 @@ describe("ApiClient", function () {
440
418
  story: { id: "fd4fa2c4-5441-434a-bf76-7660bbf1a09d" },
441
419
  },
442
420
  ],
443
- }
421
+ },
444
422
  ],
445
423
  });
446
- assert.deepEqual(
447
- ["c/1/42", "s/1/264f46f9", "s/1/1e5acfe4", "c/1/43", "sc/1/38586"],
448
- collection.cacheKeys(1)
449
- );
424
+ assert.deepEqual(["c/1/42", "s/1/264f46f9", "s/1/1e5acfe4", "c/1/43", "sc/1/38586"], collection.cacheKeys(1));
450
425
  });
451
426
 
452
427
  it("should include nested collection and stories cache tags only upto depth when depth is passed", function () {
@@ -473,7 +448,7 @@ describe("ApiClient", function () {
473
448
  automated: false,
474
449
  id: "700",
475
450
  items: [
476
- { type: "story", story: { id: "abcdef12" }},
451
+ { type: "story", story: { id: "abcdef12" } },
477
452
  {
478
453
  type: "collection",
479
454
  "collection-cache-keys": ["c/1/850", "sc/1/112"],
@@ -499,13 +474,13 @@ describe("ApiClient", function () {
499
474
  { type: "story", story: { id: "xyz12" } },
500
475
  {
501
476
  id: 851,
502
- 'associated-metadata': {},
503
- type: 'collection',
504
- name: 'review-fashion',
505
- slug: 'review-fashion',
506
- template: 'default',
507
- metadata: { 'cover-image': null },
508
- 'collection-date': null
477
+ "associated-metadata": {},
478
+ type: "collection",
479
+ name: "review-fashion",
480
+ slug: "review-fashion",
481
+ template: "default",
482
+ metadata: { "cover-image": null },
483
+ "collection-date": null,
509
484
  },
510
485
  ],
511
486
  },
@@ -516,21 +491,21 @@ describe("ApiClient", function () {
516
491
  ],
517
492
  });
518
493
  assert.deepEqual(
519
- [
520
- "c/1/42",
521
- "sc/1/38586",
522
- "c/1/500",
523
- "sc/1/38587",
524
- "c/1/600",
525
- "sc/1/38588",
526
- "c/1/700",
527
- "s/1/abcdef12",
528
- "c/1/850",
529
- "c/1/800",
530
- "c/1/900",
531
- "s/1/xyz12",
532
- "c/1/851"
533
- ],
494
+ [
495
+ "c/1/42",
496
+ "sc/1/38586",
497
+ "c/1/500",
498
+ "sc/1/38587",
499
+ "c/1/600",
500
+ "sc/1/38588",
501
+ "c/1/700",
502
+ "s/1/abcdef12",
503
+ "c/1/850",
504
+ "c/1/800",
505
+ "c/1/900",
506
+ "s/1/xyz12",
507
+ "c/1/851",
508
+ ],
534
509
  collection.cacheKeys(1, 3)
535
510
  );
536
511
  });
@@ -559,7 +534,7 @@ describe("ApiClient", function () {
559
534
  automated: false,
560
535
  id: "700",
561
536
  items: [
562
- { type: "story", story: { id: "abcdef12" }},
537
+ { type: "story", story: { id: "abcdef12" } },
563
538
  {
564
539
  type: "collection",
565
540
  "collection-cache-keys": ["c/1/850", "sc/1/112"],
@@ -629,7 +604,7 @@ describe("ApiClient", function () {
629
604
  },
630
605
  ],
631
606
  },
632
- { type: "story", story: { id: "abcdef12" }},
607
+ { type: "story", story: { id: "abcdef12" } },
633
608
  ],
634
609
  });
635
610
 
@@ -650,10 +625,7 @@ describe("ApiClient", function () {
650
625
  },
651
626
  ],
652
627
  });
653
- assert.deepEqual(
654
- ["c/1/42", "sc/1/38586", "c/1/500", "s/1/abcdef12"],
655
- collection.cacheKeys(1)
656
- );
628
+ assert.deepEqual(["c/1/42", "sc/1/38586", "c/1/500", "s/1/abcdef12"], collection.cacheKeys(1));
657
629
  });
658
630
 
659
631
  it("should add all nested collection cache tags even when leaf collection does not have much data", function () {
@@ -670,22 +642,19 @@ describe("ApiClient", function () {
670
642
  { type: "story", story: { id: "abcdef12" } },
671
643
  {
672
644
  id: 147182,
673
- 'associated-metadata': {},
674
- type: 'collection',
675
- name: 'review-fashion',
676
- slug: 'review-fashion',
677
- template: 'default',
678
- metadata: { 'cover-image': null },
679
- 'collection-date': null
680
- }
645
+ "associated-metadata": {},
646
+ type: "collection",
647
+ name: "review-fashion",
648
+ slug: "review-fashion",
649
+ template: "default",
650
+ metadata: { "cover-image": null },
651
+ "collection-date": null,
652
+ },
681
653
  ],
682
654
  },
683
655
  ],
684
656
  });
685
- assert.deepEqual(
686
- ["c/1/42", "sc/1/38586", "c/1/500", "s/1/abcdef12", "c/1/147182"],
687
- collection.cacheKeys(1)
688
- );
657
+ assert.deepEqual(["c/1/42", "sc/1/38586", "c/1/500", "s/1/abcdef12", "c/1/147182"], collection.cacheKeys(1));
689
658
  });
690
659
 
691
660
  it("can also find the cache key for a sorter", function () {