@commercetools-frontend/application-cli 1.8.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
1
  import { cac } from 'cac';
2
2
  import _Object$keys from '@babel/runtime-corejs3/core-js-stable/object/keys';
3
3
  import _Object$getOwnPropertySymbols from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols';
4
+ import _filterInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/filter';
4
5
  import _Object$getOwnPropertyDescriptor from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor';
5
6
  import _forEachInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/for-each';
6
7
  import _Object$getOwnPropertyDescriptors from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors';
@@ -8,24 +9,34 @@ import _Object$defineProperties from '@babel/runtime-corejs3/core-js-stable/obje
8
9
  import _Object$defineProperty from '@babel/runtime-corejs3/core-js-stable/object/define-property';
9
10
  import _slicedToArray from '@babel/runtime-corejs3/helpers/esm/slicedToArray';
10
11
  import _defineProperty from '@babel/runtime-corejs3/helpers/esm/defineProperty';
11
- import _filterInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/filter';
12
12
  import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map';
13
13
  import _Object$entries from '@babel/runtime-corejs3/core-js-stable/object/entries';
14
- import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/concat';
15
- import fs from 'fs';
16
- import path from 'path';
14
+ import _Set from '@babel/runtime-corejs3/core-js-stable/set';
15
+ import _flatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/flat';
16
+ import fs from 'node:fs';
17
+ import path$1 from 'node:path';
17
18
  import { Listr } from 'listr2';
18
19
  import execa from 'execa';
19
20
  import { cosmiconfig } from 'cosmiconfig';
20
21
  import { findRootSync } from '@manypkg/find-root';
22
+ import path from 'path';
23
+ import _possibleConstructorReturn from '@babel/runtime-corejs3/helpers/esm/possibleConstructorReturn';
24
+ import _get from '@babel/runtime-corejs3/helpers/esm/get';
25
+ import _getPrototypeOf from '@babel/runtime-corejs3/helpers/esm/getPrototypeOf';
26
+ import _inherits from '@babel/runtime-corejs3/helpers/esm/inherits';
27
+ import _classCallCheck from '@babel/runtime-corejs3/helpers/esm/classCallCheck';
28
+ import _createClass from '@babel/runtime-corejs3/helpers/esm/createClass';
29
+ import _Reflect$construct from '@babel/runtime-corejs3/core-js-stable/reflect/construct';
30
+ import fs$1 from 'fs';
21
31
  import dotenv from 'dotenv';
22
32
  import _findInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/find';
23
33
  import _JSON$stringify from '@babel/runtime-corejs3/core-js-stable/json/stringify';
24
34
  import { processConfig } from '@commercetools-frontend/application-config';
25
35
  import { getSupportedLocales } from '@commercetools-frontend/l10n';
36
+ import { c as clusterContexts } from '../../dist/storage-buckets-config-7845a091.esm.js';
26
37
  import _sliceInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/slice';
27
- import fetch from 'node-fetch';
28
38
  import { Validator } from 'jsonschema';
39
+ import 'ts-deepmerge';
29
40
 
30
41
  function getApplicationDirectory(cwd) {
31
42
  return fs.realpathSync(cwd);
@@ -40,19 +51,167 @@ function isCI() {
40
51
  return process.env.CI === true || process.env.CI === 'true';
41
52
  }
42
53
 
43
- function createApplicationIndexUploadScript(_ref) {
44
- let packageManagerName = _ref.packageManagerName,
45
- bucketUrl = _ref.bucketUrl,
46
- cdnUrl = _ref.cdnUrl,
47
- bucketEnvironment = _ref.bucketEnvironment,
48
- buildRevision = _ref.buildRevision,
49
- buildNumber = _ref.buildNumber,
50
- applicationIndexOutFile = _ref.applicationIndexOutFile;
51
- const uploadScriptContent = `#!/usr/bin/env bash
54
+ function ownKeys$4(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
55
+ function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var _context3, _context4; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context3 = ownKeys$4(Object(t), !0)).call(_context3, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context4 = ownKeys$4(Object(t))).call(_context4, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
56
+ function _callSuper(_this, derived, args) {
57
+ function isNativeReflectConstruct() {
58
+ if (typeof Reflect === "undefined" || !_Reflect$construct) return false;
59
+ if (_Reflect$construct.sham) return false;
60
+ if (typeof Proxy === "function") return true;
61
+ try {
62
+ return !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {}));
63
+ } catch (e) {
64
+ return false;
65
+ }
66
+ }
67
+ derived = _getPrototypeOf(derived);
68
+ return _possibleConstructorReturn(_this, isNativeReflectConstruct() ? _Reflect$construct(derived, args || [], _getPrototypeOf(_this).constructor) : derived.apply(_this, args));
69
+ }
70
+ let StorageProvider = /*#__PURE__*/function () {
71
+ function StorageProvider() {
72
+ _classCallCheck(this, StorageProvider);
73
+ }
74
+ _createClass(StorageProvider, [{
75
+ key: "getBucketNamespace",
76
+ value:
77
+ /**
78
+ * Construct the storage bucket URL for the specific application and cloud environment.
79
+ *
80
+ * 1. Static assets are uploaded to `:bucketRegion/:prNumber?/:applicationName`
81
+ * 2. The application index is uploaded to `:bucketRegion/:prNumber?/:applicationName/:cloudEnvironment`
82
+ *
83
+ * This allows all cloud environments sharing the same static assets while each application's index
84
+ * is uploaded with different headers (e.g. CSP rules).
85
+ */
86
+ function getBucketNamespace(prNumber) {
87
+ if (!prNumber) return;
88
+ if (prNumber === 'merchant-center-preview') return prNumber;
89
+ return `mc-${prNumber}`;
90
+ }
91
+
92
+ /**
93
+ * Construct the storage bucket URL for the specific application and cloud environment.
94
+ */
95
+ }, {
96
+ key: "getAssetsBucketUrl",
97
+ value: function getAssetsBucketUrl(_ref) {
98
+ var _context;
99
+ let bucketProtocol = _ref.bucketProtocol,
100
+ bucketRegion = _ref.bucketRegion,
101
+ bucketNamespace = _ref.bucketNamespace,
102
+ applicationName = _ref.applicationName;
103
+ const assetsBucketUrl = _filterInstanceProperty(_context = [bucketRegion, bucketNamespace, applicationName]).call(_context, Boolean).join('/');
104
+ return `${bucketProtocol}${assetsBucketUrl}`;
105
+ }
106
+ }, {
107
+ key: "getApplicationIndexBucketUrl",
108
+ value: function getApplicationIndexBucketUrl(_ref2) {
109
+ let bucketProtocol = _ref2.bucketProtocol,
110
+ bucketRegion = _ref2.bucketRegion,
111
+ bucketNamespace = _ref2.bucketNamespace,
112
+ prNumber = _ref2.prNumber,
113
+ applicationName = _ref2.applicationName,
114
+ bucketEnvironment = _ref2.bucketEnvironment;
115
+ const applicationAssetsBucketUrl = this.getAssetsBucketUrl({
116
+ bucketProtocol,
117
+ bucketRegion,
118
+ bucketNamespace,
119
+ prNumber,
120
+ applicationName
121
+ });
122
+ const applicationIndexBucketUrl = `${applicationAssetsBucketUrl}/${bucketEnvironment}`;
123
+ return applicationIndexBucketUrl;
124
+ }
125
+ }, {
126
+ key: "getCdnUrl",
127
+ value: function getCdnUrl(_ref3) {
128
+ var _context2;
129
+ let publicBaseUrl = _ref3.publicBaseUrl,
130
+ bucketRegion = _ref3.bucketRegion,
131
+ prNumber = _ref3.prNumber,
132
+ applicationName = _ref3.applicationName;
133
+ return _filterInstanceProperty(_context2 = [publicBaseUrl, bucketRegion, this.getBucketNamespace(prNumber), applicationName]).call(_context2, Boolean).join('/');
134
+ }
135
+ }]);
136
+ return StorageProvider;
137
+ }();
138
+ let GoogleStorageProvider = /*#__PURE__*/function (_StorageProvider) {
139
+ _inherits(GoogleStorageProvider, _StorageProvider);
140
+ function GoogleStorageProvider() {
141
+ _classCallCheck(this, GoogleStorageProvider);
142
+ return _callSuper(this, GoogleStorageProvider, arguments);
143
+ }
144
+ _createClass(GoogleStorageProvider, [{
145
+ key: "getTag",
146
+ value: function getTag() {
147
+ return 'gs';
148
+ }
149
+ }, {
150
+ key: "getProtocol",
151
+ value: function getProtocol() {
152
+ return 'gs://';
153
+ }
154
+ }, {
155
+ key: "getPublicBaseUrl",
156
+ value: function getPublicBaseUrl() {
157
+ return 'https://storage.googleapis.com';
158
+ }
159
+ }, {
160
+ key: "getCdnUrl",
161
+ value: function getCdnUrl(config) {
162
+ return _get(_getPrototypeOf(GoogleStorageProvider.prototype), "getCdnUrl", this).call(this, _objectSpread$4({
163
+ publicBaseUrl: this.getPublicBaseUrl()
164
+ }, config));
165
+ }
166
+ }, {
167
+ key: "getAssetsBucketUrl",
168
+ value: function getAssetsBucketUrl(config) {
169
+ return _get(_getPrototypeOf(GoogleStorageProvider.prototype), "getAssetsBucketUrl", this).call(this, _objectSpread$4({
170
+ bucketProtocol: this.getProtocol(),
171
+ bucketNamespace: _get(_getPrototypeOf(GoogleStorageProvider.prototype), "getBucketNamespace", this).call(this, config.prNumber)
172
+ }, config));
173
+ }
174
+ }, {
175
+ key: "getApplicationIndexBucketUrl",
176
+ value: function getApplicationIndexBucketUrl(config) {
177
+ return _get(_getPrototypeOf(GoogleStorageProvider.prototype), "getApplicationIndexBucketUrl", this).call(this, _objectSpread$4({
178
+ bucketProtocol: this.getProtocol(),
179
+ bucketNamespace: _get(_getPrototypeOf(GoogleStorageProvider.prototype), "getBucketNamespace", this).call(this, config.prNumber)
180
+ }, config));
181
+ }
182
+ }]);
183
+ return GoogleStorageProvider;
184
+ }(StorageProvider); // TODO: to be implemented.
185
+ function getStorageProvider(storageProvider) {
186
+ switch (storageProvider) {
187
+ case 'gs':
188
+ return new GoogleStorageProvider();
189
+ default:
190
+ throw new Error(`Storage provider ${storageProvider} not supported`);
191
+ }
192
+ }
193
+
194
+ let GoogleStorageUploadScriptsGenerator = /*#__PURE__*/function () {
195
+ function GoogleStorageUploadScriptsGenerator() {
196
+ _classCallCheck(this, GoogleStorageUploadScriptsGenerator);
197
+ }
198
+ _createClass(GoogleStorageUploadScriptsGenerator, [{
199
+ key: "getApplicationIndexUploadScript",
200
+ value: function getApplicationIndexUploadScript(_ref) {
201
+ let packageManagerName = _ref.packageManagerName,
202
+ bucketUrl = _ref.bucketUrl,
203
+ cdnUrl = _ref.cdnUrl,
204
+ bucketEnvironment = _ref.bucketEnvironment,
205
+ buildRevision = _ref.buildRevision,
206
+ buildNumber = _ref.buildNumber,
207
+ applicationIndexOutFile = _ref.applicationIndexOutFile;
208
+ return `
209
+ #!/usr/bin/env bash
52
210
 
53
211
  set -e
54
212
 
55
- echo "Uploading compiled ${applicationIndexOutFile} to bucket ${bucketUrl}"
213
+ echo "Uploading compiled ${applicationIndexOutFile} to Google Storage bucket ${bucketUrl}"
214
+
56
215
  gcloud storage cp \\
57
216
  "$(dirname "$0")/${applicationIndexOutFile}" \\
58
217
  "${bucketUrl}/" \\
@@ -75,14 +234,15 @@ gcloud storage cp \\
75
234
  --content-type="application/json" \\
76
235
  --cache-control="public,max-age=0,no-transform"
77
236
  `;
78
- return uploadScriptContent;
79
- }
80
-
81
- function createApplicationAssetsUploadScript(_ref) {
82
- let bucketUrl = _ref.bucketUrl,
83
- assetsPath = _ref.assetsPath,
84
- skipMenu = _ref.skipMenu;
85
- const uploadScriptContent = `#!/usr/bin/env bash
237
+ }
238
+ }, {
239
+ key: "getProductionBundlesUploadScript",
240
+ value: function getProductionBundlesUploadScript(_ref2) {
241
+ let bucketUrl = _ref2.bucketUrl,
242
+ assetsPath = _ref2.assetsPath,
243
+ skipMenu = _ref2.skipMenu;
244
+ return `
245
+ #!/usr/bin/env bash
86
246
 
87
247
  set -e
88
248
 
@@ -95,7 +255,7 @@ set -e
95
255
  # "valid" lifetime of an asset to be cached.
96
256
  # 4. The '-n' will skip uploading existing files and prevents them to
97
257
  # be overwritten
98
- echo "Uploading static assets to bucket ${bucketUrl}"
258
+ echo "Uploading static assets to Google Storage bucket ${bucketUrl}"
99
259
 
100
260
  gcloud storage cp \\
101
261
  ${assetsPath}/public/{*.css,*.js,*.js.map,*.png,*.html,robots.txt} \\
@@ -134,7 +294,17 @@ else
134
294
  --cache-control="public,max-age=0,no-transform"
135
295
  fi
136
296
  `;
137
- return uploadScriptContent;
297
+ }
298
+ }]);
299
+ return GoogleStorageUploadScriptsGenerator;
300
+ }(); // TODO: To be implemented.
301
+ function getUploadScriptsGenerator(storageProvider) {
302
+ switch (storageProvider) {
303
+ case 'gs':
304
+ return new GoogleStorageUploadScriptsGenerator();
305
+ default:
306
+ throw new Error(`Storage provider ${storageProvider} not supported`);
307
+ }
138
308
  }
139
309
 
140
310
  function ownKeys$3(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -148,7 +318,7 @@ function loadDotenvFiles(_ref) {
148
318
  }
149
319
 
150
320
  // Check if the given path exists.
151
- if (!fs.existsSync(dotenvPath)) {
321
+ if (!fs$1.existsSync(dotenvPath)) {
152
322
  throw new Error(`The dotenv folder path does not exist: "${dotenvPath}".`);
153
323
  }
154
324
 
@@ -175,74 +345,29 @@ function loadDotenvFiles(_ref) {
175
345
  }
176
346
 
177
347
  function ownKeys$2(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
178
- function _objectSpread$2(e) { for (var r = 1; r < arguments.length; r++) { var _context5, _context6; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context5 = ownKeys$2(Object(t), !0)).call(_context5, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context6 = ownKeys$2(Object(t))).call(_context6, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
179
- const buckedConfigExplorer = cosmiconfig('google-storage-buckets');
180
- function assertCollapsedBucketEnvironmentConfig(bucketEnvironmentConfigOrBucketEnvironment) {
181
- return typeof bucketEnvironmentConfigOrBucketEnvironment == 'string';
182
- }
183
- function assertExpandedBucketEnvironmentConfig(bucketEnvironmentConfigOrBucketEnvironment) {
184
- return typeof bucketEnvironmentConfigOrBucketEnvironment == 'object' && typeof bucketEnvironmentConfigOrBucketEnvironment.cloudEnvironment == 'string' && typeof bucketEnvironmentConfigOrBucketEnvironment.bucketEnvironment == 'string';
185
- }
348
+ function _objectSpread$2(e) { for (var r = 1; r < arguments.length; r++) { var _context4, _context5; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context4 = ownKeys$2(Object(t), !0)).call(_context4, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context5 = ownKeys$2(Object(t))).call(_context5, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
349
+ const storageBucketConfigExplorer = cosmiconfig('storage-buckets', {
350
+ searchStrategy: 'project'
351
+ });
186
352
  function writeUploadScriptFile(_ref) {
187
353
  let fileName = _ref.fileName,
188
354
  fileContent = _ref.fileContent,
189
355
  filePath = _ref.filePath;
190
- fs.writeFileSync(path.join(filePath, fileName), fileContent, {
356
+ fs.writeFileSync(path$1.join(filePath, fileName), fileContent, {
191
357
  // Make the script executable
192
358
  mode: 0o755,
193
359
  encoding: 'utf8'
194
360
  });
195
361
  }
196
- function getBucketNamespace(prNumber) {
197
- if (!prNumber) return;
198
- if (prNumber === 'merchant-center-preview') return prNumber;
199
- return `mc-${prNumber}`;
200
- }
201
-
202
- /**
203
- * Construct the storage bucket URL for the specific application and cloud environment.
204
- *
205
- * 1. Static assets are uploaded to `:bucketRegion/:prNumber?/:applicationName`
206
- * 2. The application index is uploaded to `:bucketRegion/:prNumber?/:applicationName/:cloudEnvironment`
207
- *
208
- * This allows all cloud environments sharing the same static assets while each application's index
209
- * is uploaded with different headers (e.g. CSP rules).
210
- */
211
-
212
- function getApplicationAssetsBucketUrl(_ref2) {
213
- var _context;
214
- let bucketRegion = _ref2.bucketRegion,
215
- prNumber = _ref2.prNumber,
216
- applicationName = _ref2.applicationName;
217
- const applicationAssetsBucketUrl = _filterInstanceProperty(_context = [`gs://${bucketRegion}`, getBucketNamespace(prNumber), applicationName]).call(_context, Boolean);
218
- return applicationAssetsBucketUrl.join('/');
219
- }
220
- function getApplicationIndexBucketUrl(_ref3) {
221
- let bucketRegion = _ref3.bucketRegion,
222
- prNumber = _ref3.prNumber,
223
- applicationName = _ref3.applicationName,
224
- bucketEnvironment = _ref3.bucketEnvironment;
225
- const applicationAssetsBucketUrl = getApplicationAssetsBucketUrl({
226
- bucketRegion,
227
- prNumber,
228
- applicationName
229
- });
230
- const applicationIndexBucketUrl = `${applicationAssetsBucketUrl}/${bucketEnvironment}`;
231
- return applicationIndexBucketUrl;
232
- }
233
- function getCdnUrl(_ref4) {
234
- var _context2;
235
- let bucketRegion = _ref4.bucketRegion,
236
- prNumber = _ref4.prNumber,
237
- applicationName = _ref4.applicationName;
238
- return _filterInstanceProperty(_context2 = [`https://storage.googleapis.com/${bucketRegion}`, getBucketNamespace(prNumber), applicationName]).call(_context2, Boolean).join('/');
239
- }
240
- async function compileApplicationAssets(_ref5) {
241
- let cliFlags = _ref5.cliFlags,
242
- bucketRegion = _ref5.bucketRegion,
243
- paths = _ref5.paths;
244
- const applicationAssetsUploadScriptContent = createApplicationAssetsUploadScript({
245
- bucketUrl: getApplicationAssetsBucketUrl({
362
+ async function compileApplicationAssets(_ref2) {
363
+ let cliFlags = _ref2.cliFlags,
364
+ storageProvider = _ref2.storageProvider,
365
+ uploadScriptsGenerator = _ref2.uploadScriptsGenerator,
366
+ bucketRegion = _ref2.bucketRegion,
367
+ paths = _ref2.paths;
368
+ const applicationAssetsUploadScriptContent = uploadScriptsGenerator.getProductionBundlesUploadScript({
369
+ storageProvider,
370
+ bucketUrl: storageProvider.getAssetsBucketUrl({
246
371
  bucketRegion,
247
372
  prNumber: cliFlags.prNumber,
248
373
  applicationName: cliFlags.applicationName
@@ -250,21 +375,23 @@ async function compileApplicationAssets(_ref5) {
250
375
  assetsPath: paths.assetsPath,
251
376
  skipMenu: cliFlags.skipMenu
252
377
  });
253
- const parsedApplicationAssetsUploadScriptFile = path.parse(cliFlags.applicationAssetsUploadScriptOutFile);
378
+ const parsedApplicationAssetsUploadScriptFile = path$1.parse(cliFlags.applicationAssetsUploadScriptOutFile);
254
379
  const applicationAssetsUploadScriptFileName = `${parsedApplicationAssetsUploadScriptFile.name}-${bucketRegion}${parsedApplicationAssetsUploadScriptFile.ext}`;
255
380
  writeUploadScriptFile({
256
381
  fileName: applicationAssetsUploadScriptFileName,
257
382
  fileContent: applicationAssetsUploadScriptContent,
258
- filePath: paths.deploymentsPath
383
+ filePath: path$1.join(paths.deploymentsPath, storageProvider.getTag())
259
384
  });
260
385
  }
261
- async function compileEnvironmentApplicationIndexes(_ref6) {
262
- let cliFlags = _ref6.cliFlags,
263
- paths = _ref6.paths,
264
- bucketRegion = _ref6.bucketRegion,
265
- cloudEnvironment = _ref6.cloudEnvironment,
266
- bucketEnvironment = _ref6.bucketEnvironment;
267
- const cloudEnvironmentDeploymentPath = path.join(paths.deploymentsPath, cloudEnvironment);
386
+ async function compileEnvironmentApplicationIndexes(_ref3) {
387
+ let cliFlags = _ref3.cliFlags,
388
+ storageProvider = _ref3.storageProvider,
389
+ uploadScriptsGenerator = _ref3.uploadScriptsGenerator,
390
+ paths = _ref3.paths,
391
+ bucketRegion = _ref3.bucketRegion,
392
+ cloudEnvironment = _ref3.cloudEnvironment,
393
+ bucketEnvironment = _ref3.bucketEnvironment;
394
+ const cloudEnvironmentDeploymentPath = path$1.join(paths.deploymentsPath, storageProvider.getTag(), cloudEnvironment);
268
395
  // Ensure the folder exists
269
396
  const createDeploymentsFolderResult = await execa('mkdir', ['-p', cloudEnvironmentDeploymentPath], {
270
397
  encoding: 'utf8'
@@ -274,7 +401,7 @@ async function compileEnvironmentApplicationIndexes(_ref6) {
274
401
  }
275
402
 
276
403
  // Construct the proper CDN URL for the specific application
277
- const cdnUrl = getCdnUrl({
404
+ const cdnUrl = storageProvider.getCdnUrl({
278
405
  bucketRegion,
279
406
  prNumber: cliFlags.prNumber,
280
407
  applicationName: cliFlags.applicationName
@@ -317,9 +444,10 @@ async function compileEnvironmentApplicationIndexes(_ref6) {
317
444
  if (compileResult.failed) {
318
445
  throw new Error(compileResult.stderr);
319
446
  }
320
- const applicationIndexUploadScriptContent = createApplicationIndexUploadScript({
447
+ const applicationIndexUploadScriptContent = uploadScriptsGenerator.getApplicationIndexUploadScript({
448
+ storageProvider,
321
449
  packageManagerName: cliFlags.packageManagerName,
322
- bucketUrl: getApplicationIndexBucketUrl({
450
+ bucketUrl: storageProvider.getApplicationIndexBucketUrl({
323
451
  bucketRegion,
324
452
  prNumber: cliFlags.prNumber,
325
453
  applicationName: cliFlags.applicationName,
@@ -331,8 +459,6 @@ async function compileEnvironmentApplicationIndexes(_ref6) {
331
459
  buildNumber: cliFlags.buildNumber,
332
460
  applicationIndexOutFile: cliFlags.applicationIndexOutFile
333
461
  });
334
- // Generate bash scripts to run the `gcloud storage` upload command.
335
-
336
462
  writeUploadScriptFile({
337
463
  fileName: cliFlags.applicationIndexUploadScriptOutFile,
338
464
  fileContent: applicationIndexUploadScriptContent,
@@ -340,23 +466,22 @@ async function compileEnvironmentApplicationIndexes(_ref6) {
340
466
  });
341
467
 
342
468
  // Move the compiled `index.html` to the deployments folder of the related cloud environment.
343
-
344
- const moveResult = await execa('mv', [path.join(paths.publicAssetsPath, 'index.html'), path.join(cloudEnvironmentDeploymentPath, cliFlags.applicationIndexOutFile)]);
469
+ const moveResult = await execa('mv', [path$1.join(paths.publicAssetsPath, 'index.html'), path$1.join(cloudEnvironmentDeploymentPath, cliFlags.applicationIndexOutFile)]);
345
470
  if (moveResult.failed) {
346
471
  throw new Error(moveResult.stderr);
347
472
  }
348
473
  }
349
474
  async function command$3(cliFlags, cwd) {
350
- var _context3;
475
+ var _context;
351
476
  let cloudEnvironmentsGroupedByBucketRegions;
352
477
  try {
353
478
  // This is the list of the supported cloud environments and their related bucket location.
354
- cloudEnvironmentsGroupedByBucketRegions = await buckedConfigExplorer.search();
479
+ cloudEnvironmentsGroupedByBucketRegions = await storageBucketConfigExplorer.search();
355
480
  } catch (e) {
356
- throw new Error('Failed loading a Google Bucket configuration. Create a cosmiconfig for `google-storage-buckets` for example `google-storage-buckets.config.cjs`.');
481
+ throw new Error('Failed to load a storage bucket configuration. Create a cosmiconfig for `storage-buckets` for example `storage-buckets.config.cjs`.');
357
482
  }
358
483
  if (!cloudEnvironmentsGroupedByBucketRegions) {
359
- throw new Error('Failed loading a Google Bucket configuration');
484
+ throw new Error('Failed loading a storage bucket configuration');
360
485
  }
361
486
  const applicationDirectory = getApplicationDirectory(cwd);
362
487
  let assetsPath;
@@ -369,48 +494,70 @@ async function command$3(cliFlags, cwd) {
369
494
  const paths = {
370
495
  publicAssetsPath: resolveInApplication('public', cwd),
371
496
  deploymentsPath: resolveInApplication('deployments', cwd),
372
- dotenvPath: cliFlags.dotenvFolder && path.join(monorepoRoot.rootDir, cliFlags.dotenvFolder),
497
+ dotenvPath: cliFlags.dotenvFolder && path$1.join(monorepoRoot.rootDir, cliFlags.dotenvFolder),
373
498
  assetsPath
374
499
  };
375
- const taskList = new Listr(_mapInstanceProperty(_context3 = _Object$entries(cloudEnvironmentsGroupedByBucketRegions.config)).call(_context3, _ref7 => {
376
- let _ref8 = _slicedToArray(_ref7, 2),
377
- bucketRegion = _ref8[0],
378
- bucketEnvironmentConfigs = _ref8[1];
500
+ const defaultStorageProviders = ['gs'];
501
+ const taskList = new Listr(_mapInstanceProperty(_context = _Object$entries(cloudEnvironmentsGroupedByBucketRegions.config)).call(_context, _ref4 => {
502
+ let _ref5 = _slicedToArray(_ref4, 2),
503
+ bucketRegion = _ref5[0],
504
+ bucketEnvironmentConfigs = _ref5[1];
379
505
  return {
380
506
  title: `Compiling for bucket region ${bucketRegion}`,
381
- task: () => {
382
- var _context4;
383
- return new Listr(_concatInstanceProperty(_context4 = _mapInstanceProperty(bucketEnvironmentConfigs).call(bucketEnvironmentConfigs, bucketEnvironmentConfigOrBucketEnvironment => {
384
- let cloudEnvironment = '';
385
- let bucketEnvironment = '';
386
- if (assertExpandedBucketEnvironmentConfig(bucketEnvironmentConfigOrBucketEnvironment)) {
387
- cloudEnvironment = bucketEnvironmentConfigOrBucketEnvironment.cloudEnvironment;
388
- bucketEnvironment = bucketEnvironmentConfigOrBucketEnvironment.bucketEnvironment;
389
- } else if (assertCollapsedBucketEnvironmentConfig(bucketEnvironmentConfigOrBucketEnvironment)) {
390
- cloudEnvironment = bucketEnvironmentConfigOrBucketEnvironment;
391
- bucketEnvironment = bucketEnvironmentConfigOrBucketEnvironment;
392
- }
507
+ task: (_bucketRegionCtx, bucketRegionTask) => {
508
+ var _context2;
509
+ // NOTE: Application assets need to be compiled
510
+ // for all storage providers once per region.
511
+ const allStorageProvidersForBucketRegion = [...new _Set(_flatInstanceProperty(_context2 = _mapInstanceProperty(bucketEnvironmentConfigs).call(bucketEnvironmentConfigs, bucketEnvironmentConfig => bucketEnvironmentConfig.storageProviders || defaultStorageProviders)).call(_context2))];
512
+ const allApplicationAssetTasks = _mapInstanceProperty(allStorageProvidersForBucketRegion).call(allStorageProvidersForBucketRegion, storageProviderTag => {
513
+ const storageProvider = getStorageProvider(storageProviderTag);
514
+ const uploadScriptsGenerator = getUploadScriptsGenerator(storageProviderTag);
393
515
  return {
394
- title: `Compiling application index for environment ${cloudEnvironment} and bucket ${bucketEnvironment}`,
395
- task: () => compileEnvironmentApplicationIndexes({
516
+ title: `Compiling application assets for '${storageProviderTag}'`,
517
+ task: () => compileApplicationAssets({
396
518
  cliFlags,
397
- paths,
398
- bucketRegion,
399
- cloudEnvironment,
400
- bucketEnvironment
519
+ storageProvider,
520
+ uploadScriptsGenerator,
521
+ bucketRegion: bucketRegion,
522
+ paths
401
523
  })
402
524
  };
403
- })).call(_context4, {
404
- title: `Compiling application assets`,
405
- task: () => compileApplicationAssets({
406
- cliFlags,
407
- bucketRegion,
408
- paths
409
- })
410
- }));
525
+ });
526
+ const allApplicationIndexTasks = _mapInstanceProperty(bucketEnvironmentConfigs).call(bucketEnvironmentConfigs, bucketEnvironmentConfig => {
527
+ const cloudEnvironment = bucketEnvironmentConfig.cloudEnvironment,
528
+ bucketEnvironment = bucketEnvironmentConfig.bucketEnvironment,
529
+ storageProviders = bucketEnvironmentConfig.storageProviders;
530
+ return {
531
+ title: `Compiling for cloud environment '${cloudEnvironment}'`,
532
+ task: (_storageProviderCtx, storageProviderTask) => {
533
+ var _context3;
534
+ const applicationIndexTasksForStorageProviders = _mapInstanceProperty(_context3 = storageProviders || defaultStorageProviders).call(_context3, storageProviderTag => {
535
+ const storageProvider = getStorageProvider(storageProviderTag);
536
+ const uploadScriptsGenerator = getUploadScriptsGenerator(storageProviderTag);
537
+ return {
538
+ title: `Compiling application index for storage provider '${storageProviderTag}'`,
539
+ task: () => {
540
+ return compileEnvironmentApplicationIndexes({
541
+ cliFlags,
542
+ storageProvider,
543
+ uploadScriptsGenerator,
544
+ paths,
545
+ bucketRegion: bucketRegion,
546
+ cloudEnvironment,
547
+ bucketEnvironment
548
+ });
549
+ }
550
+ };
551
+ });
552
+ return storageProviderTask.newListr(applicationIndexTasksForStorageProviders);
553
+ }
554
+ };
555
+ });
556
+ return bucketRegionTask.newListr([...allApplicationIndexTasks, ...allApplicationAssetTasks]);
411
557
  }
412
558
  };
413
559
  }), {
560
+ // @ts-ignore
414
561
  renderer: isCI() ? 'verbose' : 'default'
415
562
  });
416
563
  await taskList.run();
@@ -501,21 +648,23 @@ const mapApplicationMenuConfigToGraqhQLMenuJson = config => {
501
648
  const doesCloudEnvironmentExist = _ref => {
502
649
  let dotenvPath = _ref.dotenvPath,
503
650
  cloudEnvironment = _ref.cloudEnvironment;
504
- return fs.existsSync(path.join(dotenvPath ?? '', cloudEnvironment));
651
+ return fs$1.existsSync(path.join(dotenvPath ?? '', `.env.${cloudEnvironment}`));
505
652
  };
506
653
  async function command$2(cliFlags, cwd) {
507
654
  const applicationDirectory = getApplicationDirectory(cwd);
508
655
  const monorepoRoot = findRootSync(cwd);
509
656
  const dotenvPath = cliFlags.dotenvFolder && path.join(monorepoRoot.rootDir, cliFlags.dotenvFolder);
657
+
658
+ // The env itself is not important for the menu. However, the application config
659
+ // uses environment placeholders and therefore we need to provide the variables for it.
660
+ // TODO: Remove after all repositories migrated to NCR.
661
+ const cloudEnvironment = doesCloudEnvironmentExist({
662
+ dotenvPath,
663
+ cloudEnvironment: clusterContexts['ctp_staging_gcp_europe-west1_v1']
664
+ }) ? clusterContexts['ctp_staging_gcp_europe-west1_v1'] : 'ctp-gcp-staging';
510
665
  const processEnv = _objectSpread$1(_objectSpread$1({}, loadDotenvFiles({
511
666
  dotenvPath,
512
- // The env itself is not important for the menu. However, the application config
513
- // uses environment placeholders and therefore we need to provide the variables for it.
514
- // TODO: Remove after all repositories migrated to NCR.
515
- cloudEnvironment: doesCloudEnvironmentExist({
516
- dotenvPath,
517
- cloudEnvironment: '.env.ctp_staging_gcp_europe-west1_v1'
518
- }) ? 'ctp_staging_gcp_europe-west1_v1' : 'ctp-gcp-staging'
667
+ cloudEnvironment
519
668
  })), {}, {
520
669
  // Again, make sure that the environment is "development", otherwise
521
670
  // the menu config won't be available.
@@ -531,7 +680,7 @@ async function command$2(cliFlags, cwd) {
531
680
  });
532
681
  const applicationMenu = mapApplicationMenuConfigToGraqhQLMenuJson(applicationRuntimeConfig);
533
682
  const formattedJson = _JSON$stringify(applicationMenu, null, 2);
534
- fs.writeFileSync(path.join(applicationDirectory, 'menu.json'), formattedJson, {
683
+ fs$1.writeFileSync(path.join(applicationDirectory, 'menu.json'), formattedJson, {
535
684
  encoding: 'utf8'
536
685
  });
537
686
  }
@@ -564,7 +713,7 @@ async function command$1(cliFlags) {
564
713
  // Logging to stdout which is from where it will be picked
565
714
  // up by the caller (a bash script).
566
715
  if (cliFlags.outFile) {
567
- fs.writeFileSync(cliFlags.outFile, formattedJson, {
716
+ fs$1.writeFileSync(cliFlags.outFile, formattedJson, {
568
717
  encoding: 'utf8'
569
718
  });
570
719
  } else {
@@ -685,14 +834,14 @@ async function command(cliFlags) {
685
834
  const menuJsonPath = cliFlags.inputFile;
686
835
  const isAppbarMenu = cliFlags.navigation === 'top';
687
836
  if (!menuJsonPath) throw new Error(`--input-file cannot be empty. please provide the path of compiled menu.json`);
688
- if (!fs.existsSync(menuJsonPath)) throw new Error(`The menu.json file doesn't exist: ${menuJsonPath}`);
689
- const menuJson = fs.readFileSync(menuJsonPath, 'utf-8');
837
+ if (!fs$1.existsSync(menuJsonPath)) throw new Error(`The menu.json file doesn't exist: ${menuJsonPath}`);
838
+ const menuJson = fs$1.readFileSync(menuJsonPath, 'utf-8');
690
839
  return validateMenu(JSON.parse(menuJson), isAppbarMenu ? appbarMenuSchema : navbarMenuSchema);
691
840
  }
692
841
 
693
842
  var pkgJson = {
694
843
  name: "@commercetools-frontend/application-cli",
695
- version: "1.8.1",
844
+ version: "2.1.0",
696
845
  description: "Internal CLI to manage Merchant Center application deployments across various environments.",
697
846
  keywords: [
698
847
  "commercetools",
@@ -715,28 +864,28 @@ var pkgJson = {
715
864
  },
716
865
  dependencies: {
717
866
  "@babel/core": "^7.22.11",
718
- "@babel/runtime": "^7.21.0",
719
867
  "@babel/runtime-corejs3": "^7.21.0",
720
- "@commercetools-frontend/application-config": "22.11.0",
721
- "@commercetools-frontend/constants": "22.11.0",
722
- "@commercetools-frontend/l10n": "22.11.0",
868
+ "@babel/runtime": "^7.21.0",
869
+ "@commercetools-frontend/application-config": "22.16.0",
870
+ "@commercetools-frontend/constants": "22.16.0",
871
+ "@commercetools-frontend/l10n": "22.16.0",
723
872
  "@manypkg/find-root": "2.2.1",
724
873
  cac: "^6.7.14",
725
- cosmiconfig: "8.3.6",
726
- dotenv: "16.3.1",
874
+ cosmiconfig: "9.0.0",
875
+ dotenv: "16.3.2",
727
876
  execa: "5.1.1",
728
877
  jsonschema: "^1.4.1",
729
- listr2: "6.6.1",
730
- "node-fetch": "2.7.0"
878
+ listr2: "8.0.1",
879
+ "node-fetch": "2.7.0",
880
+ "ts-deepmerge": "7.0.0"
731
881
  },
732
882
  devDependencies: {
733
883
  "@tsconfig/node20": "20.1.2",
734
- "@types/node": "20.8.0",
735
- "@types/node-fetch": "2.6.2",
884
+ "@types/node": "20.11.5",
736
885
  typescript: "5.2.2"
737
886
  },
738
887
  engines: {
739
- node: ">=14",
888
+ node: ">=18",
740
889
  npm: ">=6"
741
890
  },
742
891
  publishConfig: {