UNPKG

11.4 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports.default = void 0;
5
6var jsonPatch = _interopRequireWildcard(require("fast-json-patch"));
7
8var _deepExtend = _interopRequireDefault(require("deep-extend"));
9
10var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));
11
12function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
14function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
15
16function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
18function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
19
20function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
21
22function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
23
24var _default = {
25 add,
26 replace,
27 remove,
28 merge,
29 mergeDeep,
30 context,
31 getIn,
32 applyPatch,
33 parentPathMatch,
34 flatten,
35 fullyNormalizeArray,
36 normalizeArray,
37 isPromise,
38 forEachNew,
39 forEachNewPrimitive,
40 isJsonPatch,
41 isContextPatch,
42 isPatch,
43 isMutation,
44 isAdditiveMutation,
45 isGenerator,
46 isFunction,
47 isObject,
48 isError
49};
50exports.default = _default;
51
52function applyPatch(obj, patch, opts) {
53 opts = opts || {};
54 patch = _objectSpread(_objectSpread({}, patch), {}, {
55 path: patch.path && normalizeJSONPath(patch.path)
56 });
57
58 if (patch.op === 'merge') {
59 const newValue = getInByJsonPath(obj, patch.path);
60 Object.assign(newValue, patch.value);
61 jsonPatch.applyPatch(obj, [replace(patch.path, newValue)]);
62 } else if (patch.op === 'mergeDeep') {
63 const currentValue = getInByJsonPath(obj, patch.path); // Iterate the properties of the patch
64 // eslint-disable-next-line no-restricted-syntax, guard-for-in
65
66 for (const prop in patch.value) {
67 const propVal = patch.value[prop];
68 const isArray = Array.isArray(propVal);
69
70 if (isArray) {
71 // deepExtend doesn't merge arrays, so we will do it manually
72 const existing = currentValue[prop] || [];
73 currentValue[prop] = existing.concat(propVal);
74 } else if (isObject(propVal) && !isArray) {
75 // If it's an object, iterate it's keys and merge
76 // if there are conflicting keys, merge deep, otherwise shallow merge
77 let currentObj = _objectSpread({}, currentValue[prop]); // eslint-disable-next-line no-restricted-syntax
78
79
80 for (const key in propVal) {
81 if (Object.prototype.hasOwnProperty.call(currentObj, key)) {
82 // if there is a single conflicting key, just deepExtend the entire value
83 // and break from the loop (since all future keys are also merged)
84 // We do this because we can't deepExtend two primitives
85 // (currentObj[key] & propVal[key] may be primitives).
86 //
87 // we also deeply assign here, since we aren't in control of
88 // how deepExtend affects existing nested objects
89 currentObj = (0, _deepExtend.default)((0, _cloneDeep.default)(currentObj), propVal);
90 break;
91 } else {
92 Object.assign(currentObj, {
93 [key]: propVal[key]
94 });
95 }
96 }
97
98 currentValue[prop] = currentObj;
99 } else {
100 // It's a primitive, just replace existing
101 currentValue[prop] = propVal;
102 }
103 }
104 } else if (patch.op === 'add' && patch.path === '' && isObject(patch.value)) {
105 // { op: 'add', path: '', value: { a: 1, b: 2 }}
106 // has no effect: json patch refuses to do anything.
107 // so let's break that patch down into a set of patches,
108 // one for each key in the intended root value.
109 const patches = Object.keys(patch.value).reduce((arr, key) => {
110 arr.push({
111 op: 'add',
112 path: `/${normalizeJSONPath(key)}`,
113 value: patch.value[key]
114 });
115 return arr;
116 }, []);
117 jsonPatch.applyPatch(obj, patches);
118 } else if (patch.op === 'replace' && patch.path === '') {
119 let {
120 value
121 } = patch;
122
123 if (opts.allowMetaPatches && patch.meta && isAdditiveMutation(patch) && (Array.isArray(patch.value) || isObject(patch.value))) {
124 value = _objectSpread(_objectSpread({}, value), patch.meta);
125 }
126
127 obj = value;
128 } else {
129 jsonPatch.applyPatch(obj, [patch]); // Attach metadata to the resulting value.
130
131 if (opts.allowMetaPatches && patch.meta && isAdditiveMutation(patch) && (Array.isArray(patch.value) || isObject(patch.value))) {
132 const currentValue = getInByJsonPath(obj, patch.path);
133
134 const newValue = _objectSpread(_objectSpread({}, currentValue), patch.meta);
135
136 jsonPatch.applyPatch(obj, [replace(patch.path, newValue)]);
137 }
138 }
139
140 return obj;
141}
142
143function normalizeJSONPath(path) {
144 if (Array.isArray(path)) {
145 if (path.length < 1) {
146 return '';
147 }
148
149 return `/${path.map(item => {
150 // eslint-disable-line prefer-template
151 return (item + '').replace(/~/g, '~0').replace(/\//g, '~1'); // eslint-disable-line prefer-template
152 }).join('/')}`;
153 }
154
155 return path;
156} // =========================
157// JSON-Patch Wrappers
158// =========================
159
160
161function add(path, value) {
162 return {
163 op: 'add',
164 path,
165 value
166 };
167} // function _get(path) {
168// return { op: '_get', path };
169// }
170
171
172function replace(path, value, meta) {
173 return {
174 op: 'replace',
175 path,
176 value,
177 meta
178 };
179}
180
181function remove(path) {
182 return {
183 op: 'remove',
184 path
185 };
186} // Custom wrappers
187
188
189function merge(path, value) {
190 return {
191 type: 'mutation',
192 op: 'merge',
193 path,
194 value
195 };
196} // Custom wrappers
197
198
199function mergeDeep(path, value) {
200 return {
201 type: 'mutation',
202 op: 'mergeDeep',
203 path,
204 value
205 };
206}
207
208function context(path, value) {
209 return {
210 type: 'context',
211 path,
212 value
213 };
214} // =========================
215// Iterators
216// =========================
217
218
219function forEachNew(mutations, fn) {
220 try {
221 return forEachNewPatch(mutations, forEach, fn);
222 } catch (e) {
223 return e;
224 }
225}
226
227function forEachNewPrimitive(mutations, fn) {
228 try {
229 return forEachNewPatch(mutations, forEachPrimitive, fn);
230 } catch (e) {
231 return e;
232 }
233}
234
235function forEachNewPatch(mutations, fn, callback) {
236 const res = mutations.filter(isAdditiveMutation).map(mutation => {
237 return fn(mutation.value, callback, mutation.path);
238 }) || [];
239 const flat = flatten(res);
240 const clean = cleanArray(flat);
241 return clean;
242}
243
244function forEachPrimitive(obj, fn, basePath) {
245 basePath = basePath || [];
246
247 if (Array.isArray(obj)) {
248 return obj.map((val, key) => {
249 return forEachPrimitive(val, fn, basePath.concat(key));
250 });
251 }
252
253 if (isObject(obj)) {
254 return Object.keys(obj).map(key => {
255 return forEachPrimitive(obj[key], fn, basePath.concat(key));
256 });
257 }
258
259 return fn(obj, basePath[basePath.length - 1], basePath);
260}
261
262function forEach(obj, fn, basePath) {
263 basePath = basePath || [];
264 let results = [];
265
266 if (basePath.length > 0) {
267 const newResults = fn(obj, basePath[basePath.length - 1], basePath);
268
269 if (newResults) {
270 results = results.concat(newResults);
271 }
272 }
273
274 if (Array.isArray(obj)) {
275 const arrayResults = obj.map((val, key) => {
276 return forEach(val, fn, basePath.concat(key));
277 });
278
279 if (arrayResults) {
280 results = results.concat(arrayResults);
281 }
282 } else if (isObject(obj)) {
283 const moreResults = Object.keys(obj).map(key => {
284 return forEach(obj[key], fn, basePath.concat(key));
285 });
286
287 if (moreResults) {
288 results = results.concat(moreResults);
289 }
290 }
291
292 results = flatten(results);
293 return results;
294} // =========================
295// Paths
296// =========================
297
298
299function parentPathMatch(path, arr) {
300 if (!Array.isArray(arr)) {
301 return false;
302 }
303
304 for (let i = 0, len = arr.length; i < len; i += 1) {
305 if (arr[i] !== path[i]) {
306 return false;
307 }
308 }
309
310 return true;
311}
312
313function getIn(obj, path) {
314 return path.reduce((val, token) => {
315 if (typeof token !== 'undefined' && val) {
316 return val[token];
317 }
318
319 return val;
320 }, obj);
321} // =========================
322// Array
323// =========================
324
325
326function fullyNormalizeArray(arr) {
327 return cleanArray(flatten(normalizeArray(arr)));
328}
329
330function normalizeArray(arr) {
331 return Array.isArray(arr) ? arr : [arr];
332}
333
334function flatten(arr) {
335 return [].concat(...arr.map(val => {
336 return Array.isArray(val) ? flatten(val) : val;
337 }));
338}
339
340function cleanArray(arr) {
341 return arr.filter(elm => typeof elm !== 'undefined');
342} // =========================
343// Is-Thing.
344// =========================
345
346
347function isObject(val) {
348 return val && typeof val === 'object';
349}
350
351function isPromise(val) {
352 return isObject(val) && isFunction(val.then);
353}
354
355function isFunction(val) {
356 return val && typeof val === 'function';
357}
358
359function isError(patch) {
360 return patch instanceof Error;
361}
362
363function isJsonPatch(patch) {
364 if (isPatch(patch)) {
365 const {
366 op
367 } = patch;
368 return op === 'add' || op === 'remove' || op === 'replace';
369 }
370
371 return false;
372}
373
374function isGenerator(thing) {
375 return Object.prototype.toString.call(thing) === '[object GeneratorFunction]';
376}
377
378function isMutation(patch) {
379 return isJsonPatch(patch) || isPatch(patch) && patch.type === 'mutation';
380}
381
382function isAdditiveMutation(patch) {
383 return isMutation(patch) && (patch.op === 'add' || patch.op === 'replace' || patch.op === 'merge' || patch.op === 'mergeDeep');
384}
385
386function isContextPatch(patch) {
387 return isPatch(patch) && patch.type === 'context';
388}
389
390function isPatch(patch) {
391 return patch && typeof patch === 'object';
392}
393
394function getInByJsonPath(obj, jsonPath) {
395 try {
396 return jsonPatch.getValueByPointer(obj, jsonPath);
397 } catch (e) {
398 console.error(e); // eslint-disable-line no-console
399
400 return {};
401 }
402}
\No newline at end of file