@bright.global/arboretum-sdk 0.1.0-rc.3 → 0.1.0-rc.5

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.
@@ -78,7 +78,6 @@ import { pagesByTagId } from "./sitemap/methods/pages-by-tag-id";
78
78
  import { pagesByIds } from "./sitemap/methods/pages-by-ids";
79
79
  import { pagesByPaths } from "./sitemap/methods/pages-by-paths";
80
80
  import { regenerate } from "./sitemap/methods/regenerate";
81
- import { search } from "./sitemap/methods/search";
82
81
  import { status } from "./sitemap/methods/status";
83
82
  import { right } from "../utils/fp-utils";
84
83
  import { pages } from "./sitemap/methods/pages";
@@ -87,6 +86,8 @@ import { cachedData } from "./sitemap/methods/cached-data";
87
86
  import { buildPagesByTagEagerly } from "./sitemap/helpers/build-pages-by-tag-eagerly";
88
87
  import { homePage } from "./sitemap/methods/home-page";
89
88
  import { orphanedPages } from "./sitemap/methods/orphaned-pages";
89
+ import { searchOrphanedPages } from "./sitemap/methods/search-orphaned-pages";
90
+ import { search } from "./sitemap/methods/search";
90
91
  var pageTagIdPrefix = "page";
91
92
  var pageHomeTagId = "".concat(pageTagIdPrefix, "Home");
92
93
  var localeTagIdPrefix = "locale";
@@ -170,6 +171,7 @@ export var createArboretumClient = function (config) { return __awaiter(void 0,
170
171
  status: status(ctx_1),
171
172
  cachedData: cachedData(ctx_1),
172
173
  orphanedPages: orphanedPages(ctx_1),
174
+ searchOrphanedPages: searchOrphanedPages(ctx_1),
173
175
  },
174
176
  warnings: dataE.right.warnings,
175
177
  }];
@@ -0,0 +1,5 @@
1
+ export var CONSTANTS = {
2
+ search: {
3
+ minSearchScore: 0.4,
4
+ },
5
+ };
@@ -105,7 +105,7 @@ var cmaOnlyEntriesStatusMap = function (_a, contentfulClientType, options) {
105
105
  });
106
106
  };
107
107
  export var pageEntries = function (ctx, apiClient, cmaPreviewClientApi) { return __awaiter(void 0, void 0, void 0, function () {
108
- var options, pageContentTypes, pageEntriesPromise, statusRecordPromise, _a, pageEntries, cmaOnlyStatusRecord;
108
+ var options, pageContentTypes, pageEntriesPromise, statusRecordPromise, _a, pageEntries, cmaOnlyStatusRecord, homePages, allPages;
109
109
  return __generator(this, function (_b) {
110
110
  switch (_b.label) {
111
111
  case 0:
@@ -134,15 +134,21 @@ export var pageEntries = function (ctx, apiClient, cmaPreviewClientApi) { return
134
134
  ])];
135
135
  case 1:
136
136
  _a = __read.apply(void 0, [_b.sent(), 2]), pageEntries = _a[0], cmaOnlyStatusRecord = _a[1];
137
- return [2 /*return*/, arrayToMap(function (e) { return e.sys.id; })(function (entry) {
138
- var cmaOnlyStatus = ctx.contentfulClientType === "cma-client"
139
- ? entryStatus(entry.sys) || cmaOnlyStatusRecord.get(entry.sys.id)
140
- : undefined;
141
- if (cmaOnlyStatus) {
142
- entry.sys = __assign(__assign({}, entry.sys), { cmaOnlyStatus: cmaOnlyStatus });
143
- }
144
- return entry;
145
- })(pageEntries.flat())];
137
+ homePages = [];
138
+ allPages = new Map(pageEntries.flat().map(function (entry) {
139
+ var _a;
140
+ if ((_a = entry.metadata) === null || _a === void 0 ? void 0 : _a.tags.find(function (t) { return t.sys.id.startsWith(ctx.pageHomeTagId); })) {
141
+ homePages.push(entry);
142
+ }
143
+ var cmaOnlyStatus = ctx.contentfulClientType === "cma-client"
144
+ ? entryStatus(entry.sys) || cmaOnlyStatusRecord.get(entry.sys.id)
145
+ : undefined;
146
+ if (cmaOnlyStatus) {
147
+ entry.sys = __assign(__assign({}, entry.sys), { cmaOnlyStatus: cmaOnlyStatus });
148
+ }
149
+ return [entry.sys.id, entry];
150
+ }));
151
+ return [2 /*return*/, { allPages: allPages, homePages: homePages }];
146
152
  }
147
153
  });
148
154
  }); };
@@ -59,71 +59,73 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
59
59
  }
60
60
  return to.concat(ar || Array.prototype.slice.call(from));
61
61
  };
62
- import { mockedEntrySysId, multipleContentTypesMockedContentfulEntriesClientApi, } from './helpers/__mocks__/mocked-contentful-entries-client-api';
63
- import { pageEntries } from './page-entries';
62
+ import { mockedEntrySysId, multipleContentTypesMockedContentfulEntriesClientApi, } from "./helpers/__mocks__/mocked-contentful-entries-client-api";
63
+ import { pageEntries } from "./page-entries";
64
64
  var productTypesOptions = function (productTypesIds) {
65
65
  var seed = {};
66
66
  return productTypesIds.reduce(function (acc, ct) {
67
67
  acc[ct] = {
68
- slugFieldId: 'slug',
68
+ slugFieldId: "slug",
69
69
  };
70
70
  return acc;
71
71
  }, seed);
72
72
  };
73
73
  describe(pageEntries, function () {
74
- test('Handle case where there are no page entries', function () { return __awaiter(void 0, void 0, void 0, function () {
74
+ test("Handle case where there are no page entries", function () { return __awaiter(void 0, void 0, void 0, function () {
75
75
  var singleTestPageContentType, testPageContentTypes, entries1, entries2;
76
76
  return __generator(this, function (_a) {
77
77
  switch (_a.label) {
78
78
  case 0:
79
- singleTestPageContentType = ['page1ContentType'];
79
+ singleTestPageContentType = ["page1ContentType"];
80
80
  testPageContentTypes = __spreadArray(__spreadArray([], __read(singleTestPageContentType), false), [
81
- 'page2ContentType',
81
+ "page2ContentType",
82
82
  ], false);
83
83
  return [4 /*yield*/, pageEntries({
84
- contentfulClientType: 'cda-client',
84
+ contentfulClientType: "cda-client",
85
85
  options: {
86
86
  pageContentTypes: productTypesOptions(singleTestPageContentType),
87
87
  },
88
88
  preview: false,
89
+ pageHomeTagId: "homePage",
89
90
  }, multipleContentTypesMockedContentfulEntriesClientApi(singleTestPageContentType.map(function (contentType) { return ({
90
91
  contentType: contentType,
91
92
  total: 0,
92
93
  }); })))];
93
94
  case 1:
94
95
  entries1 = _a.sent();
95
- expect(entries1.size).toBe(0);
96
+ expect(entries1.allPages.size).toBe(0);
96
97
  return [4 /*yield*/, pageEntries({
97
- contentfulClientType: 'cda-client',
98
+ contentfulClientType: "cda-client",
98
99
  options: {
99
100
  pageContentTypes: productTypesOptions(testPageContentTypes),
100
101
  },
101
102
  preview: false,
103
+ pageHomeTagId: "homePage",
102
104
  }, multipleContentTypesMockedContentfulEntriesClientApi(testPageContentTypes.map(function (contentType) { return ({
103
105
  contentType: contentType,
104
106
  total: 0,
105
107
  }); })))];
106
108
  case 2:
107
109
  entries2 = _a.sent();
108
- expect(entries2.size).toBe(0);
110
+ expect(entries2.allPages.size).toBe(0);
109
111
  return [2 /*return*/];
110
112
  }
111
113
  });
112
114
  }); });
113
115
  describe(pageEntries, function () {
114
- test('Handle case where there are page entries', function () { return __awaiter(void 0, void 0, void 0, function () {
116
+ test("Handle case where there are page entries", function () { return __awaiter(void 0, void 0, void 0, function () {
115
117
  var singleTestPageContentType, testPageContentTypes, entries1, entries1Ids, expectedEntries1Ids, entries2, entries2Ids, expectedEntries2Ids;
116
118
  return __generator(this, function (_a) {
117
119
  switch (_a.label) {
118
120
  case 0:
119
121
  singleTestPageContentType = [
120
- { contentType: 'page1ContentType', total: 101 },
122
+ { contentType: "page1ContentType", total: 101 },
121
123
  ];
122
124
  testPageContentTypes = __spreadArray(__spreadArray([], __read(singleTestPageContentType), false), [
123
- { contentType: 'page2ContentType', total: 1001 },
125
+ { contentType: "page2ContentType", total: 1001 },
124
126
  ], false);
125
127
  return [4 /*yield*/, pageEntries({
126
- contentfulClientType: 'cda-client',
128
+ contentfulClientType: "cda-client",
127
129
  options: {
128
130
  pageContentTypes: productTypesOptions(singleTestPageContentType.map(function (_a) {
129
131
  var contentType = _a.contentType;
@@ -131,10 +133,11 @@ describe(pageEntries, function () {
131
133
  })),
132
134
  },
133
135
  preview: false,
136
+ pageHomeTagId: "homePage",
134
137
  }, multipleContentTypesMockedContentfulEntriesClientApi(singleTestPageContentType))];
135
138
  case 1:
136
139
  entries1 = _a.sent();
137
- entries1Ids = __spreadArray([], __read(entries1.values()), false).map(function (e) { return e.sys.id; });
140
+ entries1Ids = __spreadArray([], __read(entries1.allPages.values()), false).map(function (e) { return e.sys.id; });
138
141
  expectedEntries1Ids = singleTestPageContentType.flatMap(function (_a) {
139
142
  var total = _a.total, contentType = _a.contentType;
140
143
  return __spreadArray([], __read(Array(total).keys()), false).map(function (_, idx) {
@@ -143,7 +146,7 @@ describe(pageEntries, function () {
143
146
  });
144
147
  expect(entries1Ids).toEqual(expectedEntries1Ids);
145
148
  return [4 /*yield*/, pageEntries({
146
- contentfulClientType: 'cda-client',
149
+ contentfulClientType: "cda-client",
147
150
  options: {
148
151
  pageContentTypes: productTypesOptions(testPageContentTypes.map(function (_a) {
149
152
  var contentType = _a.contentType;
@@ -151,10 +154,11 @@ describe(pageEntries, function () {
151
154
  })),
152
155
  },
153
156
  preview: false,
157
+ pageHomeTagId: "homePage",
154
158
  }, multipleContentTypesMockedContentfulEntriesClientApi(testPageContentTypes))];
155
159
  case 2:
156
160
  entries2 = _a.sent();
157
- entries2Ids = __spreadArray([], __read(entries2.values()), false).map(function (e) { return e.sys.id; });
161
+ entries2Ids = __spreadArray([], __read(entries2.allPages.values()), false).map(function (e) { return e.sys.id; });
158
162
  expectedEntries2Ids = testPageContentTypes.flatMap(function (_a) {
159
163
  var total = _a.total, contentType = _a.contentType;
160
164
  return __spreadArray([], __read(Array(total).keys()), false).map(function (_, idx) {
@@ -70,15 +70,14 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
70
70
  }
71
71
  return to.concat(ar || Array.prototype.slice.call(from));
72
72
  };
73
- import { pageEntries } from './page-entries';
74
- import { left, right } from '../../utils/fp-utils';
75
- import { contentTypes } from './content-types';
76
- import { locales } from './locales';
77
- import { homePages } from './home-page';
78
- import { redirectEntries } from './redirect-entries';
79
- import { homePagesByTagId } from './helpers/home-pages-by-tag-id';
73
+ import { pageEntries } from "./page-entries";
74
+ import { left, right } from "../../utils/fp-utils";
75
+ import { contentTypes } from "./content-types";
76
+ import { locales } from "./locales";
77
+ import { redirectEntries } from "./redirect-entries";
78
+ import { homePagesByTagId, } from "./helpers/home-pages-by-tag-id";
80
79
  export var sitemapData = function (ctx) { return __awaiter(void 0, void 0, void 0, function () {
81
- var _a, pages, redirects, ct, l, hp, warnings, pagesByTagId;
80
+ var _a, pages, redirects, ct, l, warnings, pagesByTagId;
82
81
  return __generator(this, function (_b) {
83
82
  switch (_b.label) {
84
83
  case 0: return [4 /*yield*/, Promise.all([
@@ -86,20 +85,19 @@ export var sitemapData = function (ctx) { return __awaiter(void 0, void 0, void
86
85
  redirectEntries(ctx),
87
86
  contentTypes(ctx),
88
87
  locales(ctx),
89
- homePages(ctx, ctx.pageHomeTagId),
90
88
  ])];
91
89
  case 1:
92
- _a = __read.apply(void 0, [_b.sent(), 5]), pages = _a[0], redirects = _a[1], ct = _a[2], l = _a[3], hp = _a[4];
90
+ _a = __read.apply(void 0, [_b.sent(), 4]), pages = _a[0], redirects = _a[1], ct = _a[2], l = _a[3];
93
91
  warnings = [];
94
92
  ct.warnings && warnings.push.apply(warnings, __spreadArray([], __read(ct.warnings), false));
95
- if (l._tag === 'Left') {
93
+ if (l._tag === "Left") {
96
94
  return [2 /*return*/, left([l.left])];
97
95
  }
98
96
  else {
99
- pagesByTagId = homePagesByTagId(ctx, l.right, hp);
97
+ pagesByTagId = homePagesByTagId(ctx, l.right, pages.homePages);
100
98
  pagesByTagId.warnings && warnings.push.apply(warnings, __spreadArray([], __read(pagesByTagId.warnings), false));
101
99
  return [2 /*return*/, right({
102
- data: __assign(__assign({}, l.right), { homePagesByTagId: pagesByTagId.homePagesByTagId, contentTypes: ct.contentTypes, pages: pages, redirects: redirects }),
100
+ data: __assign(__assign({}, l.right), { homePagesByTagId: pagesByTagId.homePagesByTagId, contentTypes: ct.contentTypes, pages: pages.allPages, redirects: redirects }),
103
101
  warnings: warnings.length > 0 ? warnings : undefined,
104
102
  })];
105
103
  }
@@ -0,0 +1,41 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import { phraseSimilarity } from "../../../utils/phrase-similarity";
13
+ import { CONSTANTS } from "../../constants";
14
+ import { orphanedPages } from "./orphaned-pages";
15
+ var orphanedPagePhraseSimilarity = function (page, phrase) {
16
+ var slugSimilarity = phraseSimilarity(phrase, page.slug);
17
+ var idSimilarity = phraseSimilarity(phrase, page.id);
18
+ var titleSimilarity = page.title ? phraseSimilarity(phrase, page.title) : 0;
19
+ return Math.max(slugSimilarity, idSimilarity, titleSimilarity);
20
+ };
21
+ export var searchOrphanedPages = function (ctx) {
22
+ return function (phrase, localeCode, limit) {
23
+ var pages = orphanedPages(ctx)({ localeCode: localeCode });
24
+ if (pages._tag === "Right") {
25
+ return pages.right
26
+ .map(function (page) {
27
+ var searchScore = orphanedPagePhraseSimilarity(page, phrase);
28
+ return __assign(__assign({}, page), { searchScore: searchScore });
29
+ })
30
+ .filter(function (_a) {
31
+ var searchScore = _a.searchScore;
32
+ return searchScore >= CONSTANTS.search.minSearchScore;
33
+ })
34
+ .sort(function (a, b) { return b.searchScore - a.searchScore; })
35
+ .slice(0, limit);
36
+ }
37
+ else {
38
+ return [];
39
+ }
40
+ };
41
+ };
@@ -1,97 +1,53 @@
1
- var __read = (this && this.__read) || function (o, n) {
2
- var m = typeof Symbol === "function" && o[Symbol.iterator];
3
- if (!m) return o;
4
- var i = m.call(o), r, ar = [], e;
5
- try {
6
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
7
- }
8
- catch (error) { e = { error: error }; }
9
- finally {
10
- try {
11
- if (r && !r.done && (m = i["return"])) m.call(i);
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
12
7
  }
13
- finally { if (e) throw e.error; }
14
- }
15
- return ar;
16
- };
17
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
18
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
19
- if (ar || !(i in from)) {
20
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
21
- ar[i] = from[i];
22
- }
23
- }
24
- return to.concat(ar || Array.prototype.slice.call(from));
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
25
11
  };
26
- import { stringSimilarity } from '../../../utils/string-similarity';
27
- import { localizedSitemapFromCacheOrBuildEff } from '../helpers/build-localized-sitemap';
28
- import { toArboretumPageWithMissingData } from '../adapters/to-arboretum-page-with-missing-data-adapter';
29
- import { redirectToArboretumPage } from '../adapters/redirect-to-arboretum-page-adapter';
30
- var minPhraseSimilarity = 0.4;
31
- var defaultLimit = 20;
32
- var pagePhraseSimilarity = function (page, path, phrase) {
33
- var slugSimilarity = stringSimilarity(phrase, page.slug);
34
- var pathSimilarity = stringSimilarity(phrase, path);
35
- var idSimilarity = stringSimilarity(phrase, page.sys.id);
36
- return Math.max.apply(Math, [slugSimilarity, pathSimilarity, idSimilarity]);
12
+ import { phraseSimilarity } from "../../../utils/phrase-similarity";
13
+ import { CONSTANTS } from "../../constants";
14
+ import { pages } from "./pages";
15
+ var pagePhraseSimilarity = function (page, phrase) {
16
+ var slugSimilarity = phraseSimilarity(phrase, page.slug);
17
+ var pathSimilarity = phraseSimilarity(phrase, page.path);
18
+ var idSimilarity = phraseSimilarity(phrase, page.id);
19
+ var titleSimilarity = page.title ? phraseSimilarity(phrase, page.title) : 0;
20
+ return Math.max(slugSimilarity, pathSimilarity, idSimilarity, titleSimilarity);
37
21
  };
38
22
  var redirectPhraseSimilarity = function (redirect, phrase) {
39
- var pathSimilarity = stringSimilarity(phrase, redirect.path);
40
- var idSimilarity = stringSimilarity(phrase, redirect.sys.id);
41
- return Math.max.apply(Math, [pathSimilarity, idSimilarity]);
42
- };
43
- var localizedRecursiveSearch = function (localeCode, localizedSitemap, phrase, parentPath, currentPage) {
44
- var getPath = function (page) {
45
- return page.sys.id === localizedSitemap.root.sys.id
46
- ? parentPath
47
- : parentPath + '/' + page.slug;
48
- };
49
- var phraseSimilarity = currentPage.type === 'page'
50
- ? pagePhraseSimilarity(currentPage, getPath(currentPage), phrase)
51
- : redirectPhraseSimilarity(currentPage, phrase);
52
- var childrenResults = currentPage.type === 'page'
53
- ? currentPage.childPages.flatMap(function (_a) {
54
- var id = _a.sys.id;
55
- var childPage = localizedSitemap.sitemap.get(id);
56
- var path = getPath(currentPage);
57
- return childPage
58
- ? localizedRecursiveSearch(localeCode, localizedSitemap, phrase, path, childPage)
59
- : [];
60
- })
61
- : [];
62
- var res = [];
63
- if (phraseSimilarity >= minPhraseSimilarity) {
64
- res.push({
65
- phraseSimilarity: phraseSimilarity,
66
- page: currentPage.type === 'page'
67
- ? toArboretumPageWithMissingData(localeCode)(currentPage, undefined, undefined)
68
- : redirectToArboretumPage(localeCode)(currentPage),
69
- });
70
- }
71
- res.push.apply(res, __spreadArray([], __read(childrenResults), false));
72
- return res;
23
+ var pathSimilarity = phraseSimilarity(phrase, redirect.path);
24
+ var idSimilarity = phraseSimilarity(phrase, redirect.id);
25
+ var titleSimilarity = redirect.title
26
+ ? phraseSimilarity(phrase, redirect.title)
27
+ : 0;
28
+ return Math.max(pathSimilarity, idSimilarity, titleSimilarity);
73
29
  };
74
30
  // Primitive implementation that can be inefficient for large sitemaps
75
31
  export var search = function (ctx) {
76
32
  return function (phrase, localeCode, limit) {
77
- return __spreadArray([], __read(ctx.data.locales.values()), false).filter(function (locale) { return (localeCode ? locale.code === localeCode : true); })
78
- .flatMap(function (locale) {
79
- var sitemap = localizedSitemapFromCacheOrBuildEff(ctx, locale);
80
- var homePage = sitemap._tag === 'Right'
81
- ? sitemap.right.sitemap.get(sitemap.right.root.sys.id)
82
- : undefined;
83
- if (sitemap._tag === 'Right' && homePage) {
84
- return localizedRecursiveSearch(locale.code, sitemap.right, phrase, "/".concat(locale.code), homePage);
85
- }
86
- else {
87
- return [];
88
- }
89
- })
90
- .sort(function (a, b) { return b.phraseSimilarity - a.phraseSimilarity; })
91
- .slice(0, limit || defaultLimit)
92
- .map(function (_a) {
93
- var page = _a.page;
94
- return page;
95
- });
33
+ var allPages = pages(ctx)({ localeCode: localeCode });
34
+ if (allPages._tag === "Right") {
35
+ return allPages.right
36
+ .map(function (page) {
37
+ var searchScore = page.type === "page"
38
+ ? pagePhraseSimilarity(page, phrase)
39
+ : redirectPhraseSimilarity(page, phrase);
40
+ return __assign(__assign({}, page), { searchScore: searchScore });
41
+ })
42
+ .filter(function (_a) {
43
+ var searchScore = _a.searchScore;
44
+ return searchScore >= CONSTANTS.search.minSearchScore;
45
+ })
46
+ .sort(function (a, b) { return b.searchScore - a.searchScore; })
47
+ .slice(0, limit);
48
+ }
49
+ else {
50
+ return [];
51
+ }
96
52
  };
97
53
  };
@@ -0,0 +1,6 @@
1
+ import { stringSimilarity } from "./string-similarity";
2
+ export var phraseSimilarity = function (phrase, value) {
3
+ var s1 = stringSimilarity(phrase, value);
4
+ var s2 = stringSimilarity(phrase, value.slice(0, phrase.length));
5
+ return s1 > s2 ? s1 : s2;
6
+ };
@@ -21,7 +21,7 @@ export function stringSimilarity(str1, str2, gramSize) {
21
21
  var e_1, _a;
22
22
  if (gramSize === void 0) { gramSize = 2; }
23
23
  function getNGrams(s, len) {
24
- s = ' '.repeat(len - 1) + s.toLowerCase() + ' '.repeat(len - 1);
24
+ s = " ".repeat(len - 1) + s.toLowerCase() + " ".repeat(len - 1);
25
25
  var v = new Array(s.length - len + 1);
26
26
  for (var i = 0; i < v.length; i++) {
27
27
  v[i] = s.slice(i, i + len);
@@ -81,7 +81,6 @@ var pages_by_tag_id_1 = require("./sitemap/methods/pages-by-tag-id");
81
81
  var pages_by_ids_1 = require("./sitemap/methods/pages-by-ids");
82
82
  var pages_by_paths_1 = require("./sitemap/methods/pages-by-paths");
83
83
  var regenerate_1 = require("./sitemap/methods/regenerate");
84
- var search_1 = require("./sitemap/methods/search");
85
84
  var status_1 = require("./sitemap/methods/status");
86
85
  var fp_utils_1 = require("../utils/fp-utils");
87
86
  var pages_1 = require("./sitemap/methods/pages");
@@ -90,6 +89,8 @@ var cached_data_1 = require("./sitemap/methods/cached-data");
90
89
  var build_pages_by_tag_eagerly_1 = require("./sitemap/helpers/build-pages-by-tag-eagerly");
91
90
  var home_page_1 = require("./sitemap/methods/home-page");
92
91
  var orphaned_pages_1 = require("./sitemap/methods/orphaned-pages");
92
+ var search_orphaned_pages_1 = require("./sitemap/methods/search-orphaned-pages");
93
+ var search_1 = require("./sitemap/methods/search");
93
94
  var pageTagIdPrefix = "page";
94
95
  var pageHomeTagId = "".concat(pageTagIdPrefix, "Home");
95
96
  var localeTagIdPrefix = "locale";
@@ -173,6 +174,7 @@ var createArboretumClient = function (config) { return __awaiter(void 0, void 0,
173
174
  status: (0, status_1.status)(ctx_1),
174
175
  cachedData: (0, cached_data_1.cachedData)(ctx_1),
175
176
  orphanedPages: (0, orphaned_pages_1.orphanedPages)(ctx_1),
177
+ searchOrphanedPages: (0, search_orphaned_pages_1.searchOrphanedPages)(ctx_1),
176
178
  },
177
179
  warnings: dataE.right.warnings,
178
180
  }];
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONSTANTS = void 0;
4
+ exports.CONSTANTS = {
5
+ search: {
6
+ minSearchScore: 0.4,
7
+ },
8
+ };
@@ -108,7 +108,7 @@ var cmaOnlyEntriesStatusMap = function (_a, contentfulClientType, options) {
108
108
  });
109
109
  };
110
110
  var pageEntries = function (ctx, apiClient, cmaPreviewClientApi) { return __awaiter(void 0, void 0, void 0, function () {
111
- var options, pageContentTypes, pageEntriesPromise, statusRecordPromise, _a, pageEntries, cmaOnlyStatusRecord;
111
+ var options, pageContentTypes, pageEntriesPromise, statusRecordPromise, _a, pageEntries, cmaOnlyStatusRecord, homePages, allPages;
112
112
  return __generator(this, function (_b) {
113
113
  switch (_b.label) {
114
114
  case 0:
@@ -137,15 +137,21 @@ var pageEntries = function (ctx, apiClient, cmaPreviewClientApi) { return __awai
137
137
  ])];
138
138
  case 1:
139
139
  _a = __read.apply(void 0, [_b.sent(), 2]), pageEntries = _a[0], cmaOnlyStatusRecord = _a[1];
140
- return [2 /*return*/, (0, array_to_map_1.arrayToMap)(function (e) { return e.sys.id; })(function (entry) {
141
- var cmaOnlyStatus = ctx.contentfulClientType === "cma-client"
142
- ? (0, entry_status_1.entryStatus)(entry.sys) || cmaOnlyStatusRecord.get(entry.sys.id)
143
- : undefined;
144
- if (cmaOnlyStatus) {
145
- entry.sys = __assign(__assign({}, entry.sys), { cmaOnlyStatus: cmaOnlyStatus });
146
- }
147
- return entry;
148
- })(pageEntries.flat())];
140
+ homePages = [];
141
+ allPages = new Map(pageEntries.flat().map(function (entry) {
142
+ var _a;
143
+ if ((_a = entry.metadata) === null || _a === void 0 ? void 0 : _a.tags.find(function (t) { return t.sys.id.startsWith(ctx.pageHomeTagId); })) {
144
+ homePages.push(entry);
145
+ }
146
+ var cmaOnlyStatus = ctx.contentfulClientType === "cma-client"
147
+ ? (0, entry_status_1.entryStatus)(entry.sys) || cmaOnlyStatusRecord.get(entry.sys.id)
148
+ : undefined;
149
+ if (cmaOnlyStatus) {
150
+ entry.sys = __assign(__assign({}, entry.sys), { cmaOnlyStatus: cmaOnlyStatus });
151
+ }
152
+ return [entry.sys.id, entry];
153
+ }));
154
+ return [2 /*return*/, { allPages: allPages, homePages: homePages }];
149
155
  }
150
156
  });
151
157
  }); };
@@ -67,65 +67,67 @@ var productTypesOptions = function (productTypesIds) {
67
67
  var seed = {};
68
68
  return productTypesIds.reduce(function (acc, ct) {
69
69
  acc[ct] = {
70
- slugFieldId: 'slug',
70
+ slugFieldId: "slug",
71
71
  };
72
72
  return acc;
73
73
  }, seed);
74
74
  };
75
75
  describe(page_entries_1.pageEntries, function () {
76
- test('Handle case where there are no page entries', function () { return __awaiter(void 0, void 0, void 0, function () {
76
+ test("Handle case where there are no page entries", function () { return __awaiter(void 0, void 0, void 0, function () {
77
77
  var singleTestPageContentType, testPageContentTypes, entries1, entries2;
78
78
  return __generator(this, function (_a) {
79
79
  switch (_a.label) {
80
80
  case 0:
81
- singleTestPageContentType = ['page1ContentType'];
81
+ singleTestPageContentType = ["page1ContentType"];
82
82
  testPageContentTypes = __spreadArray(__spreadArray([], __read(singleTestPageContentType), false), [
83
- 'page2ContentType',
83
+ "page2ContentType",
84
84
  ], false);
85
85
  return [4 /*yield*/, (0, page_entries_1.pageEntries)({
86
- contentfulClientType: 'cda-client',
86
+ contentfulClientType: "cda-client",
87
87
  options: {
88
88
  pageContentTypes: productTypesOptions(singleTestPageContentType),
89
89
  },
90
90
  preview: false,
91
+ pageHomeTagId: "homePage",
91
92
  }, (0, mocked_contentful_entries_client_api_1.multipleContentTypesMockedContentfulEntriesClientApi)(singleTestPageContentType.map(function (contentType) { return ({
92
93
  contentType: contentType,
93
94
  total: 0,
94
95
  }); })))];
95
96
  case 1:
96
97
  entries1 = _a.sent();
97
- expect(entries1.size).toBe(0);
98
+ expect(entries1.allPages.size).toBe(0);
98
99
  return [4 /*yield*/, (0, page_entries_1.pageEntries)({
99
- contentfulClientType: 'cda-client',
100
+ contentfulClientType: "cda-client",
100
101
  options: {
101
102
  pageContentTypes: productTypesOptions(testPageContentTypes),
102
103
  },
103
104
  preview: false,
105
+ pageHomeTagId: "homePage",
104
106
  }, (0, mocked_contentful_entries_client_api_1.multipleContentTypesMockedContentfulEntriesClientApi)(testPageContentTypes.map(function (contentType) { return ({
105
107
  contentType: contentType,
106
108
  total: 0,
107
109
  }); })))];
108
110
  case 2:
109
111
  entries2 = _a.sent();
110
- expect(entries2.size).toBe(0);
112
+ expect(entries2.allPages.size).toBe(0);
111
113
  return [2 /*return*/];
112
114
  }
113
115
  });
114
116
  }); });
115
117
  describe(page_entries_1.pageEntries, function () {
116
- test('Handle case where there are page entries', function () { return __awaiter(void 0, void 0, void 0, function () {
118
+ test("Handle case where there are page entries", function () { return __awaiter(void 0, void 0, void 0, function () {
117
119
  var singleTestPageContentType, testPageContentTypes, entries1, entries1Ids, expectedEntries1Ids, entries2, entries2Ids, expectedEntries2Ids;
118
120
  return __generator(this, function (_a) {
119
121
  switch (_a.label) {
120
122
  case 0:
121
123
  singleTestPageContentType = [
122
- { contentType: 'page1ContentType', total: 101 },
124
+ { contentType: "page1ContentType", total: 101 },
123
125
  ];
124
126
  testPageContentTypes = __spreadArray(__spreadArray([], __read(singleTestPageContentType), false), [
125
- { contentType: 'page2ContentType', total: 1001 },
127
+ { contentType: "page2ContentType", total: 1001 },
126
128
  ], false);
127
129
  return [4 /*yield*/, (0, page_entries_1.pageEntries)({
128
- contentfulClientType: 'cda-client',
130
+ contentfulClientType: "cda-client",
129
131
  options: {
130
132
  pageContentTypes: productTypesOptions(singleTestPageContentType.map(function (_a) {
131
133
  var contentType = _a.contentType;
@@ -133,10 +135,11 @@ describe(page_entries_1.pageEntries, function () {
133
135
  })),
134
136
  },
135
137
  preview: false,
138
+ pageHomeTagId: "homePage",
136
139
  }, (0, mocked_contentful_entries_client_api_1.multipleContentTypesMockedContentfulEntriesClientApi)(singleTestPageContentType))];
137
140
  case 1:
138
141
  entries1 = _a.sent();
139
- entries1Ids = __spreadArray([], __read(entries1.values()), false).map(function (e) { return e.sys.id; });
142
+ entries1Ids = __spreadArray([], __read(entries1.allPages.values()), false).map(function (e) { return e.sys.id; });
140
143
  expectedEntries1Ids = singleTestPageContentType.flatMap(function (_a) {
141
144
  var total = _a.total, contentType = _a.contentType;
142
145
  return __spreadArray([], __read(Array(total).keys()), false).map(function (_, idx) {
@@ -145,7 +148,7 @@ describe(page_entries_1.pageEntries, function () {
145
148
  });
146
149
  expect(entries1Ids).toEqual(expectedEntries1Ids);
147
150
  return [4 /*yield*/, (0, page_entries_1.pageEntries)({
148
- contentfulClientType: 'cda-client',
151
+ contentfulClientType: "cda-client",
149
152
  options: {
150
153
  pageContentTypes: productTypesOptions(testPageContentTypes.map(function (_a) {
151
154
  var contentType = _a.contentType;
@@ -153,10 +156,11 @@ describe(page_entries_1.pageEntries, function () {
153
156
  })),
154
157
  },
155
158
  preview: false,
159
+ pageHomeTagId: "homePage",
156
160
  }, (0, mocked_contentful_entries_client_api_1.multipleContentTypesMockedContentfulEntriesClientApi)(testPageContentTypes))];
157
161
  case 2:
158
162
  entries2 = _a.sent();
159
- entries2Ids = __spreadArray([], __read(entries2.values()), false).map(function (e) { return e.sys.id; });
163
+ entries2Ids = __spreadArray([], __read(entries2.allPages.values()), false).map(function (e) { return e.sys.id; });
160
164
  expectedEntries2Ids = testPageContentTypes.flatMap(function (_a) {
161
165
  var total = _a.total, contentType = _a.contentType;
162
166
  return __spreadArray([], __read(Array(total).keys()), false).map(function (_, idx) {
@@ -77,11 +77,10 @@ var page_entries_1 = require("./page-entries");
77
77
  var fp_utils_1 = require("../../utils/fp-utils");
78
78
  var content_types_1 = require("./content-types");
79
79
  var locales_1 = require("./locales");
80
- var home_page_1 = require("./home-page");
81
80
  var redirect_entries_1 = require("./redirect-entries");
82
81
  var home_pages_by_tag_id_1 = require("./helpers/home-pages-by-tag-id");
83
82
  var sitemapData = function (ctx) { return __awaiter(void 0, void 0, void 0, function () {
84
- var _a, pages, redirects, ct, l, hp, warnings, pagesByTagId;
83
+ var _a, pages, redirects, ct, l, warnings, pagesByTagId;
85
84
  return __generator(this, function (_b) {
86
85
  switch (_b.label) {
87
86
  case 0: return [4 /*yield*/, Promise.all([
@@ -89,20 +88,19 @@ var sitemapData = function (ctx) { return __awaiter(void 0, void 0, void 0, func
89
88
  (0, redirect_entries_1.redirectEntries)(ctx),
90
89
  (0, content_types_1.contentTypes)(ctx),
91
90
  (0, locales_1.locales)(ctx),
92
- (0, home_page_1.homePages)(ctx, ctx.pageHomeTagId),
93
91
  ])];
94
92
  case 1:
95
- _a = __read.apply(void 0, [_b.sent(), 5]), pages = _a[0], redirects = _a[1], ct = _a[2], l = _a[3], hp = _a[4];
93
+ _a = __read.apply(void 0, [_b.sent(), 4]), pages = _a[0], redirects = _a[1], ct = _a[2], l = _a[3];
96
94
  warnings = [];
97
95
  ct.warnings && warnings.push.apply(warnings, __spreadArray([], __read(ct.warnings), false));
98
- if (l._tag === 'Left') {
96
+ if (l._tag === "Left") {
99
97
  return [2 /*return*/, (0, fp_utils_1.left)([l.left])];
100
98
  }
101
99
  else {
102
- pagesByTagId = (0, home_pages_by_tag_id_1.homePagesByTagId)(ctx, l.right, hp);
100
+ pagesByTagId = (0, home_pages_by_tag_id_1.homePagesByTagId)(ctx, l.right, pages.homePages);
103
101
  pagesByTagId.warnings && warnings.push.apply(warnings, __spreadArray([], __read(pagesByTagId.warnings), false));
104
102
  return [2 /*return*/, (0, fp_utils_1.right)({
105
- data: __assign(__assign({}, l.right), { homePagesByTagId: pagesByTagId.homePagesByTagId, contentTypes: ct.contentTypes, pages: pages, redirects: redirects }),
103
+ data: __assign(__assign({}, l.right), { homePagesByTagId: pagesByTagId.homePagesByTagId, contentTypes: ct.contentTypes, pages: pages.allPages, redirects: redirects }),
106
104
  warnings: warnings.length > 0 ? warnings : undefined,
107
105
  })];
108
106
  }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.searchOrphanedPages = void 0;
15
+ var phrase_similarity_1 = require("../../../utils/phrase-similarity");
16
+ var constants_1 = require("../../constants");
17
+ var orphaned_pages_1 = require("./orphaned-pages");
18
+ var orphanedPagePhraseSimilarity = function (page, phrase) {
19
+ var slugSimilarity = (0, phrase_similarity_1.phraseSimilarity)(phrase, page.slug);
20
+ var idSimilarity = (0, phrase_similarity_1.phraseSimilarity)(phrase, page.id);
21
+ var titleSimilarity = page.title ? (0, phrase_similarity_1.phraseSimilarity)(phrase, page.title) : 0;
22
+ return Math.max(slugSimilarity, idSimilarity, titleSimilarity);
23
+ };
24
+ var searchOrphanedPages = function (ctx) {
25
+ return function (phrase, localeCode, limit) {
26
+ var pages = (0, orphaned_pages_1.orphanedPages)(ctx)({ localeCode: localeCode });
27
+ if (pages._tag === "Right") {
28
+ return pages.right
29
+ .map(function (page) {
30
+ var searchScore = orphanedPagePhraseSimilarity(page, phrase);
31
+ return __assign(__assign({}, page), { searchScore: searchScore });
32
+ })
33
+ .filter(function (_a) {
34
+ var searchScore = _a.searchScore;
35
+ return searchScore >= constants_1.CONSTANTS.search.minSearchScore;
36
+ })
37
+ .sort(function (a, b) { return b.searchScore - a.searchScore; })
38
+ .slice(0, limit);
39
+ }
40
+ else {
41
+ return [];
42
+ }
43
+ };
44
+ };
45
+ exports.searchOrphanedPages = searchOrphanedPages;
@@ -1,101 +1,57 @@
1
1
  "use strict";
2
- var __read = (this && this.__read) || function (o, n) {
3
- var m = typeof Symbol === "function" && o[Symbol.iterator];
4
- if (!m) return o;
5
- var i = m.call(o), r, ar = [], e;
6
- try {
7
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8
- }
9
- catch (error) { e = { error: error }; }
10
- finally {
11
- try {
12
- if (r && !r.done && (m = i["return"])) m.call(i);
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
13
8
  }
14
- finally { if (e) throw e.error; }
15
- }
16
- return ar;
17
- };
18
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
19
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
20
- if (ar || !(i in from)) {
21
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
22
- ar[i] = from[i];
23
- }
24
- }
25
- return to.concat(ar || Array.prototype.slice.call(from));
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
26
12
  };
27
13
  Object.defineProperty(exports, "__esModule", { value: true });
28
14
  exports.search = void 0;
29
- var string_similarity_1 = require("../../../utils/string-similarity");
30
- var build_localized_sitemap_1 = require("../helpers/build-localized-sitemap");
31
- var to_arboretum_page_with_missing_data_adapter_1 = require("../adapters/to-arboretum-page-with-missing-data-adapter");
32
- var redirect_to_arboretum_page_adapter_1 = require("../adapters/redirect-to-arboretum-page-adapter");
33
- var minPhraseSimilarity = 0.4;
34
- var defaultLimit = 20;
35
- var pagePhraseSimilarity = function (page, path, phrase) {
36
- var slugSimilarity = (0, string_similarity_1.stringSimilarity)(phrase, page.slug);
37
- var pathSimilarity = (0, string_similarity_1.stringSimilarity)(phrase, path);
38
- var idSimilarity = (0, string_similarity_1.stringSimilarity)(phrase, page.sys.id);
39
- return Math.max.apply(Math, [slugSimilarity, pathSimilarity, idSimilarity]);
15
+ var phrase_similarity_1 = require("../../../utils/phrase-similarity");
16
+ var constants_1 = require("../../constants");
17
+ var pages_1 = require("./pages");
18
+ var pagePhraseSimilarity = function (page, phrase) {
19
+ var slugSimilarity = (0, phrase_similarity_1.phraseSimilarity)(phrase, page.slug);
20
+ var pathSimilarity = (0, phrase_similarity_1.phraseSimilarity)(phrase, page.path);
21
+ var idSimilarity = (0, phrase_similarity_1.phraseSimilarity)(phrase, page.id);
22
+ var titleSimilarity = page.title ? (0, phrase_similarity_1.phraseSimilarity)(phrase, page.title) : 0;
23
+ return Math.max(slugSimilarity, pathSimilarity, idSimilarity, titleSimilarity);
40
24
  };
41
25
  var redirectPhraseSimilarity = function (redirect, phrase) {
42
- var pathSimilarity = (0, string_similarity_1.stringSimilarity)(phrase, redirect.path);
43
- var idSimilarity = (0, string_similarity_1.stringSimilarity)(phrase, redirect.sys.id);
44
- return Math.max.apply(Math, [pathSimilarity, idSimilarity]);
45
- };
46
- var localizedRecursiveSearch = function (localeCode, localizedSitemap, phrase, parentPath, currentPage) {
47
- var getPath = function (page) {
48
- return page.sys.id === localizedSitemap.root.sys.id
49
- ? parentPath
50
- : parentPath + '/' + page.slug;
51
- };
52
- var phraseSimilarity = currentPage.type === 'page'
53
- ? pagePhraseSimilarity(currentPage, getPath(currentPage), phrase)
54
- : redirectPhraseSimilarity(currentPage, phrase);
55
- var childrenResults = currentPage.type === 'page'
56
- ? currentPage.childPages.flatMap(function (_a) {
57
- var id = _a.sys.id;
58
- var childPage = localizedSitemap.sitemap.get(id);
59
- var path = getPath(currentPage);
60
- return childPage
61
- ? localizedRecursiveSearch(localeCode, localizedSitemap, phrase, path, childPage)
62
- : [];
63
- })
64
- : [];
65
- var res = [];
66
- if (phraseSimilarity >= minPhraseSimilarity) {
67
- res.push({
68
- phraseSimilarity: phraseSimilarity,
69
- page: currentPage.type === 'page'
70
- ? (0, to_arboretum_page_with_missing_data_adapter_1.toArboretumPageWithMissingData)(localeCode)(currentPage, undefined, undefined)
71
- : (0, redirect_to_arboretum_page_adapter_1.redirectToArboretumPage)(localeCode)(currentPage),
72
- });
73
- }
74
- res.push.apply(res, __spreadArray([], __read(childrenResults), false));
75
- return res;
26
+ var pathSimilarity = (0, phrase_similarity_1.phraseSimilarity)(phrase, redirect.path);
27
+ var idSimilarity = (0, phrase_similarity_1.phraseSimilarity)(phrase, redirect.id);
28
+ var titleSimilarity = redirect.title
29
+ ? (0, phrase_similarity_1.phraseSimilarity)(phrase, redirect.title)
30
+ : 0;
31
+ return Math.max(pathSimilarity, idSimilarity, titleSimilarity);
76
32
  };
77
33
  // Primitive implementation that can be inefficient for large sitemaps
78
34
  var search = function (ctx) {
79
35
  return function (phrase, localeCode, limit) {
80
- return __spreadArray([], __read(ctx.data.locales.values()), false).filter(function (locale) { return (localeCode ? locale.code === localeCode : true); })
81
- .flatMap(function (locale) {
82
- var sitemap = (0, build_localized_sitemap_1.localizedSitemapFromCacheOrBuildEff)(ctx, locale);
83
- var homePage = sitemap._tag === 'Right'
84
- ? sitemap.right.sitemap.get(sitemap.right.root.sys.id)
85
- : undefined;
86
- if (sitemap._tag === 'Right' && homePage) {
87
- return localizedRecursiveSearch(locale.code, sitemap.right, phrase, "/".concat(locale.code), homePage);
88
- }
89
- else {
90
- return [];
91
- }
92
- })
93
- .sort(function (a, b) { return b.phraseSimilarity - a.phraseSimilarity; })
94
- .slice(0, limit || defaultLimit)
95
- .map(function (_a) {
96
- var page = _a.page;
97
- return page;
98
- });
36
+ var allPages = (0, pages_1.pages)(ctx)({ localeCode: localeCode });
37
+ if (allPages._tag === "Right") {
38
+ return allPages.right
39
+ .map(function (page) {
40
+ var searchScore = page.type === "page"
41
+ ? pagePhraseSimilarity(page, phrase)
42
+ : redirectPhraseSimilarity(page, phrase);
43
+ return __assign(__assign({}, page), { searchScore: searchScore });
44
+ })
45
+ .filter(function (_a) {
46
+ var searchScore = _a.searchScore;
47
+ return searchScore >= constants_1.CONSTANTS.search.minSearchScore;
48
+ })
49
+ .sort(function (a, b) { return b.searchScore - a.searchScore; })
50
+ .slice(0, limit);
51
+ }
52
+ else {
53
+ return [];
54
+ }
99
55
  };
100
56
  };
101
57
  exports.search = search;
@@ -109,7 +109,14 @@ export type ArboretumPageT = ArboretumPageBaseT & {
109
109
  [key: string]: any;
110
110
  };
111
111
  };
112
+ export type OrphanedArboretumPageT = Omit<ArboretumPageT, "path" | "totalDirectChildrenCount" | "ancestors" | "children">;
113
+ export type OrphanedArboretumPageSearchResultT = OrphanedArboretumPageT & {
114
+ searchScore: number;
115
+ };
112
116
  export type ArboretumPageNodeT = ArboretumPageT | ArboretumRedirectT | ArboretumAliasT;
117
+ export type ArboretumPageSearchResultNodeT = ArboretumPageNodeT & {
118
+ searchScore: number;
119
+ };
113
120
  export type OptionsT = {
114
121
  withChildren?: boolean;
115
122
  withAncestors?: boolean;
@@ -132,7 +139,7 @@ export type ArboretumClientT = {
132
139
  status: "OK";
133
140
  warnings?: Array<string>;
134
141
  }>;
135
- search: (phrase: string, localeCode?: string, limit?: number) => Array<ArboretumPageNodeT>;
142
+ search: (phrase: string, localeCode?: string, limit?: number) => Array<ArboretumPageSearchResultNodeT>;
136
143
  status: () => {
137
144
  lastUpdatedAt: string;
138
145
  pagesCount: number;
@@ -145,6 +152,7 @@ export type ArboretumClientT = {
145
152
  limit?: number;
146
153
  skip?: number;
147
154
  localeCode?: string;
148
- }) => Either<string, Array<Omit<ArboretumPageT, "path" | "totalDirectChildrenCount" | "ancestors" | "children">>>;
155
+ }) => Either<string, Array<OrphanedArboretumPageT>>;
156
+ searchOrphanedPages: (phrase: string, localeCode?: string, limit?: number) => Array<OrphanedArboretumPageSearchResultT>;
149
157
  };
150
158
  export {};
@@ -0,0 +1,5 @@
1
+ export declare const CONSTANTS: {
2
+ search: {
3
+ minSearchScore: number;
4
+ };
5
+ };
@@ -1,3 +1,7 @@
1
1
  import { ArboretumClientCtx } from "../arboretum-client.impl";
2
+ import { EntryT } from "../../clients/contentful-client/contentful-client";
2
3
  import { EntriesT } from "./sitemap-data";
3
- export declare const pageEntries: (ctx: Pick<ArboretumClientCtx, "options" | "contentfulClientType" | "preview">, apiClient: Pick<ArboretumClientCtx["clientApi"], "getEntries">, cmaPreviewClientApi?: Pick<NonNullable<ArboretumClientCtx["cmaPreviewClientApi"]>, "getEntries">) => Promise<EntriesT>;
4
+ export declare const pageEntries: (ctx: Pick<ArboretumClientCtx, "options" | "contentfulClientType" | "preview" | "pageHomeTagId">, apiClient: Pick<ArboretumClientCtx["clientApi"], "getEntries">, cmaPreviewClientApi?: Pick<NonNullable<ArboretumClientCtx["cmaPreviewClientApi"]>, "getEntries">) => Promise<{
5
+ allPages: EntriesT;
6
+ homePages: Array<EntryT>;
7
+ }>;
@@ -1,17 +1,17 @@
1
- import { Either } from '../../utils/fp-utils';
2
- import { ArboretumClientCtx } from '../arboretum-client.impl';
3
- import { ContentTypesT } from './content-types';
4
- import { LocalesT } from './locales';
5
- import { EntryIdT, EntryT } from '../../clients/contentful-client/contentful-client';
6
- import { HomePagesByTagIdT } from './helpers/home-pages-by-tag-id';
1
+ import { Either } from "../../utils/fp-utils";
2
+ import { ArboretumClientCtx } from "../arboretum-client.impl";
3
+ import { ContentTypesT } from "./content-types";
4
+ import { LocalesT } from "./locales";
5
+ import { EntryIdT, EntryT } from "../../clients/contentful-client/contentful-client";
6
+ import { HomePagesByTagIdT } from "./helpers/home-pages-by-tag-id";
7
7
  export type EntriesT = Map<EntryIdT, EntryT>;
8
8
  export type SitemapDataT = LocalesT & {
9
9
  contentTypes: ContentTypesT;
10
10
  pages: EntriesT;
11
11
  redirects: Array<EntryT>;
12
- homePagesByTagId: HomePagesByTagIdT['homePagesByTagId'];
12
+ homePagesByTagId: HomePagesByTagIdT["homePagesByTagId"];
13
13
  };
14
- export declare const sitemapData: (ctx: Pick<ArboretumClientCtx, 'clientApi' | 'options' | 'pageHomeTagId' | 'localeTagIdPrefix' | 'contentfulClientType' | 'cmaPreviewClientApi' | 'preview' | 'pageTagIdPrefix'>) => Promise<Either<string[], {
14
+ export declare const sitemapData: (ctx: Pick<ArboretumClientCtx, "clientApi" | "options" | "pageHomeTagId" | "localeTagIdPrefix" | "contentfulClientType" | "cmaPreviewClientApi" | "preview" | "pageTagIdPrefix">) => Promise<Either<string[], {
15
15
  data: SitemapDataT;
16
16
  warnings?: string[] | undefined;
17
17
  }>>;
@@ -0,0 +1,3 @@
1
+ import { ArboretumClientT } from "../../../arboretum-client";
2
+ import { ArboretumClientCtx } from "../../arboretum-client.impl";
3
+ export declare const searchOrphanedPages: (ctx: Pick<ArboretumClientCtx, "data" | "sitemap" | "options" | "pageHomeTagId">) => ArboretumClientT["searchOrphanedPages"];
@@ -1,3 +1,3 @@
1
- import { ArboretumClientT } from '../../../arboretum-client';
2
- import { ArboretumClientCtx } from '../../arboretum-client.impl';
3
- export declare const search: (ctx: Pick<ArboretumClientCtx, 'data' | 'sitemap' | 'options' | 'pageHomeTagId'>) => ArboretumClientT['search'];
1
+ import { ArboretumClientT } from "../../../arboretum-client";
2
+ import { ArboretumClientCtx } from "../../arboretum-client.impl";
3
+ export declare const search: (ctx: Pick<ArboretumClientCtx, "data" | "sitemap" | "options" | "pageHomeTagId">) => ArboretumClientT["search"];
@@ -0,0 +1 @@
1
+ export declare const phraseSimilarity: (phrase: string, value: string) => number;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.phraseSimilarity = void 0;
4
+ var string_similarity_1 = require("./string-similarity");
5
+ var phraseSimilarity = function (phrase, value) {
6
+ var s1 = (0, string_similarity_1.stringSimilarity)(phrase, value);
7
+ var s2 = (0, string_similarity_1.stringSimilarity)(phrase, value.slice(0, phrase.length));
8
+ return s1 > s2 ? s1 : s2;
9
+ };
10
+ exports.phraseSimilarity = phraseSimilarity;
@@ -24,7 +24,7 @@ function stringSimilarity(str1, str2, gramSize) {
24
24
  var e_1, _a;
25
25
  if (gramSize === void 0) { gramSize = 2; }
26
26
  function getNGrams(s, len) {
27
- s = ' '.repeat(len - 1) + s.toLowerCase() + ' '.repeat(len - 1);
27
+ s = " ".repeat(len - 1) + s.toLowerCase() + " ".repeat(len - 1);
28
28
  var v = new Array(s.length - len + 1);
29
29
  for (var i = 0; i < v.length; i++) {
30
30
  v[i] = s.slice(i, i + len);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bright.global/arboretum-sdk",
3
- "version": "0.1.0-rc.3",
3
+ "version": "0.1.0-rc.5",
4
4
  "license": "MIT",
5
5
  "description": "The sitemap for contentful",
6
6
  "dependencies": {},
@@ -1,75 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- var __generator = (this && this.__generator) || function (thisArg, body) {
11
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
- function verb(n) { return function (v) { return step([n, v]); }; }
14
- function step(op) {
15
- if (f) throw new TypeError("Generator is already executing.");
16
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
- if (y = 0, t) op = [op[0] & 2, t.value];
19
- switch (op[0]) {
20
- case 0: case 1: t = op; break;
21
- case 4: _.label++; return { value: op[1], done: false };
22
- case 5: _.label++; y = op[1]; op = [0]; continue;
23
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
- default:
25
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
- if (t[2]) _.ops.pop();
30
- _.trys.pop(); continue;
31
- }
32
- op = body.call(thisArg, _);
33
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
- }
36
- };
37
- export var homePages = function (ctx, homePageTagId) { return __awaiter(void 0, void 0, void 0, function () {
38
- var homePages;
39
- var _a;
40
- return __generator(this, function (_b) {
41
- switch (_b.label) {
42
- case 0: return [4 /*yield*/, ctx.clientApi.getEntries((_a = {},
43
- _a["metadata.tags.sys.id[in]"] = homePageTagId,
44
- _a.include = 0,
45
- _a.select =
46
- /* For some reason select param causes errors in CMA. I'm getting the following response:
47
- {
48
- "status": 400,
49
- "statusText": "Bad Request",
50
- "message": "The query you sent was invalid. Probably a filter or ordering specification is not applicable to the type of a field.",
51
- "details": {
52
- "errors": [
53
- {
54
- "name": "select",
55
- "details": "Select is only applicable when querying a collection of entities."
56
- }
57
- ]
58
- },
59
- "request": {
60
- "url": "/spaces/8h4rcnu50txt/environments/dacjan-test/public/entries",
61
- "method": "get",
62
- ...
63
- },
64
- }*/
65
- ctx.contentfulClientType === "cma-client"
66
- ? undefined
67
- : ["sys.id", "metadata"].join(","),
68
- _a.order = "sys.createdAt",
69
- _a))];
70
- case 1:
71
- homePages = (_b.sent()).items;
72
- return [2 /*return*/, homePages];
73
- }
74
- });
75
- }); };
@@ -1,79 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.homePages = void 0;
40
- var homePages = function (ctx, homePageTagId) { return __awaiter(void 0, void 0, void 0, function () {
41
- var homePages;
42
- var _a;
43
- return __generator(this, function (_b) {
44
- switch (_b.label) {
45
- case 0: return [4 /*yield*/, ctx.clientApi.getEntries((_a = {},
46
- _a["metadata.tags.sys.id[in]"] = homePageTagId,
47
- _a.include = 0,
48
- _a.select =
49
- /* For some reason select param causes errors in CMA. I'm getting the following response:
50
- {
51
- "status": 400,
52
- "statusText": "Bad Request",
53
- "message": "The query you sent was invalid. Probably a filter or ordering specification is not applicable to the type of a field.",
54
- "details": {
55
- "errors": [
56
- {
57
- "name": "select",
58
- "details": "Select is only applicable when querying a collection of entities."
59
- }
60
- ]
61
- },
62
- "request": {
63
- "url": "/spaces/8h4rcnu50txt/environments/dacjan-test/public/entries",
64
- "method": "get",
65
- ...
66
- },
67
- }*/
68
- ctx.contentfulClientType === "cma-client"
69
- ? undefined
70
- : ["sys.id", "metadata"].join(","),
71
- _a.order = "sys.createdAt",
72
- _a))];
73
- case 1:
74
- homePages = (_b.sent()).items;
75
- return [2 /*return*/, homePages];
76
- }
77
- });
78
- }); };
79
- exports.homePages = homePages;
@@ -1,3 +0,0 @@
1
- import { ArboretumClientCtx } from "../arboretum-client.impl";
2
- import { EntryT } from "../../clients/contentful-client/contentful-client";
3
- export declare const homePages: (ctx: Pick<ArboretumClientCtx, "clientApi" | "localeTagIdPrefix" | "contentfulClientType">, homePageTagId: string) => Promise<Array<EntryT>>;