source: node_modules/swagger-client/es/specmap/lib/index.js@ d24f17c

main
Last change on this file since d24f17c was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 7.1 KB
Line 
1import * as jsonPatch from 'fast-json-patch';
2import deepmerge from 'deepmerge';
3export default {
4 add,
5 replace,
6 remove,
7 merge,
8 mergeDeep,
9 context,
10 getIn,
11 applyPatch,
12 parentPathMatch,
13 flatten,
14 fullyNormalizeArray,
15 normalizeArray,
16 isPromise,
17 forEachNew,
18 forEachNewPrimitive,
19 isJsonPatch,
20 isContextPatch,
21 isPatch,
22 isMutation,
23 isAdditiveMutation,
24 isGenerator,
25 isFunction,
26 isObject,
27 isError
28};
29function applyPatch(obj, patch, opts) {
30 opts = opts || {};
31 patch = {
32 ...patch,
33 path: patch.path && normalizeJSONPath(patch.path)
34 };
35 if (patch.op === 'merge') {
36 const newValue = getInByJsonPath(obj, patch.path);
37 Object.assign(newValue, patch.value);
38 jsonPatch.applyPatch(obj, [replace(patch.path, newValue)]);
39 } else if (patch.op === 'mergeDeep') {
40 const currentValue = getInByJsonPath(obj, patch.path);
41 const newValue = deepmerge(currentValue, patch.value);
42 obj = jsonPatch.applyPatch(obj, [replace(patch.path, newValue)]).newDocument;
43 } else if (patch.op === 'add' && patch.path === '' && isObject(patch.value)) {
44 // { op: 'add', path: '', value: { a: 1, b: 2 }}
45 // has no effect: json patch refuses to do anything.
46 // so let's break that patch down into a set of patches,
47 // one for each key in the intended root value.
48
49 const patches = Object.keys(patch.value).reduce((arr, key) => {
50 arr.push({
51 op: 'add',
52 path: `/${normalizeJSONPath(key)}`,
53 value: patch.value[key]
54 });
55 return arr;
56 }, []);
57 jsonPatch.applyPatch(obj, patches);
58 } else if (patch.op === 'replace' && patch.path === '') {
59 let {
60 value
61 } = patch;
62 if (opts.allowMetaPatches && patch.meta && isAdditiveMutation(patch) && (Array.isArray(patch.value) || isObject(patch.value))) {
63 value = {
64 ...value,
65 ...patch.meta
66 };
67 }
68 obj = value;
69 } else {
70 jsonPatch.applyPatch(obj, [patch]);
71
72 // Attach metadata to the resulting value.
73 if (opts.allowMetaPatches && patch.meta && isAdditiveMutation(patch) && (Array.isArray(patch.value) || isObject(patch.value))) {
74 const currentValue = getInByJsonPath(obj, patch.path);
75 const newValue = {
76 ...currentValue,
77 ...patch.meta
78 };
79 jsonPatch.applyPatch(obj, [replace(patch.path, newValue)]);
80 }
81 }
82 return obj;
83}
84function normalizeJSONPath(path) {
85 if (Array.isArray(path)) {
86 if (path.length < 1) {
87 return '';
88 }
89 return `/${path.map(item =>
90 // eslint-disable-line prefer-template
91 (item + '').replace(/~/g, '~0').replace(/\//g, '~1') // eslint-disable-line prefer-template
92 ).join('/')}`;
93 }
94 return path;
95}
96
97// =========================
98// JSON-Patch Wrappers
99// =========================
100
101function add(path, value) {
102 return {
103 op: 'add',
104 path,
105 value
106 };
107}
108
109// function _get(path) {
110// return { op: '_get', path };
111// }
112
113function replace(path, value, meta) {
114 return {
115 op: 'replace',
116 path,
117 value,
118 meta
119 };
120}
121function remove(path) {
122 return {
123 op: 'remove',
124 path
125 };
126}
127
128// Custom wrappers
129function merge(path, value) {
130 return {
131 type: 'mutation',
132 op: 'merge',
133 path,
134 value
135 };
136}
137
138// Custom wrappers
139function mergeDeep(path, value) {
140 return {
141 type: 'mutation',
142 op: 'mergeDeep',
143 path,
144 value
145 };
146}
147function context(path, value) {
148 return {
149 type: 'context',
150 path,
151 value
152 };
153}
154
155// =========================
156// Iterators
157// =========================
158
159function forEachNew(mutations, fn) {
160 try {
161 return forEachNewPatch(mutations, forEach, fn);
162 } catch (e) {
163 return e;
164 }
165}
166function forEachNewPrimitive(mutations, fn) {
167 try {
168 return forEachNewPatch(mutations, forEachPrimitive, fn);
169 } catch (e) {
170 return e;
171 }
172}
173function forEachNewPatch(mutations, fn, callback) {
174 const res = mutations.filter(isAdditiveMutation).map(mutation => fn(mutation.value, callback, mutation.path)) || [];
175 const flat = flatten(res);
176 const clean = cleanArray(flat);
177 return clean;
178}
179function forEachPrimitive(obj, fn, basePath) {
180 basePath = basePath || [];
181 if (Array.isArray(obj)) {
182 return obj.map((val, key) => forEachPrimitive(val, fn, basePath.concat(key)));
183 }
184 if (isObject(obj)) {
185 return Object.keys(obj).map(key => forEachPrimitive(obj[key], fn, basePath.concat(key)));
186 }
187 return fn(obj, basePath[basePath.length - 1], basePath);
188}
189function forEach(obj, fn, basePath) {
190 basePath = basePath || [];
191 let results = [];
192 if (basePath.length > 0) {
193 const newResults = fn(obj, basePath[basePath.length - 1], basePath);
194 if (newResults) {
195 results = results.concat(newResults);
196 }
197 }
198 if (Array.isArray(obj)) {
199 const arrayResults = obj.map((val, key) => forEach(val, fn, basePath.concat(key)));
200 if (arrayResults) {
201 results = results.concat(arrayResults);
202 }
203 } else if (isObject(obj)) {
204 const moreResults = Object.keys(obj).map(key => forEach(obj[key], fn, basePath.concat(key)));
205 if (moreResults) {
206 results = results.concat(moreResults);
207 }
208 }
209 results = flatten(results);
210 return results;
211}
212
213// =========================
214// Paths
215// =========================
216
217function parentPathMatch(path, arr) {
218 if (!Array.isArray(arr)) {
219 return false;
220 }
221 for (let i = 0, len = arr.length; i < len; i += 1) {
222 if (arr[i] !== path[i]) {
223 return false;
224 }
225 }
226 return true;
227}
228function getIn(obj, path) {
229 return path.reduce((val, token) => {
230 if (typeof token !== 'undefined' && val) {
231 return val[token];
232 }
233 return val;
234 }, obj);
235}
236
237// =========================
238// Array
239// =========================
240
241function fullyNormalizeArray(arr) {
242 return cleanArray(flatten(normalizeArray(arr)));
243}
244function normalizeArray(arr) {
245 return Array.isArray(arr) ? arr : [arr];
246}
247function flatten(arr) {
248 return [].concat(...arr.map(val => Array.isArray(val) ? flatten(val) : val));
249}
250function cleanArray(arr) {
251 return arr.filter(elm => typeof elm !== 'undefined');
252}
253
254// =========================
255// Is-Thing.
256// =========================
257
258function isObject(val) {
259 return val && typeof val === 'object';
260}
261function isPromise(val) {
262 return isObject(val) && isFunction(val.then);
263}
264function isFunction(val) {
265 return val && typeof val === 'function';
266}
267function isError(patch) {
268 return patch instanceof Error;
269}
270function isJsonPatch(patch) {
271 if (isPatch(patch)) {
272 const {
273 op
274 } = patch;
275 return op === 'add' || op === 'remove' || op === 'replace';
276 }
277 return false;
278}
279function isGenerator(thing) {
280 return Object.prototype.toString.call(thing) === '[object GeneratorFunction]';
281}
282function isMutation(patch) {
283 return isJsonPatch(patch) || isPatch(patch) && patch.type === 'mutation';
284}
285function isAdditiveMutation(patch) {
286 return isMutation(patch) && (patch.op === 'add' || patch.op === 'replace' || patch.op === 'merge' || patch.op === 'mergeDeep');
287}
288function isContextPatch(patch) {
289 return isPatch(patch) && patch.type === 'context';
290}
291function isPatch(patch) {
292 return patch && typeof patch === 'object';
293}
294function getInByJsonPath(obj, jsonPath) {
295 try {
296 return jsonPatch.getValueByPointer(obj, jsonPath);
297 } catch (e) {
298 console.error(e); // eslint-disable-line no-console
299 return {};
300 }
301}
Note: See TracBrowser for help on using the repository browser.