@commercetools-frontend/application-config 22.2.1 → 22.3.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.
- package/dist/commercetools-frontend-application-config.cjs.dev.js +64 -129
- package/dist/commercetools-frontend-application-config.cjs.prod.js +64 -129
- package/dist/commercetools-frontend-application-config.esm.js +64 -129
- package/dist/declarations/src/constants.d.ts +2 -0
- 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,24 +557,26 @@ 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',
|
|
606
567
|
GCP_EU: 'gcp-eu',
|
|
607
568
|
GCP_US: 'gcp-us',
|
|
608
569
|
AWS_FRA: 'aws-fra',
|
|
609
|
-
AWS_OHIO: 'aws-ohio'
|
|
570
|
+
AWS_OHIO: 'aws-ohio',
|
|
571
|
+
AWS_CN: 'aws-cn'
|
|
610
572
|
};
|
|
611
573
|
const MC_API_URLS = {
|
|
612
574
|
GCP_AU: 'https://mc-api.australia-southeast1.gcp.commercetools.com',
|
|
613
575
|
GCP_EU: 'https://mc-api.europe-west1.gcp.commercetools.com',
|
|
614
576
|
GCP_US: 'https://mc-api.us-central1.gcp.commercetools.com',
|
|
615
577
|
AWS_FRA: 'https://mc-api.eu-central-1.aws.commercetools.com',
|
|
616
|
-
AWS_OHIO: 'https://mc-api.us-east-2.aws.commercetools.com'
|
|
578
|
+
AWS_OHIO: 'https://mc-api.us-east-2.aws.commercetools.com',
|
|
579
|
+
AWS_CN: 'https://mc-api.cn-northwest-1.aws.commercetools.cn'
|
|
617
580
|
};
|
|
618
581
|
|
|
619
582
|
const ajv = new Ajv({
|
|
@@ -621,33 +584,25 @@ const ajv = new Ajv({
|
|
|
621
584
|
useDefaults: true
|
|
622
585
|
});
|
|
623
586
|
const validate = ajv.compile(schemaJson);
|
|
624
|
-
|
|
625
587
|
const printErrors = errors => {
|
|
626
588
|
if (!errors) {
|
|
627
589
|
return 'No errors';
|
|
628
590
|
}
|
|
629
|
-
|
|
630
591
|
return _mapInstanceProperty(errors).call(errors, error => {
|
|
631
592
|
var _context, _context2, _context3;
|
|
632
|
-
|
|
633
593
|
const baseMessage = _concatInstanceProperty(_context = "".concat(error.instancePath, " ")).call(_context, error.message);
|
|
634
|
-
|
|
635
594
|
switch (error.keyword) {
|
|
636
595
|
case 'additionalProperties':
|
|
637
596
|
return _concatInstanceProperty(_context2 = "".concat(baseMessage, ": ")).call(_context2, error.params.additionalProperty);
|
|
638
|
-
|
|
639
597
|
case 'enum':
|
|
640
598
|
return _concatInstanceProperty(_context3 = "".concat(baseMessage, ": ")).call(_context3, error.params.allowedValues.toString());
|
|
641
|
-
|
|
642
599
|
default:
|
|
643
600
|
return baseMessage;
|
|
644
601
|
}
|
|
645
602
|
}).join('\n');
|
|
646
603
|
};
|
|
647
|
-
|
|
648
604
|
const validateConfig = config => {
|
|
649
605
|
const valid = validate(config);
|
|
650
|
-
|
|
651
606
|
if (!valid) {
|
|
652
607
|
throw new Error(printErrors(validate.errors));
|
|
653
608
|
}
|
|
@@ -659,87 +614,73 @@ const validateEntryPointUriPath = config => {
|
|
|
659
614
|
};
|
|
660
615
|
const validateSubmenuLinks = config => {
|
|
661
616
|
var _context4;
|
|
662
|
-
|
|
663
617
|
const uriPathSet = new _Set();
|
|
664
|
-
|
|
665
618
|
_forEachInstanceProperty(_context4 = config.submenuLinks).call(_context4, _ref => {
|
|
666
619
|
let uriPath = _ref.uriPath;
|
|
667
|
-
|
|
668
620
|
if (uriPathSet.has(uriPath)) {
|
|
669
621
|
throw new Error('Duplicate URI path. Every submenu link must have a unique URI path value');
|
|
670
622
|
}
|
|
671
|
-
|
|
672
623
|
uriPathSet.add(uriPath);
|
|
673
624
|
});
|
|
674
625
|
};
|
|
675
626
|
const validateAdditionalOAuthScopes = config => {
|
|
676
627
|
var _config$additionalOAu;
|
|
677
|
-
|
|
678
628
|
const additionalPermissionNames = new _Set();
|
|
679
629
|
(_config$additionalOAu = config.additionalOAuthScopes) === null || _config$additionalOAu === void 0 ? void 0 : _forEachInstanceProperty(_config$additionalOAu).call(_config$additionalOAu, _ref2 => {
|
|
680
630
|
let name = _ref2.name,
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
631
|
+
view = _ref2.view,
|
|
632
|
+
manage = _ref2.manage;
|
|
684
633
|
if ((_Array$isArray(view) && view.length === 0 || !view) && (_Array$isArray(manage) && manage.length === 0 || !manage)) {
|
|
685
634
|
throw new Error("At least one OAuth Scope for permission group name \"".concat(name, "\" is required"));
|
|
686
635
|
} else if (additionalPermissionNames.has(name)) {
|
|
687
636
|
throw new Error("Duplicate additional permission group name \"".concat(name, "\". Every additional permission must have a unique name"));
|
|
688
637
|
}
|
|
689
|
-
|
|
690
638
|
if (!name.match(PERMISSION_GROUP_NAME_REGEX)) {
|
|
691
639
|
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
640
|
}
|
|
693
|
-
|
|
694
641
|
additionalPermissionNames.add(name);
|
|
695
642
|
});
|
|
696
643
|
};
|
|
697
644
|
|
|
698
645
|
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
646
|
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; }
|
|
647
|
+
|
|
648
|
+
// The `uriPath` of each submenu link is supposed to be defined relative
|
|
701
649
|
// to the `entryPointUriPath`. Computing the full path is done internally to keep
|
|
702
650
|
// the configuration simple.
|
|
703
|
-
|
|
704
651
|
const computeUriPath = (uriPath, entryPointUriPath) => {
|
|
705
652
|
var _context;
|
|
706
|
-
|
|
707
653
|
// In case the `uriPath` is only `/`, it means that the link is supposed to be
|
|
708
654
|
// treated the same as the main application path. In this case, the return value
|
|
709
655
|
// should not contain any unnecessary trailing slash and therefore we use the `entryPointUriPath`.
|
|
710
|
-
if (uriPath === '/') return entryPointUriPath;
|
|
656
|
+
if (uriPath === '/') return entryPointUriPath;
|
|
657
|
+
// In case the `uriPath` is already configured including the `entryPointUriPath`,
|
|
711
658
|
// we return the `uriPath` as-is.
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
659
|
+
if (_startsWithInstanceProperty(uriPath).call(uriPath, "".concat(entryPointUriPath, "/"))) return uriPath;
|
|
660
|
+
// Return the full path including the `entryPointUriPath` as a prefix.
|
|
715
661
|
return _concatInstanceProperty(_context = "".concat(entryPointUriPath, "/")).call(_context, uriPath);
|
|
716
662
|
};
|
|
717
|
-
|
|
718
663
|
const getPermissions = appConfig => {
|
|
719
664
|
var _context2, _appConfig$additional, _context3;
|
|
720
|
-
|
|
721
665
|
const additionalResourceAccessKeyToOauthScopeMap = _reduceInstanceProperty(_context2 = appConfig.additionalOAuthScopes || []).call(_context2, (previousOauthScope, _ref) => {
|
|
722
666
|
let name = _ref.name,
|
|
723
|
-
|
|
724
|
-
|
|
667
|
+
view = _ref.view,
|
|
668
|
+
manage = _ref.manage;
|
|
725
669
|
const formattedResourceKey = formatEntryPointUriPathToResourceAccessKey(name);
|
|
726
670
|
return _objectSpread$1(_objectSpread$1({}, previousOauthScope), {}, {
|
|
727
671
|
["view".concat(formattedResourceKey)]: view,
|
|
728
672
|
["manage".concat(formattedResourceKey)]: manage
|
|
729
673
|
});
|
|
730
674
|
}, {});
|
|
731
|
-
|
|
732
675
|
const additionalPermissionNames = ((_appConfig$additional = appConfig.additionalOAuthScopes) === null || _appConfig$additional === void 0 ? void 0 : _mapInstanceProperty(_appConfig$additional).call(_appConfig$additional, _ref2 => {
|
|
733
676
|
let name = _ref2.name;
|
|
734
677
|
return name;
|
|
735
678
|
})) || [];
|
|
736
679
|
const permissionKeys = entryPointUriPathToResourceAccesses(appConfig.entryPointUriPath, additionalPermissionNames);
|
|
737
|
-
|
|
738
680
|
const additionalPermissions = _mapInstanceProperty(_context3 = _Object$keys(additionalResourceAccessKeyToOauthScopeMap)).call(_context3, additionalResourceAccessKey => ({
|
|
739
681
|
name: permissionKeys[additionalResourceAccessKey],
|
|
740
682
|
oAuthScopes: additionalResourceAccessKeyToOauthScopeMap[additionalResourceAccessKey]
|
|
741
683
|
}));
|
|
742
|
-
|
|
743
684
|
return [{
|
|
744
685
|
name: permissionKeys.view,
|
|
745
686
|
oAuthScopes: appConfig.oAuthScopes.view
|
|
@@ -748,10 +689,8 @@ const getPermissions = appConfig => {
|
|
|
748
689
|
oAuthScopes: appConfig.oAuthScopes.manage
|
|
749
690
|
}, ...additionalPermissions];
|
|
750
691
|
};
|
|
751
|
-
|
|
752
692
|
function transformCustomApplicationConfigToData(appConfig) {
|
|
753
693
|
var _context4;
|
|
754
|
-
|
|
755
694
|
validateEntryPointUriPath(appConfig);
|
|
756
695
|
validateSubmenuLinks(appConfig);
|
|
757
696
|
validateAdditionalOAuthScopes(appConfig);
|
|
@@ -772,44 +711,37 @@ function transformCustomApplicationConfigToData(appConfig) {
|
|
|
772
711
|
|
|
773
712
|
const mapCloudIdentifierToApiUrl = key => {
|
|
774
713
|
var _context;
|
|
775
|
-
|
|
776
714
|
switch (key) {
|
|
777
715
|
case CLOUD_IDENTIFIERS.GCP_AU:
|
|
778
716
|
return MC_API_URLS.GCP_AU;
|
|
779
|
-
|
|
780
717
|
case CLOUD_IDENTIFIERS.GCP_EU:
|
|
781
718
|
return MC_API_URLS.GCP_EU;
|
|
782
|
-
|
|
783
719
|
case CLOUD_IDENTIFIERS.GCP_US:
|
|
784
720
|
return MC_API_URLS.GCP_US;
|
|
785
|
-
|
|
786
721
|
case CLOUD_IDENTIFIERS.AWS_FRA:
|
|
787
722
|
return MC_API_URLS.AWS_FRA;
|
|
788
|
-
|
|
789
723
|
case CLOUD_IDENTIFIERS.AWS_OHIO:
|
|
790
724
|
return MC_API_URLS.AWS_OHIO;
|
|
791
|
-
|
|
725
|
+
case CLOUD_IDENTIFIERS.AWS_CN:
|
|
726
|
+
return MC_API_URLS.AWS_CN;
|
|
792
727
|
default:
|
|
793
728
|
// We would probably never get to this point, as the JSON schema validation
|
|
794
729
|
// kicks in before.
|
|
795
730
|
throw new Error(_concatInstanceProperty(_context = "Unknown cloud identifier \"".concat(key, "\". Supported values: ")).call(_context, _Object$values(CLOUD_IDENTIFIERS).toString()));
|
|
796
731
|
}
|
|
797
732
|
};
|
|
798
|
-
|
|
799
733
|
const getUniqueValues = function () {
|
|
800
734
|
let initialValues = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
801
735
|
let additionalValues = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
802
736
|
return uniq([...initialValues, ...additionalValues]);
|
|
803
737
|
};
|
|
804
|
-
|
|
805
738
|
const nonProductionEnvironment = ['development', 'test'];
|
|
806
|
-
|
|
807
|
-
|
|
739
|
+
const getIsProd = env =>
|
|
740
|
+
// TL;DR: in case the `MC_APP_ENV` is defined, we consider that it's
|
|
808
741
|
// a production environment unless it's one of `development` or `test`.
|
|
809
742
|
// This allows to use for example the `staging` value, which from the
|
|
810
743
|
// application perspective is still considered a production environment.
|
|
811
744
|
env.MC_APP_ENV ? !_includesInstanceProperty(nonProductionEnvironment).call(nonProductionEnvironment, env.MC_APP_ENV) : env.NODE_ENV === 'production';
|
|
812
|
-
|
|
813
745
|
const getOrThrow = (fn, errorMessage) => {
|
|
814
746
|
try {
|
|
815
747
|
return fn();
|
|
@@ -819,35 +751,30 @@ const getOrThrow = (fn, errorMessage) => {
|
|
|
819
751
|
};
|
|
820
752
|
|
|
821
753
|
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
754
|
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
755
|
// TODO: make it configurable.
|
|
825
756
|
const developmentPort = 3001;
|
|
826
757
|
const developmentAppUrl = "http://localhost:".concat(developmentPort);
|
|
827
|
-
|
|
828
758
|
const trimTrailingSlash = value => value.replace(/\/$/, '');
|
|
829
|
-
|
|
830
759
|
const omitDevConfigIfEmpty = devConfig => {
|
|
831
|
-
if (
|
|
760
|
+
if (
|
|
761
|
+
// @ts-expect-error: the `accountLinks` is not explicitly typed as it's only used by the account app.
|
|
832
762
|
devConfig !== null && devConfig !== void 0 && devConfig.accountLinks || devConfig !== null && devConfig !== void 0 && devConfig.menuLinks || devConfig !== null && devConfig !== void 0 && devConfig.oidc) return devConfig;
|
|
833
763
|
return undefined;
|
|
834
|
-
};
|
|
835
|
-
// again will result in returning the cached value.
|
|
836
|
-
|
|
764
|
+
};
|
|
837
765
|
|
|
766
|
+
// Keep a reference to the config so that requiring the module
|
|
767
|
+
// again will result in returning the cached value.
|
|
838
768
|
let cachedConfig;
|
|
839
|
-
|
|
840
769
|
const processConfig = function () {
|
|
841
770
|
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
771
|
let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
772
|
+
_ref$disableCache = _ref.disableCache,
|
|
773
|
+
disableCache = _ref$disableCache === void 0 ? false : _ref$disableCache,
|
|
774
|
+
_ref$processEnv = _ref.processEnv,
|
|
775
|
+
processEnv = _ref$processEnv === void 0 ? process.env : _ref$processEnv,
|
|
776
|
+
_ref$applicationPath = _ref.applicationPath,
|
|
777
|
+
applicationPath = _ref$applicationPath === void 0 ? fs.realpathSync(process.cwd()) : _ref$applicationPath;
|
|
851
778
|
if (cachedConfig && !disableCache) return cachedConfig;
|
|
852
779
|
const rawConfig = loadConfig(applicationPath);
|
|
853
780
|
validateConfig(rawConfig);
|
|
@@ -859,26 +786,33 @@ const processConfig = function () {
|
|
|
859
786
|
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
787
|
const isProd = getIsProd(processEnv);
|
|
861
788
|
const additionalAppEnv = (_appConfig$additional = appConfig.additionalEnv) !== null && _appConfig$additional !== void 0 ? _appConfig$additional : {};
|
|
862
|
-
const revision = (_ref3 = additionalAppEnv.revision) !== null && _ref3 !== void 0 ? _ref3 : '';
|
|
789
|
+
const revision = (_ref3 = additionalAppEnv.revision) !== null && _ref3 !== void 0 ? _ref3 : '';
|
|
790
|
+
|
|
791
|
+
// Parse all the supported URLs, which gets implicitly validated
|
|
863
792
|
|
|
864
793
|
const envAppUrl = isProd ? customApplicationData.url : developmentAppUrl;
|
|
865
|
-
const appUrl = getOrThrow(() => new _URL(envAppUrl), "Invalid application URL: \"".concat(envAppUrl, "\""));
|
|
794
|
+
const appUrl = getOrThrow(() => new _URL(envAppUrl), "Invalid application URL: \"".concat(envAppUrl, "\""));
|
|
866
795
|
|
|
796
|
+
// Use `||` instead of `??` to include empty string values.
|
|
867
797
|
const envCdnUrl = isProd ? appConfig.env.production.cdnUrl || appUrl.href : developmentAppUrl;
|
|
868
798
|
const cdnUrl = getOrThrow(() => new _URL(envCdnUrl), "Invalid application CDN URL: \"".concat(envCdnUrl, "\""));
|
|
869
|
-
const mcApiUrl = getOrThrow(() => new _URL(
|
|
870
|
-
|
|
799
|
+
const mcApiUrl = getOrThrow(() => new _URL(
|
|
800
|
+
// Use `||` instead of `??` to include empty string values.
|
|
801
|
+
appConfig.mcApiUrl || mapCloudIdentifierToApiUrl(appConfig.cloudIdentifier)), "Invalid MC API URL: \"".concat(appConfig.mcApiUrl, "\""));
|
|
802
|
+
|
|
803
|
+
// The real application ID is only used in production.
|
|
871
804
|
// In development, we prefix the entry point with the "__local" prefix.
|
|
872
805
|
// This is important to determine to which URL the MC should redirect to
|
|
873
806
|
// after successful login.
|
|
874
|
-
|
|
875
807
|
const applicationId = isProd ? _concatInstanceProperty(_context = "".concat(customApplicationData.id, ":")).call(_context, customApplicationData.entryPointUriPath) : "__local:".concat(customApplicationData.entryPointUriPath);
|
|
876
808
|
const developmentConfig = isProd ? undefined : omitDevConfigIfEmpty({
|
|
877
809
|
oidc: omitEmpty({
|
|
878
|
-
authorizeUrl: [
|
|
810
|
+
authorizeUrl: [
|
|
811
|
+
// In case the MC API url points to localhost, we need to point
|
|
879
812
|
// to a local running dev login page to handle the workflow properly.
|
|
880
813
|
mcApiUrl.hostname === 'localhost' ? mcApiUrl.origin.replace(mcApiUrl.port, String(developmentPort)) : mcApiUrl.origin.replace('mc-api', 'mc'), '/login/authorize'].join(''),
|
|
881
|
-
initialProjectKey:
|
|
814
|
+
initialProjectKey:
|
|
815
|
+
// For the `account` application, we should unset the projectKey.
|
|
882
816
|
customApplicationData.entryPointUriPath === 'account' ? undefined : appConfig.env.development.initialProjectKey,
|
|
883
817
|
teamId: (_appConfig$env$develo = appConfig.env.development) === null || _appConfig$env$develo === void 0 ? void 0 : _appConfig$env$develo.teamId,
|
|
884
818
|
oAuthScopes: appConfig.oAuthScopes,
|
|
@@ -926,8 +860,8 @@ const processConfig = function () {
|
|
|
926
860
|
return cachedConfig;
|
|
927
861
|
};
|
|
928
862
|
|
|
929
|
-
const jsdom = new JSDOM('');
|
|
930
|
-
|
|
863
|
+
const jsdom = new JSDOM('');
|
|
864
|
+
// @ts-expect-error: jsdom returns DOMWindow, which doesn't match Window dompurify expects
|
|
931
865
|
const DOMPurify = createDOMPurify(jsdom.window);
|
|
932
866
|
function sanitizeSvg(data) {
|
|
933
867
|
return DOMPurify.sanitize(data, {
|
|
@@ -935,7 +869,8 @@ function sanitizeSvg(data) {
|
|
|
935
869
|
svg: true
|
|
936
870
|
},
|
|
937
871
|
RETURN_DOM: true,
|
|
938
|
-
FORBID_ATTR: [
|
|
872
|
+
FORBID_ATTR: [
|
|
873
|
+
// To avoid injection by using `style="filter:url(\"data:image/svg+xml,<svg`
|
|
939
874
|
'style']
|
|
940
875
|
}).innerHTML;
|
|
941
876
|
}
|
|
@@ -6,6 +6,7 @@ export declare const CLOUD_IDENTIFIERS: {
|
|
|
6
6
|
readonly GCP_US: "gcp-us";
|
|
7
7
|
readonly AWS_FRA: "aws-fra";
|
|
8
8
|
readonly AWS_OHIO: "aws-ohio";
|
|
9
|
+
readonly AWS_CN: "aws-cn";
|
|
9
10
|
};
|
|
10
11
|
export declare const MC_API_URLS: {
|
|
11
12
|
readonly GCP_AU: "https://mc-api.australia-southeast1.gcp.commercetools.com";
|
|
@@ -13,4 +14,5 @@ export declare const MC_API_URLS: {
|
|
|
13
14
|
readonly GCP_US: "https://mc-api.us-central1.gcp.commercetools.com";
|
|
14
15
|
readonly AWS_FRA: "https://mc-api.eu-central-1.aws.commercetools.com";
|
|
15
16
|
readonly AWS_OHIO: "https://mc-api.us-east-2.aws.commercetools.com";
|
|
17
|
+
readonly AWS_CN: "https://mc-api.cn-northwest-1.aws.commercetools.cn";
|
|
16
18
|
};
|
|
@@ -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
|
});
|