@commercetools-frontend/application-config 22.2.0 → 22.3.0
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.
- package/dist/commercetools-frontend-application-config.cjs.dev.js +58 -127
- package/dist/commercetools-frontend-application-config.cjs.prod.js +58 -127
- package/dist/commercetools-frontend-application-config.esm.js +58 -127
- package/dist/{formatters-a0d40c36.esm.js → formatters-3609951b.esm.js} +13 -22
- package/dist/{formatters-a6cf66a7.cjs.dev.js → formatters-4f8eba33.cjs.prod.js} +13 -22
- package/dist/{formatters-b42c3866.cjs.prod.js → formatters-c6356c75.cjs.dev.js} +13 -22
- package/package.json +24 -10
- package/scripts/load-js-module.js +0 -0
- package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.dev.js +1 -1
- package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.prod.js +1 -1
- package/ssr/dist/commercetools-frontend-application-config-ssr.esm.js +1 -1
|
@@ -28,7 +28,7 @@ import _JSON$stringify from '@babel/runtime-corejs3/core-js-stable/json/stringif
|
|
|
28
28
|
import _startsWithInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/starts-with';
|
|
29
29
|
import _reduceInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/reduce';
|
|
30
30
|
import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map';
|
|
31
|
-
import { f as formatEntryPointUriPathToResourceAccessKey, e as entryPointUriPathToResourceAccesses } from './formatters-
|
|
31
|
+
import { f as formatEntryPointUriPathToResourceAccessKey, e as entryPointUriPathToResourceAccesses } from './formatters-3609951b.esm.js';
|
|
32
32
|
import _Set from '@babel/runtime-corejs3/core-js-stable/set';
|
|
33
33
|
import _Array$isArray from '@babel/runtime-corejs3/core-js-stable/array/is-array';
|
|
34
34
|
import Ajv from 'ajv';
|
|
@@ -41,28 +41,19 @@ import '@babel/runtime-corejs3/core-js-stable/object/entries';
|
|
|
41
41
|
import 'lodash/upperFirst';
|
|
42
42
|
|
|
43
43
|
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
44
|
-
|
|
45
44
|
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
46
|
-
|
|
47
45
|
let MissingOrInvalidConfigError = /*#__PURE__*/function (_Error) {
|
|
48
46
|
_inherits(MissingOrInvalidConfigError, _Error);
|
|
49
|
-
|
|
50
47
|
var _super = _createSuper(MissingOrInvalidConfigError);
|
|
51
|
-
|
|
52
48
|
function MissingOrInvalidConfigError(message) {
|
|
53
49
|
var _this;
|
|
54
|
-
|
|
55
50
|
_classCallCheck(this, MissingOrInvalidConfigError);
|
|
56
|
-
|
|
57
51
|
_this = _super.call(this, message);
|
|
58
|
-
|
|
59
52
|
_Object$defineProperty(_assertThisInitialized(_this), 'name', {
|
|
60
53
|
value: 'MissingOrInvalidConfigError'
|
|
61
54
|
});
|
|
62
|
-
|
|
63
55
|
return _this;
|
|
64
56
|
}
|
|
65
|
-
|
|
66
57
|
return _createClass(MissingOrInvalidConfigError);
|
|
67
58
|
}( /*#__PURE__*/_wrapNativeSuper(Error));
|
|
68
59
|
|
|
@@ -70,30 +61,27 @@ let MissingOrInvalidConfigError = /*#__PURE__*/function (_Error) {
|
|
|
70
61
|
// for instance in respect to both source files and dist files.
|
|
71
62
|
const findPackageRootPath = dir => {
|
|
72
63
|
const packageJsonPath = path.join(dir, 'package.json');
|
|
73
|
-
|
|
74
64
|
if (fs.existsSync(packageJsonPath)) {
|
|
75
65
|
return dir;
|
|
76
66
|
}
|
|
77
|
-
|
|
78
67
|
const parentDir = path.join(dir, '..');
|
|
79
68
|
return findPackageRootPath(parentDir);
|
|
80
69
|
};
|
|
81
|
-
|
|
82
70
|
const loadJsModule = filePath => {
|
|
83
|
-
const packageRootPath = findPackageRootPath(
|
|
84
|
-
|
|
71
|
+
const packageRootPath = findPackageRootPath(
|
|
72
|
+
// Start from the parent folder
|
|
73
|
+
path.join(__dirname, '..'));
|
|
74
|
+
// Load the JS module using a child process. This is primarly to avoid
|
|
85
75
|
// unwanted behaviors using `@babel/register` in the main process.
|
|
86
76
|
// The loader script does the actual `require` of the given `filePath`
|
|
87
77
|
// and uses `@babel/register` to correctly parse and execute the file.
|
|
88
78
|
// The "required module output" is then written into `stdout` and parsed
|
|
89
79
|
// as JSON.
|
|
90
|
-
|
|
91
80
|
const output = execFileSync('node', [path.join(packageRootPath, 'scripts/load-js-module.js'), filePath], {
|
|
92
81
|
encoding: 'utf8'
|
|
93
82
|
});
|
|
94
83
|
return JSON.parse(output);
|
|
95
84
|
};
|
|
96
|
-
|
|
97
85
|
const moduleName = 'custom-application-config';
|
|
98
86
|
const explorer = cosmiconfigSync(moduleName, {
|
|
99
87
|
// Restrict the supported file formats / names
|
|
@@ -108,24 +96,21 @@ const explorer = cosmiconfigSync(moduleName, {
|
|
|
108
96
|
});
|
|
109
97
|
const getConfigPath = () => {
|
|
110
98
|
const configFile = explorer.search();
|
|
111
|
-
|
|
112
99
|
if (!configFile) {
|
|
113
100
|
throw new Error("Missing or invalid Custom Application configuration file.");
|
|
114
101
|
}
|
|
115
|
-
|
|
116
102
|
return configFile.filepath;
|
|
117
103
|
};
|
|
118
|
-
|
|
119
104
|
const loadConfig = applicationPath => {
|
|
120
105
|
const configFile = explorer.search(applicationPath);
|
|
121
|
-
|
|
122
106
|
if (!configFile || !configFile.config) {
|
|
123
107
|
throw new MissingOrInvalidConfigError("Missing or invalid Custom Application configuration file.");
|
|
124
108
|
}
|
|
125
|
-
|
|
126
109
|
return configFile.config;
|
|
127
110
|
};
|
|
128
111
|
|
|
112
|
+
// Transifex's Structured JSON format.
|
|
113
|
+
// https://help.transifex.com/en/articles/6220899-structured-json
|
|
129
114
|
/**
|
|
130
115
|
* NOTE:
|
|
131
116
|
* Allows variable placeholders. Supported types are:
|
|
@@ -137,70 +122,52 @@ const variableSyntax = /\${([ ~:\w.'",\-/()@]+?)}/g;
|
|
|
137
122
|
const envRefSyntax = /^env:/g;
|
|
138
123
|
const intlRefSyntax = /^intl:/g;
|
|
139
124
|
const filePathRefSyntax = /^path:/g;
|
|
140
|
-
|
|
141
|
-
|
|
125
|
+
const hasVariablePlaceholder = valueOfEnvConfig => typeof valueOfEnvConfig === 'string' &&
|
|
126
|
+
// Using `{regex}.test()` might cause false positives if called multiple
|
|
142
127
|
// times on a global regular expression:
|
|
143
128
|
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test
|
|
144
129
|
// As with exec() (or in combination with it), test() called multiple times
|
|
145
130
|
// on the same global regular expression instance will advance past the previous match.
|
|
146
131
|
Boolean(valueOfEnvConfig.match(variableSyntax));
|
|
147
|
-
|
|
148
132
|
const isEnvVariablePlaceholder = valueOfPlaceholder => Boolean(valueOfPlaceholder.match(envRefSyntax));
|
|
149
|
-
|
|
150
133
|
const isIntlVariablePlaceholder = valueOfPlaceholder => Boolean(valueOfPlaceholder.match(intlRefSyntax));
|
|
151
|
-
|
|
152
134
|
const isFilePathVariablePlaceholder = valueOfPlaceholder => Boolean(valueOfPlaceholder.match(filePathRefSyntax));
|
|
153
|
-
|
|
154
135
|
const isStructuredJson = message => (message === null || message === void 0 ? void 0 : message.string) !== undefined;
|
|
155
|
-
|
|
156
136
|
const substituteEnvVariablePlaceholder = (valueOfPlaceholder, matchedString, valueOfEnvConfig, loadingOptions) => {
|
|
157
137
|
const _valueOfPlaceholder$s = valueOfPlaceholder.split(':'),
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
138
|
+
_valueOfPlaceholder$s2 = _slicedToArray(_valueOfPlaceholder$s, 2),
|
|
139
|
+
requestedEnvVar = _valueOfPlaceholder$s2[1];
|
|
161
140
|
const hasEnvField = loadingOptions.processEnv.hasOwnProperty(requestedEnvVar);
|
|
162
|
-
|
|
163
141
|
if (!hasEnvField) {
|
|
164
142
|
var _context;
|
|
165
|
-
|
|
166
143
|
throw new Error(_concatInstanceProperty(_context = "Missing environment variable '".concat(requestedEnvVar, "' specified in config as 'env:")).call(_context, requestedEnvVar, "'."));
|
|
167
144
|
}
|
|
168
|
-
|
|
169
145
|
const escapedMatchedString = matchedString.replace(/[${}:]/g, '\\$&');
|
|
170
146
|
return valueOfEnvConfig.replace(new RegExp("(".concat(escapedMatchedString, ")+"), 'g'), loadingOptions.processEnv[requestedEnvVar]);
|
|
171
147
|
};
|
|
172
|
-
|
|
173
148
|
const substituteIntlVariablePlaceholder = (valueOfPlaceholder, matchedString, valueOfEnvConfig, loadingOptions) => {
|
|
174
149
|
const _valueOfPlaceholder$s3 = valueOfPlaceholder.split(':'),
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
150
|
+
_valueOfPlaceholder$s4 = _slicedToArray(_valueOfPlaceholder$s3, 3),
|
|
151
|
+
locale = _valueOfPlaceholder$s4[1],
|
|
152
|
+
requestedIntlMessageId = _valueOfPlaceholder$s4[2];
|
|
179
153
|
const translationsFilePath = require.resolve("./i18n/data/".concat(locale, ".json"), {
|
|
180
154
|
paths: ["".concat(loadingOptions.applicationPath, "/src"), loadingOptions.applicationPath]
|
|
181
155
|
});
|
|
182
|
-
|
|
183
156
|
const translations = require(translationsFilePath);
|
|
184
|
-
|
|
185
157
|
const hasIntlMessage = translations.hasOwnProperty(requestedIntlMessageId);
|
|
186
|
-
|
|
187
158
|
if (!hasIntlMessage) {
|
|
188
159
|
var _context2, _context3;
|
|
189
|
-
|
|
190
160
|
throw new Error(_concatInstanceProperty(_context2 = _concatInstanceProperty(_context3 = "Missing message key '".concat(requestedIntlMessageId, "' specified in config as 'intl:")).call(_context3, locale, ":")).call(_context2, requestedIntlMessageId, "'."));
|
|
191
161
|
}
|
|
192
|
-
|
|
193
162
|
const translation = translations[requestedIntlMessageId];
|
|
194
163
|
const translationValue = isStructuredJson(translation) ? translation.string : translation;
|
|
195
164
|
const escapedMatchedString = matchedString.replace(/[${}:]/g, '\\$&');
|
|
196
165
|
return valueOfEnvConfig.replace(new RegExp("(".concat(escapedMatchedString, ")+"), 'g'), translationValue);
|
|
197
166
|
};
|
|
198
|
-
|
|
199
167
|
const substituteFilePathVariablePlaceholder = (valueOfPlaceholder, matchedString, valueOfEnvConfig, loadingOptions) => {
|
|
200
168
|
const _valueOfPlaceholder$s5 = valueOfPlaceholder.split(':'),
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
169
|
+
_valueOfPlaceholder$s6 = _slicedToArray(_valueOfPlaceholder$s5, 2),
|
|
170
|
+
filePathOrModule = _valueOfPlaceholder$s6[1];
|
|
204
171
|
const content = fs.readFileSync(require.resolve(filePathOrModule, {
|
|
205
172
|
// Relative paths should be resolved from the application folder.
|
|
206
173
|
paths: [loadingOptions.applicationPath]
|
|
@@ -210,20 +177,15 @@ const substituteFilePathVariablePlaceholder = (valueOfPlaceholder, matchedString
|
|
|
210
177
|
const escapedMatchedString = matchedString.replace(/[${}:]/g, '\\$&');
|
|
211
178
|
return valueOfEnvConfig.replace(new RegExp("(".concat(escapedMatchedString, ")+"), 'g'), content);
|
|
212
179
|
};
|
|
213
|
-
|
|
214
180
|
const getValueOfPlaceholder = valueWithPlaceholder => valueWithPlaceholder.replace(variableSyntax, (_match, varName) => _trimInstanceProperty(varName).call(varName)).replace(/\s/g, '');
|
|
215
|
-
|
|
216
181
|
const substituteVariablePlaceholders = (config, loadingOptions) => JSON.parse(_JSON$stringify(config), (_key, value) => {
|
|
217
182
|
// Only strings are allowed
|
|
218
183
|
let substitutedValue = value;
|
|
219
|
-
|
|
220
184
|
if (hasVariablePlaceholder(substitutedValue)) {
|
|
221
185
|
const matchResult = substitutedValue.match(variableSyntax);
|
|
222
|
-
|
|
223
186
|
if (matchResult) {
|
|
224
187
|
_forEachInstanceProperty(matchResult).call(matchResult, matchedString => {
|
|
225
188
|
const valueOfPlaceholder = getValueOfPlaceholder(matchedString);
|
|
226
|
-
|
|
227
189
|
if (isEnvVariablePlaceholder(valueOfPlaceholder)) {
|
|
228
190
|
substitutedValue = substituteEnvVariablePlaceholder(valueOfPlaceholder, matchedString, substitutedValue, loadingOptions);
|
|
229
191
|
} else if (isIntlVariablePlaceholder(valueOfPlaceholder)) {
|
|
@@ -234,7 +196,6 @@ const substituteVariablePlaceholders = (config, loadingOptions) => JSON.parse(_J
|
|
|
234
196
|
});
|
|
235
197
|
}
|
|
236
198
|
}
|
|
237
|
-
|
|
238
199
|
return substitutedValue;
|
|
239
200
|
});
|
|
240
201
|
|
|
@@ -596,10 +557,10 @@ var schemaJson = {
|
|
|
596
557
|
* non-consecutive underscores and hyphens. Leading and trailing underscore and hyphens are also not allowed.
|
|
597
558
|
*/
|
|
598
559
|
const ENTRY_POINT_URI_PATH_REGEX = /^[^-_#]([0-9a-z]|[-_](?![-_])){0,62}[^-_#]$/g;
|
|
560
|
+
|
|
599
561
|
/**
|
|
600
562
|
* The permission group name may be between 2 and 64 characters and only contain alphanumeric lowercase characters and non-consecutive hyphens. Leading and trailing hyphens are also not allowed.
|
|
601
563
|
*/
|
|
602
|
-
|
|
603
564
|
const PERMISSION_GROUP_NAME_REGEX = /^[^-#]([a-z]|[-](?![-])){0,62}[^-#]$/g;
|
|
604
565
|
const CLOUD_IDENTIFIERS = {
|
|
605
566
|
GCP_AU: 'gcp-au',
|
|
@@ -621,33 +582,25 @@ const ajv = new Ajv({
|
|
|
621
582
|
useDefaults: true
|
|
622
583
|
});
|
|
623
584
|
const validate = ajv.compile(schemaJson);
|
|
624
|
-
|
|
625
585
|
const printErrors = errors => {
|
|
626
586
|
if (!errors) {
|
|
627
587
|
return 'No errors';
|
|
628
588
|
}
|
|
629
|
-
|
|
630
589
|
return _mapInstanceProperty(errors).call(errors, error => {
|
|
631
590
|
var _context, _context2, _context3;
|
|
632
|
-
|
|
633
591
|
const baseMessage = _concatInstanceProperty(_context = "".concat(error.instancePath, " ")).call(_context, error.message);
|
|
634
|
-
|
|
635
592
|
switch (error.keyword) {
|
|
636
593
|
case 'additionalProperties':
|
|
637
594
|
return _concatInstanceProperty(_context2 = "".concat(baseMessage, ": ")).call(_context2, error.params.additionalProperty);
|
|
638
|
-
|
|
639
595
|
case 'enum':
|
|
640
596
|
return _concatInstanceProperty(_context3 = "".concat(baseMessage, ": ")).call(_context3, error.params.allowedValues.toString());
|
|
641
|
-
|
|
642
597
|
default:
|
|
643
598
|
return baseMessage;
|
|
644
599
|
}
|
|
645
600
|
}).join('\n');
|
|
646
601
|
};
|
|
647
|
-
|
|
648
602
|
const validateConfig = config => {
|
|
649
603
|
const valid = validate(config);
|
|
650
|
-
|
|
651
604
|
if (!valid) {
|
|
652
605
|
throw new Error(printErrors(validate.errors));
|
|
653
606
|
}
|
|
@@ -659,87 +612,73 @@ const validateEntryPointUriPath = config => {
|
|
|
659
612
|
};
|
|
660
613
|
const validateSubmenuLinks = config => {
|
|
661
614
|
var _context4;
|
|
662
|
-
|
|
663
615
|
const uriPathSet = new _Set();
|
|
664
|
-
|
|
665
616
|
_forEachInstanceProperty(_context4 = config.submenuLinks).call(_context4, _ref => {
|
|
666
617
|
let uriPath = _ref.uriPath;
|
|
667
|
-
|
|
668
618
|
if (uriPathSet.has(uriPath)) {
|
|
669
619
|
throw new Error('Duplicate URI path. Every submenu link must have a unique URI path value');
|
|
670
620
|
}
|
|
671
|
-
|
|
672
621
|
uriPathSet.add(uriPath);
|
|
673
622
|
});
|
|
674
623
|
};
|
|
675
624
|
const validateAdditionalOAuthScopes = config => {
|
|
676
625
|
var _config$additionalOAu;
|
|
677
|
-
|
|
678
626
|
const additionalPermissionNames = new _Set();
|
|
679
627
|
(_config$additionalOAu = config.additionalOAuthScopes) === null || _config$additionalOAu === void 0 ? void 0 : _forEachInstanceProperty(_config$additionalOAu).call(_config$additionalOAu, _ref2 => {
|
|
680
628
|
let name = _ref2.name,
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
629
|
+
view = _ref2.view,
|
|
630
|
+
manage = _ref2.manage;
|
|
684
631
|
if ((_Array$isArray(view) && view.length === 0 || !view) && (_Array$isArray(manage) && manage.length === 0 || !manage)) {
|
|
685
632
|
throw new Error("At least one OAuth Scope for permission group name \"".concat(name, "\" is required"));
|
|
686
633
|
} else if (additionalPermissionNames.has(name)) {
|
|
687
634
|
throw new Error("Duplicate additional permission group name \"".concat(name, "\". Every additional permission must have a unique name"));
|
|
688
635
|
}
|
|
689
|
-
|
|
690
636
|
if (!name.match(PERMISSION_GROUP_NAME_REGEX)) {
|
|
691
637
|
throw new Error("Additional permission group name \"".concat(name, "\" is invalid. The value may be between 2 and 64 characters and only contain alphabetic lowercase characters and non-consecutive hyphens. Leading and trailing hyphens are also not allowed"));
|
|
692
638
|
}
|
|
693
|
-
|
|
694
639
|
additionalPermissionNames.add(name);
|
|
695
640
|
});
|
|
696
641
|
};
|
|
697
642
|
|
|
698
643
|
function ownKeys$1(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
699
|
-
|
|
700
644
|
function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var _context5, _context6; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty(_context5 = ownKeys$1(Object(source), !0)).call(_context5, function (key) { _defineProperty(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context6 = ownKeys$1(Object(source))).call(_context6, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
645
|
+
|
|
646
|
+
// The `uriPath` of each submenu link is supposed to be defined relative
|
|
701
647
|
// to the `entryPointUriPath`. Computing the full path is done internally to keep
|
|
702
648
|
// the configuration simple.
|
|
703
|
-
|
|
704
649
|
const computeUriPath = (uriPath, entryPointUriPath) => {
|
|
705
650
|
var _context;
|
|
706
|
-
|
|
707
651
|
// In case the `uriPath` is only `/`, it means that the link is supposed to be
|
|
708
652
|
// treated the same as the main application path. In this case, the return value
|
|
709
653
|
// should not contain any unnecessary trailing slash and therefore we use the `entryPointUriPath`.
|
|
710
|
-
if (uriPath === '/') return entryPointUriPath;
|
|
654
|
+
if (uriPath === '/') return entryPointUriPath;
|
|
655
|
+
// In case the `uriPath` is already configured including the `entryPointUriPath`,
|
|
711
656
|
// we return the `uriPath` as-is.
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
657
|
+
if (_startsWithInstanceProperty(uriPath).call(uriPath, "".concat(entryPointUriPath, "/"))) return uriPath;
|
|
658
|
+
// Return the full path including the `entryPointUriPath` as a prefix.
|
|
715
659
|
return _concatInstanceProperty(_context = "".concat(entryPointUriPath, "/")).call(_context, uriPath);
|
|
716
660
|
};
|
|
717
|
-
|
|
718
661
|
const getPermissions = appConfig => {
|
|
719
662
|
var _context2, _appConfig$additional, _context3;
|
|
720
|
-
|
|
721
663
|
const additionalResourceAccessKeyToOauthScopeMap = _reduceInstanceProperty(_context2 = appConfig.additionalOAuthScopes || []).call(_context2, (previousOauthScope, _ref) => {
|
|
722
664
|
let name = _ref.name,
|
|
723
|
-
|
|
724
|
-
|
|
665
|
+
view = _ref.view,
|
|
666
|
+
manage = _ref.manage;
|
|
725
667
|
const formattedResourceKey = formatEntryPointUriPathToResourceAccessKey(name);
|
|
726
668
|
return _objectSpread$1(_objectSpread$1({}, previousOauthScope), {}, {
|
|
727
669
|
["view".concat(formattedResourceKey)]: view,
|
|
728
670
|
["manage".concat(formattedResourceKey)]: manage
|
|
729
671
|
});
|
|
730
672
|
}, {});
|
|
731
|
-
|
|
732
673
|
const additionalPermissionNames = ((_appConfig$additional = appConfig.additionalOAuthScopes) === null || _appConfig$additional === void 0 ? void 0 : _mapInstanceProperty(_appConfig$additional).call(_appConfig$additional, _ref2 => {
|
|
733
674
|
let name = _ref2.name;
|
|
734
675
|
return name;
|
|
735
676
|
})) || [];
|
|
736
677
|
const permissionKeys = entryPointUriPathToResourceAccesses(appConfig.entryPointUriPath, additionalPermissionNames);
|
|
737
|
-
|
|
738
678
|
const additionalPermissions = _mapInstanceProperty(_context3 = _Object$keys(additionalResourceAccessKeyToOauthScopeMap)).call(_context3, additionalResourceAccessKey => ({
|
|
739
679
|
name: permissionKeys[additionalResourceAccessKey],
|
|
740
680
|
oAuthScopes: additionalResourceAccessKeyToOauthScopeMap[additionalResourceAccessKey]
|
|
741
681
|
}));
|
|
742
|
-
|
|
743
682
|
return [{
|
|
744
683
|
name: permissionKeys.view,
|
|
745
684
|
oAuthScopes: appConfig.oAuthScopes.view
|
|
@@ -748,10 +687,8 @@ const getPermissions = appConfig => {
|
|
|
748
687
|
oAuthScopes: appConfig.oAuthScopes.manage
|
|
749
688
|
}, ...additionalPermissions];
|
|
750
689
|
};
|
|
751
|
-
|
|
752
690
|
function transformCustomApplicationConfigToData(appConfig) {
|
|
753
691
|
var _context4;
|
|
754
|
-
|
|
755
692
|
validateEntryPointUriPath(appConfig);
|
|
756
693
|
validateSubmenuLinks(appConfig);
|
|
757
694
|
validateAdditionalOAuthScopes(appConfig);
|
|
@@ -772,44 +709,35 @@ function transformCustomApplicationConfigToData(appConfig) {
|
|
|
772
709
|
|
|
773
710
|
const mapCloudIdentifierToApiUrl = key => {
|
|
774
711
|
var _context;
|
|
775
|
-
|
|
776
712
|
switch (key) {
|
|
777
713
|
case CLOUD_IDENTIFIERS.GCP_AU:
|
|
778
714
|
return MC_API_URLS.GCP_AU;
|
|
779
|
-
|
|
780
715
|
case CLOUD_IDENTIFIERS.GCP_EU:
|
|
781
716
|
return MC_API_URLS.GCP_EU;
|
|
782
|
-
|
|
783
717
|
case CLOUD_IDENTIFIERS.GCP_US:
|
|
784
718
|
return MC_API_URLS.GCP_US;
|
|
785
|
-
|
|
786
719
|
case CLOUD_IDENTIFIERS.AWS_FRA:
|
|
787
720
|
return MC_API_URLS.AWS_FRA;
|
|
788
|
-
|
|
789
721
|
case CLOUD_IDENTIFIERS.AWS_OHIO:
|
|
790
722
|
return MC_API_URLS.AWS_OHIO;
|
|
791
|
-
|
|
792
723
|
default:
|
|
793
724
|
// We would probably never get to this point, as the JSON schema validation
|
|
794
725
|
// kicks in before.
|
|
795
726
|
throw new Error(_concatInstanceProperty(_context = "Unknown cloud identifier \"".concat(key, "\". Supported values: ")).call(_context, _Object$values(CLOUD_IDENTIFIERS).toString()));
|
|
796
727
|
}
|
|
797
728
|
};
|
|
798
|
-
|
|
799
729
|
const getUniqueValues = function () {
|
|
800
730
|
let initialValues = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
801
731
|
let additionalValues = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
802
732
|
return uniq([...initialValues, ...additionalValues]);
|
|
803
733
|
};
|
|
804
|
-
|
|
805
734
|
const nonProductionEnvironment = ['development', 'test'];
|
|
806
|
-
|
|
807
|
-
|
|
735
|
+
const getIsProd = env =>
|
|
736
|
+
// TL;DR: in case the `MC_APP_ENV` is defined, we consider that it's
|
|
808
737
|
// a production environment unless it's one of `development` or `test`.
|
|
809
738
|
// This allows to use for example the `staging` value, which from the
|
|
810
739
|
// application perspective is still considered a production environment.
|
|
811
740
|
env.MC_APP_ENV ? !_includesInstanceProperty(nonProductionEnvironment).call(nonProductionEnvironment, env.MC_APP_ENV) : env.NODE_ENV === 'production';
|
|
812
|
-
|
|
813
741
|
const getOrThrow = (fn, errorMessage) => {
|
|
814
742
|
try {
|
|
815
743
|
return fn();
|
|
@@ -819,35 +747,30 @@ const getOrThrow = (fn, errorMessage) => {
|
|
|
819
747
|
};
|
|
820
748
|
|
|
821
749
|
function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
822
|
-
|
|
823
750
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context3, _context4; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty(_context3 = ownKeys(Object(source), !0)).call(_context3, function (key) { _defineProperty(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context4 = ownKeys(Object(source))).call(_context4, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
824
751
|
// TODO: make it configurable.
|
|
825
752
|
const developmentPort = 3001;
|
|
826
753
|
const developmentAppUrl = "http://localhost:".concat(developmentPort);
|
|
827
|
-
|
|
828
754
|
const trimTrailingSlash = value => value.replace(/\/$/, '');
|
|
829
|
-
|
|
830
755
|
const omitDevConfigIfEmpty = devConfig => {
|
|
831
|
-
if (
|
|
756
|
+
if (
|
|
757
|
+
// @ts-expect-error: the `accountLinks` is not explicitly typed as it's only used by the account app.
|
|
832
758
|
devConfig !== null && devConfig !== void 0 && devConfig.accountLinks || devConfig !== null && devConfig !== void 0 && devConfig.menuLinks || devConfig !== null && devConfig !== void 0 && devConfig.oidc) return devConfig;
|
|
833
759
|
return undefined;
|
|
834
|
-
};
|
|
835
|
-
// again will result in returning the cached value.
|
|
836
|
-
|
|
760
|
+
};
|
|
837
761
|
|
|
762
|
+
// Keep a reference to the config so that requiring the module
|
|
763
|
+
// again will result in returning the cached value.
|
|
838
764
|
let cachedConfig;
|
|
839
|
-
|
|
840
765
|
const processConfig = function () {
|
|
841
766
|
var _ref2, _processEnv$MC_APP_EN, _appConfig$additional, _ref3, _context, _appConfig$env$develo, _appConfig$headers, _appConfig$headers2, _appConfig$headers2$c, _context2, _appConfig$headers3, _appConfig$headers3$c, _appConfig$headers4, _appConfig$headers4$c;
|
|
842
|
-
|
|
843
767
|
let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
768
|
+
_ref$disableCache = _ref.disableCache,
|
|
769
|
+
disableCache = _ref$disableCache === void 0 ? false : _ref$disableCache,
|
|
770
|
+
_ref$processEnv = _ref.processEnv,
|
|
771
|
+
processEnv = _ref$processEnv === void 0 ? process.env : _ref$processEnv,
|
|
772
|
+
_ref$applicationPath = _ref.applicationPath,
|
|
773
|
+
applicationPath = _ref$applicationPath === void 0 ? fs.realpathSync(process.cwd()) : _ref$applicationPath;
|
|
851
774
|
if (cachedConfig && !disableCache) return cachedConfig;
|
|
852
775
|
const rawConfig = loadConfig(applicationPath);
|
|
853
776
|
validateConfig(rawConfig);
|
|
@@ -859,26 +782,33 @@ const processConfig = function () {
|
|
|
859
782
|
const appEnvKey = (_ref2 = (_processEnv$MC_APP_EN = processEnv.MC_APP_ENV) !== null && _processEnv$MC_APP_EN !== void 0 ? _processEnv$MC_APP_EN : processEnv.NODE_ENV) !== null && _ref2 !== void 0 ? _ref2 : 'development';
|
|
860
783
|
const isProd = getIsProd(processEnv);
|
|
861
784
|
const additionalAppEnv = (_appConfig$additional = appConfig.additionalEnv) !== null && _appConfig$additional !== void 0 ? _appConfig$additional : {};
|
|
862
|
-
const revision = (_ref3 = additionalAppEnv.revision) !== null && _ref3 !== void 0 ? _ref3 : '';
|
|
785
|
+
const revision = (_ref3 = additionalAppEnv.revision) !== null && _ref3 !== void 0 ? _ref3 : '';
|
|
786
|
+
|
|
787
|
+
// Parse all the supported URLs, which gets implicitly validated
|
|
863
788
|
|
|
864
789
|
const envAppUrl = isProd ? customApplicationData.url : developmentAppUrl;
|
|
865
|
-
const appUrl = getOrThrow(() => new _URL(envAppUrl), "Invalid application URL: \"".concat(envAppUrl, "\""));
|
|
790
|
+
const appUrl = getOrThrow(() => new _URL(envAppUrl), "Invalid application URL: \"".concat(envAppUrl, "\""));
|
|
866
791
|
|
|
792
|
+
// Use `||` instead of `??` to include empty string values.
|
|
867
793
|
const envCdnUrl = isProd ? appConfig.env.production.cdnUrl || appUrl.href : developmentAppUrl;
|
|
868
794
|
const cdnUrl = getOrThrow(() => new _URL(envCdnUrl), "Invalid application CDN URL: \"".concat(envCdnUrl, "\""));
|
|
869
|
-
const mcApiUrl = getOrThrow(() => new _URL(
|
|
870
|
-
|
|
795
|
+
const mcApiUrl = getOrThrow(() => new _URL(
|
|
796
|
+
// Use `||` instead of `??` to include empty string values.
|
|
797
|
+
appConfig.mcApiUrl || mapCloudIdentifierToApiUrl(appConfig.cloudIdentifier)), "Invalid MC API URL: \"".concat(appConfig.mcApiUrl, "\""));
|
|
798
|
+
|
|
799
|
+
// The real application ID is only used in production.
|
|
871
800
|
// In development, we prefix the entry point with the "__local" prefix.
|
|
872
801
|
// This is important to determine to which URL the MC should redirect to
|
|
873
802
|
// after successful login.
|
|
874
|
-
|
|
875
803
|
const applicationId = isProd ? _concatInstanceProperty(_context = "".concat(customApplicationData.id, ":")).call(_context, customApplicationData.entryPointUriPath) : "__local:".concat(customApplicationData.entryPointUriPath);
|
|
876
804
|
const developmentConfig = isProd ? undefined : omitDevConfigIfEmpty({
|
|
877
805
|
oidc: omitEmpty({
|
|
878
|
-
authorizeUrl: [
|
|
806
|
+
authorizeUrl: [
|
|
807
|
+
// In case the MC API url points to localhost, we need to point
|
|
879
808
|
// to a local running dev login page to handle the workflow properly.
|
|
880
809
|
mcApiUrl.hostname === 'localhost' ? mcApiUrl.origin.replace(mcApiUrl.port, String(developmentPort)) : mcApiUrl.origin.replace('mc-api', 'mc'), '/login/authorize'].join(''),
|
|
881
|
-
initialProjectKey:
|
|
810
|
+
initialProjectKey:
|
|
811
|
+
// For the `account` application, we should unset the projectKey.
|
|
882
812
|
customApplicationData.entryPointUriPath === 'account' ? undefined : appConfig.env.development.initialProjectKey,
|
|
883
813
|
teamId: (_appConfig$env$develo = appConfig.env.development) === null || _appConfig$env$develo === void 0 ? void 0 : _appConfig$env$develo.teamId,
|
|
884
814
|
oAuthScopes: appConfig.oAuthScopes,
|
|
@@ -926,8 +856,8 @@ const processConfig = function () {
|
|
|
926
856
|
return cachedConfig;
|
|
927
857
|
};
|
|
928
858
|
|
|
929
|
-
const jsdom = new JSDOM('');
|
|
930
|
-
|
|
859
|
+
const jsdom = new JSDOM('');
|
|
860
|
+
// @ts-expect-error: jsdom returns DOMWindow, which doesn't match Window dompurify expects
|
|
931
861
|
const DOMPurify = createDOMPurify(jsdom.window);
|
|
932
862
|
function sanitizeSvg(data) {
|
|
933
863
|
return DOMPurify.sanitize(data, {
|
|
@@ -935,7 +865,8 @@ function sanitizeSvg(data) {
|
|
|
935
865
|
svg: true
|
|
936
866
|
},
|
|
937
867
|
RETURN_DOM: true,
|
|
938
|
-
FORBID_ATTR: [
|
|
868
|
+
FORBID_ATTR: [
|
|
869
|
+
// To avoid injection by using `style="filter:url(\"data:image/svg+xml,<svg`
|
|
939
870
|
'style']
|
|
940
871
|
}).innerHTML;
|
|
941
872
|
}
|
|
@@ -15,9 +15,7 @@ import _Object$entries from '@babel/runtime-corejs3/core-js-stable/object/entrie
|
|
|
15
15
|
import upperFirst from 'lodash/upperFirst';
|
|
16
16
|
|
|
17
17
|
function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
18
|
-
|
|
19
18
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context8, _context9; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty(_context8 = ownKeys(Object(source), !0)).call(_context8, function (key) { _defineProperty(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context9 = ownKeys(Object(source))).call(_context9, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
20
|
-
|
|
21
19
|
/**
|
|
22
20
|
* The function formats the `entryPointUriPath` to a resource access key.
|
|
23
21
|
* It makes the first character of the string and the next character after a special character an uppercase.
|
|
@@ -32,11 +30,14 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
32
30
|
*/
|
|
33
31
|
const formatEntryPointUriPathToResourceAccessKey = entryPointUriPath => {
|
|
34
32
|
var _context, _context2;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
.split('_')
|
|
38
|
-
|
|
39
|
-
.
|
|
33
|
+
return _mapInstanceProperty(_context = _mapInstanceProperty(_context2 = entryPointUriPath
|
|
34
|
+
// Splits the string by underscore.
|
|
35
|
+
.split('_')
|
|
36
|
+
// Uppercase the first character of each word split.
|
|
37
|
+
).call(_context2, upperFirst)
|
|
38
|
+
// Join the words by an underscore.
|
|
39
|
+
.join('_')
|
|
40
|
+
// Each word is split by a hyphen.
|
|
40
41
|
.split('-')).call(_context, (word, i) => {
|
|
41
42
|
// Regex below checking if the character is numeric.
|
|
42
43
|
// If the word after the hyphen is numeric, replace the hyphen with a forward slash.
|
|
@@ -44,10 +45,10 @@ const formatEntryPointUriPathToResourceAccessKey = entryPointUriPath => {
|
|
|
44
45
|
if (i > 0 && /^-?\d+$/.test(word[0])) {
|
|
45
46
|
return "/".concat(word);
|
|
46
47
|
}
|
|
47
|
-
|
|
48
48
|
return upperFirst(word);
|
|
49
49
|
}).join('');
|
|
50
50
|
};
|
|
51
|
+
|
|
51
52
|
/**
|
|
52
53
|
* The function formats the permission group name to a resource access key.
|
|
53
54
|
* It makes the first character of the string and the next character after a special character (`-`) an uppercase.
|
|
@@ -56,46 +57,36 @@ const formatEntryPointUriPathToResourceAccessKey = entryPointUriPath => {
|
|
|
56
57
|
* - books --> Books
|
|
57
58
|
* - the-books --> TheBooks
|
|
58
59
|
*/
|
|
59
|
-
|
|
60
|
-
|
|
61
60
|
const formatPermissionGroupNameToResourceAccessKey = permissionGroupName => {
|
|
62
61
|
var _context3;
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
return _mapInstanceProperty(_context3 = permissionGroupName
|
|
63
|
+
// Each word is split by a hyphen.
|
|
65
64
|
.split('-')).call(_context3, upperFirst).join('');
|
|
66
65
|
};
|
|
67
|
-
|
|
68
66
|
function entryPointUriPathToResourceAccesses(entryPointUriPath, permissionGroupNames) {
|
|
69
67
|
var _context4;
|
|
70
|
-
|
|
71
68
|
const resourceAccessKey = formatEntryPointUriPathToResourceAccessKey(entryPointUriPath);
|
|
72
69
|
const defaultResourceAccesses = {
|
|
73
70
|
view: "view".concat(resourceAccessKey),
|
|
74
71
|
manage: "manage".concat(resourceAccessKey)
|
|
75
72
|
};
|
|
76
|
-
|
|
77
73
|
const additionalResourceAccesses = _reduceInstanceProperty(_context4 = permissionGroupNames !== null && permissionGroupNames !== void 0 ? permissionGroupNames : []).call(_context4, (resourceAccesses, permissionGroupName) => {
|
|
78
74
|
var _context5, _context6;
|
|
79
|
-
|
|
80
75
|
const additionalResourceAccessKey = formatPermissionGroupNameToResourceAccessKey(permissionGroupName);
|
|
81
76
|
return _objectSpread(_objectSpread({}, resourceAccesses), {}, {
|
|
82
77
|
["view".concat(additionalResourceAccessKey)]: _concatInstanceProperty(_context5 = "".concat(defaultResourceAccesses.view)).call(_context5, additionalResourceAccessKey),
|
|
83
78
|
["manage".concat(additionalResourceAccessKey)]: _concatInstanceProperty(_context6 = "".concat(defaultResourceAccesses.manage)).call(_context6, additionalResourceAccessKey)
|
|
84
79
|
});
|
|
85
80
|
}, {});
|
|
86
|
-
|
|
87
81
|
return _objectSpread(_objectSpread({}, defaultResourceAccesses), additionalResourceAccesses);
|
|
88
82
|
}
|
|
89
|
-
|
|
90
83
|
function entryPointUriPathToPermissionKeys(entryPointUriPath, permissionGroupNames) {
|
|
91
84
|
var _context7;
|
|
92
|
-
|
|
93
85
|
const resourceAccesses = entryPointUriPathToResourceAccesses(entryPointUriPath, permissionGroupNames !== null && permissionGroupNames !== void 0 ? permissionGroupNames : []);
|
|
94
86
|
return _reduceInstanceProperty(_context7 = _Object$entries(resourceAccesses)).call(_context7, (permissionKeys, _ref) => {
|
|
95
87
|
let _ref2 = _slicedToArray(_ref, 2),
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
88
|
+
resourceAccessKey = _ref2[0],
|
|
89
|
+
resourceAccessValue = _ref2[1];
|
|
99
90
|
return _objectSpread(_objectSpread({}, permissionKeys), {}, {
|
|
100
91
|
[upperFirst(resourceAccessKey)]: upperFirst(resourceAccessValue)
|
|
101
92
|
});
|