@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.
Files changed (33) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/client.d.ts +26 -0
  4. package/custom-application.schema.json +301 -0
  5. package/custom-view.schema.json +248 -0
  6. package/dist/commercetools-frontend-application-config.cjs.d.ts +2 -0
  7. package/dist/commercetools-frontend-application-config.cjs.dev.js +1351 -0
  8. package/dist/commercetools-frontend-application-config.cjs.js +7 -0
  9. package/dist/commercetools-frontend-application-config.cjs.prod.js +1351 -0
  10. package/dist/commercetools-frontend-application-config.esm.js +1303 -0
  11. package/dist/declarations/src/constants.d.ts +34 -0
  12. package/dist/declarations/src/errors.d.ts +4 -0
  13. package/dist/declarations/src/formatters.d.ts +33 -0
  14. package/dist/declarations/src/index.d.ts +7 -0
  15. package/dist/declarations/src/load-config.d.ts +11 -0
  16. package/dist/declarations/src/process-config.d.ts +6 -0
  17. package/dist/declarations/src/sanitize-svg.d.ts +1 -0
  18. package/dist/declarations/src/schemas/generated/custom-application.schema.d.ts +164 -0
  19. package/dist/declarations/src/schemas/generated/custom-view.schema.d.ts +139 -0
  20. package/dist/declarations/src/ssr.d.ts +1 -0
  21. package/dist/declarations/src/types/generated/settings.d.ts +1653 -0
  22. package/dist/declarations/src/types.d.ts +108 -0
  23. package/dist/formatters-7f327585.cjs.prod.js +123 -0
  24. package/dist/formatters-882eafa8.esm.js +101 -0
  25. package/dist/formatters-a76b45b9.cjs.dev.js +123 -0
  26. package/package.json +73 -0
  27. package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.d.ts +2 -0
  28. package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.dev.js +29 -0
  29. package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.js +7 -0
  30. package/ssr/dist/commercetools-frontend-application-config-ssr.cjs.prod.js +29 -0
  31. package/ssr/dist/commercetools-frontend-application-config-ssr.esm.js +16 -0
  32. package/ssr/package.json +4 -0
  33. 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-7f327585.cjs.prod.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;