@commercetools-frontend/application-config 0.0.0-CRAFT-1791-20251006162610
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/LICENSE +21 -0
- package/README.md +7 -0
- package/client.d.ts +26 -0
- package/custom-application.schema.json +301 -0
- package/custom-view.schema.json +248 -0
- package/dist/commercetools-frontend-application-config.cjs.d.ts +2 -0
- package/dist/commercetools-frontend-application-config.cjs.dev.js +1351 -0
- package/dist/commercetools-frontend-application-config.cjs.js +7 -0
- package/dist/commercetools-frontend-application-config.cjs.prod.js +1351 -0
- package/dist/commercetools-frontend-application-config.esm.js +1303 -0
- package/dist/declarations/src/constants.d.ts +34 -0
- package/dist/declarations/src/errors.d.ts +4 -0
- package/dist/declarations/src/formatters.d.ts +33 -0
- package/dist/declarations/src/index.d.ts +7 -0
- package/dist/declarations/src/load-config.d.ts +11 -0
- package/dist/declarations/src/process-config.d.ts +6 -0
- package/dist/declarations/src/sanitize-svg.d.ts +1 -0
- package/dist/declarations/src/schemas/generated/custom-application.schema.d.ts +164 -0
- package/dist/declarations/src/schemas/generated/custom-view.schema.d.ts +139 -0
- package/dist/declarations/src/ssr.d.ts +1 -0
- package/dist/declarations/src/types/generated/settings.d.ts +1653 -0
- package/dist/declarations/src/types.d.ts +108 -0
- package/dist/formatters-7f327585.cjs.prod.js +123 -0
- package/dist/formatters-882eafa8.esm.js +101 -0
- package/dist/formatters-a76b45b9.cjs.dev.js +123 -0
- package/package.json +73 -0
- package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.d.ts +2 -0
- package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.dev.js +29 -0
- package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.js +7 -0
- package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.prod.js +29 -0
- package/ssr/dist/commercetools-frontend-application-config-ssr.esm.js +16 -0
- package/ssr/package.json +4 -0
- package/tsconfig-mc-app.json +29 -0
|
@@ -0,0 +1,1351 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
|
|
6
|
+
var _Object$getOwnPropertySymbols = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols');
|
|
7
|
+
var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/filter');
|
|
8
|
+
var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
|
|
9
|
+
var _forEachInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/for-each');
|
|
10
|
+
var _Object$getOwnPropertyDescriptors = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors');
|
|
11
|
+
var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/object/define-properties');
|
|
12
|
+
var _Object$defineProperty = require('@babel/runtime-corejs3/core-js-stable/object/define-property');
|
|
13
|
+
var _defineProperty = require('@babel/runtime-corejs3/helpers/defineProperty');
|
|
14
|
+
var _includesInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/includes');
|
|
15
|
+
var _URL = require('@babel/runtime-corejs3/core-js-stable/url');
|
|
16
|
+
var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
|
|
17
|
+
var fs$1 = require('node:fs');
|
|
18
|
+
var path = require('node:path');
|
|
19
|
+
var omitEmpty = require('omit-empty-es');
|
|
20
|
+
var constants = require('@commercetools-frontend/constants');
|
|
21
|
+
var _slicedToArray = require('@babel/runtime-corejs3/helpers/slicedToArray');
|
|
22
|
+
var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/map');
|
|
23
|
+
var _parseInt = require('@babel/runtime-corejs3/core-js-stable/parse-int');
|
|
24
|
+
var fs = require('node:fs/promises');
|
|
25
|
+
var cosmiconfig = require('cosmiconfig');
|
|
26
|
+
var cosmiconfigTypescriptLoader = require('cosmiconfig-typescript-loader');
|
|
27
|
+
var _Reflect$construct = require('@babel/runtime-corejs3/core-js-stable/reflect/construct');
|
|
28
|
+
var _createClass = require('@babel/runtime-corejs3/helpers/createClass');
|
|
29
|
+
var _classCallCheck = require('@babel/runtime-corejs3/helpers/classCallCheck');
|
|
30
|
+
var _possibleConstructorReturn = require('@babel/runtime-corejs3/helpers/possibleConstructorReturn');
|
|
31
|
+
var _getPrototypeOf = require('@babel/runtime-corejs3/helpers/getPrototypeOf');
|
|
32
|
+
var _inherits = require('@babel/runtime-corejs3/helpers/inherits');
|
|
33
|
+
var _wrapNativeSuper = require('@babel/runtime-corejs3/helpers/wrapNativeSuper');
|
|
34
|
+
var _trimInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/trim');
|
|
35
|
+
var _JSON$stringify = require('@babel/runtime-corejs3/core-js-stable/json/stringify');
|
|
36
|
+
var _startsWithInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/starts-with');
|
|
37
|
+
var _reduceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/reduce');
|
|
38
|
+
var formatters = require('./formatters-a76b45b9.cjs.dev.js');
|
|
39
|
+
var _Set = require('@babel/runtime-corejs3/core-js-stable/set');
|
|
40
|
+
var _Array$isArray = require('@babel/runtime-corejs3/core-js-stable/array/is-array');
|
|
41
|
+
var Ajv = require('ajv');
|
|
42
|
+
var _Object$values = require('@babel/runtime-corejs3/core-js-stable/object/values');
|
|
43
|
+
var uniq = require('lodash/uniq');
|
|
44
|
+
var createDOMPurify = require('dompurify');
|
|
45
|
+
var jsdom$1 = require('jsdom');
|
|
46
|
+
require('@babel/runtime-corejs3/core-js-stable/object/entries');
|
|
47
|
+
require('lodash/upperFirst');
|
|
48
|
+
|
|
49
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
50
|
+
|
|
51
|
+
var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
|
|
52
|
+
var _Object$getOwnPropertySymbols__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertySymbols);
|
|
53
|
+
var _filterInstanceProperty__default = /*#__PURE__*/_interopDefault(_filterInstanceProperty);
|
|
54
|
+
var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
|
|
55
|
+
var _forEachInstanceProperty__default = /*#__PURE__*/_interopDefault(_forEachInstanceProperty);
|
|
56
|
+
var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptors);
|
|
57
|
+
var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
|
|
58
|
+
var _Object$defineProperty__default = /*#__PURE__*/_interopDefault(_Object$defineProperty);
|
|
59
|
+
var _includesInstanceProperty__default = /*#__PURE__*/_interopDefault(_includesInstanceProperty);
|
|
60
|
+
var _URL__default = /*#__PURE__*/_interopDefault(_URL);
|
|
61
|
+
var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
|
|
62
|
+
var fs__default$1 = /*#__PURE__*/_interopDefault(fs$1);
|
|
63
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
64
|
+
var omitEmpty__default = /*#__PURE__*/_interopDefault(omitEmpty);
|
|
65
|
+
var _mapInstanceProperty__default = /*#__PURE__*/_interopDefault(_mapInstanceProperty);
|
|
66
|
+
var _parseInt__default = /*#__PURE__*/_interopDefault(_parseInt);
|
|
67
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
68
|
+
var _Reflect$construct__default = /*#__PURE__*/_interopDefault(_Reflect$construct);
|
|
69
|
+
var _trimInstanceProperty__default = /*#__PURE__*/_interopDefault(_trimInstanceProperty);
|
|
70
|
+
var _JSON$stringify__default = /*#__PURE__*/_interopDefault(_JSON$stringify);
|
|
71
|
+
var _startsWithInstanceProperty__default = /*#__PURE__*/_interopDefault(_startsWithInstanceProperty);
|
|
72
|
+
var _reduceInstanceProperty__default = /*#__PURE__*/_interopDefault(_reduceInstanceProperty);
|
|
73
|
+
var _Set__default = /*#__PURE__*/_interopDefault(_Set);
|
|
74
|
+
var _Array$isArray__default = /*#__PURE__*/_interopDefault(_Array$isArray);
|
|
75
|
+
var Ajv__default = /*#__PURE__*/_interopDefault(Ajv);
|
|
76
|
+
var _Object$values__default = /*#__PURE__*/_interopDefault(_Object$values);
|
|
77
|
+
var uniq__default = /*#__PURE__*/_interopDefault(uniq);
|
|
78
|
+
var createDOMPurify__default = /*#__PURE__*/_interopDefault(createDOMPurify);
|
|
79
|
+
|
|
80
|
+
const CLOUD_IDENTIFIERS = {
|
|
81
|
+
GCP_AU: 'gcp-au',
|
|
82
|
+
GCP_EU: 'gcp-eu',
|
|
83
|
+
GCP_US: 'gcp-us',
|
|
84
|
+
AWS_EU: 'aws-eu',
|
|
85
|
+
AWS_US: 'aws-us',
|
|
86
|
+
/**
|
|
87
|
+
* @deprecated: use `AWS_EU` instead
|
|
88
|
+
*/
|
|
89
|
+
AWS_FRA: 'aws-fra',
|
|
90
|
+
/**
|
|
91
|
+
* @deprecated: use `AWS_US` instead
|
|
92
|
+
*/
|
|
93
|
+
AWS_OHIO: 'aws-ohio'
|
|
94
|
+
};
|
|
95
|
+
const MC_API_URLS = {
|
|
96
|
+
[CLOUD_IDENTIFIERS.GCP_AU]: 'https://mc-api.australia-southeast1.gcp.commercetools.com',
|
|
97
|
+
[CLOUD_IDENTIFIERS.GCP_EU]: 'https://mc-api.europe-west1.gcp.commercetools.com',
|
|
98
|
+
[CLOUD_IDENTIFIERS.GCP_US]: 'https://mc-api.us-central1.gcp.commercetools.com',
|
|
99
|
+
[CLOUD_IDENTIFIERS.AWS_EU]: 'https://mc-api.eu-central-1.aws.commercetools.com',
|
|
100
|
+
[CLOUD_IDENTIFIERS.AWS_US]: 'https://mc-api.us-east-2.aws.commercetools.com',
|
|
101
|
+
/**
|
|
102
|
+
* @deprecated: use `AWS_EU` instead
|
|
103
|
+
*/
|
|
104
|
+
[CLOUD_IDENTIFIERS.AWS_FRA]: 'https://mc-api.eu-central-1.aws.commercetools.com',
|
|
105
|
+
/**
|
|
106
|
+
* @deprecated: use `AWS_US` instead
|
|
107
|
+
*/
|
|
108
|
+
[CLOUD_IDENTIFIERS.AWS_OHIO]: 'https://mc-api.us-east-2.aws.commercetools.com'
|
|
109
|
+
};
|
|
110
|
+
const LOADED_CONFIG_TYPES = {
|
|
111
|
+
CUSTOM_APPLICATION: 'custom-application',
|
|
112
|
+
CUSTOM_VIEW: 'custom-view'
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? _Reflect$construct__default["default"](o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
116
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct__default["default"](Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); }
|
|
117
|
+
let MissingOrInvalidConfigError = /*#__PURE__*/function (_Error) {
|
|
118
|
+
function MissingOrInvalidConfigError(message) {
|
|
119
|
+
var _this;
|
|
120
|
+
_classCallCheck(this, MissingOrInvalidConfigError);
|
|
121
|
+
_this = _callSuper(this, MissingOrInvalidConfigError, [message]);
|
|
122
|
+
_Object$defineProperty__default["default"](_this, 'name', {
|
|
123
|
+
value: 'MissingOrInvalidConfigError'
|
|
124
|
+
});
|
|
125
|
+
return _this;
|
|
126
|
+
}
|
|
127
|
+
_inherits(MissingOrInvalidConfigError, _Error);
|
|
128
|
+
return _createClass(MissingOrInvalidConfigError);
|
|
129
|
+
}(/*#__PURE__*/_wrapNativeSuper(Error));
|
|
130
|
+
|
|
131
|
+
// See the following issues for more context, contributing to failing Jest tests:
|
|
132
|
+
// - Issue: https://github.com/nodejs/node/issues/40058
|
|
133
|
+
// - Resolution: https://github.com/nodejs/node/pull/48510 (Node v20.8.0)
|
|
134
|
+
// Copied from @commitlint/load/src/utils/load-config.ts
|
|
135
|
+
const isDynamicAwaitSupported = () => {
|
|
136
|
+
var _context;
|
|
137
|
+
const _process$version$repl = _mapInstanceProperty__default["default"](_context = process.version.replace('v', '').split('.')).call(_context, val => _parseInt__default["default"](val)),
|
|
138
|
+
_process$version$repl2 = _slicedToArray(_process$version$repl, 2),
|
|
139
|
+
major = _process$version$repl2[0],
|
|
140
|
+
minor = _process$version$repl2[1];
|
|
141
|
+
return major >= 20 && minor >= 8;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// Is the given directory set up to use ESM (ECMAScript Modules)?
|
|
145
|
+
// Copied from @commitlint/load/src/utils/load-config.ts
|
|
146
|
+
const isEsmModule = async cwd => {
|
|
147
|
+
const packagePath = path__default["default"].join(cwd, 'package.json');
|
|
148
|
+
try {
|
|
149
|
+
const packageJSON = await fs__default["default"].readFile(packagePath, {
|
|
150
|
+
encoding: 'utf-8'
|
|
151
|
+
});
|
|
152
|
+
return JSON.parse(packageJSON)?.type === 'module';
|
|
153
|
+
} catch (error) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
const createExplorerFor = async configFileName => {
|
|
158
|
+
// Copied from @commitlint/load/src/utils/load-config.ts
|
|
159
|
+
let tsLoaderInstance;
|
|
160
|
+
const tsLoader = function () {
|
|
161
|
+
if (!tsLoaderInstance) {
|
|
162
|
+
tsLoaderInstance = cosmiconfigTypescriptLoader.TypeScriptLoader();
|
|
163
|
+
}
|
|
164
|
+
return tsLoaderInstance(...arguments);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// If dynamic await is supported (Node >= v20.8.0) or directory uses ESM, support
|
|
168
|
+
// async js/cjs loaders (dynamic import). Otherwise, use synchronous js/cjs loaders.
|
|
169
|
+
const loaders = isDynamicAwaitSupported() || (await isEsmModule(process.cwd())) ? cosmiconfig.defaultLoaders : cosmiconfig.defaultLoadersSync;
|
|
170
|
+
return cosmiconfig.cosmiconfig(configFileName, {
|
|
171
|
+
searchStrategy: 'project',
|
|
172
|
+
searchPlaces: [`${configFileName}.js`, `${configFileName}.cjs`, `${configFileName}.mjs`, `${configFileName}.ts`],
|
|
173
|
+
loaders: {
|
|
174
|
+
'.js': loaders['.js'],
|
|
175
|
+
'.cjs': loaders['.cjs'],
|
|
176
|
+
'.mjs': tsLoader,
|
|
177
|
+
'.ts': tsLoader
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
const getConfigPath = async () => {
|
|
182
|
+
const customApplicationExplorer = await createExplorerFor('custom-application-config');
|
|
183
|
+
const customViewExplorer = await createExplorerFor('custom-view-config');
|
|
184
|
+
const customApplicationConfigFile = await customApplicationExplorer.search();
|
|
185
|
+
const customViewConfigFile = await customViewExplorer.search();
|
|
186
|
+
if (!customApplicationConfigFile && !customViewConfigFile) {
|
|
187
|
+
throw new Error(`Missing or invalid configuration file.`);
|
|
188
|
+
}
|
|
189
|
+
return customApplicationConfigFile?.filepath || customViewConfigFile?.filepath;
|
|
190
|
+
};
|
|
191
|
+
const loadConfig = async applicationPath => {
|
|
192
|
+
const customApplicationExplorer = await createExplorerFor('custom-application-config');
|
|
193
|
+
const customViewExplorer = await createExplorerFor('custom-view-config');
|
|
194
|
+
const customApplicationConfigFile = await customApplicationExplorer.search(applicationPath);
|
|
195
|
+
const customViewConfigFile = await customViewExplorer.search(applicationPath);
|
|
196
|
+
if ((!customApplicationConfigFile || !customApplicationConfigFile.config) && (!customViewConfigFile || !customViewConfigFile.config)) {
|
|
197
|
+
throw new MissingOrInvalidConfigError(`Missing or invalid configuration file.`);
|
|
198
|
+
}
|
|
199
|
+
if (customApplicationConfigFile && customViewConfigFile) {
|
|
200
|
+
throw new MissingOrInvalidConfigError(`Found configuration files for both Custom Application and Custom View. Please remove one of them.`);
|
|
201
|
+
}
|
|
202
|
+
return customViewConfigFile || customApplicationConfigFile;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// Transifex's Structured JSON format.
|
|
206
|
+
// https://help.transifex.com/en/articles/6220899-structured-json
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* NOTE:
|
|
210
|
+
* Allows variable placeholders. Supported types are:
|
|
211
|
+
* - `env`: For example `${env:MC_API_URL}`.
|
|
212
|
+
* - `intl`: For example `${intl:en:Menu.title}`.
|
|
213
|
+
* - `path`: For example `${path:./app.svg}`, or `${path:@commercetools-frontend/assets/application-icons/rocket.svg}`.
|
|
214
|
+
*/
|
|
215
|
+
const variableSyntax = /\${([ ~:\w.'",\-/()@]+?)}/g;
|
|
216
|
+
const envRefSyntax = /^env:/g;
|
|
217
|
+
const intlRefSyntax = /^intl:/g;
|
|
218
|
+
const filePathRefSyntax = /^path:/g;
|
|
219
|
+
const hasVariablePlaceholder = valueOfEnvConfig => typeof valueOfEnvConfig === 'string' &&
|
|
220
|
+
// Using `{regex}.test()` might cause false positives if called multiple
|
|
221
|
+
// times on a global regular expression:
|
|
222
|
+
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test
|
|
223
|
+
// As with exec() (or in combination with it), test() called multiple times
|
|
224
|
+
// on the same global regular expression instance will advance past the previous match.
|
|
225
|
+
Boolean(valueOfEnvConfig.match(variableSyntax));
|
|
226
|
+
const isEnvVariablePlaceholder = valueOfPlaceholder => Boolean(valueOfPlaceholder.match(envRefSyntax));
|
|
227
|
+
const isIntlVariablePlaceholder = valueOfPlaceholder => Boolean(valueOfPlaceholder.match(intlRefSyntax));
|
|
228
|
+
const isFilePathVariablePlaceholder = valueOfPlaceholder => Boolean(valueOfPlaceholder.match(filePathRefSyntax));
|
|
229
|
+
const isStructuredJson = message => message?.string !== undefined;
|
|
230
|
+
const substituteEnvVariablePlaceholder = (valueOfPlaceholder, matchedString, valueOfEnvConfig, loadingOptions) => {
|
|
231
|
+
const _valueOfPlaceholder$s = valueOfPlaceholder.split(':'),
|
|
232
|
+
_valueOfPlaceholder$s2 = _slicedToArray(_valueOfPlaceholder$s, 2),
|
|
233
|
+
requestedEnvVar = _valueOfPlaceholder$s2[1];
|
|
234
|
+
const hasEnvField = loadingOptions.processEnv.hasOwnProperty(requestedEnvVar);
|
|
235
|
+
if (!hasEnvField) {
|
|
236
|
+
throw new Error(`Missing environment variable '${requestedEnvVar}' specified in config as 'env:${requestedEnvVar}'.`);
|
|
237
|
+
}
|
|
238
|
+
const escapedMatchedString = matchedString.replace(/[${}:]/g, '\\$&');
|
|
239
|
+
return valueOfEnvConfig.replace(new RegExp(`(${escapedMatchedString})+`, 'g'), loadingOptions.processEnv[requestedEnvVar]);
|
|
240
|
+
};
|
|
241
|
+
const substituteIntlVariablePlaceholder = (valueOfPlaceholder, matchedString, valueOfEnvConfig, loadingOptions) => {
|
|
242
|
+
const _valueOfPlaceholder$s3 = valueOfPlaceholder.split(':'),
|
|
243
|
+
_valueOfPlaceholder$s4 = _slicedToArray(_valueOfPlaceholder$s3, 3),
|
|
244
|
+
locale = _valueOfPlaceholder$s4[1],
|
|
245
|
+
requestedIntlMessageId = _valueOfPlaceholder$s4[2];
|
|
246
|
+
const translationsFilePath = require.resolve(`./i18n/data/${locale}.json`, {
|
|
247
|
+
paths: [`${loadingOptions.applicationPath}/src`, loadingOptions.applicationPath]
|
|
248
|
+
});
|
|
249
|
+
const translations = require(translationsFilePath);
|
|
250
|
+
const hasIntlMessage = translations.hasOwnProperty(requestedIntlMessageId);
|
|
251
|
+
if (!hasIntlMessage) {
|
|
252
|
+
throw new Error(`Missing message key '${requestedIntlMessageId}' specified in config as 'intl:${locale}:${requestedIntlMessageId}'.`);
|
|
253
|
+
}
|
|
254
|
+
const translation = translations[requestedIntlMessageId];
|
|
255
|
+
const translationValue = isStructuredJson(translation) ? translation.string : translation;
|
|
256
|
+
const escapedMatchedString = matchedString.replace(/[${}:]/g, '\\$&');
|
|
257
|
+
return valueOfEnvConfig.replace(new RegExp(`(${escapedMatchedString})+`, 'g'), translationValue);
|
|
258
|
+
};
|
|
259
|
+
const substituteFilePathVariablePlaceholder = (valueOfPlaceholder, matchedString, valueOfEnvConfig, loadingOptions) => {
|
|
260
|
+
const _valueOfPlaceholder$s5 = valueOfPlaceholder.split(':'),
|
|
261
|
+
_valueOfPlaceholder$s6 = _slicedToArray(_valueOfPlaceholder$s5, 2),
|
|
262
|
+
filePathOrModule = _valueOfPlaceholder$s6[1];
|
|
263
|
+
const content = fs__default$1["default"].readFileSync(require.resolve(filePathOrModule, {
|
|
264
|
+
// Relative paths should be resolved from the application folder.
|
|
265
|
+
paths: [loadingOptions.applicationPath]
|
|
266
|
+
}), {
|
|
267
|
+
encoding: 'utf-8'
|
|
268
|
+
});
|
|
269
|
+
const escapedMatchedString = matchedString.replace(/[${}:]/g, '\\$&');
|
|
270
|
+
return valueOfEnvConfig.replace(new RegExp(`(${escapedMatchedString})+`, 'g'), content);
|
|
271
|
+
};
|
|
272
|
+
const getValueOfPlaceholder = valueWithPlaceholder => valueWithPlaceholder.replace(variableSyntax, (_match, varName) => _trimInstanceProperty__default["default"](varName).call(varName)).replace(/\s/g, '');
|
|
273
|
+
const substituteVariablePlaceholders = (config, loadingOptions) => JSON.parse(_JSON$stringify__default["default"](config), (_key, value) => {
|
|
274
|
+
// Only strings are allowed
|
|
275
|
+
let substitutedValue = value;
|
|
276
|
+
if (hasVariablePlaceholder(substitutedValue)) {
|
|
277
|
+
const matchResult = substitutedValue.match(variableSyntax);
|
|
278
|
+
if (matchResult) {
|
|
279
|
+
_forEachInstanceProperty__default["default"](matchResult).call(matchResult, matchedString => {
|
|
280
|
+
const valueOfPlaceholder = getValueOfPlaceholder(matchedString);
|
|
281
|
+
if (isEnvVariablePlaceholder(valueOfPlaceholder)) {
|
|
282
|
+
substitutedValue = substituteEnvVariablePlaceholder(valueOfPlaceholder, matchedString, substitutedValue, loadingOptions);
|
|
283
|
+
} else if (isIntlVariablePlaceholder(valueOfPlaceholder)) {
|
|
284
|
+
substitutedValue = substituteIntlVariablePlaceholder(valueOfPlaceholder, matchedString, substitutedValue, loadingOptions);
|
|
285
|
+
} else if (isFilePathVariablePlaceholder(valueOfPlaceholder)) {
|
|
286
|
+
substitutedValue = substituteFilePathVariablePlaceholder(valueOfPlaceholder, matchedString, substitutedValue, loadingOptions);
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return substitutedValue;
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
var customApplicationSchemaJson = {
|
|
295
|
+
$schema: "http://json-schema.org/draft-07/schema",
|
|
296
|
+
$id: "https://docs.commercetools.com/merchant-center-customizations/custom-application.schema.json",
|
|
297
|
+
title: "JSON schema for Custom Application configuration files",
|
|
298
|
+
type: "object",
|
|
299
|
+
definitions: {
|
|
300
|
+
cspDirective: {
|
|
301
|
+
type: "array",
|
|
302
|
+
items: {
|
|
303
|
+
type: "string"
|
|
304
|
+
},
|
|
305
|
+
uniqueItems: true
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
properties: {
|
|
309
|
+
name: {
|
|
310
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#name",
|
|
311
|
+
type: "string"
|
|
312
|
+
},
|
|
313
|
+
description: {
|
|
314
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#description",
|
|
315
|
+
type: "string"
|
|
316
|
+
},
|
|
317
|
+
entryPointUriPath: {
|
|
318
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#entrypointuripath",
|
|
319
|
+
type: "string"
|
|
320
|
+
},
|
|
321
|
+
cloudIdentifier: {
|
|
322
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#cloudidentifier",
|
|
323
|
+
type: "string"
|
|
324
|
+
},
|
|
325
|
+
mcApiUrl: {
|
|
326
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#mcapiurl",
|
|
327
|
+
type: "string"
|
|
328
|
+
},
|
|
329
|
+
oAuthScopes: {
|
|
330
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#oauthscopes",
|
|
331
|
+
type: "object",
|
|
332
|
+
properties: {
|
|
333
|
+
view: {
|
|
334
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#oauthscopesview",
|
|
335
|
+
type: "array",
|
|
336
|
+
"default": [
|
|
337
|
+
],
|
|
338
|
+
items: {
|
|
339
|
+
type: "string",
|
|
340
|
+
pattern: "view_(.*)"
|
|
341
|
+
},
|
|
342
|
+
uniqueItems: true
|
|
343
|
+
},
|
|
344
|
+
manage: {
|
|
345
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#oauthscopesmanage",
|
|
346
|
+
type: "array",
|
|
347
|
+
"default": [
|
|
348
|
+
],
|
|
349
|
+
items: {
|
|
350
|
+
type: "string",
|
|
351
|
+
pattern: "manage_(.*)"
|
|
352
|
+
},
|
|
353
|
+
uniqueItems: true
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
additionalProperties: false,
|
|
357
|
+
required: [
|
|
358
|
+
"view",
|
|
359
|
+
"manage"
|
|
360
|
+
]
|
|
361
|
+
},
|
|
362
|
+
additionalOAuthScopes: {
|
|
363
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#additionaloauthscopes",
|
|
364
|
+
type: "array",
|
|
365
|
+
"default": [
|
|
366
|
+
],
|
|
367
|
+
uniqueItems: true,
|
|
368
|
+
items: {
|
|
369
|
+
type: "object",
|
|
370
|
+
properties: {
|
|
371
|
+
name: {
|
|
372
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#additionaloauthscopesname",
|
|
373
|
+
type: "string"
|
|
374
|
+
},
|
|
375
|
+
view: {
|
|
376
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#additionaloauthscopesview",
|
|
377
|
+
type: "array",
|
|
378
|
+
"default": [
|
|
379
|
+
],
|
|
380
|
+
items: {
|
|
381
|
+
type: "string",
|
|
382
|
+
pattern: "view_(.*)"
|
|
383
|
+
},
|
|
384
|
+
uniqueItems: true
|
|
385
|
+
},
|
|
386
|
+
manage: {
|
|
387
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#additionaloauthscopesmanage",
|
|
388
|
+
type: "array",
|
|
389
|
+
"default": [
|
|
390
|
+
],
|
|
391
|
+
items: {
|
|
392
|
+
type: "string",
|
|
393
|
+
pattern: "manage_(.*)"
|
|
394
|
+
},
|
|
395
|
+
uniqueItems: true
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
additionalProperties: false,
|
|
399
|
+
required: [
|
|
400
|
+
"name",
|
|
401
|
+
"view",
|
|
402
|
+
"manage"
|
|
403
|
+
]
|
|
404
|
+
}
|
|
405
|
+
},
|
|
406
|
+
env: {
|
|
407
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#env",
|
|
408
|
+
type: "object",
|
|
409
|
+
properties: {
|
|
410
|
+
development: {
|
|
411
|
+
type: "object",
|
|
412
|
+
properties: {
|
|
413
|
+
initialProjectKey: {
|
|
414
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#envdevelopmentinitialprojectkey",
|
|
415
|
+
type: "string"
|
|
416
|
+
},
|
|
417
|
+
teamId: {
|
|
418
|
+
type: "string"
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
additionalProperties: false,
|
|
422
|
+
required: [
|
|
423
|
+
"initialProjectKey"
|
|
424
|
+
]
|
|
425
|
+
},
|
|
426
|
+
production: {
|
|
427
|
+
type: "object",
|
|
428
|
+
properties: {
|
|
429
|
+
applicationId: {
|
|
430
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#envproductionapplicationid",
|
|
431
|
+
type: "string"
|
|
432
|
+
},
|
|
433
|
+
url: {
|
|
434
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#envproductionurl",
|
|
435
|
+
type: "string"
|
|
436
|
+
},
|
|
437
|
+
cdnUrl: {
|
|
438
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#envproductioncdnurl",
|
|
439
|
+
type: "string"
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
additionalProperties: false,
|
|
443
|
+
required: [
|
|
444
|
+
"applicationId",
|
|
445
|
+
"url"
|
|
446
|
+
]
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
additionalProperties: false,
|
|
450
|
+
required: [
|
|
451
|
+
"development",
|
|
452
|
+
"production"
|
|
453
|
+
]
|
|
454
|
+
},
|
|
455
|
+
additionalEnv: {
|
|
456
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#additionalenv",
|
|
457
|
+
type: "object"
|
|
458
|
+
},
|
|
459
|
+
headers: {
|
|
460
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#headers",
|
|
461
|
+
type: "object",
|
|
462
|
+
properties: {
|
|
463
|
+
csp: {
|
|
464
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#headerscsp",
|
|
465
|
+
type: "object",
|
|
466
|
+
properties: {
|
|
467
|
+
"connect-src": {
|
|
468
|
+
$ref: "#/definitions/cspDirective"
|
|
469
|
+
},
|
|
470
|
+
"font-src": {
|
|
471
|
+
$ref: "#/definitions/cspDirective"
|
|
472
|
+
},
|
|
473
|
+
"img-src": {
|
|
474
|
+
$ref: "#/definitions/cspDirective"
|
|
475
|
+
},
|
|
476
|
+
"script-src": {
|
|
477
|
+
$ref: "#/definitions/cspDirective"
|
|
478
|
+
},
|
|
479
|
+
"style-src": {
|
|
480
|
+
$ref: "#/definitions/cspDirective"
|
|
481
|
+
},
|
|
482
|
+
"frame-src": {
|
|
483
|
+
$ref: "#/definitions/cspDirective"
|
|
484
|
+
},
|
|
485
|
+
"media-src": {
|
|
486
|
+
$ref: "#/definitions/cspDirective"
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
additionalProperties: false,
|
|
490
|
+
required: [
|
|
491
|
+
"connect-src"
|
|
492
|
+
]
|
|
493
|
+
},
|
|
494
|
+
permissionsPolicies: {
|
|
495
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#headerspermissionspolicies",
|
|
496
|
+
type: "object"
|
|
497
|
+
},
|
|
498
|
+
strictTransportSecurity: {
|
|
499
|
+
type: "array",
|
|
500
|
+
items: {
|
|
501
|
+
"enum": [
|
|
502
|
+
"includeSubDomains",
|
|
503
|
+
"preload"
|
|
504
|
+
]
|
|
505
|
+
},
|
|
506
|
+
uniqueItems: true,
|
|
507
|
+
deprecated: true
|
|
508
|
+
}
|
|
509
|
+
},
|
|
510
|
+
additionalProperties: false
|
|
511
|
+
},
|
|
512
|
+
icon: {
|
|
513
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#icon",
|
|
514
|
+
type: "string"
|
|
515
|
+
},
|
|
516
|
+
mainMenuLink: {
|
|
517
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#mainmenulink",
|
|
518
|
+
type: "object",
|
|
519
|
+
properties: {
|
|
520
|
+
defaultLabel: {
|
|
521
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#mainmenulinkdefaultlabel",
|
|
522
|
+
type: "string"
|
|
523
|
+
},
|
|
524
|
+
labelAllLocales: {
|
|
525
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#mainmenulinklabelalllocales",
|
|
526
|
+
type: "array",
|
|
527
|
+
"default": [
|
|
528
|
+
],
|
|
529
|
+
items: {
|
|
530
|
+
type: "object",
|
|
531
|
+
properties: {
|
|
532
|
+
locale: {
|
|
533
|
+
type: "string",
|
|
534
|
+
"enum": [
|
|
535
|
+
"en",
|
|
536
|
+
"de",
|
|
537
|
+
"es",
|
|
538
|
+
"fr-FR",
|
|
539
|
+
"pt-BR"
|
|
540
|
+
]
|
|
541
|
+
},
|
|
542
|
+
value: {
|
|
543
|
+
type: "string"
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
additionalProperties: false,
|
|
547
|
+
required: [
|
|
548
|
+
"locale",
|
|
549
|
+
"value"
|
|
550
|
+
]
|
|
551
|
+
}
|
|
552
|
+
},
|
|
553
|
+
permissions: {
|
|
554
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#mainmenulinkpermissions",
|
|
555
|
+
type: "array",
|
|
556
|
+
"default": [
|
|
557
|
+
],
|
|
558
|
+
items: {
|
|
559
|
+
type: "string"
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
},
|
|
563
|
+
additionalProperties: true,
|
|
564
|
+
required: [
|
|
565
|
+
"defaultLabel",
|
|
566
|
+
"labelAllLocales",
|
|
567
|
+
"permissions"
|
|
568
|
+
]
|
|
569
|
+
},
|
|
570
|
+
submenuLinks: {
|
|
571
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#submenulinks",
|
|
572
|
+
"default": [
|
|
573
|
+
],
|
|
574
|
+
type: "array",
|
|
575
|
+
items: {
|
|
576
|
+
type: "object",
|
|
577
|
+
properties: {
|
|
578
|
+
uriPath: {
|
|
579
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#submenulinksuripath",
|
|
580
|
+
type: "string"
|
|
581
|
+
},
|
|
582
|
+
defaultLabel: {
|
|
583
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#submenulinksdefaultlabel",
|
|
584
|
+
type: "string"
|
|
585
|
+
},
|
|
586
|
+
labelAllLocales: {
|
|
587
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#submenulinkslabelalllocales",
|
|
588
|
+
type: "array",
|
|
589
|
+
"default": [
|
|
590
|
+
],
|
|
591
|
+
items: {
|
|
592
|
+
type: "object",
|
|
593
|
+
properties: {
|
|
594
|
+
locale: {
|
|
595
|
+
type: "string",
|
|
596
|
+
"enum": [
|
|
597
|
+
"en",
|
|
598
|
+
"de",
|
|
599
|
+
"es",
|
|
600
|
+
"fr-FR",
|
|
601
|
+
"pt-BR"
|
|
602
|
+
]
|
|
603
|
+
},
|
|
604
|
+
value: {
|
|
605
|
+
type: "string"
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
additionalProperties: false,
|
|
609
|
+
required: [
|
|
610
|
+
"locale",
|
|
611
|
+
"value"
|
|
612
|
+
]
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
permissions: {
|
|
616
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-application-config#submenulinkspermissions",
|
|
617
|
+
type: "array",
|
|
618
|
+
"default": [
|
|
619
|
+
],
|
|
620
|
+
items: {
|
|
621
|
+
type: "string"
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
},
|
|
625
|
+
additionalProperties: true,
|
|
626
|
+
required: [
|
|
627
|
+
"uriPath",
|
|
628
|
+
"defaultLabel",
|
|
629
|
+
"labelAllLocales",
|
|
630
|
+
"permissions"
|
|
631
|
+
]
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
additionalProperties: true,
|
|
636
|
+
required: [
|
|
637
|
+
"name",
|
|
638
|
+
"entryPointUriPath",
|
|
639
|
+
"cloudIdentifier",
|
|
640
|
+
"env",
|
|
641
|
+
"oAuthScopes",
|
|
642
|
+
"icon",
|
|
643
|
+
"mainMenuLink",
|
|
644
|
+
"submenuLinks"
|
|
645
|
+
]
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
var customViewSchemaJson = {
|
|
649
|
+
$schema: "http://json-schema.org/draft-07/schema",
|
|
650
|
+
$id: "https://docs.commercetools.com/merchant-center-customizations/custom-view.schema.json",
|
|
651
|
+
title: "JSON schema for Custom View configuration files",
|
|
652
|
+
type: "object",
|
|
653
|
+
definitions: {
|
|
654
|
+
cspDirective: {
|
|
655
|
+
type: "array",
|
|
656
|
+
items: {
|
|
657
|
+
type: "string"
|
|
658
|
+
},
|
|
659
|
+
uniqueItems: true
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
properties: {
|
|
663
|
+
name: {
|
|
664
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#name",
|
|
665
|
+
type: "string"
|
|
666
|
+
},
|
|
667
|
+
description: {
|
|
668
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#description",
|
|
669
|
+
type: "string"
|
|
670
|
+
},
|
|
671
|
+
cloudIdentifier: {
|
|
672
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#cloudidentifier",
|
|
673
|
+
type: "string"
|
|
674
|
+
},
|
|
675
|
+
mcApiUrl: {
|
|
676
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#mcapiurl",
|
|
677
|
+
type: "string"
|
|
678
|
+
},
|
|
679
|
+
oAuthScopes: {
|
|
680
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#oauthscopes",
|
|
681
|
+
type: "object",
|
|
682
|
+
properties: {
|
|
683
|
+
view: {
|
|
684
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#oauthscopesview",
|
|
685
|
+
type: "array",
|
|
686
|
+
"default": [
|
|
687
|
+
],
|
|
688
|
+
items: {
|
|
689
|
+
type: "string",
|
|
690
|
+
pattern: "view_(.*)"
|
|
691
|
+
},
|
|
692
|
+
uniqueItems: true
|
|
693
|
+
},
|
|
694
|
+
manage: {
|
|
695
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#oauthscopesmanage",
|
|
696
|
+
type: "array",
|
|
697
|
+
"default": [
|
|
698
|
+
],
|
|
699
|
+
items: {
|
|
700
|
+
type: "string",
|
|
701
|
+
pattern: "manage_(.*)"
|
|
702
|
+
},
|
|
703
|
+
uniqueItems: true
|
|
704
|
+
}
|
|
705
|
+
},
|
|
706
|
+
additionalProperties: false,
|
|
707
|
+
required: [
|
|
708
|
+
"view",
|
|
709
|
+
"manage"
|
|
710
|
+
]
|
|
711
|
+
},
|
|
712
|
+
additionalOAuthScopes: {
|
|
713
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#additionaloauthscopes",
|
|
714
|
+
type: "array",
|
|
715
|
+
"default": [
|
|
716
|
+
],
|
|
717
|
+
uniqueItems: true,
|
|
718
|
+
items: {
|
|
719
|
+
type: "object",
|
|
720
|
+
properties: {
|
|
721
|
+
name: {
|
|
722
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#additionaloauthscopesname",
|
|
723
|
+
type: "string"
|
|
724
|
+
},
|
|
725
|
+
view: {
|
|
726
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#additionaloauthscopesview",
|
|
727
|
+
type: "array",
|
|
728
|
+
"default": [
|
|
729
|
+
],
|
|
730
|
+
items: {
|
|
731
|
+
type: "string",
|
|
732
|
+
pattern: "view_(.*)"
|
|
733
|
+
},
|
|
734
|
+
uniqueItems: true
|
|
735
|
+
},
|
|
736
|
+
manage: {
|
|
737
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#additionaloauthscopesmanage",
|
|
738
|
+
type: "array",
|
|
739
|
+
"default": [
|
|
740
|
+
],
|
|
741
|
+
items: {
|
|
742
|
+
type: "string",
|
|
743
|
+
pattern: "manage_(.*)"
|
|
744
|
+
},
|
|
745
|
+
uniqueItems: true
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
additionalProperties: false,
|
|
749
|
+
required: [
|
|
750
|
+
"name",
|
|
751
|
+
"view",
|
|
752
|
+
"manage"
|
|
753
|
+
]
|
|
754
|
+
}
|
|
755
|
+
},
|
|
756
|
+
env: {
|
|
757
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#env",
|
|
758
|
+
type: "object",
|
|
759
|
+
properties: {
|
|
760
|
+
development: {
|
|
761
|
+
type: "object",
|
|
762
|
+
properties: {
|
|
763
|
+
initialProjectKey: {
|
|
764
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#envdevelopmentinitialprojectkey",
|
|
765
|
+
type: "string"
|
|
766
|
+
},
|
|
767
|
+
teamId: {
|
|
768
|
+
type: "string"
|
|
769
|
+
},
|
|
770
|
+
hostUriPath: {
|
|
771
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#envdevelopmenthosturipath",
|
|
772
|
+
type: "string"
|
|
773
|
+
}
|
|
774
|
+
},
|
|
775
|
+
additionalProperties: false,
|
|
776
|
+
required: [
|
|
777
|
+
"initialProjectKey"
|
|
778
|
+
]
|
|
779
|
+
},
|
|
780
|
+
production: {
|
|
781
|
+
type: "object",
|
|
782
|
+
properties: {
|
|
783
|
+
customViewId: {
|
|
784
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#envproductioncustomviewid",
|
|
785
|
+
type: "string"
|
|
786
|
+
},
|
|
787
|
+
url: {
|
|
788
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#envproductionurl",
|
|
789
|
+
type: "string"
|
|
790
|
+
},
|
|
791
|
+
cdnUrl: {
|
|
792
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#envproductioncdnurl",
|
|
793
|
+
type: "string"
|
|
794
|
+
}
|
|
795
|
+
},
|
|
796
|
+
additionalProperties: false,
|
|
797
|
+
required: [
|
|
798
|
+
"customViewId",
|
|
799
|
+
"url"
|
|
800
|
+
]
|
|
801
|
+
}
|
|
802
|
+
},
|
|
803
|
+
additionalProperties: false,
|
|
804
|
+
required: [
|
|
805
|
+
"development",
|
|
806
|
+
"production"
|
|
807
|
+
]
|
|
808
|
+
},
|
|
809
|
+
additionalEnv: {
|
|
810
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#additionalenv",
|
|
811
|
+
type: "object"
|
|
812
|
+
},
|
|
813
|
+
headers: {
|
|
814
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#headers",
|
|
815
|
+
type: "object",
|
|
816
|
+
properties: {
|
|
817
|
+
csp: {
|
|
818
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#headerscsp",
|
|
819
|
+
type: "object",
|
|
820
|
+
properties: {
|
|
821
|
+
"connect-src": {
|
|
822
|
+
$ref: "#/definitions/cspDirective"
|
|
823
|
+
},
|
|
824
|
+
"font-src": {
|
|
825
|
+
$ref: "#/definitions/cspDirective"
|
|
826
|
+
},
|
|
827
|
+
"img-src": {
|
|
828
|
+
$ref: "#/definitions/cspDirective"
|
|
829
|
+
},
|
|
830
|
+
"script-src": {
|
|
831
|
+
$ref: "#/definitions/cspDirective"
|
|
832
|
+
},
|
|
833
|
+
"style-src": {
|
|
834
|
+
$ref: "#/definitions/cspDirective"
|
|
835
|
+
},
|
|
836
|
+
"frame-src": {
|
|
837
|
+
$ref: "#/definitions/cspDirective"
|
|
838
|
+
},
|
|
839
|
+
"media-src": {
|
|
840
|
+
$ref: "#/definitions/cspDirective"
|
|
841
|
+
}
|
|
842
|
+
},
|
|
843
|
+
additionalProperties: false,
|
|
844
|
+
required: [
|
|
845
|
+
"connect-src"
|
|
846
|
+
]
|
|
847
|
+
},
|
|
848
|
+
permissionsPolicies: {
|
|
849
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#headerspermissionspolicies",
|
|
850
|
+
type: "object"
|
|
851
|
+
},
|
|
852
|
+
strictTransportSecurity: {
|
|
853
|
+
type: "array",
|
|
854
|
+
items: {
|
|
855
|
+
"enum": [
|
|
856
|
+
"includeSubDomains",
|
|
857
|
+
"preload"
|
|
858
|
+
]
|
|
859
|
+
},
|
|
860
|
+
uniqueItems: true,
|
|
861
|
+
deprecated: true
|
|
862
|
+
}
|
|
863
|
+
},
|
|
864
|
+
additionalProperties: false
|
|
865
|
+
},
|
|
866
|
+
labelAllLocales: {
|
|
867
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#labelalllocales",
|
|
868
|
+
type: "array",
|
|
869
|
+
"default": [
|
|
870
|
+
],
|
|
871
|
+
items: {
|
|
872
|
+
type: "object",
|
|
873
|
+
properties: {
|
|
874
|
+
locale: {
|
|
875
|
+
type: "string",
|
|
876
|
+
"enum": [
|
|
877
|
+
"en",
|
|
878
|
+
"de",
|
|
879
|
+
"es",
|
|
880
|
+
"fr-FR",
|
|
881
|
+
"pt-BR"
|
|
882
|
+
]
|
|
883
|
+
},
|
|
884
|
+
value: {
|
|
885
|
+
type: "string"
|
|
886
|
+
}
|
|
887
|
+
},
|
|
888
|
+
additionalProperties: false,
|
|
889
|
+
required: [
|
|
890
|
+
"locale",
|
|
891
|
+
"value"
|
|
892
|
+
]
|
|
893
|
+
}
|
|
894
|
+
},
|
|
895
|
+
type: {
|
|
896
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#type",
|
|
897
|
+
type: "string",
|
|
898
|
+
"enum": [
|
|
899
|
+
"CustomPanel"
|
|
900
|
+
]
|
|
901
|
+
},
|
|
902
|
+
typeSettings: {
|
|
903
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#typesettings",
|
|
904
|
+
type: "object",
|
|
905
|
+
properties: {
|
|
906
|
+
size: {
|
|
907
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#typesettingssize",
|
|
908
|
+
type: "string",
|
|
909
|
+
"enum": [
|
|
910
|
+
"SMALL",
|
|
911
|
+
"LARGE"
|
|
912
|
+
]
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
},
|
|
916
|
+
locators: {
|
|
917
|
+
description: "See https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/custom-view-config#locators",
|
|
918
|
+
type: "array",
|
|
919
|
+
"default": [
|
|
920
|
+
],
|
|
921
|
+
items: {
|
|
922
|
+
type: "string"
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
},
|
|
926
|
+
additionalProperties: true,
|
|
927
|
+
required: [
|
|
928
|
+
"name",
|
|
929
|
+
"cloudIdentifier",
|
|
930
|
+
"env",
|
|
931
|
+
"oAuthScopes",
|
|
932
|
+
"labelAllLocales",
|
|
933
|
+
"type",
|
|
934
|
+
"locators"
|
|
935
|
+
]
|
|
936
|
+
};
|
|
937
|
+
|
|
938
|
+
const ajv = new Ajv__default["default"]({
|
|
939
|
+
strict: true,
|
|
940
|
+
useDefaults: true
|
|
941
|
+
});
|
|
942
|
+
const validateCustomApplicationConfig = ajv.compile(customApplicationSchemaJson);
|
|
943
|
+
const validateCustomViewConfig = ajv.compile(customViewSchemaJson);
|
|
944
|
+
const printErrors = errors => {
|
|
945
|
+
if (!errors) {
|
|
946
|
+
return 'No errors';
|
|
947
|
+
}
|
|
948
|
+
return _mapInstanceProperty__default["default"](errors).call(errors, error => {
|
|
949
|
+
const baseMessage = `${error.instancePath} ${error.message}`;
|
|
950
|
+
switch (error.keyword) {
|
|
951
|
+
case 'additionalProperties':
|
|
952
|
+
return `${baseMessage}: ${error.params.additionalProperty}`;
|
|
953
|
+
case 'enum':
|
|
954
|
+
return `${baseMessage}: ${error.params.allowedValues.toString()}`;
|
|
955
|
+
default:
|
|
956
|
+
return baseMessage;
|
|
957
|
+
}
|
|
958
|
+
}).join('\n');
|
|
959
|
+
};
|
|
960
|
+
const validateConfig = (configType, config) => {
|
|
961
|
+
let validation;
|
|
962
|
+
if (configType === LOADED_CONFIG_TYPES.CUSTOM_APPLICATION) {
|
|
963
|
+
validation = validateCustomApplicationConfig;
|
|
964
|
+
} else if (configType === LOADED_CONFIG_TYPES.CUSTOM_VIEW) {
|
|
965
|
+
validation = validateCustomViewConfig;
|
|
966
|
+
} else {
|
|
967
|
+
throw new Error(`Invalid config type "${configType}", expected ${_Object$keys__default["default"](LOADED_CONFIG_TYPES).toString()}`);
|
|
968
|
+
}
|
|
969
|
+
const isValid = validation(config);
|
|
970
|
+
if (!isValid) {
|
|
971
|
+
throw new Error(printErrors(validation.errors));
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
const validateEntryPointUriPath = config => {
|
|
975
|
+
if (!config.entryPointUriPath.match(constants.ENTRY_POINT_URI_PATH_REGEX)) {
|
|
976
|
+
throw new Error('Invalid "entryPointUriPath". The value may be between 2 and 64 characters and only contain alphanumeric lowercase characters, non-consecutive underscores and hyphens. Leading and trailing underscores and hyphens are also not allowed.');
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
const validateSubmenuLinks = config => {
|
|
980
|
+
var _context;
|
|
981
|
+
const uriPathSet = new _Set__default["default"]();
|
|
982
|
+
_forEachInstanceProperty__default["default"](_context = config.submenuLinks).call(_context, _ref => {
|
|
983
|
+
let uriPath = _ref.uriPath;
|
|
984
|
+
if (uriPathSet.has(uriPath)) {
|
|
985
|
+
throw new Error('Duplicate URI path. Every submenu link must have a unique URI path value');
|
|
986
|
+
}
|
|
987
|
+
uriPathSet.add(uriPath);
|
|
988
|
+
});
|
|
989
|
+
};
|
|
990
|
+
const validateAdditionalOAuthScopes = config => {
|
|
991
|
+
const additionalPermissionNames = new _Set__default["default"]();
|
|
992
|
+
config.additionalOAuthScopes?.forEach(_ref2 => {
|
|
993
|
+
let name = _ref2.name,
|
|
994
|
+
view = _ref2.view,
|
|
995
|
+
manage = _ref2.manage;
|
|
996
|
+
if ((_Array$isArray__default["default"](view) && view.length === 0 || !view) && (_Array$isArray__default["default"](manage) && manage.length === 0 || !manage)) {
|
|
997
|
+
throw new Error(`At least one OAuth Scope for permission group name "${name}" is required`);
|
|
998
|
+
} else if (additionalPermissionNames.has(name)) {
|
|
999
|
+
throw new Error(`Duplicate additional permission group name "${name}". Every additional permission must have a unique name`);
|
|
1000
|
+
}
|
|
1001
|
+
if (!name.match(constants.PERMISSION_GROUP_NAME_REGEX)) {
|
|
1002
|
+
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`);
|
|
1003
|
+
}
|
|
1004
|
+
additionalPermissionNames.add(name);
|
|
1005
|
+
});
|
|
1006
|
+
};
|
|
1007
|
+
|
|
1008
|
+
function ownKeys$1(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
1009
|
+
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__default["default"](_context4 = ownKeys$1(Object(t), !0)).call(_context4, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context5 = ownKeys$1(Object(t))).call(_context5, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
|
|
1010
|
+
|
|
1011
|
+
// The `uriPath` of each submenu link is supposed to be defined relative
|
|
1012
|
+
// to the `entryPointUriPath`. Computing the full path is done internally to keep
|
|
1013
|
+
// the configuration simple.
|
|
1014
|
+
const computeUriPath = (uriPath, entryPointUriPath) => {
|
|
1015
|
+
// In case the `uriPath` is only `/`, it means that the link is supposed to be
|
|
1016
|
+
// treated the same as the main application path. In this case, the return value
|
|
1017
|
+
// should not contain any unnecessary trailing slash and therefore we use the `entryPointUriPath`.
|
|
1018
|
+
if (uriPath === '/') return entryPointUriPath;
|
|
1019
|
+
// In case the `uriPath` is already configured including the `entryPointUriPath`,
|
|
1020
|
+
// we return the `uriPath` as-is.
|
|
1021
|
+
if (_startsWithInstanceProperty__default["default"](uriPath).call(uriPath, `${entryPointUriPath}/`)) return uriPath;
|
|
1022
|
+
// Return the full path including the `entryPointUriPath` as a prefix.
|
|
1023
|
+
return `${entryPointUriPath}/${uriPath}`;
|
|
1024
|
+
};
|
|
1025
|
+
const getPermissions = appConfig => {
|
|
1026
|
+
var _context, _context2;
|
|
1027
|
+
const additionalResourceAccessKeyToOauthScopeMap = _reduceInstanceProperty__default["default"](_context = appConfig.additionalOAuthScopes || []).call(_context, (previousOauthScope, _ref) => {
|
|
1028
|
+
let name = _ref.name,
|
|
1029
|
+
view = _ref.view,
|
|
1030
|
+
manage = _ref.manage;
|
|
1031
|
+
const formattedResourceKey = formatters.formatEntryPointUriPathToResourceAccessKey(name);
|
|
1032
|
+
return _objectSpread$1(_objectSpread$1({}, previousOauthScope), {}, {
|
|
1033
|
+
[`view${formattedResourceKey}`]: view,
|
|
1034
|
+
[`manage${formattedResourceKey}`]: manage
|
|
1035
|
+
});
|
|
1036
|
+
}, {});
|
|
1037
|
+
const additionalPermissionNames = appConfig.additionalOAuthScopes?.map(_ref2 => {
|
|
1038
|
+
let name = _ref2.name;
|
|
1039
|
+
return name;
|
|
1040
|
+
}) || [];
|
|
1041
|
+
const permissionKeys = formatters.entryPointUriPathToResourceAccesses(appConfig.entryPointUriPath ||
|
|
1042
|
+
// In case the `entryPointUriPath` is not defined it is because the
|
|
1043
|
+
// configuration is for a custom view. In this case we use the
|
|
1044
|
+
// default entry point uri path.
|
|
1045
|
+
constants.CUSTOM_VIEW_HOST_ENTRY_POINT_URI_PATH, additionalPermissionNames);
|
|
1046
|
+
const additionalPermissions = _mapInstanceProperty__default["default"](_context2 = _Object$keys__default["default"](additionalResourceAccessKeyToOauthScopeMap)).call(_context2, additionalResourceAccessKey => ({
|
|
1047
|
+
name: permissionKeys[additionalResourceAccessKey],
|
|
1048
|
+
oAuthScopes: additionalResourceAccessKeyToOauthScopeMap[additionalResourceAccessKey]
|
|
1049
|
+
}));
|
|
1050
|
+
return [{
|
|
1051
|
+
name: permissionKeys.view,
|
|
1052
|
+
oAuthScopes: appConfig.oAuthScopes.view
|
|
1053
|
+
}, {
|
|
1054
|
+
name: permissionKeys.manage,
|
|
1055
|
+
oAuthScopes: appConfig.oAuthScopes.manage
|
|
1056
|
+
}, ...additionalPermissions];
|
|
1057
|
+
};
|
|
1058
|
+
function transformCustomApplicationConfigToData(appConfig) {
|
|
1059
|
+
var _context3;
|
|
1060
|
+
validateEntryPointUriPath(appConfig);
|
|
1061
|
+
validateSubmenuLinks(appConfig);
|
|
1062
|
+
validateAdditionalOAuthScopes(appConfig);
|
|
1063
|
+
return {
|
|
1064
|
+
id: appConfig.env.production.applicationId,
|
|
1065
|
+
name: appConfig.name,
|
|
1066
|
+
description: appConfig.description,
|
|
1067
|
+
entryPointUriPath: appConfig.entryPointUriPath,
|
|
1068
|
+
url: appConfig.env.production.url,
|
|
1069
|
+
permissions: getPermissions(appConfig),
|
|
1070
|
+
icon: appConfig.icon,
|
|
1071
|
+
mainMenuLink: appConfig.mainMenuLink,
|
|
1072
|
+
submenuLinks: _mapInstanceProperty__default["default"](_context3 = appConfig.submenuLinks).call(_context3, submenuLink => _objectSpread$1(_objectSpread$1({}, submenuLink), {}, {
|
|
1073
|
+
uriPath: computeUriPath(submenuLink.uriPath, appConfig.entryPointUriPath)
|
|
1074
|
+
}))
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
function transformCustomViewConfigToData(customViewConfig) {
|
|
1078
|
+
validateAdditionalOAuthScopes(customViewConfig);
|
|
1079
|
+
return {
|
|
1080
|
+
id: customViewConfig.env.production.customViewId,
|
|
1081
|
+
defaultLabel: customViewConfig.name,
|
|
1082
|
+
labelAllLocales: customViewConfig.labelAllLocales,
|
|
1083
|
+
description: customViewConfig.description,
|
|
1084
|
+
url: customViewConfig.env.production.url,
|
|
1085
|
+
permissions: getPermissions(customViewConfig),
|
|
1086
|
+
locators: customViewConfig.locators,
|
|
1087
|
+
type: customViewConfig.type,
|
|
1088
|
+
typeSettings: customViewConfig.typeSettings
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
function transformConfigurationToData(configType, configuration) {
|
|
1092
|
+
if (configType === LOADED_CONFIG_TYPES.CUSTOM_APPLICATION) {
|
|
1093
|
+
return transformCustomApplicationConfigToData(configuration);
|
|
1094
|
+
} else if (configType === LOADED_CONFIG_TYPES.CUSTOM_VIEW) {
|
|
1095
|
+
return transformCustomViewConfigToData(configuration);
|
|
1096
|
+
} else {
|
|
1097
|
+
throw new Error(`Invalid config type: ${configType}`);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
const mapCloudIdentifierToApiUrl = key => {
|
|
1102
|
+
switch (key) {
|
|
1103
|
+
case CLOUD_IDENTIFIERS.GCP_AU:
|
|
1104
|
+
return MC_API_URLS[CLOUD_IDENTIFIERS.GCP_AU];
|
|
1105
|
+
case CLOUD_IDENTIFIERS.GCP_EU:
|
|
1106
|
+
return MC_API_URLS[CLOUD_IDENTIFIERS.GCP_EU];
|
|
1107
|
+
case CLOUD_IDENTIFIERS.GCP_US:
|
|
1108
|
+
return MC_API_URLS[CLOUD_IDENTIFIERS.GCP_US];
|
|
1109
|
+
case CLOUD_IDENTIFIERS.AWS_EU:
|
|
1110
|
+
case CLOUD_IDENTIFIERS.AWS_FRA:
|
|
1111
|
+
return MC_API_URLS[CLOUD_IDENTIFIERS.AWS_EU];
|
|
1112
|
+
case CLOUD_IDENTIFIERS.AWS_US:
|
|
1113
|
+
case CLOUD_IDENTIFIERS.AWS_OHIO:
|
|
1114
|
+
return MC_API_URLS[CLOUD_IDENTIFIERS.AWS_US];
|
|
1115
|
+
default:
|
|
1116
|
+
// We would probably never get to this point, as the JSON schema validation
|
|
1117
|
+
// kicks in before.
|
|
1118
|
+
throw new Error(`Unknown cloud identifier "${key}". Supported values: ${_Object$values__default["default"](CLOUD_IDENTIFIERS).toString()}`);
|
|
1119
|
+
}
|
|
1120
|
+
};
|
|
1121
|
+
const getUniqueValues = function () {
|
|
1122
|
+
let initialValues = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
1123
|
+
let additionalValues = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
1124
|
+
return uniq__default["default"]([...initialValues, ...additionalValues]);
|
|
1125
|
+
};
|
|
1126
|
+
const nonProductionEnvironment = ['development', 'test'];
|
|
1127
|
+
const getIsProd = env =>
|
|
1128
|
+
// TL;DR: in case the `MC_APP_ENV` is defined, we consider that it's
|
|
1129
|
+
// a production environment unless it's one of `development` or `test`.
|
|
1130
|
+
// This allows to use for example the `staging` value, which from the
|
|
1131
|
+
// application perspective is still considered a production environment.
|
|
1132
|
+
env.MC_APP_ENV ? !_includesInstanceProperty__default["default"](nonProductionEnvironment).call(nonProductionEnvironment, env.MC_APP_ENV) : env.NODE_ENV === 'production';
|
|
1133
|
+
const getOrThrow = (fn, errorMessage) => {
|
|
1134
|
+
try {
|
|
1135
|
+
return fn();
|
|
1136
|
+
} catch (error) {
|
|
1137
|
+
throw new Error(errorMessage);
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
|
|
1141
|
+
function ownKeys(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
1142
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context2, _context3; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context2 = ownKeys(Object(t), !0)).call(_context2, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context3 = ownKeys(Object(t))).call(_context3, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
|
|
1143
|
+
// TODO: make it configurable.
|
|
1144
|
+
const developmentPort = 3001;
|
|
1145
|
+
const developmentAppUrl = `http://localhost:${developmentPort}`;
|
|
1146
|
+
const getLoadedConfigurationType = configFileName => {
|
|
1147
|
+
if (_includesInstanceProperty__default["default"](configFileName).call(configFileName, 'custom-view-config')) {
|
|
1148
|
+
return LOADED_CONFIG_TYPES.CUSTOM_VIEW;
|
|
1149
|
+
}
|
|
1150
|
+
return LOADED_CONFIG_TYPES.CUSTOM_APPLICATION;
|
|
1151
|
+
};
|
|
1152
|
+
const trimTrailingSlash = value => value.replace(/\/$/, '');
|
|
1153
|
+
const omitDevConfigIfEmpty = devConfig => {
|
|
1154
|
+
if (devConfig && (Object.hasOwn(devConfig, 'accountLinks') || Object.hasOwn(devConfig, 'menuLinks') || Object.hasOwn(devConfig, 'customViewHostUrl') || Object.hasOwn(devConfig, 'oidc'))) {
|
|
1155
|
+
return devConfig;
|
|
1156
|
+
}
|
|
1157
|
+
return undefined;
|
|
1158
|
+
};
|
|
1159
|
+
const isCustomViewData = data => data.entryPointUriPath === undefined;
|
|
1160
|
+
const getRuntimeEnvironmentConfigForDevelopment = _ref => {
|
|
1161
|
+
let isProd = _ref.isProd,
|
|
1162
|
+
configurationData = _ref.configurationData,
|
|
1163
|
+
mcApiUrl = _ref.mcApiUrl,
|
|
1164
|
+
appConfig = _ref.appConfig,
|
|
1165
|
+
entryPointUriPath = _ref.entryPointUriPath;
|
|
1166
|
+
if (isProd) {
|
|
1167
|
+
return undefined;
|
|
1168
|
+
}
|
|
1169
|
+
const oidcConfig = omitEmpty__default["default"](_objectSpread(_objectSpread({
|
|
1170
|
+
authorizeUrl: [
|
|
1171
|
+
// In case the MC API url points to localhost, we need to point
|
|
1172
|
+
// to a local running dev login page to handle the workflow properly.
|
|
1173
|
+
mcApiUrl.hostname === 'localhost' ? mcApiUrl.origin.replace(mcApiUrl.port, String(developmentPort)) : mcApiUrl.origin.replace('mc-api', 'mc'), '/login/authorize'].join(''),
|
|
1174
|
+
initialProjectKey:
|
|
1175
|
+
// For the `account` application, we should unset the projectKey.
|
|
1176
|
+
entryPointUriPath === 'account' ? undefined : appConfig.env.development.initialProjectKey
|
|
1177
|
+
}, appConfig.env.development?.teamId && _objectSpread({
|
|
1178
|
+
teamId: appConfig.env.development.teamId
|
|
1179
|
+
}, isCustomViewData(configurationData) ? {
|
|
1180
|
+
customViewId: configurationData.id
|
|
1181
|
+
} : {
|
|
1182
|
+
applicationId: configurationData.id
|
|
1183
|
+
})), {}, {
|
|
1184
|
+
oAuthScopes: appConfig.oAuthScopes,
|
|
1185
|
+
additionalOAuthScopes: appConfig?.additionalOAuthScopes
|
|
1186
|
+
}));
|
|
1187
|
+
if (isCustomViewData(configurationData)) {
|
|
1188
|
+
const hostUriPath = appConfig.env.development.hostUriPath;
|
|
1189
|
+
const defaultHostUriPath = oidcConfig.initialProjectKey ? `/${oidcConfig.initialProjectKey}/${entryPointUriPath}` : `/${entryPointUriPath}`;
|
|
1190
|
+
const hostUrl = new _URL__default["default"](hostUriPath || defaultHostUriPath, developmentAppUrl);
|
|
1191
|
+
return omitDevConfigIfEmpty({
|
|
1192
|
+
oidc: oidcConfig,
|
|
1193
|
+
customViewConfig: configurationData,
|
|
1194
|
+
customViewHostUrl: hostUrl.href
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
return omitDevConfigIfEmpty({
|
|
1198
|
+
oidc: oidcConfig,
|
|
1199
|
+
menuLinks: _objectSpread(_objectSpread({
|
|
1200
|
+
icon: configurationData.icon
|
|
1201
|
+
}, configurationData.mainMenuLink), {}, {
|
|
1202
|
+
submenuLinks: configurationData.submenuLinks
|
|
1203
|
+
}),
|
|
1204
|
+
// @ts-expect-error: the `accountLinks` is not explicitly typed as it's only used by the account app.
|
|
1205
|
+
accountLinks: appConfig.accountLinks
|
|
1206
|
+
});
|
|
1207
|
+
};
|
|
1208
|
+
const getRuntimeEnvironmentConfig = _ref2 => {
|
|
1209
|
+
let isProd = _ref2.isProd,
|
|
1210
|
+
configurationData = _ref2.configurationData,
|
|
1211
|
+
additionalAppEnv = _ref2.additionalAppEnv,
|
|
1212
|
+
mcApiUrl = _ref2.mcApiUrl,
|
|
1213
|
+
cdnUrl = _ref2.cdnUrl,
|
|
1214
|
+
appUrl = _ref2.appUrl,
|
|
1215
|
+
appEnvKey = _ref2.appEnvKey,
|
|
1216
|
+
revision = _ref2.revision,
|
|
1217
|
+
appConfig = _ref2.appConfig;
|
|
1218
|
+
const entryPointUriPath = isCustomViewData(configurationData) ?
|
|
1219
|
+
// When the application acts as the host for Custom Views, there is no real
|
|
1220
|
+
// entry point to be used, therefore we use a special identifier.
|
|
1221
|
+
constants.CUSTOM_VIEW_HOST_ENTRY_POINT_URI_PATH : configurationData.entryPointUriPath;
|
|
1222
|
+
|
|
1223
|
+
// The real application ID is only used in production.
|
|
1224
|
+
// In development, we prefix the entry point with the "__local" prefix.
|
|
1225
|
+
// This is important to determine to which URL the MC should redirect to
|
|
1226
|
+
// after successful login.
|
|
1227
|
+
const applicationIdentifier = isProd ? `${configurationData.id}:${entryPointUriPath}` : `__local:${entryPointUriPath}`;
|
|
1228
|
+
const developmentConfig = getRuntimeEnvironmentConfigForDevelopment({
|
|
1229
|
+
isProd,
|
|
1230
|
+
configurationData,
|
|
1231
|
+
mcApiUrl,
|
|
1232
|
+
appConfig,
|
|
1233
|
+
entryPointUriPath
|
|
1234
|
+
});
|
|
1235
|
+
return _objectSpread(_objectSpread(_objectSpread({}, omitEmpty__default["default"](additionalAppEnv)), {}, {
|
|
1236
|
+
cdnUrl: cdnUrl.href,
|
|
1237
|
+
env: appEnvKey,
|
|
1238
|
+
frontendHost: appUrl.host,
|
|
1239
|
+
location: appConfig.cloudIdentifier,
|
|
1240
|
+
mcApiUrl: mcApiUrl.origin,
|
|
1241
|
+
revision,
|
|
1242
|
+
servedByProxy: isProd,
|
|
1243
|
+
// Application config
|
|
1244
|
+
applicationId: applicationIdentifier,
|
|
1245
|
+
applicationIdentifier,
|
|
1246
|
+
applicationName: isCustomViewData(configurationData) ? configurationData.defaultLabel : configurationData.name,
|
|
1247
|
+
entryPointUriPath
|
|
1248
|
+
}, isCustomViewData(configurationData) ? {
|
|
1249
|
+
customViewId: configurationData.id
|
|
1250
|
+
} : {}), developmentConfig ? {
|
|
1251
|
+
__DEVELOPMENT__: developmentConfig
|
|
1252
|
+
} : {});
|
|
1253
|
+
};
|
|
1254
|
+
|
|
1255
|
+
// Keep a reference to the config so that requiring the module
|
|
1256
|
+
// again will result in returning the cached value.
|
|
1257
|
+
let cachedConfig;
|
|
1258
|
+
const processConfig = async function () {
|
|
1259
|
+
var _context;
|
|
1260
|
+
let _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
1261
|
+
_ref3$disableCache = _ref3.disableCache,
|
|
1262
|
+
disableCache = _ref3$disableCache === void 0 ? false : _ref3$disableCache,
|
|
1263
|
+
_ref3$processEnv = _ref3.processEnv,
|
|
1264
|
+
processEnv = _ref3$processEnv === void 0 ? process.env : _ref3$processEnv,
|
|
1265
|
+
_ref3$applicationPath = _ref3.applicationPath,
|
|
1266
|
+
applicationPath = _ref3$applicationPath === void 0 ? fs__default$1["default"].realpathSync(process.cwd()) : _ref3$applicationPath;
|
|
1267
|
+
if (cachedConfig && !disableCache) return cachedConfig;
|
|
1268
|
+
const _await$loadConfig = await loadConfig(applicationPath),
|
|
1269
|
+
filepath = _await$loadConfig.filepath,
|
|
1270
|
+
rawConfig = _await$loadConfig.config;
|
|
1271
|
+
const configType = getLoadedConfigurationType(path.parse(filepath).name);
|
|
1272
|
+
validateConfig(configType, rawConfig);
|
|
1273
|
+
const appConfig = substituteVariablePlaceholders(rawConfig, {
|
|
1274
|
+
applicationPath,
|
|
1275
|
+
processEnv
|
|
1276
|
+
});
|
|
1277
|
+
const configurationData = transformConfigurationToData(configType, appConfig);
|
|
1278
|
+
const appEnvKey = processEnv.MC_APP_ENV ?? processEnv.NODE_ENV ?? 'development';
|
|
1279
|
+
const isProd = getIsProd(processEnv);
|
|
1280
|
+
const additionalAppEnv = appConfig.additionalEnv ?? {};
|
|
1281
|
+
const revision = additionalAppEnv.revision ?? '';
|
|
1282
|
+
|
|
1283
|
+
// Parse all the supported URLs, which gets implicitly validated
|
|
1284
|
+
|
|
1285
|
+
const envAppUrl = isProd ? configurationData.url : developmentAppUrl;
|
|
1286
|
+
const appUrl = getOrThrow(() => new _URL__default["default"](envAppUrl), `Invalid application URL: "${envAppUrl}"`);
|
|
1287
|
+
|
|
1288
|
+
// Use `||` instead of `??` to include empty string values.
|
|
1289
|
+
const envCdnUrl = isProd ? appConfig.env.production.cdnUrl || appUrl.href : developmentAppUrl;
|
|
1290
|
+
const cdnUrl = getOrThrow(() => new _URL__default["default"](envCdnUrl), `Invalid application CDN URL: "${envCdnUrl}"`);
|
|
1291
|
+
const mcApiUrl = getOrThrow(() => new _URL__default["default"](
|
|
1292
|
+
// Use `||` instead of `??` to include empty string values.
|
|
1293
|
+
appConfig.mcApiUrl || mapCloudIdentifierToApiUrl(appConfig.cloudIdentifier)), `Invalid MC API URL: "${appConfig.mcApiUrl}"`);
|
|
1294
|
+
cachedConfig = {
|
|
1295
|
+
data: configurationData,
|
|
1296
|
+
env: getRuntimeEnvironmentConfig({
|
|
1297
|
+
isProd,
|
|
1298
|
+
configurationData,
|
|
1299
|
+
additionalAppEnv,
|
|
1300
|
+
appConfig,
|
|
1301
|
+
appEnvKey,
|
|
1302
|
+
appUrl,
|
|
1303
|
+
cdnUrl,
|
|
1304
|
+
mcApiUrl,
|
|
1305
|
+
revision
|
|
1306
|
+
}),
|
|
1307
|
+
headers: _objectSpread(_objectSpread({}, appConfig.headers), {}, {
|
|
1308
|
+
csp: _objectSpread(_objectSpread({}, appConfig.headers?.csp), {}, {
|
|
1309
|
+
// We need to make sure the URL we use in these CSP headers have a slash in the end,
|
|
1310
|
+
// otherwise it might create an invalid value when application/CDN URL points to a
|
|
1311
|
+
// non-root directory (ex: https://www.my-domain.com/app). This is a valid URL but from
|
|
1312
|
+
// the CSP point of view, it will say only the file `app` can be used as a source, so
|
|
1313
|
+
// any other file from that domain will be forbidden. Using the slash (ex: https://www.my-domain.com/app/)
|
|
1314
|
+
// at the end it's like using a wildcard so anything 'below' `app` will be allowed.
|
|
1315
|
+
'connect-src': getUniqueValues(appConfig.headers?.csp?.['connect-src'], _concatInstanceProperty__default["default"](_context = [mcApiUrl.origin]).call(_context, isProd ? [`${trimTrailingSlash(appUrl.href)}/`] : [])),
|
|
1316
|
+
'script-src': getUniqueValues(appConfig.headers?.csp?.['script-src'], isProd ? [`${trimTrailingSlash(appUrl.href)}/`, `${trimTrailingSlash(cdnUrl.href)}/`] : []),
|
|
1317
|
+
'style-src': getUniqueValues(appConfig.headers?.csp?.['style-src'], isProd ? [`${trimTrailingSlash(appUrl.href)}/`, `${trimTrailingSlash(cdnUrl.href)}/`] : [])
|
|
1318
|
+
})
|
|
1319
|
+
})
|
|
1320
|
+
};
|
|
1321
|
+
return cachedConfig;
|
|
1322
|
+
};
|
|
1323
|
+
|
|
1324
|
+
const jsdom = new jsdom$1.JSDOM('');
|
|
1325
|
+
const DOMPurify = createDOMPurify__default["default"](jsdom.window);
|
|
1326
|
+
function sanitizeSvg(data) {
|
|
1327
|
+
return DOMPurify.sanitize(data, {
|
|
1328
|
+
USE_PROFILES: {
|
|
1329
|
+
svg: true
|
|
1330
|
+
},
|
|
1331
|
+
FORBID_ATTR: [
|
|
1332
|
+
// To avoid injection by using `style="filter:url(\"data:image/svg+xml,<svg`
|
|
1333
|
+
'style']
|
|
1334
|
+
});
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
Object.defineProperty(exports, 'ENTRY_POINT_URI_PATH_REGEX', {
|
|
1338
|
+
enumerable: true,
|
|
1339
|
+
get: function () { return constants.ENTRY_POINT_URI_PATH_REGEX; }
|
|
1340
|
+
});
|
|
1341
|
+
Object.defineProperty(exports, 'PERMISSION_GROUP_NAME_REGEX', {
|
|
1342
|
+
enumerable: true,
|
|
1343
|
+
get: function () { return constants.PERMISSION_GROUP_NAME_REGEX; }
|
|
1344
|
+
});
|
|
1345
|
+
exports.CLOUD_IDENTIFIERS = CLOUD_IDENTIFIERS;
|
|
1346
|
+
exports.LOADED_CONFIG_TYPES = LOADED_CONFIG_TYPES;
|
|
1347
|
+
exports.MC_API_URLS = MC_API_URLS;
|
|
1348
|
+
exports.MissingOrInvalidConfigError = MissingOrInvalidConfigError;
|
|
1349
|
+
exports.getConfigPath = getConfigPath;
|
|
1350
|
+
exports.processConfig = processConfig;
|
|
1351
|
+
exports.sanitizeSvg = sanitizeSvg;
|