@commercetools-frontend/application-config 22.30.2 → 22.31.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 +57 -67
- package/dist/commercetools-frontend-application-config.cjs.prod.js +57 -67
- package/dist/commercetools-frontend-application-config.esm.js +56 -66
- package/dist/declarations/src/formatters.d.ts +20 -0
- package/dist/declarations/src/schemas/generated/custom-application.schema.d.ts +97 -0
- package/dist/declarations/src/schemas/generated/custom-view.schema.d.ts +82 -0
- package/dist/declarations/src/types/generated/settings.d.ts +15 -0
- package/dist/declarations/src/types.d.ts +38 -0
- package/dist/{formatters-2a857809.cjs.prod.js → formatters-7f327585.cjs.prod.js} +10 -13
- package/dist/{formatters-80a6c235.esm.js → formatters-882eafa8.esm.js} +10 -12
- package/dist/{formatters-a09672cf.cjs.dev.js → formatters-a76b45b9.cjs.dev.js} +10 -13
- package/package.json +4 -4
- package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.dev.js +1 -2
- package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.prod.js +1 -2
- package/ssr/dist/commercetools-frontend-application-config-ssr.esm.js +1 -2
- package/tsconfig-mc-app.json +1 -1
|
@@ -8,8 +8,8 @@ import _Object$defineProperties from '@babel/runtime-corejs3/core-js-stable/obje
|
|
|
8
8
|
import _Object$defineProperty from '@babel/runtime-corejs3/core-js-stable/object/define-property';
|
|
9
9
|
import _defineProperty from '@babel/runtime-corejs3/helpers/esm/defineProperty';
|
|
10
10
|
import _includesInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/includes';
|
|
11
|
-
import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/concat';
|
|
12
11
|
import _URL from '@babel/runtime-corejs3/core-js-stable/url';
|
|
12
|
+
import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/concat';
|
|
13
13
|
import fs from 'node:fs';
|
|
14
14
|
import path, { parse } from 'node:path';
|
|
15
15
|
import omitEmpty from 'omit-empty-es';
|
|
@@ -31,7 +31,7 @@ import _JSON$stringify from '@babel/runtime-corejs3/core-js-stable/json/stringif
|
|
|
31
31
|
import _startsWithInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/starts-with';
|
|
32
32
|
import _reduceInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/reduce';
|
|
33
33
|
import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map';
|
|
34
|
-
import { f as formatEntryPointUriPathToResourceAccessKey, e as entryPointUriPathToResourceAccesses } from './formatters-
|
|
34
|
+
import { f as formatEntryPointUriPathToResourceAccessKey, e as entryPointUriPathToResourceAccesses } from './formatters-882eafa8.esm.js';
|
|
35
35
|
import _Set from '@babel/runtime-corejs3/core-js-stable/set';
|
|
36
36
|
import _Array$isArray from '@babel/runtime-corejs3/core-js-stable/array/is-array';
|
|
37
37
|
import Ajv from 'ajv';
|
|
@@ -118,7 +118,7 @@ const loadJsModule = filePath => {
|
|
|
118
118
|
const createExplorerFor = configFileName => {
|
|
119
119
|
return cosmiconfigSync(configFileName, {
|
|
120
120
|
// Restrict the supported file formats / names
|
|
121
|
-
searchPlaces: [
|
|
121
|
+
searchPlaces: [`.${configFileName}rc`, `.${configFileName}.json`, `.${configFileName}.js`, `.${configFileName}.cjs`, `.${configFileName}.mjs`, `.${configFileName}.ts`, `${configFileName}.json`, `${configFileName}.js`, `${configFileName}.cjs`, `${configFileName}.mjs`, `${configFileName}.ts`],
|
|
122
122
|
loaders: {
|
|
123
123
|
noExt: defaultLoaders['.json'],
|
|
124
124
|
'.js': loadJsModule,
|
|
@@ -134,18 +134,18 @@ const getConfigPath = () => {
|
|
|
134
134
|
const customApplicationConfigFile = customApplicationExplorer.search();
|
|
135
135
|
const customViewConfigFile = customViewExplorer.search();
|
|
136
136
|
if (!customApplicationConfigFile && !customViewConfigFile) {
|
|
137
|
-
throw new Error(
|
|
137
|
+
throw new Error(`Missing or invalid configuration file.`);
|
|
138
138
|
}
|
|
139
|
-
return
|
|
139
|
+
return customApplicationConfigFile?.filepath || customViewConfigFile?.filepath;
|
|
140
140
|
};
|
|
141
141
|
const loadConfig = applicationPath => {
|
|
142
142
|
const customApplicationConfigFile = customApplicationExplorer.search(applicationPath);
|
|
143
143
|
const customViewConfigFile = customViewExplorer.search(applicationPath);
|
|
144
144
|
if ((!customApplicationConfigFile || !customApplicationConfigFile.config) && (!customViewConfigFile || !customViewConfigFile.config)) {
|
|
145
|
-
throw new MissingOrInvalidConfigError(
|
|
145
|
+
throw new MissingOrInvalidConfigError(`Missing or invalid configuration file.`);
|
|
146
146
|
}
|
|
147
147
|
if (customApplicationConfigFile && customViewConfigFile) {
|
|
148
|
-
throw new MissingOrInvalidConfigError(
|
|
148
|
+
throw new MissingOrInvalidConfigError(`Found configuration files for both Custom Application and Custom View. Please remove one of them.`);
|
|
149
149
|
}
|
|
150
150
|
return customViewConfigFile || customApplicationConfigFile;
|
|
151
151
|
};
|
|
@@ -174,37 +174,35 @@ Boolean(valueOfEnvConfig.match(variableSyntax));
|
|
|
174
174
|
const isEnvVariablePlaceholder = valueOfPlaceholder => Boolean(valueOfPlaceholder.match(envRefSyntax));
|
|
175
175
|
const isIntlVariablePlaceholder = valueOfPlaceholder => Boolean(valueOfPlaceholder.match(intlRefSyntax));
|
|
176
176
|
const isFilePathVariablePlaceholder = valueOfPlaceholder => Boolean(valueOfPlaceholder.match(filePathRefSyntax));
|
|
177
|
-
const isStructuredJson = message =>
|
|
177
|
+
const isStructuredJson = message => message?.string !== undefined;
|
|
178
178
|
const substituteEnvVariablePlaceholder = (valueOfPlaceholder, matchedString, valueOfEnvConfig, loadingOptions) => {
|
|
179
179
|
const _valueOfPlaceholder$s = valueOfPlaceholder.split(':'),
|
|
180
180
|
_valueOfPlaceholder$s2 = _slicedToArray(_valueOfPlaceholder$s, 2),
|
|
181
181
|
requestedEnvVar = _valueOfPlaceholder$s2[1];
|
|
182
182
|
const hasEnvField = loadingOptions.processEnv.hasOwnProperty(requestedEnvVar);
|
|
183
183
|
if (!hasEnvField) {
|
|
184
|
-
|
|
185
|
-
throw new Error(_concatInstanceProperty(_context = "Missing environment variable '".concat(requestedEnvVar, "' specified in config as 'env:")).call(_context, requestedEnvVar, "'."));
|
|
184
|
+
throw new Error(`Missing environment variable '${requestedEnvVar}' specified in config as 'env:${requestedEnvVar}'.`);
|
|
186
185
|
}
|
|
187
186
|
const escapedMatchedString = matchedString.replace(/[${}:]/g, '\\$&');
|
|
188
|
-
return valueOfEnvConfig.replace(new RegExp(
|
|
187
|
+
return valueOfEnvConfig.replace(new RegExp(`(${escapedMatchedString})+`, 'g'), loadingOptions.processEnv[requestedEnvVar]);
|
|
189
188
|
};
|
|
190
189
|
const substituteIntlVariablePlaceholder = (valueOfPlaceholder, matchedString, valueOfEnvConfig, loadingOptions) => {
|
|
191
190
|
const _valueOfPlaceholder$s3 = valueOfPlaceholder.split(':'),
|
|
192
191
|
_valueOfPlaceholder$s4 = _slicedToArray(_valueOfPlaceholder$s3, 3),
|
|
193
192
|
locale = _valueOfPlaceholder$s4[1],
|
|
194
193
|
requestedIntlMessageId = _valueOfPlaceholder$s4[2];
|
|
195
|
-
const translationsFilePath = require.resolve(
|
|
196
|
-
paths: [
|
|
194
|
+
const translationsFilePath = require.resolve(`./i18n/data/${locale}.json`, {
|
|
195
|
+
paths: [`${loadingOptions.applicationPath}/src`, loadingOptions.applicationPath]
|
|
197
196
|
});
|
|
198
197
|
const translations = require(translationsFilePath);
|
|
199
198
|
const hasIntlMessage = translations.hasOwnProperty(requestedIntlMessageId);
|
|
200
199
|
if (!hasIntlMessage) {
|
|
201
|
-
|
|
202
|
-
throw new Error(_concatInstanceProperty(_context2 = _concatInstanceProperty(_context3 = "Missing message key '".concat(requestedIntlMessageId, "' specified in config as 'intl:")).call(_context3, locale, ":")).call(_context2, requestedIntlMessageId, "'."));
|
|
200
|
+
throw new Error(`Missing message key '${requestedIntlMessageId}' specified in config as 'intl:${locale}:${requestedIntlMessageId}'.`);
|
|
203
201
|
}
|
|
204
202
|
const translation = translations[requestedIntlMessageId];
|
|
205
203
|
const translationValue = isStructuredJson(translation) ? translation.string : translation;
|
|
206
204
|
const escapedMatchedString = matchedString.replace(/[${}:]/g, '\\$&');
|
|
207
|
-
return valueOfEnvConfig.replace(new RegExp(
|
|
205
|
+
return valueOfEnvConfig.replace(new RegExp(`(${escapedMatchedString})+`, 'g'), translationValue);
|
|
208
206
|
};
|
|
209
207
|
const substituteFilePathVariablePlaceholder = (valueOfPlaceholder, matchedString, valueOfEnvConfig, loadingOptions) => {
|
|
210
208
|
const _valueOfPlaceholder$s5 = valueOfPlaceholder.split(':'),
|
|
@@ -217,7 +215,7 @@ const substituteFilePathVariablePlaceholder = (valueOfPlaceholder, matchedString
|
|
|
217
215
|
encoding: 'utf-8'
|
|
218
216
|
});
|
|
219
217
|
const escapedMatchedString = matchedString.replace(/[${}:]/g, '\\$&');
|
|
220
|
-
return valueOfEnvConfig.replace(new RegExp(
|
|
218
|
+
return valueOfEnvConfig.replace(new RegExp(`(${escapedMatchedString})+`, 'g'), content);
|
|
221
219
|
};
|
|
222
220
|
const getValueOfPlaceholder = valueWithPlaceholder => valueWithPlaceholder.replace(variableSyntax, (_match, varName) => _trimInstanceProperty(varName).call(varName)).replace(/\s/g, '');
|
|
223
221
|
const substituteVariablePlaceholders = (config, loadingOptions) => JSON.parse(_JSON$stringify(config), (_key, value) => {
|
|
@@ -893,13 +891,12 @@ const printErrors = errors => {
|
|
|
893
891
|
return 'No errors';
|
|
894
892
|
}
|
|
895
893
|
return _mapInstanceProperty(errors).call(errors, error => {
|
|
896
|
-
|
|
897
|
-
const baseMessage = _concatInstanceProperty(_context = "".concat(error.instancePath, " ")).call(_context, error.message);
|
|
894
|
+
const baseMessage = `${error.instancePath} ${error.message}`;
|
|
898
895
|
switch (error.keyword) {
|
|
899
896
|
case 'additionalProperties':
|
|
900
|
-
return
|
|
897
|
+
return `${baseMessage}: ${error.params.additionalProperty}`;
|
|
901
898
|
case 'enum':
|
|
902
|
-
return
|
|
899
|
+
return `${baseMessage}: ${error.params.allowedValues.toString()}`;
|
|
903
900
|
default:
|
|
904
901
|
return baseMessage;
|
|
905
902
|
}
|
|
@@ -912,8 +909,7 @@ const validateConfig = (configType, config) => {
|
|
|
912
909
|
} else if (configType === LOADED_CONFIG_TYPES.CUSTOM_VIEW) {
|
|
913
910
|
validation = validateCustomViewConfig;
|
|
914
911
|
} else {
|
|
915
|
-
|
|
916
|
-
throw new Error(_concatInstanceProperty(_context4 = "Invalid config type \"".concat(configType, "\", expected ")).call(_context4, _Object$keys(LOADED_CONFIG_TYPES).toString()));
|
|
912
|
+
throw new Error(`Invalid config type "${configType}", expected ${_Object$keys(LOADED_CONFIG_TYPES).toString()}`);
|
|
917
913
|
}
|
|
918
914
|
const isValid = validation(config);
|
|
919
915
|
if (!isValid) {
|
|
@@ -926,9 +922,9 @@ const validateEntryPointUriPath = config => {
|
|
|
926
922
|
}
|
|
927
923
|
};
|
|
928
924
|
const validateSubmenuLinks = config => {
|
|
929
|
-
var
|
|
925
|
+
var _context;
|
|
930
926
|
const uriPathSet = new _Set();
|
|
931
|
-
_forEachInstanceProperty(
|
|
927
|
+
_forEachInstanceProperty(_context = config.submenuLinks).call(_context, _ref => {
|
|
932
928
|
let uriPath = _ref.uriPath;
|
|
933
929
|
if (uriPathSet.has(uriPath)) {
|
|
934
930
|
throw new Error('Duplicate URI path. Every submenu link must have a unique URI path value');
|
|
@@ -937,64 +933,62 @@ const validateSubmenuLinks = config => {
|
|
|
937
933
|
});
|
|
938
934
|
};
|
|
939
935
|
const validateAdditionalOAuthScopes = config => {
|
|
940
|
-
var _config$additionalOAu;
|
|
941
936
|
const additionalPermissionNames = new _Set();
|
|
942
|
-
|
|
937
|
+
config.additionalOAuthScopes?.forEach(_ref2 => {
|
|
943
938
|
let name = _ref2.name,
|
|
944
939
|
view = _ref2.view,
|
|
945
940
|
manage = _ref2.manage;
|
|
946
941
|
if ((_Array$isArray(view) && view.length === 0 || !view) && (_Array$isArray(manage) && manage.length === 0 || !manage)) {
|
|
947
|
-
throw new Error(
|
|
942
|
+
throw new Error(`At least one OAuth Scope for permission group name "${name}" is required`);
|
|
948
943
|
} else if (additionalPermissionNames.has(name)) {
|
|
949
|
-
throw new Error(
|
|
944
|
+
throw new Error(`Duplicate additional permission group name "${name}". Every additional permission must have a unique name`);
|
|
950
945
|
}
|
|
951
946
|
if (!name.match(PERMISSION_GROUP_NAME_REGEX)) {
|
|
952
|
-
throw new Error(
|
|
947
|
+
throw new Error(`Additional permission group name "${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`);
|
|
953
948
|
}
|
|
954
949
|
additionalPermissionNames.add(name);
|
|
955
950
|
});
|
|
956
951
|
};
|
|
957
952
|
|
|
958
953
|
function ownKeys$1(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
959
|
-
function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var
|
|
954
|
+
function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var _context4, _context5; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context4 = ownKeys$1(Object(t), !0)).call(_context4, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context5 = ownKeys$1(Object(t))).call(_context5, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
960
955
|
|
|
961
956
|
// The `uriPath` of each submenu link is supposed to be defined relative
|
|
962
957
|
// to the `entryPointUriPath`. Computing the full path is done internally to keep
|
|
963
958
|
// the configuration simple.
|
|
964
959
|
const computeUriPath = (uriPath, entryPointUriPath) => {
|
|
965
|
-
var _context;
|
|
966
960
|
// In case the `uriPath` is only `/`, it means that the link is supposed to be
|
|
967
961
|
// treated the same as the main application path. In this case, the return value
|
|
968
962
|
// should not contain any unnecessary trailing slash and therefore we use the `entryPointUriPath`.
|
|
969
963
|
if (uriPath === '/') return entryPointUriPath;
|
|
970
964
|
// In case the `uriPath` is already configured including the `entryPointUriPath`,
|
|
971
965
|
// we return the `uriPath` as-is.
|
|
972
|
-
if (_startsWithInstanceProperty(uriPath).call(uriPath,
|
|
966
|
+
if (_startsWithInstanceProperty(uriPath).call(uriPath, `${entryPointUriPath}/`)) return uriPath;
|
|
973
967
|
// Return the full path including the `entryPointUriPath` as a prefix.
|
|
974
|
-
return
|
|
968
|
+
return `${entryPointUriPath}/${uriPath}`;
|
|
975
969
|
};
|
|
976
970
|
const getPermissions = appConfig => {
|
|
977
|
-
var
|
|
978
|
-
const additionalResourceAccessKeyToOauthScopeMap = _reduceInstanceProperty(
|
|
971
|
+
var _context, _context2;
|
|
972
|
+
const additionalResourceAccessKeyToOauthScopeMap = _reduceInstanceProperty(_context = appConfig.additionalOAuthScopes || []).call(_context, (previousOauthScope, _ref) => {
|
|
979
973
|
let name = _ref.name,
|
|
980
974
|
view = _ref.view,
|
|
981
975
|
manage = _ref.manage;
|
|
982
976
|
const formattedResourceKey = formatEntryPointUriPathToResourceAccessKey(name);
|
|
983
977
|
return _objectSpread$1(_objectSpread$1({}, previousOauthScope), {}, {
|
|
984
|
-
[
|
|
985
|
-
[
|
|
978
|
+
[`view${formattedResourceKey}`]: view,
|
|
979
|
+
[`manage${formattedResourceKey}`]: manage
|
|
986
980
|
});
|
|
987
981
|
}, {});
|
|
988
|
-
const additionalPermissionNames =
|
|
982
|
+
const additionalPermissionNames = appConfig.additionalOAuthScopes?.map(_ref2 => {
|
|
989
983
|
let name = _ref2.name;
|
|
990
984
|
return name;
|
|
991
|
-
})
|
|
985
|
+
}) || [];
|
|
992
986
|
const permissionKeys = entryPointUriPathToResourceAccesses(appConfig.entryPointUriPath ||
|
|
993
987
|
// In case the `entryPointUriPath` is not defined it is because the
|
|
994
988
|
// configuration is for a custom view. In this case we use the
|
|
995
989
|
// default entry point uri path.
|
|
996
990
|
CUSTOM_VIEW_HOST_ENTRY_POINT_URI_PATH, additionalPermissionNames);
|
|
997
|
-
const additionalPermissions = _mapInstanceProperty(
|
|
991
|
+
const additionalPermissions = _mapInstanceProperty(_context2 = _Object$keys(additionalResourceAccessKeyToOauthScopeMap)).call(_context2, additionalResourceAccessKey => ({
|
|
998
992
|
name: permissionKeys[additionalResourceAccessKey],
|
|
999
993
|
oAuthScopes: additionalResourceAccessKeyToOauthScopeMap[additionalResourceAccessKey]
|
|
1000
994
|
}));
|
|
@@ -1007,7 +1001,7 @@ const getPermissions = appConfig => {
|
|
|
1007
1001
|
}, ...additionalPermissions];
|
|
1008
1002
|
};
|
|
1009
1003
|
function transformCustomApplicationConfigToData(appConfig) {
|
|
1010
|
-
var
|
|
1004
|
+
var _context3;
|
|
1011
1005
|
validateEntryPointUriPath(appConfig);
|
|
1012
1006
|
validateSubmenuLinks(appConfig);
|
|
1013
1007
|
validateAdditionalOAuthScopes(appConfig);
|
|
@@ -1020,7 +1014,7 @@ function transformCustomApplicationConfigToData(appConfig) {
|
|
|
1020
1014
|
permissions: getPermissions(appConfig),
|
|
1021
1015
|
icon: appConfig.icon,
|
|
1022
1016
|
mainMenuLink: appConfig.mainMenuLink,
|
|
1023
|
-
submenuLinks: _mapInstanceProperty(
|
|
1017
|
+
submenuLinks: _mapInstanceProperty(_context3 = appConfig.submenuLinks).call(_context3, submenuLink => _objectSpread$1(_objectSpread$1({}, submenuLink), {}, {
|
|
1024
1018
|
uriPath: computeUriPath(submenuLink.uriPath, appConfig.entryPointUriPath)
|
|
1025
1019
|
}))
|
|
1026
1020
|
};
|
|
@@ -1045,12 +1039,11 @@ function transformConfigurationToData(configType, configuration) {
|
|
|
1045
1039
|
} else if (configType === LOADED_CONFIG_TYPES.CUSTOM_VIEW) {
|
|
1046
1040
|
return transformCustomViewConfigToData(configuration);
|
|
1047
1041
|
} else {
|
|
1048
|
-
throw new Error(
|
|
1042
|
+
throw new Error(`Invalid config type: ${configType}`);
|
|
1049
1043
|
}
|
|
1050
1044
|
}
|
|
1051
1045
|
|
|
1052
1046
|
const mapCloudIdentifierToApiUrl = key => {
|
|
1053
|
-
var _context;
|
|
1054
1047
|
switch (key) {
|
|
1055
1048
|
case CLOUD_IDENTIFIERS.GCP_AU:
|
|
1056
1049
|
return MC_API_URLS.GCP_AU;
|
|
@@ -1069,7 +1062,7 @@ const mapCloudIdentifierToApiUrl = key => {
|
|
|
1069
1062
|
default:
|
|
1070
1063
|
// We would probably never get to this point, as the JSON schema validation
|
|
1071
1064
|
// kicks in before.
|
|
1072
|
-
throw new Error(
|
|
1065
|
+
throw new Error(`Unknown cloud identifier "${key}". Supported values: ${_Object$values(CLOUD_IDENTIFIERS).toString()}`);
|
|
1073
1066
|
}
|
|
1074
1067
|
};
|
|
1075
1068
|
const getUniqueValues = function () {
|
|
@@ -1093,10 +1086,10 @@ const getOrThrow = (fn, errorMessage) => {
|
|
|
1093
1086
|
};
|
|
1094
1087
|
|
|
1095
1088
|
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
1096
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var
|
|
1089
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context2, _context3; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context2 = ownKeys(Object(t), !0)).call(_context2, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context3 = ownKeys(Object(t))).call(_context3, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
1097
1090
|
// TODO: make it configurable.
|
|
1098
1091
|
const developmentPort = 3001;
|
|
1099
|
-
const developmentAppUrl =
|
|
1092
|
+
const developmentAppUrl = `http://localhost:${developmentPort}`;
|
|
1100
1093
|
const getLoadedConfigurationType = configFileName => {
|
|
1101
1094
|
if (_includesInstanceProperty(configFileName).call(configFileName, 'custom-view-config')) {
|
|
1102
1095
|
return LOADED_CONFIG_TYPES.CUSTOM_VIEW;
|
|
@@ -1112,7 +1105,6 @@ const omitDevConfigIfEmpty = devConfig => {
|
|
|
1112
1105
|
};
|
|
1113
1106
|
const isCustomViewData = data => data.entryPointUriPath === undefined;
|
|
1114
1107
|
const getRuntimeEnvironmentConfigForDevelopment = _ref => {
|
|
1115
|
-
var _appConfig$env$develo;
|
|
1116
1108
|
let isProd = _ref.isProd,
|
|
1117
1109
|
configurationData = _ref.configurationData,
|
|
1118
1110
|
mcApiUrl = _ref.mcApiUrl,
|
|
@@ -1129,7 +1121,7 @@ const getRuntimeEnvironmentConfigForDevelopment = _ref => {
|
|
|
1129
1121
|
initialProjectKey:
|
|
1130
1122
|
// For the `account` application, we should unset the projectKey.
|
|
1131
1123
|
entryPointUriPath === 'account' ? undefined : appConfig.env.development.initialProjectKey
|
|
1132
|
-
},
|
|
1124
|
+
}, appConfig.env.development?.teamId && _objectSpread({
|
|
1133
1125
|
teamId: appConfig.env.development.teamId
|
|
1134
1126
|
}, isCustomViewData(configurationData) ? {
|
|
1135
1127
|
customViewId: configurationData.id
|
|
@@ -1137,12 +1129,11 @@ const getRuntimeEnvironmentConfigForDevelopment = _ref => {
|
|
|
1137
1129
|
applicationId: configurationData.id
|
|
1138
1130
|
})), {}, {
|
|
1139
1131
|
oAuthScopes: appConfig.oAuthScopes,
|
|
1140
|
-
additionalOAuthScopes: appConfig
|
|
1132
|
+
additionalOAuthScopes: appConfig?.additionalOAuthScopes
|
|
1141
1133
|
}));
|
|
1142
1134
|
if (isCustomViewData(configurationData)) {
|
|
1143
|
-
var _context;
|
|
1144
1135
|
const hostUriPath = appConfig.env.development.hostUriPath;
|
|
1145
|
-
const defaultHostUriPath = oidcConfig.initialProjectKey ?
|
|
1136
|
+
const defaultHostUriPath = oidcConfig.initialProjectKey ? `/${oidcConfig.initialProjectKey}/${entryPointUriPath}` : `/${entryPointUriPath}`;
|
|
1146
1137
|
const hostUrl = new _URL(hostUriPath || defaultHostUriPath, developmentAppUrl);
|
|
1147
1138
|
return omitDevConfigIfEmpty({
|
|
1148
1139
|
oidc: oidcConfig,
|
|
@@ -1162,7 +1153,6 @@ const getRuntimeEnvironmentConfigForDevelopment = _ref => {
|
|
|
1162
1153
|
});
|
|
1163
1154
|
};
|
|
1164
1155
|
const getRuntimeEnvironmentConfig = _ref2 => {
|
|
1165
|
-
var _context2;
|
|
1166
1156
|
let isProd = _ref2.isProd,
|
|
1167
1157
|
configurationData = _ref2.configurationData,
|
|
1168
1158
|
additionalAppEnv = _ref2.additionalAppEnv,
|
|
@@ -1181,7 +1171,7 @@ const getRuntimeEnvironmentConfig = _ref2 => {
|
|
|
1181
1171
|
// In development, we prefix the entry point with the "__local" prefix.
|
|
1182
1172
|
// This is important to determine to which URL the MC should redirect to
|
|
1183
1173
|
// after successful login.
|
|
1184
|
-
const applicationIdentifier = isProd ?
|
|
1174
|
+
const applicationIdentifier = isProd ? `${configurationData.id}:${entryPointUriPath}` : `__local:${entryPointUriPath}`;
|
|
1185
1175
|
const developmentConfig = getRuntimeEnvironmentConfigForDevelopment({
|
|
1186
1176
|
isProd,
|
|
1187
1177
|
configurationData,
|
|
@@ -1213,7 +1203,7 @@ const getRuntimeEnvironmentConfig = _ref2 => {
|
|
|
1213
1203
|
// again will result in returning the cached value.
|
|
1214
1204
|
let cachedConfig;
|
|
1215
1205
|
const processConfig = function () {
|
|
1216
|
-
var
|
|
1206
|
+
var _context;
|
|
1217
1207
|
let _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
1218
1208
|
_ref3$disableCache = _ref3.disableCache,
|
|
1219
1209
|
disableCache = _ref3$disableCache === void 0 ? false : _ref3$disableCache,
|
|
@@ -1232,22 +1222,22 @@ const processConfig = function () {
|
|
|
1232
1222
|
processEnv
|
|
1233
1223
|
});
|
|
1234
1224
|
const configurationData = transformConfigurationToData(configType, appConfig);
|
|
1235
|
-
const appEnvKey =
|
|
1225
|
+
const appEnvKey = processEnv.MC_APP_ENV ?? processEnv.NODE_ENV ?? 'development';
|
|
1236
1226
|
const isProd = getIsProd(processEnv);
|
|
1237
|
-
const additionalAppEnv =
|
|
1238
|
-
const revision =
|
|
1227
|
+
const additionalAppEnv = appConfig.additionalEnv ?? {};
|
|
1228
|
+
const revision = additionalAppEnv.revision ?? '';
|
|
1239
1229
|
|
|
1240
1230
|
// Parse all the supported URLs, which gets implicitly validated
|
|
1241
1231
|
|
|
1242
1232
|
const envAppUrl = isProd ? configurationData.url : developmentAppUrl;
|
|
1243
|
-
const appUrl = getOrThrow(() => new _URL(envAppUrl),
|
|
1233
|
+
const appUrl = getOrThrow(() => new _URL(envAppUrl), `Invalid application URL: "${envAppUrl}"`);
|
|
1244
1234
|
|
|
1245
1235
|
// Use `||` instead of `??` to include empty string values.
|
|
1246
1236
|
const envCdnUrl = isProd ? appConfig.env.production.cdnUrl || appUrl.href : developmentAppUrl;
|
|
1247
|
-
const cdnUrl = getOrThrow(() => new _URL(envCdnUrl),
|
|
1237
|
+
const cdnUrl = getOrThrow(() => new _URL(envCdnUrl), `Invalid application CDN URL: "${envCdnUrl}"`);
|
|
1248
1238
|
const mcApiUrl = getOrThrow(() => new _URL(
|
|
1249
1239
|
// Use `||` instead of `??` to include empty string values.
|
|
1250
|
-
appConfig.mcApiUrl || mapCloudIdentifierToApiUrl(appConfig.cloudIdentifier)),
|
|
1240
|
+
appConfig.mcApiUrl || mapCloudIdentifierToApiUrl(appConfig.cloudIdentifier)), `Invalid MC API URL: "${appConfig.mcApiUrl}"`);
|
|
1251
1241
|
cachedConfig = {
|
|
1252
1242
|
data: configurationData,
|
|
1253
1243
|
env: getRuntimeEnvironmentConfig({
|
|
@@ -1262,16 +1252,16 @@ const processConfig = function () {
|
|
|
1262
1252
|
revision
|
|
1263
1253
|
}),
|
|
1264
1254
|
headers: _objectSpread(_objectSpread({}, appConfig.headers), {}, {
|
|
1265
|
-
csp: _objectSpread(_objectSpread({},
|
|
1255
|
+
csp: _objectSpread(_objectSpread({}, appConfig.headers?.csp), {}, {
|
|
1266
1256
|
// We need to make sure the URL we use in these CSP headers have a slash in the end,
|
|
1267
1257
|
// otherwise it might create an invalid value when application/CDN URL points to a
|
|
1268
1258
|
// non-root directory (ex: https://www.my-domain.com/app). This is a valid URL but from
|
|
1269
1259
|
// the CSP point of view, it will say only the file `app` can be used as a source, so
|
|
1270
1260
|
// any other file from that domain will be forbidden. Using the slash (ex: https://www.my-domain.com/app/)
|
|
1271
1261
|
// at the end it's like using a wildcard so anything 'below' `app` will be allowed.
|
|
1272
|
-
'connect-src': getUniqueValues(
|
|
1273
|
-
'script-src': getUniqueValues(
|
|
1274
|
-
'style-src': getUniqueValues(
|
|
1262
|
+
'connect-src': getUniqueValues(appConfig.headers?.csp?.['connect-src'], _concatInstanceProperty(_context = [mcApiUrl.origin]).call(_context, isProd ? [`${trimTrailingSlash(appUrl.href)}/`] : [])),
|
|
1263
|
+
'script-src': getUniqueValues(appConfig.headers?.csp?.['script-src'], isProd ? [`${trimTrailingSlash(appUrl.href)}/`, `${trimTrailingSlash(cdnUrl.href)}/`] : []),
|
|
1264
|
+
'style-src': getUniqueValues(appConfig.headers?.csp?.['style-src'], isProd ? [`${trimTrailingSlash(appUrl.href)}/`, `${trimTrailingSlash(cdnUrl.href)}/`] : [])
|
|
1275
1265
|
})
|
|
1276
1266
|
})
|
|
1277
1267
|
};
|
|
@@ -2,7 +2,27 @@ import type { CamelCase } from './types';
|
|
|
2
2
|
type TImplicitCustomApplicationResourceAccesses<PermissionGroupName extends string = ''> = Record<`view` | `manage` | `view${Capitalize<CamelCase<PermissionGroupName>>}` | `manage${Capitalize<CamelCase<PermissionGroupName>>}`, string>;
|
|
3
3
|
type TImplicitCustomViewResourceAccesses<PermissionGroupName extends string = ''> = TImplicitCustomApplicationResourceAccesses<PermissionGroupName>;
|
|
4
4
|
type TImplicitCustomApplicationPermissionKeys<PermissionGroupName extends string = ''> = Record<`View` | `Manage` | `View${Capitalize<CamelCase<PermissionGroupName>>}` | `Manage${Capitalize<CamelCase<PermissionGroupName>>}`, string>;
|
|
5
|
+
/**
|
|
6
|
+
* The function formats the `entryPointUriPath` to a resource access key.
|
|
7
|
+
* It makes the first character of the string and the next character after a special character an uppercase.
|
|
8
|
+
* It replaces hyphen(-) with a forward slash(/) if the hyphen(-) is followed by a number.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* - avengers --> Avengers
|
|
12
|
+
* - the-avengers --> TheAvengers
|
|
13
|
+
* - the_avengers --> The_Avengers
|
|
14
|
+
* - avengers-01 --> Avengers/01
|
|
15
|
+
* - avengers_01 --> Avengers_01
|
|
16
|
+
*/
|
|
5
17
|
declare const formatEntryPointUriPathToResourceAccessKey: (entryPointUriPath: string) => string;
|
|
18
|
+
/**
|
|
19
|
+
* The function formats the permission group name to a resource access key.
|
|
20
|
+
* It makes the first character of the string and the next character after a special character (`-`) an uppercase.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* - books --> Books
|
|
24
|
+
* - the-books --> TheBooks
|
|
25
|
+
*/
|
|
6
26
|
declare const formatPermissionGroupNameToResourceAccessKey: (permissionGroupName: string) => string;
|
|
7
27
|
declare function entryPointUriPathToResourceAccesses(entryPointUriPath: string): TImplicitCustomApplicationResourceAccesses<''>;
|
|
8
28
|
declare function entryPointUriPathToResourceAccesses<PermissionGroupName extends string>(entryPointUriPath: string, permissionGroupNames: PermissionGroupName[]): TImplicitCustomApplicationResourceAccesses<PermissionGroupName>;
|
|
@@ -1,34 +1,95 @@
|
|
|
1
|
+
|
|
1
2
|
export type CspDirective = string[];
|
|
2
3
|
export interface JSONSchemaForCustomApplicationConfigurationFiles {
|
|
4
|
+
/**
|
|
5
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#name
|
|
6
|
+
*/
|
|
3
7
|
name: string;
|
|
8
|
+
/**
|
|
9
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#description
|
|
10
|
+
*/
|
|
4
11
|
description?: string;
|
|
12
|
+
/**
|
|
13
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#entrypointuripath
|
|
14
|
+
*/
|
|
5
15
|
entryPointUriPath: string;
|
|
16
|
+
/**
|
|
17
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#cloudidentifier
|
|
18
|
+
*/
|
|
6
19
|
cloudIdentifier: string;
|
|
20
|
+
/**
|
|
21
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#mcapiurl
|
|
22
|
+
*/
|
|
7
23
|
mcApiUrl?: string;
|
|
24
|
+
/**
|
|
25
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#oauthscopes
|
|
26
|
+
*/
|
|
8
27
|
oAuthScopes: {
|
|
28
|
+
/**
|
|
29
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#oauthscopesview
|
|
30
|
+
*/
|
|
9
31
|
view: string[];
|
|
32
|
+
/**
|
|
33
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#oauthscopesmanage
|
|
34
|
+
*/
|
|
10
35
|
manage: string[];
|
|
11
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#additionaloauthscopes
|
|
39
|
+
*/
|
|
12
40
|
additionalOAuthScopes?: {
|
|
41
|
+
/**
|
|
42
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#additionaloauthscopesname
|
|
43
|
+
*/
|
|
13
44
|
name: string;
|
|
45
|
+
/**
|
|
46
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#additionaloauthscopesview
|
|
47
|
+
*/
|
|
14
48
|
view: string[];
|
|
49
|
+
/**
|
|
50
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#additionaloauthscopesmanage
|
|
51
|
+
*/
|
|
15
52
|
manage: string[];
|
|
16
53
|
}[];
|
|
54
|
+
/**
|
|
55
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#env
|
|
56
|
+
*/
|
|
17
57
|
env: {
|
|
18
58
|
development: {
|
|
59
|
+
/**
|
|
60
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#envdevelopmentinitialprojectkey
|
|
61
|
+
*/
|
|
19
62
|
initialProjectKey: string;
|
|
20
63
|
teamId?: string;
|
|
21
64
|
};
|
|
22
65
|
production: {
|
|
66
|
+
/**
|
|
67
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#envproductionapplicationid
|
|
68
|
+
*/
|
|
23
69
|
applicationId: string;
|
|
70
|
+
/**
|
|
71
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#envproductionurl
|
|
72
|
+
*/
|
|
24
73
|
url: string;
|
|
74
|
+
/**
|
|
75
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#envproductioncdnurl
|
|
76
|
+
*/
|
|
25
77
|
cdnUrl?: string;
|
|
26
78
|
};
|
|
27
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#additionalenv
|
|
82
|
+
*/
|
|
28
83
|
additionalEnv?: {
|
|
29
84
|
[k: string]: unknown;
|
|
30
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#headers
|
|
88
|
+
*/
|
|
31
89
|
headers?: {
|
|
90
|
+
/**
|
|
91
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#headerscsp
|
|
92
|
+
*/
|
|
32
93
|
csp?: {
|
|
33
94
|
'connect-src': CspDirective;
|
|
34
95
|
'font-src'?: CspDirective;
|
|
@@ -37,28 +98,64 @@ export interface JSONSchemaForCustomApplicationConfigurationFiles {
|
|
|
37
98
|
'style-src'?: CspDirective;
|
|
38
99
|
'frame-src'?: CspDirective;
|
|
39
100
|
};
|
|
101
|
+
/**
|
|
102
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#headerspermissionspolicies
|
|
103
|
+
*/
|
|
40
104
|
permissionsPolicies?: {
|
|
41
105
|
[k: string]: unknown;
|
|
42
106
|
};
|
|
107
|
+
/**
|
|
108
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#headersstricttransportsecurity
|
|
109
|
+
*/
|
|
43
110
|
strictTransportSecurity?: ('includeSubDomains' | 'preload')[];
|
|
44
111
|
};
|
|
112
|
+
/**
|
|
113
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#icon
|
|
114
|
+
*/
|
|
45
115
|
icon: string;
|
|
116
|
+
/**
|
|
117
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#mainmenulink
|
|
118
|
+
*/
|
|
46
119
|
mainMenuLink: {
|
|
120
|
+
/**
|
|
121
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#mainmenulinkdefaultlabel
|
|
122
|
+
*/
|
|
47
123
|
defaultLabel: string;
|
|
124
|
+
/**
|
|
125
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#mainmenulinklabelalllocales
|
|
126
|
+
*/
|
|
48
127
|
labelAllLocales: {
|
|
49
128
|
locale: 'en' | 'de' | 'es' | 'fr-FR' | 'pt-BR' | 'zh-CN';
|
|
50
129
|
value: string;
|
|
51
130
|
}[];
|
|
131
|
+
/**
|
|
132
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#mainmenulinkpermissions
|
|
133
|
+
*/
|
|
52
134
|
permissions: string[];
|
|
53
135
|
[k: string]: unknown;
|
|
54
136
|
};
|
|
137
|
+
/**
|
|
138
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#submenulinks
|
|
139
|
+
*/
|
|
55
140
|
submenuLinks: {
|
|
141
|
+
/**
|
|
142
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#submenulinksuripath
|
|
143
|
+
*/
|
|
56
144
|
uriPath: string;
|
|
145
|
+
/**
|
|
146
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#submenulinksdefaultlabel
|
|
147
|
+
*/
|
|
57
148
|
defaultLabel: string;
|
|
149
|
+
/**
|
|
150
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#submenulinkslabelalllocales
|
|
151
|
+
*/
|
|
58
152
|
labelAllLocales: {
|
|
59
153
|
locale: 'en' | 'de' | 'es' | 'fr-FR' | 'pt-BR' | 'zh-CN';
|
|
60
154
|
value: string;
|
|
61
155
|
}[];
|
|
156
|
+
/**
|
|
157
|
+
* See https://docs.commercetools.com/merchant-center-customizations/api-reference/custom-application-config#submenulinkspermissions
|
|
158
|
+
*/
|
|
62
159
|
permissions: string[];
|
|
63
160
|
[k: string]: unknown;
|
|
64
161
|
}[];
|