UNPKG

3.2 kBJavaScriptView Raw
1import { cloneDeep, isFunction, isPlainObject } from 'lodash-es';
2import { createAggregateError, isErrorLike } from './errors';
3import { parseJSONCOrError } from './util';
4/** Converts a GraphQL ConfigurationCascade value to a value of this library's ConfigurationCascade type. */
5export function gqlToCascade({ subjects, }) {
6 const cascade = {
7 subjects: [],
8 merged: null,
9 };
10 const allSettings = [];
11 const allSettingsErrors = [];
12 for (const subject of subjects) {
13 const settings = subject.latestSettings && parseJSONCOrError(subject.latestSettings.configuration.contents);
14 cascade.subjects.push({ subject, settings });
15 if (isErrorLike(settings)) {
16 allSettingsErrors.push(settings);
17 }
18 else if (settings !== null) {
19 allSettings.push(settings);
20 }
21 }
22 if (allSettingsErrors.length > 0) {
23 cascade.merged = createAggregateError(allSettingsErrors);
24 }
25 else {
26 cascade.merged = mergeSettings(allSettings);
27 }
28 return cascade;
29}
30/**
31 * Deeply merges the settings without modifying any of the input values. The array is ordered from lowest to
32 * highest precedence in the merge.
33 *
34 * TODO(sqs): In the future, this will pass a CustomMergeFunctions value to merge.
35 */
36export function mergeSettings(values) {
37 if (values.length === 0) {
38 return null;
39 }
40 const target = cloneDeep(values[0]);
41 for (const value of values.slice(1)) {
42 merge(target, value);
43 }
44 return target;
45}
46/**
47 * Deeply merges add into base (modifying base). The merged value for a key path can be customized by providing a
48 * function at the same key path in custom.
49 *
50 * Most callers should use mergeSettings, which uses the set of CustomMergeFunctions that are required to properly
51 * merge settings.
52 */
53export function merge(base, add, custom) {
54 for (const key of Object.keys(add)) {
55 if (key in base) {
56 const customEntry = custom && custom[key];
57 if (customEntry && isFunction(customEntry)) {
58 base[key] = customEntry(base[key], add[key]);
59 }
60 else if (isPlainObject(base[key]) && isPlainObject(add[key])) {
61 merge(base[key], add[key], customEntry);
62 }
63 else {
64 base[key] = add[key];
65 }
66 }
67 else {
68 base[key] = add[key];
69 }
70 }
71}
72/**
73 * The conventional ordering of extension configuration subject types in a list.
74 */
75export const SUBJECT_TYPE_ORDER = ['Client', 'User', 'Org', 'Site'];
76export function subjectTypeHeader(nodeType) {
77 switch (nodeType) {
78 case 'Client':
79 return null;
80 case 'Site':
81 return null;
82 case 'Org':
83 return 'Organization:';
84 case 'User':
85 return null;
86 }
87}
88export function subjectLabel(subject) {
89 switch (subject.__typename) {
90 case 'Client':
91 return 'Client';
92 case 'Site':
93 return 'Everyone';
94 case 'Org':
95 return subject.name;
96 case 'User':
97 return subject.username;
98 }
99}
100//# sourceMappingURL=settings.js.map
\No newline at end of file