contentful-resolve-response 1.8.2 → 1.9.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.
@@ -0,0 +1,14 @@
1
+ export default resolveResponse;
2
+ /**
3
+ * ResolveResponse Function
4
+ * Resolves contentful response to normalized form.
5
+ * @param {Object} response Contentful response
6
+ * @param {{removeUnresolved: Boolean, itemEntryPoints: Array<String>}|{}} options
7
+ * @param {Boolean} options.removeUnresolved - Remove unresolved links default:false
8
+ * @param {Array<String>} options.itemEntryPoints - Resolve links only in those item properties
9
+ * @return {Object}
10
+ */
11
+ declare function resolveResponse(response: any, options: {
12
+ removeUnresolved: boolean;
13
+ itemEntryPoints: Array<string>;
14
+ } | {}): any;
package/dist/cjs/index.js CHANGED
@@ -1,39 +1,19 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
-
7
- var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
8
-
9
- var _fastCopy = require('fast-copy');
10
-
11
- var _fastCopy2 = _interopRequireDefault(_fastCopy);
12
-
13
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
-
15
- function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
16
-
17
- var UNRESOLVED_LINK = {}; // unique object to avoid polyfill bloat using Symbol()
18
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const fast_copy_1 = require("fast-copy");
4
+ const UNRESOLVED_LINK = {}; // Unique object to avoid polyfill bloat using Symbol()
19
5
  /**
20
- * isLink Function
6
+ * IsLink Function
21
7
  * Checks if the object has sys.type "Link"
22
8
  * @param object
23
9
  */
24
- var isLink = function isLink(object) {
25
- return object && object.sys && object.sys.type === 'Link';
26
- };
27
-
10
+ const isLink = (object) => object && object.sys && object.sys.type === 'Link';
28
11
  /**
29
- * isResourceLink Function
12
+ * IsResourceLink Function
30
13
  * Checks if the object has sys.type "ResourceLink"
31
14
  * @param object
32
15
  */
33
- var isResourceLink = function isResourceLink(object) {
34
- return object && object.sys && object.sys.type === 'ResourceLink';
35
- };
36
-
16
+ const isResourceLink = (object) => object && object.sys && object.sys.type === 'ResourceLink';
37
17
  /**
38
18
  * Creates a key with spaceId and a key without for entityMap
39
19
  *
@@ -45,14 +25,12 @@ var isResourceLink = function isResourceLink(object) {
45
25
  * @param {String} sys.space.id
46
26
  * @return {string[]}
47
27
  */
48
- var makeEntityMapKeys = function makeEntityMapKeys(sys) {
49
- if (sys.space && sys.environment) {
50
- return [`${sys.type}!${sys.id}`, `${sys.space.sys.id}!${sys.environment.sys.id}!${sys.type}!${sys.id}`];
51
- }
52
-
53
- return [`${sys.type}!${sys.id}`];
28
+ const makeEntityMapKeys = (sys) => {
29
+ if (sys.space && sys.environment) {
30
+ return [`${sys.type}!${sys.id}`, `${sys.space.sys.id}!${sys.environment.sys.id}!${sys.type}!${sys.id}`];
31
+ }
32
+ return [`${sys.type}!${sys.id}`];
54
33
  };
55
-
56
34
  /**
57
35
  * Looks up in entityMap
58
36
  *
@@ -64,149 +42,149 @@ var makeEntityMapKeys = function makeEntityMapKeys(sys) {
64
42
  * @param {String} linkData.urn
65
43
  * @return {String}
66
44
  */
67
- var lookupInEntityMap = function lookupInEntityMap(entityMap, linkData) {
68
- var entryId = linkData.entryId,
69
- linkType = linkData.linkType,
70
- spaceId = linkData.spaceId,
71
- environmentId = linkData.environmentId;
72
-
73
-
74
- if (spaceId && environmentId) {
75
- return entityMap.get(`${spaceId}!${environmentId}!${linkType}!${entryId}`);
76
- }
77
-
78
- return entityMap.get(`${linkType}!${entryId}`);
45
+ const lookupInEntityMap = (entityMap, linkData) => {
46
+ const { entryId, linkType, spaceId, environmentId } = linkData;
47
+ if (spaceId && environmentId) {
48
+ return entityMap.get(`${spaceId}!${environmentId}!${linkType}!${entryId}`);
49
+ }
50
+ return entityMap.get(`${linkType}!${entryId}`);
79
51
  };
80
-
81
- var getIdsFromUrn = function getIdsFromUrn(urn) {
82
- var regExp = /.*:spaces\/([^/]+)(?:\/environments\/([^/]+))?\/entries\/([^/]+)$/;
83
-
84
- if (!regExp.test(urn)) {
85
- return undefined;
86
- }
87
-
88
- var _urn$match = urn.match(regExp),
89
- _urn$match2 = _slicedToArray(_urn$match, 4),
90
- _ = _urn$match2[0],
91
- spaceId = _urn$match2[1],
92
- _urn$match2$ = _urn$match2[2],
93
- environmentId = _urn$match2$ === undefined ? 'master' : _urn$match2$,
94
- entryId = _urn$match2[3];
95
-
96
- return { spaceId, environmentId, entryId };
52
+ const getIdsFromUrn = (urn) => {
53
+ const regExp = /.*:spaces\/([^/]+)(?:\/environments\/([^/]+))?\/entries\/([^/]+)$/;
54
+ if (!regExp.test(urn)) {
55
+ return undefined;
56
+ }
57
+ // eslint-disable-next-line no-unused-vars
58
+ const [_, spaceId, environmentId = 'master', entryId] = urn.match(regExp);
59
+ return { spaceId, environmentId, entryId };
97
60
  };
98
-
99
61
  /**
100
- * getResolvedLink Function
62
+ * GetResolvedLink Function
101
63
  *
102
64
  * @param entityMap
103
65
  * @param link
104
66
  * @return {undefined}
105
67
  */
106
- var getResolvedLink = function getResolvedLink(entityMap, link) {
107
- var _link$sys = link.sys,
108
- type = _link$sys.type,
109
- linkType = _link$sys.linkType;
110
-
111
- if (type === 'ResourceLink') {
112
- if (!linkType.startsWith('Contentful:')) {
113
- return UNRESOLVED_LINK;
114
- }
115
-
116
- var urn = link.sys.urn;
117
-
118
- var _getIdsFromUrn = getIdsFromUrn(urn),
119
- spaceId = _getIdsFromUrn.spaceId,
120
- environmentId = _getIdsFromUrn.environmentId,
121
- _entryId = _getIdsFromUrn.entryId;
122
-
123
- var extractedLinkType = linkType.split(':')[1];
124
-
125
- return lookupInEntityMap(entityMap, {
126
- linkType: extractedLinkType,
127
- entryId: _entryId,
128
- spaceId,
129
- environmentId
130
- }) || UNRESOLVED_LINK;
131
- }
132
-
133
- var entryId = link.sys.id;
134
-
135
- return lookupInEntityMap(entityMap, { linkType, entryId }) || UNRESOLVED_LINK;
68
+ const getResolvedLink = (entityMap, link) => {
69
+ const { type, linkType } = link.sys;
70
+ if (type === 'ResourceLink') {
71
+ if (!linkType.startsWith('Contentful:')) {
72
+ return link;
73
+ }
74
+ const { urn } = link.sys;
75
+ const { spaceId, environmentId, entryId } = getIdsFromUrn(urn);
76
+ const extractedLinkType = linkType.split(':')[1];
77
+ return (lookupInEntityMap(entityMap, {
78
+ linkType: extractedLinkType,
79
+ entryId,
80
+ spaceId,
81
+ environmentId,
82
+ }) || UNRESOLVED_LINK);
83
+ }
84
+ const { id: entryId } = link.sys;
85
+ return lookupInEntityMap(entityMap, { linkType, entryId }) || UNRESOLVED_LINK;
136
86
  };
137
-
138
87
  /**
139
- * cleanUpLinks Function
88
+ * CleanUpUnresolvedLinks Function
140
89
  * - Removes unresolvable links from Arrays and Objects
141
90
  *
142
91
  * @param {Object[]|Object} input
143
92
  */
144
- var cleanUpLinks = function cleanUpLinks(input) {
145
- if (Array.isArray(input)) {
146
- return input.filter(function (val) {
147
- return val !== UNRESOLVED_LINK;
148
- });
149
- }
150
- for (var key in input) {
151
- if (input[key] === UNRESOLVED_LINK) {
152
- delete input[key];
93
+ const cleanUpUnresolvedLinks = (input) => {
94
+ if (Array.isArray(input)) {
95
+ return input.filter((val) => val !== UNRESOLVED_LINK);
96
+ }
97
+ for (const key in input) {
98
+ if (input[key] === UNRESOLVED_LINK) {
99
+ delete input[key];
100
+ }
101
+ }
102
+ return input;
103
+ };
104
+ const normalizeLink = (entityMap, link, removeUnresolved) => {
105
+ const resolvedLink = getResolvedLink(entityMap, link);
106
+ if (resolvedLink === UNRESOLVED_LINK) {
107
+ return removeUnresolved ? resolvedLink : link;
108
+ }
109
+ return resolvedLink;
110
+ };
111
+ const maybeNormalizeLink = (entityMap, maybeLink, removeUnresolved) => {
112
+ if (Array.isArray(maybeLink)) {
113
+ return maybeLink.reduce((acc, link) => {
114
+ const normalizedLink = maybeNormalizeLink(entityMap, link, removeUnresolved);
115
+ if (removeUnresolved && normalizedLink === UNRESOLVED_LINK) {
116
+ return acc;
117
+ }
118
+ acc.push(normalizedLink);
119
+ return acc;
120
+ }, []);
121
+ }
122
+ else if (typeof maybeLink === 'object') {
123
+ if (isLink(maybeLink) || isResourceLink(maybeLink)) {
124
+ return normalizeLink(entityMap, maybeLink, removeUnresolved);
125
+ }
153
126
  }
154
- }
155
- return input;
127
+ return maybeLink;
156
128
  };
157
-
158
129
  /**
159
- * walkMutate Function
130
+ * WalkMutate Function
160
131
  * @param input
161
132
  * @param predicate
162
133
  * @param mutator
163
134
  * @param removeUnresolved
164
135
  * @return {*}
165
136
  */
166
- var walkMutate = function walkMutate(input, predicate, mutator, removeUnresolved) {
167
- if (predicate(input)) {
168
- return mutator(input);
169
- }
170
-
171
- if (input && typeof input === 'object') {
172
- for (var key in input) {
173
- // eslint-disable-next-line no-prototype-builtins
174
- if (input.hasOwnProperty(key)) {
175
- input[key] = walkMutate(input[key], predicate, mutator, removeUnresolved);
176
- }
177
- }
178
- if (removeUnresolved) {
179
- input = cleanUpLinks(input);
180
- }
181
- }
182
- return input;
137
+ const walkMutate = (input, predicate, mutator, removeUnresolved) => {
138
+ if (predicate(input)) {
139
+ return mutator(input);
140
+ }
141
+ if (input && typeof input === 'object') {
142
+ for (const key in input) {
143
+ // eslint-disable-next-line no-prototype-builtins
144
+ if (input.hasOwnProperty(key)) {
145
+ input[key] = walkMutate(input[key], predicate, mutator, removeUnresolved);
146
+ }
147
+ }
148
+ if (removeUnresolved) {
149
+ input = cleanUpUnresolvedLinks(input);
150
+ }
151
+ }
152
+ return input;
183
153
  };
184
-
185
- var normalizeLink = function normalizeLink(entityMap, link, removeUnresolved) {
186
- var resolvedLink = getResolvedLink(entityMap, link);
187
- if (resolvedLink === UNRESOLVED_LINK) {
188
- return removeUnresolved ? resolvedLink : link;
189
- }
190
- return resolvedLink;
154
+ const makeEntryObject = (item, itemEntryPoints) => {
155
+ if (!Array.isArray(itemEntryPoints)) {
156
+ return item;
157
+ }
158
+ const entryPoints = Object.keys(item).filter((ownKey) => itemEntryPoints.indexOf(ownKey) !== -1);
159
+ return entryPoints.reduce((entryObj, entryPoint) => {
160
+ entryObj[entryPoint] = item[entryPoint];
161
+ return entryObj;
162
+ }, {});
191
163
  };
192
-
193
- var makeEntryObject = function makeEntryObject(item, itemEntryPoints) {
194
- if (!Array.isArray(itemEntryPoints)) {
195
- return item;
196
- }
197
-
198
- var entryPoints = Object.keys(item).filter(function (ownKey) {
199
- return itemEntryPoints.indexOf(ownKey) !== -1;
200
- });
201
-
202
- return entryPoints.reduce(function (entryObj, entryPoint) {
203
- entryObj[entryPoint] = item[entryPoint];
204
- return entryObj;
205
- }, {});
164
+ /**
165
+ * Only normalize the top level properties of the entrypoint (e.g. item.fields),
166
+ * as JSON fields can contain values that are objects that look like links, but are not.
167
+ */
168
+ const normalizeFromEntryPoint = (entityMap, entryPoint, removeUnresolved) => {
169
+ if (!entryPoint) {
170
+ return undefined;
171
+ }
172
+ if (Array.isArray(entryPoint)) {
173
+ return maybeNormalizeLink(entityMap, entryPoint, removeUnresolved);
174
+ }
175
+ else if (typeof entryPoint === 'object') {
176
+ return Object.entries(entryPoint).reduce((acc, [key, val]) => {
177
+ const normalizedLink = maybeNormalizeLink(entityMap, val, removeUnresolved);
178
+ if (removeUnresolved && normalizedLink === UNRESOLVED_LINK) {
179
+ return acc;
180
+ }
181
+ acc[key] = normalizedLink;
182
+ return acc;
183
+ }, {});
184
+ }
206
185
  };
207
-
208
186
  /**
209
- * resolveResponse Function
187
+ * ResolveResponse Function
210
188
  * Resolves contentful response to normalized form.
211
189
  * @param {Object} response Contentful response
212
190
  * @param {{removeUnresolved: Boolean, itemEntryPoints: Array<String>}|{}} options
@@ -214,40 +192,30 @@ var makeEntryObject = function makeEntryObject(item, itemEntryPoints) {
214
192
  * @param {Array<String>} options.itemEntryPoints - Resolve links only in those item properties
215
193
  * @return {Object}
216
194
  */
217
- var resolveResponse = function resolveResponse(response, options) {
218
- options = options || {};
219
- if (!response.items) {
220
- return [];
221
- }
222
- var responseClone = (0, _fastCopy2.default)(response);
223
- var allIncludes = Object.keys(responseClone.includes || {}).reduce(function (all, type) {
224
- return [].concat(_toConsumableArray(all), _toConsumableArray(response.includes[type]));
225
- }, []);
226
-
227
- var allEntries = [].concat(_toConsumableArray(responseClone.items), _toConsumableArray(allIncludes)).filter(function (entity) {
228
- return Boolean(entity.sys);
229
- });
230
-
231
- var entityMap = new Map(allEntries.reduce(function (acc, entity) {
232
- var entries = makeEntityMapKeys(entity.sys).map(function (key) {
233
- return [key, entity];
195
+ const resolveResponse = (response, options) => {
196
+ options ||= {};
197
+ if (!response.items) {
198
+ return [];
199
+ }
200
+ const responseClone = (0, fast_copy_1.default)(response);
201
+ const allIncludes = Object.keys(responseClone.includes || {}).reduce((all, type) => [...all, ...response.includes[type]], []);
202
+ const allEntries = [...responseClone.items, ...allIncludes].filter((entity) => Boolean(entity.sys));
203
+ const entityMap = new Map(allEntries.reduce((acc, entity) => {
204
+ const entries = makeEntityMapKeys(entity.sys).map((key) => [key, entity]);
205
+ acc.push(...entries);
206
+ return acc;
207
+ }, []));
208
+ allEntries.forEach((item) => {
209
+ if (options.itemEntryPoints && options.itemEntryPoints.length) {
210
+ for (const entryPoint of options.itemEntryPoints) {
211
+ item[entryPoint] = normalizeFromEntryPoint(entityMap, item[entryPoint], options.removeUnresolved);
212
+ }
213
+ }
214
+ else {
215
+ const entryObject = makeEntryObject(item, options.itemEntryPoints);
216
+ Object.assign(item, walkMutate(entryObject, (x) => isLink(x) || isResourceLink(x), (link) => normalizeLink(entityMap, link, options.removeUnresolved), options.removeUnresolved));
217
+ }
234
218
  });
235
- acc.push.apply(acc, _toConsumableArray(entries));
236
- return acc;
237
- }, []));
238
-
239
- allEntries.forEach(function (item) {
240
- var entryObject = makeEntryObject(item, options.itemEntryPoints);
241
-
242
- Object.assign(item, walkMutate(entryObject, function (x) {
243
- return isLink(x) || isResourceLink(x);
244
- }, function (link) {
245
- return normalizeLink(entityMap, link, options.removeUnresolved);
246
- }, options.removeUnresolved));
247
- });
248
-
249
- return responseClone.items;
219
+ return responseClone.items;
250
220
  };
251
-
252
221
  exports.default = resolveResponse;
253
- module.exports = exports.default;
@@ -0,0 +1,14 @@
1
+ export default resolveResponse;
2
+ /**
3
+ * ResolveResponse Function
4
+ * Resolves contentful response to normalized form.
5
+ * @param {Object} response Contentful response
6
+ * @param {{removeUnresolved: Boolean, itemEntryPoints: Array<String>}|{}} options
7
+ * @param {Boolean} options.removeUnresolved - Remove unresolved links default:false
8
+ * @param {Array<String>} options.itemEntryPoints - Resolve links only in those item properties
9
+ * @return {Object}
10
+ */
11
+ declare function resolveResponse(response: any, options: {
12
+ removeUnresolved: boolean;
13
+ itemEntryPoints: Array<string>;
14
+ } | {}): any;
package/dist/esm/index.js CHANGED
@@ -1,31 +1,17 @@
1
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
2
-
3
- var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
4
-
5
- function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
6
-
7
1
  import copy from 'fast-copy';
8
-
9
- var UNRESOLVED_LINK = {}; // unique object to avoid polyfill bloat using Symbol()
10
-
2
+ const UNRESOLVED_LINK = {}; // Unique object to avoid polyfill bloat using Symbol()
11
3
  /**
12
- * isLink Function
4
+ * IsLink Function
13
5
  * Checks if the object has sys.type "Link"
14
6
  * @param object
15
7
  */
16
- var isLink = function isLink(object) {
17
- return object && object.sys && object.sys.type === 'Link';
18
- };
19
-
8
+ const isLink = (object) => object && object.sys && object.sys.type === 'Link';
20
9
  /**
21
- * isResourceLink Function
10
+ * IsResourceLink Function
22
11
  * Checks if the object has sys.type "ResourceLink"
23
12
  * @param object
24
13
  */
25
- var isResourceLink = function isResourceLink(object) {
26
- return object && object.sys && object.sys.type === 'ResourceLink';
27
- };
28
-
14
+ const isResourceLink = (object) => object && object.sys && object.sys.type === 'ResourceLink';
29
15
  /**
30
16
  * Creates a key with spaceId and a key without for entityMap
31
17
  *
@@ -37,14 +23,12 @@ var isResourceLink = function isResourceLink(object) {
37
23
  * @param {String} sys.space.id
38
24
  * @return {string[]}
39
25
  */
40
- var makeEntityMapKeys = function makeEntityMapKeys(sys) {
41
- if (sys.space && sys.environment) {
42
- return [sys.type + '!' + sys.id, sys.space.sys.id + '!' + sys.environment.sys.id + '!' + sys.type + '!' + sys.id];
43
- }
44
-
45
- return [sys.type + '!' + sys.id];
26
+ const makeEntityMapKeys = (sys) => {
27
+ if (sys.space && sys.environment) {
28
+ return [`${sys.type}!${sys.id}`, `${sys.space.sys.id}!${sys.environment.sys.id}!${sys.type}!${sys.id}`];
29
+ }
30
+ return [`${sys.type}!${sys.id}`];
46
31
  };
47
-
48
32
  /**
49
33
  * Looks up in entityMap
50
34
  *
@@ -56,149 +40,149 @@ var makeEntityMapKeys = function makeEntityMapKeys(sys) {
56
40
  * @param {String} linkData.urn
57
41
  * @return {String}
58
42
  */
59
- var lookupInEntityMap = function lookupInEntityMap(entityMap, linkData) {
60
- var entryId = linkData.entryId,
61
- linkType = linkData.linkType,
62
- spaceId = linkData.spaceId,
63
- environmentId = linkData.environmentId;
64
-
65
-
66
- if (spaceId && environmentId) {
67
- return entityMap.get(spaceId + '!' + environmentId + '!' + linkType + '!' + entryId);
68
- }
69
-
70
- return entityMap.get(linkType + '!' + entryId);
43
+ const lookupInEntityMap = (entityMap, linkData) => {
44
+ const { entryId, linkType, spaceId, environmentId } = linkData;
45
+ if (spaceId && environmentId) {
46
+ return entityMap.get(`${spaceId}!${environmentId}!${linkType}!${entryId}`);
47
+ }
48
+ return entityMap.get(`${linkType}!${entryId}`);
71
49
  };
72
-
73
- var getIdsFromUrn = function getIdsFromUrn(urn) {
74
- var regExp = /.*:spaces\/([^/]+)(?:\/environments\/([^/]+))?\/entries\/([^/]+)$/;
75
-
76
- if (!regExp.test(urn)) {
77
- return undefined;
78
- }
79
-
80
- var _urn$match = urn.match(regExp),
81
- _urn$match2 = _slicedToArray(_urn$match, 4),
82
- _ = _urn$match2[0],
83
- spaceId = _urn$match2[1],
84
- _urn$match2$ = _urn$match2[2],
85
- environmentId = _urn$match2$ === undefined ? 'master' : _urn$match2$,
86
- entryId = _urn$match2[3];
87
-
88
- return { spaceId: spaceId, environmentId: environmentId, entryId: entryId };
50
+ const getIdsFromUrn = (urn) => {
51
+ const regExp = /.*:spaces\/([^/]+)(?:\/environments\/([^/]+))?\/entries\/([^/]+)$/;
52
+ if (!regExp.test(urn)) {
53
+ return undefined;
54
+ }
55
+ // eslint-disable-next-line no-unused-vars
56
+ const [_, spaceId, environmentId = 'master', entryId] = urn.match(regExp);
57
+ return { spaceId, environmentId, entryId };
89
58
  };
90
-
91
59
  /**
92
- * getResolvedLink Function
60
+ * GetResolvedLink Function
93
61
  *
94
62
  * @param entityMap
95
63
  * @param link
96
64
  * @return {undefined}
97
65
  */
98
- var getResolvedLink = function getResolvedLink(entityMap, link) {
99
- var _link$sys = link.sys,
100
- type = _link$sys.type,
101
- linkType = _link$sys.linkType;
102
-
103
- if (type === 'ResourceLink') {
104
- if (!linkType.startsWith('Contentful:')) {
105
- return UNRESOLVED_LINK;
106
- }
107
-
108
- var urn = link.sys.urn;
109
-
110
- var _getIdsFromUrn = getIdsFromUrn(urn),
111
- spaceId = _getIdsFromUrn.spaceId,
112
- environmentId = _getIdsFromUrn.environmentId,
113
- _entryId = _getIdsFromUrn.entryId;
114
-
115
- var extractedLinkType = linkType.split(':')[1];
116
-
117
- return lookupInEntityMap(entityMap, {
118
- linkType: extractedLinkType,
119
- entryId: _entryId,
120
- spaceId: spaceId,
121
- environmentId: environmentId
122
- }) || UNRESOLVED_LINK;
123
- }
124
-
125
- var entryId = link.sys.id;
126
-
127
- return lookupInEntityMap(entityMap, { linkType: linkType, entryId: entryId }) || UNRESOLVED_LINK;
66
+ const getResolvedLink = (entityMap, link) => {
67
+ const { type, linkType } = link.sys;
68
+ if (type === 'ResourceLink') {
69
+ if (!linkType.startsWith('Contentful:')) {
70
+ return link;
71
+ }
72
+ const { urn } = link.sys;
73
+ const { spaceId, environmentId, entryId } = getIdsFromUrn(urn);
74
+ const extractedLinkType = linkType.split(':')[1];
75
+ return (lookupInEntityMap(entityMap, {
76
+ linkType: extractedLinkType,
77
+ entryId,
78
+ spaceId,
79
+ environmentId,
80
+ }) || UNRESOLVED_LINK);
81
+ }
82
+ const { id: entryId } = link.sys;
83
+ return lookupInEntityMap(entityMap, { linkType, entryId }) || UNRESOLVED_LINK;
128
84
  };
129
-
130
85
  /**
131
- * cleanUpLinks Function
86
+ * CleanUpUnresolvedLinks Function
132
87
  * - Removes unresolvable links from Arrays and Objects
133
88
  *
134
89
  * @param {Object[]|Object} input
135
90
  */
136
- var cleanUpLinks = function cleanUpLinks(input) {
137
- if (Array.isArray(input)) {
138
- return input.filter(function (val) {
139
- return val !== UNRESOLVED_LINK;
140
- });
141
- }
142
- for (var key in input) {
143
- if (input[key] === UNRESOLVED_LINK) {
144
- delete input[key];
91
+ const cleanUpUnresolvedLinks = (input) => {
92
+ if (Array.isArray(input)) {
93
+ return input.filter((val) => val !== UNRESOLVED_LINK);
94
+ }
95
+ for (const key in input) {
96
+ if (input[key] === UNRESOLVED_LINK) {
97
+ delete input[key];
98
+ }
99
+ }
100
+ return input;
101
+ };
102
+ const normalizeLink = (entityMap, link, removeUnresolved) => {
103
+ const resolvedLink = getResolvedLink(entityMap, link);
104
+ if (resolvedLink === UNRESOLVED_LINK) {
105
+ return removeUnresolved ? resolvedLink : link;
106
+ }
107
+ return resolvedLink;
108
+ };
109
+ const maybeNormalizeLink = (entityMap, maybeLink, removeUnresolved) => {
110
+ if (Array.isArray(maybeLink)) {
111
+ return maybeLink.reduce((acc, link) => {
112
+ const normalizedLink = maybeNormalizeLink(entityMap, link, removeUnresolved);
113
+ if (removeUnresolved && normalizedLink === UNRESOLVED_LINK) {
114
+ return acc;
115
+ }
116
+ acc.push(normalizedLink);
117
+ return acc;
118
+ }, []);
119
+ }
120
+ else if (typeof maybeLink === 'object') {
121
+ if (isLink(maybeLink) || isResourceLink(maybeLink)) {
122
+ return normalizeLink(entityMap, maybeLink, removeUnresolved);
123
+ }
145
124
  }
146
- }
147
- return input;
125
+ return maybeLink;
148
126
  };
149
-
150
127
  /**
151
- * walkMutate Function
128
+ * WalkMutate Function
152
129
  * @param input
153
130
  * @param predicate
154
131
  * @param mutator
155
132
  * @param removeUnresolved
156
133
  * @return {*}
157
134
  */
158
- var walkMutate = function walkMutate(input, predicate, mutator, removeUnresolved) {
159
- if (predicate(input)) {
160
- return mutator(input);
161
- }
162
-
163
- if (input && (typeof input === 'undefined' ? 'undefined' : _typeof(input)) === 'object') {
164
- for (var key in input) {
165
- // eslint-disable-next-line no-prototype-builtins
166
- if (input.hasOwnProperty(key)) {
167
- input[key] = walkMutate(input[key], predicate, mutator, removeUnresolved);
168
- }
169
- }
170
- if (removeUnresolved) {
171
- input = cleanUpLinks(input);
172
- }
173
- }
174
- return input;
135
+ const walkMutate = (input, predicate, mutator, removeUnresolved) => {
136
+ if (predicate(input)) {
137
+ return mutator(input);
138
+ }
139
+ if (input && typeof input === 'object') {
140
+ for (const key in input) {
141
+ // eslint-disable-next-line no-prototype-builtins
142
+ if (input.hasOwnProperty(key)) {
143
+ input[key] = walkMutate(input[key], predicate, mutator, removeUnresolved);
144
+ }
145
+ }
146
+ if (removeUnresolved) {
147
+ input = cleanUpUnresolvedLinks(input);
148
+ }
149
+ }
150
+ return input;
175
151
  };
176
-
177
- var normalizeLink = function normalizeLink(entityMap, link, removeUnresolved) {
178
- var resolvedLink = getResolvedLink(entityMap, link);
179
- if (resolvedLink === UNRESOLVED_LINK) {
180
- return removeUnresolved ? resolvedLink : link;
181
- }
182
- return resolvedLink;
152
+ const makeEntryObject = (item, itemEntryPoints) => {
153
+ if (!Array.isArray(itemEntryPoints)) {
154
+ return item;
155
+ }
156
+ const entryPoints = Object.keys(item).filter((ownKey) => itemEntryPoints.indexOf(ownKey) !== -1);
157
+ return entryPoints.reduce((entryObj, entryPoint) => {
158
+ entryObj[entryPoint] = item[entryPoint];
159
+ return entryObj;
160
+ }, {});
183
161
  };
184
-
185
- var makeEntryObject = function makeEntryObject(item, itemEntryPoints) {
186
- if (!Array.isArray(itemEntryPoints)) {
187
- return item;
188
- }
189
-
190
- var entryPoints = Object.keys(item).filter(function (ownKey) {
191
- return itemEntryPoints.indexOf(ownKey) !== -1;
192
- });
193
-
194
- return entryPoints.reduce(function (entryObj, entryPoint) {
195
- entryObj[entryPoint] = item[entryPoint];
196
- return entryObj;
197
- }, {});
162
+ /**
163
+ * Only normalize the top level properties of the entrypoint (e.g. item.fields),
164
+ * as JSON fields can contain values that are objects that look like links, but are not.
165
+ */
166
+ const normalizeFromEntryPoint = (entityMap, entryPoint, removeUnresolved) => {
167
+ if (!entryPoint) {
168
+ return undefined;
169
+ }
170
+ if (Array.isArray(entryPoint)) {
171
+ return maybeNormalizeLink(entityMap, entryPoint, removeUnresolved);
172
+ }
173
+ else if (typeof entryPoint === 'object') {
174
+ return Object.entries(entryPoint).reduce((acc, [key, val]) => {
175
+ const normalizedLink = maybeNormalizeLink(entityMap, val, removeUnresolved);
176
+ if (removeUnresolved && normalizedLink === UNRESOLVED_LINK) {
177
+ return acc;
178
+ }
179
+ acc[key] = normalizedLink;
180
+ return acc;
181
+ }, {});
182
+ }
198
183
  };
199
-
200
184
  /**
201
- * resolveResponse Function
185
+ * ResolveResponse Function
202
186
  * Resolves contentful response to normalized form.
203
187
  * @param {Object} response Contentful response
204
188
  * @param {{removeUnresolved: Boolean, itemEntryPoints: Array<String>}|{}} options
@@ -206,39 +190,30 @@ var makeEntryObject = function makeEntryObject(item, itemEntryPoints) {
206
190
  * @param {Array<String>} options.itemEntryPoints - Resolve links only in those item properties
207
191
  * @return {Object}
208
192
  */
209
- var resolveResponse = function resolveResponse(response, options) {
210
- options = options || {};
211
- if (!response.items) {
212
- return [];
213
- }
214
- var responseClone = copy(response);
215
- var allIncludes = Object.keys(responseClone.includes || {}).reduce(function (all, type) {
216
- return [].concat(_toConsumableArray(all), _toConsumableArray(response.includes[type]));
217
- }, []);
218
-
219
- var allEntries = [].concat(_toConsumableArray(responseClone.items), _toConsumableArray(allIncludes)).filter(function (entity) {
220
- return Boolean(entity.sys);
221
- });
222
-
223
- var entityMap = new Map(allEntries.reduce(function (acc, entity) {
224
- var entries = makeEntityMapKeys(entity.sys).map(function (key) {
225
- return [key, entity];
193
+ const resolveResponse = (response, options) => {
194
+ options ||= {};
195
+ if (!response.items) {
196
+ return [];
197
+ }
198
+ const responseClone = copy(response);
199
+ const allIncludes = Object.keys(responseClone.includes || {}).reduce((all, type) => [...all, ...response.includes[type]], []);
200
+ const allEntries = [...responseClone.items, ...allIncludes].filter((entity) => Boolean(entity.sys));
201
+ const entityMap = new Map(allEntries.reduce((acc, entity) => {
202
+ const entries = makeEntityMapKeys(entity.sys).map((key) => [key, entity]);
203
+ acc.push(...entries);
204
+ return acc;
205
+ }, []));
206
+ allEntries.forEach((item) => {
207
+ if (options.itemEntryPoints && options.itemEntryPoints.length) {
208
+ for (const entryPoint of options.itemEntryPoints) {
209
+ item[entryPoint] = normalizeFromEntryPoint(entityMap, item[entryPoint], options.removeUnresolved);
210
+ }
211
+ }
212
+ else {
213
+ const entryObject = makeEntryObject(item, options.itemEntryPoints);
214
+ Object.assign(item, walkMutate(entryObject, (x) => isLink(x) || isResourceLink(x), (link) => normalizeLink(entityMap, link, options.removeUnresolved), options.removeUnresolved));
215
+ }
226
216
  });
227
- acc.push.apply(acc, _toConsumableArray(entries));
228
- return acc;
229
- }, []));
230
-
231
- allEntries.forEach(function (item) {
232
- var entryObject = makeEntryObject(item, options.itemEntryPoints);
233
-
234
- Object.assign(item, walkMutate(entryObject, function (x) {
235
- return isLink(x) || isResourceLink(x);
236
- }, function (link) {
237
- return normalizeLink(entityMap, link, options.removeUnresolved);
238
- }, options.removeUnresolved));
239
- });
240
-
241
- return responseClone.items;
217
+ return responseClone.items;
242
218
  };
243
-
244
- export default resolveResponse;
219
+ export default resolveResponse;
package/package.json CHANGED
@@ -1,20 +1,17 @@
1
1
  {
2
2
  "name": "contentful-resolve-response",
3
- "version": "1.8.2",
4
- "description": "",
3
+ "version": "1.9.1",
5
4
  "main": "./dist/cjs/index.js",
6
5
  "module": "./dist/esm/index.js",
7
- "jsnext:main": "./dist/esm/index.js",
8
6
  "scripts": {
9
- "build": "BABEL_ENV=cjs babel index.js -d dist/cjs/ && BABEL_ENV=esm babel index.js -d dist/esm/",
7
+ "build": "tsc --project tsconfig.cjs.json && tsc --project tsconfig.esm.json",
10
8
  "lint": "eslint index.js test",
11
- "test": "BABEL_ENV=cjs mocha --require babel-register 'test/**/*-test.js'",
9
+ "test": "mocha --import=tsx 'test/**/*-test.js'",
12
10
  "test-watch": "npm run test -- --watch",
13
11
  "precommit": "npm run lint",
14
12
  "prepush": "npm run test",
15
13
  "prepublishOnly": "npm run build",
16
14
  "format": "prettier --config ./.prettierrc --write \"{*.js,**/*.js,*.ts,**/*.ts,*.json,**/*.json}\"",
17
- "commitlint-circle": "commitlint-circle",
18
15
  "semantic-release": "semantic-release"
19
16
  },
20
17
  "repository": {
@@ -28,30 +25,21 @@
28
25
  "fast-copy": "^2.1.7"
29
26
  },
30
27
  "devDependencies": {
31
- "@commitlint/cli": "^18.0.0",
28
+ "@commitlint/cli": "^19.6.0",
32
29
  "@commitlint/config-conventional": "^18.0.0",
33
- "@contentful/eslint-config-backend": "^10.0.0",
30
+ "@eslint/js": "^9.16.0",
34
31
  "@semantic-release/changelog": "^6.0.1",
35
32
  "@semantic-release/git": "^10.0.1",
36
- "@timbeyer/commitlint-circle": "^4.1.1",
37
- "babel-cli": "^6.26.0",
38
- "babel-plugin-add-module-exports": "^1.0.2",
39
- "babel-preset-env": "^1.7.0",
40
- "babel-register": "^6.26.0",
41
33
  "chai": "^4.3.6",
42
34
  "dirty-chai": "^2.0.1",
43
- "eslint": "^8.9.0",
44
- "eslint-config-prettier": "^9.0.0",
45
- "eslint-plugin-import": "^2.25.4",
46
- "eslint-plugin-mocha": "^10.0.3",
47
- "eslint-plugin-node": "^11.1.0",
48
- "eslint-plugin-prettier": "^5.0.0",
49
- "eslint-plugin-promise": "^6.0.0",
50
- "eslint-plugin-standard": "^5.0.0",
35
+ "eslint": "^9.15.0",
36
+ "eslint-plugin-mocha": "^10.5.0",
51
37
  "husky": "^9.0.6",
52
- "mocha": "^10.0.0",
38
+ "mocha": "^11.0.1",
53
39
  "prettier": "^3.0.0",
54
- "semantic-release": "^19.0.5"
40
+ "semantic-release": "^19.0.5",
41
+ "tsx": "^4.19.2",
42
+ "typescript": "^5.7.2"
55
43
  },
56
44
  "files": [
57
45
  "dist"