@scandipwa/magento-scripts 2.1.4 → 2.2.0-alpha.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.
Files changed (96) hide show
  1. package/lib/config/docker.js +24 -10
  2. package/lib/config/get-magento-version-config.js +4 -1
  3. package/lib/config/php-config.js +2 -1
  4. package/lib/config/services/composer/versions/composer-1.js +1 -1
  5. package/lib/config/services/composer/versions/composer-2.2.js +8 -0
  6. package/lib/config/services/composer/versions/composer-2.js +1 -1
  7. package/lib/config/services/composer/versions/index.js +2 -1
  8. package/lib/config/services/elasticsearch/versions/elasticsearch-8.4.js +4 -1
  9. package/lib/config/services/elasticsearch/versions/elasticsearch-8.5.js +4 -1
  10. package/lib/config/services/elasticsearch/versions/elasticsearch-8.7.js +14 -0
  11. package/lib/config/services/elasticsearch/versions/index.js +3 -1
  12. package/lib/config/services/mysql/versions/mysql-8.0.js +1 -1
  13. package/lib/config/services/php/default-php-env.js +6 -0
  14. package/lib/config/services/php/versions/php-7.2.js +3 -1
  15. package/lib/config/services/php/versions/php-7.3.js +3 -1
  16. package/lib/config/services/php/versions/php-7.4.js +3 -1
  17. package/lib/config/services/php/versions/php-8.1.js +3 -1
  18. package/lib/config/services/php/versions/php-8.2.js +3 -1
  19. package/lib/config/ssl-config.js +9 -0
  20. package/lib/config/templates/nginx.fastcgi_params.template +2 -2
  21. package/lib/config/templates/nginx.template.conf +19 -2
  22. package/lib/config/templates/ssl-terminator.template.conf +2 -6
  23. package/lib/config/versions/index.js +16 -33
  24. package/lib/config/versions/magento-2.2.10.js +1 -9
  25. package/lib/config/versions/magento-2.3.0.js +1 -9
  26. package/lib/config/versions/magento-2.3.1.js +1 -9
  27. package/lib/config/versions/magento-2.3.2-p1.js +1 -9
  28. package/lib/config/versions/magento-2.3.2-p2.js +1 -9
  29. package/lib/config/versions/magento-2.3.2.js +1 -9
  30. package/lib/config/versions/magento-2.3.3-p1.js +1 -9
  31. package/lib/config/versions/magento-2.3.3.js +1 -9
  32. package/lib/config/versions/magento-2.3.4-p1.js +1 -9
  33. package/lib/config/versions/magento-2.3.4-p2.js +1 -9
  34. package/lib/config/versions/magento-2.3.4.js +1 -9
  35. package/lib/config/versions/magento-2.3.5-p1.js +1 -9
  36. package/lib/config/versions/magento-2.3.5-p2.js +1 -9
  37. package/lib/config/versions/magento-2.3.5.js +1 -14
  38. package/lib/config/versions/magento-2.3.6-p1.js +1 -9
  39. package/lib/config/versions/magento-2.3.6.js +1 -9
  40. package/lib/config/versions/magento-2.3.7-p1.js +1 -9
  41. package/lib/config/versions/magento-2.3.7-p2.js +1 -9
  42. package/lib/config/versions/magento-2.3.7-p3.js +1 -9
  43. package/lib/config/versions/magento-2.3.7-p4.js +1 -9
  44. package/lib/config/versions/magento-2.3.7.js +1 -9
  45. package/lib/config/versions/magento-2.4.0-p1.js +1 -9
  46. package/lib/config/versions/magento-2.4.0.js +1 -9
  47. package/lib/config/versions/magento-2.4.1-p1.js +1 -9
  48. package/lib/config/versions/magento-2.4.1.js +1 -9
  49. package/lib/config/versions/magento-2.4.2-p1.js +2 -10
  50. package/lib/config/versions/magento-2.4.2-p2.js +2 -10
  51. package/lib/config/versions/magento-2.4.2.js +1 -9
  52. package/lib/config/versions/magento-2.4.3-p1.js +2 -10
  53. package/lib/config/versions/magento-2.4.3-p2.js +2 -10
  54. package/lib/config/versions/magento-2.4.3-p3.js +2 -10
  55. package/lib/config/versions/magento-2.4.3.js +2 -10
  56. package/lib/config/versions/magento-2.4.4-p1.js +4 -13
  57. package/lib/config/versions/magento-2.4.4-p2.js +4 -13
  58. package/lib/config/versions/magento-2.4.4-p3.js +4 -13
  59. package/lib/config/versions/magento-2.4.4-p4.js +2 -10
  60. package/lib/config/versions/magento-2.4.4-p5.js +39 -0
  61. package/lib/config/versions/magento-2.4.4-p6.js +39 -0
  62. package/lib/config/versions/magento-2.4.4.js +4 -13
  63. package/lib/config/versions/magento-2.4.5-p1.js +4 -13
  64. package/lib/config/versions/magento-2.4.5-p2.js +4 -13
  65. package/lib/config/versions/magento-2.4.5-p3.js +2 -10
  66. package/lib/config/versions/magento-2.4.5-p4.js +39 -0
  67. package/lib/config/versions/magento-2.4.5-p5.js +39 -0
  68. package/lib/config/versions/magento-2.4.5.js +3 -12
  69. package/lib/config/versions/magento-2.4.6-p1.js +2 -10
  70. package/lib/config/versions/magento-2.4.6-p2.js +39 -0
  71. package/lib/config/versions/magento-2.4.6-p3.js +39 -0
  72. package/lib/config/versions/magento-2.4.6.js +2 -10
  73. package/lib/config/versions/magento-2.4.7-beta2.js +39 -0
  74. package/lib/tasks/database/import-remote-db/ssh/database-dump-command.js +0 -2
  75. package/lib/tasks/database/import-remote-db/ssh/readymage.js +29 -28
  76. package/lib/tasks/docker/containers/container-api.d.ts +5 -0
  77. package/lib/tasks/docker/containers/container-api.js +4 -1
  78. package/lib/tasks/docker/project-image-builder.js +21 -0
  79. package/lib/tasks/file-system/create-nginx-config.js +7 -2
  80. package/lib/tasks/file-system/create-ssl-terminator-config.js +9 -7
  81. package/lib/tasks/magento/install-magento-project.js +10 -7
  82. package/lib/tasks/magento/setup-magento/configure-elasticsearch.js +1 -1
  83. package/lib/tasks/magento/setup-magento/index-products.js +41 -1
  84. package/lib/tasks/magento/setup-magento/index.js +4 -1
  85. package/lib/tasks/magento/setup-magento/set-base-url.js +121 -13
  86. package/lib/tasks/requirements/elasticsearch-version.js +62 -6
  87. package/lib/util/config-file-validator.js +60 -19
  88. package/lib/util/config-php-json.js +2 -0
  89. package/lib/util/database.js +83 -1
  90. package/lib/util/instance-metadata.js +16 -19
  91. package/lib/util/match-filesystem.js +1 -0
  92. package/lib/util/run-magento.js +1 -0
  93. package/package.json +2 -2
  94. package/tsconfig.json +2 -1
  95. package/typings/common.d.ts +53 -0
  96. package/typings/index.d.ts +55 -0
@@ -1,5 +1,6 @@
1
1
  const UnknownError = require('../../errors/unknown-error')
2
- const { runContainerImage } = require('../../util/run-container-image')
2
+ const logger = require('@scandipwa/scandipwa-dev-utils/logger')
3
+ const { containerApi } = require('../docker/containers')
3
4
 
4
5
  /**
5
6
  * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
@@ -7,10 +8,64 @@ const { runContainerImage } = require('../../util/run-container-image')
7
8
  const checkElasticSearchVersion = () => ({
8
9
  title: 'Checking container ElasticSearch version',
9
10
  task: async (ctx, task) => {
10
- const elasticSearchVersionResponse = await runContainerImage(
11
- ctx.config.overridenConfiguration.configuration.elasticsearch.image,
12
- 'elasticsearch --version'
13
- )
11
+ const { elasticsearch } =
12
+ ctx.config.overridenConfiguration.configuration
13
+ const { ports } = ctx
14
+
15
+ let elasticSearchVersionResponse
16
+
17
+ try {
18
+ elasticSearchVersionResponse = await containerApi.run({
19
+ ...elasticsearch,
20
+ command: 'elasticsearch --version',
21
+ detach: false,
22
+ rm: true,
23
+ ports: [`127.0.0.1:${ports.elasticsearch}:9200`],
24
+ memory: '512mb'
25
+ })
26
+ } catch (e) {
27
+ elasticSearchVersionResponse = e.message
28
+ }
29
+
30
+ // if (elasticSearchVersionResponse === '') {
31
+ // const tryDisablingSwappingForES = await task.prompt({
32
+ // type: 'Select',
33
+ // message: `It looks like ElasticSearch wasn't able to start properly, do you want to try disabling swapping and running it again?
34
+
35
+ // (Note that if it works, you should edit cma.js and add this to ${logger.style.code(
36
+ // 'configuration.elasticsearch.env'
37
+ // )} as { 'bootstrap.mlockall': false })`,
38
+ // choices: [
39
+ // {
40
+ // name: 'yes',
41
+ // message: `Try disabling swapping and run ElasticSearch`
42
+ // },
43
+ // {
44
+ // name: 'no',
45
+ // message: "Skip, I don't care"
46
+ // }
47
+ // ]
48
+ // })
49
+
50
+ // if (tryDisablingSwappingForES === 'yes') {
51
+ // try {
52
+ // elasticSearchVersionResponse = await containerApi.run({
53
+ // ...elasticsearch,
54
+ // env: {
55
+ // ...elasticsearch.env,
56
+ // 'bootstrap.mlockall': false
57
+ // },
58
+ // command: 'elasticsearch --version',
59
+ // detach: false,
60
+ // rm: true,
61
+ // ports: [`127.0.0.1:${ports.elasticsearch}:9200`],
62
+ // memory: '512mb'
63
+ // })
64
+ // } catch (e) {
65
+ // elasticSearchVersionResponse = e.message
66
+ // }
67
+ // }
68
+ // }
14
69
 
15
70
  const elasticSearchVersionResponseResult =
16
71
  elasticSearchVersionResponse.match(/Version:\s(\d+\.\d+\.\d+)/i)
@@ -28,7 +83,8 @@ const checkElasticSearchVersion = () => ({
28
83
  `Cannot retrieve ElasticSearch Version!\n\n${elasticSearchVersionResponse}`
29
84
  )
30
85
  }
31
- }
86
+ },
87
+ exitOnError: false
32
88
  })
33
89
 
34
90
  module.exports = checkElasticSearchVersion
@@ -25,17 +25,7 @@ const versionValidator = (value, helpers) => {
25
25
  const isValidComposerVersion = composerVersionRegex.test(value)
26
26
 
27
27
  if (!isValidComposerVersion) {
28
- return helpers.error('any.invalid', {
29
- label: `Not a valid composer version!
30
- Allowed patterns:
31
- - latest-stable
32
- - latest-preview
33
- - latest-2.2.x
34
- - latest-2.x
35
- - latest-1.x
36
- - 2.2.21
37
- `
38
- })
28
+ return helpers.error('any.invalid')
39
29
  }
40
30
 
41
31
  return undefined
@@ -64,9 +54,25 @@ const magentoSchema = Joi.object({
64
54
  * @type {Joi.ObjectSchema<import('../../typings').SSLConfiguration>}
65
55
  */
66
56
  const sslSchema = Joi.object({
67
- enabled: Joi.bool().required(),
68
- ssl_certificate: Joi.string().required(),
69
- ssl_certificate_key: Joi.string().required()
57
+ enabled: Joi.boolean().required(),
58
+ ssl_certificate: Joi.string().optional(),
59
+ ssl_certificate_key: Joi.string().optional(),
60
+ external_provider: Joi.boolean().optional()
61
+ }).custom((d, helpers) => {
62
+ if (d.enabled) {
63
+ if (!d.ssl_certificate && !d.external_provider) {
64
+ return helpers.error(
65
+ 'ssl_certificate must be provided! or set ssl.external_provider to true!'
66
+ )
67
+ }
68
+ if (!d.ssl_certificate_key && !d.external_provider) {
69
+ return helpers.error(
70
+ 'ssl_certificate_key must be provided! or set ssl.external_provider to true!'
71
+ )
72
+ }
73
+ }
74
+
75
+ return true
70
76
  })
71
77
 
72
78
  /**
@@ -92,7 +98,10 @@ const phpConfigurationSchema = Joi.object({
92
98
  fpmConfigTemplate: Joi.string().optional(),
93
99
  configTemplate: Joi.string().optional().custom(fileExistsValidator),
94
100
  debugTemplate: Joi.string().optional().custom(fileExistsValidator),
95
- extensions: phpExtensionConfiguration.optional()
101
+ extensions: phpExtensionConfiguration.optional(),
102
+ env: Joi.object()
103
+ .pattern(Joi.string(), [Joi.string(), Joi.number()])
104
+ .optional()
96
105
  })
97
106
 
98
107
  /**
@@ -150,6 +159,19 @@ const composerConfigurationSchema = Joi.object({
150
159
  }
151
160
 
152
161
  return versionValidator(value, helper)
162
+ })
163
+ .messages({
164
+ 'any.invalid': `Composer version is not valid!
165
+ Allowed patterns:
166
+ - latest-stable
167
+ - latest-preview
168
+ - latest-2.2.x
169
+ - latest-2.x
170
+ - latest-1.x
171
+ - 2.2.21
172
+
173
+ Please check you composer configuration in cma.js!
174
+ `
153
175
  }),
154
176
  plugins: Joi.object().pattern(
155
177
  Joi.string(),
@@ -161,6 +183,23 @@ const composerConfigurationSchema = Joi.object({
161
183
  )
162
184
  })
163
185
 
186
+ /**
187
+ * @type {Joi.ObjectSchema<import('../../typings').NewRelicConfiguration>}
188
+ */
189
+ const newRelicConfigurationSchema = Joi.object({
190
+ enabled: Joi.boolean().optional(),
191
+ agentVersion: Joi.string().optional(),
192
+ licenseKey: Joi.string().optional()
193
+ }).custom((d, helpers) => {
194
+ if (d.enabled && !d.licenseKey) {
195
+ return helpers.error(
196
+ 'when newRelic is enabled license key is required!'
197
+ )
198
+ }
199
+
200
+ return true
201
+ })
202
+
164
203
  /**
165
204
  * @type {Joi.ObjectSchema<import('../../typings').CMAConfiguration['configuration']>}
166
205
  */
@@ -173,7 +212,8 @@ const configurationSchema = Joi.object({
173
212
  composer: composerConfigurationSchema.optional(),
174
213
  varnish: varnishConfigurationSchema.optional(),
175
214
  sslTerminator: nginxConfigurationSchema.optional(),
176
- maildev: serviceConfigurationSchema.optional()
215
+ maildev: serviceConfigurationSchema.optional(),
216
+ newRelic: newRelicConfigurationSchema.optional()
177
217
  })
178
218
 
179
219
  /**
@@ -182,8 +222,9 @@ const configurationSchema = Joi.object({
182
222
  const configFileSchema = Joi.object({
183
223
  magento: magentoSchema.required(),
184
224
  host: Joi.string().optional(),
225
+ storeDomains: Joi.object().pattern(Joi.string(), Joi.string()).optional(),
185
226
  ssl: sslSchema.optional(),
186
- prefix: Joi.bool().optional(),
227
+ prefix: Joi.boolean().optional(),
187
228
  configuration: configurationSchema.required()
188
229
  })
189
230
 
@@ -191,8 +232,8 @@ const configFileSchema = Joi.object({
191
232
  * @type {Joi.ObjectSchema<{ useNonOverlappingPorts:boolean, analytics:boolean }>}
192
233
  */
193
234
  const systemConfigurationSchema = Joi.object({
194
- useNonOverlappingPorts: Joi.bool().optional(),
195
- analytics: Joi.bool().optional()
235
+ useNonOverlappingPorts: Joi.boolean().optional(),
236
+ analytics: Joi.boolean().optional()
196
237
  })
197
238
 
198
239
  module.exports = {
@@ -5,6 +5,8 @@ const pathExists = require('./path-exists')
5
5
 
6
6
  /**
7
7
  * @param {import('../../typings/context').ListrContext} ctx
8
+ *
9
+ * @returns {Promise<import('../../typings/common').ConfigPHPType | null>}
8
10
  */
9
11
  const configPhpToJson = async (ctx) => {
10
12
  const configPhpOnSystemPath = path.join(
@@ -99,7 +99,89 @@ const isTableExists = async (database, tableName, { databaseConnection }) => {
99
99
  return tableCount > 0
100
100
  }
101
101
 
102
+ /**
103
+ * @param {TemplateStringsArray} sqlString
104
+ * @param {...any} variables
105
+ * @returns {string}
106
+ */
107
+ const sql = (sqlString, ...variables) => {
108
+ return sqlString.reduce(
109
+ (acc, val, i) =>
110
+ `${acc}${
111
+ typeof variables[i] === 'undefined'
112
+ ? ''
113
+ : typeof variables[i] === 'string'
114
+ ? `'${variables[i]}'`
115
+ : String(variables[i])
116
+ }${val}`,
117
+ ''
118
+ )
119
+ }
120
+
121
+ /**
122
+ * @param {Object} param0
123
+ * @param {string} param0.table
124
+ * @param {[string, string, any][]} param0.where
125
+ * @param {Record<string, any>} param0.data
126
+ * @param {import('../../typings/context').ListrContext} param1
127
+ */
128
+ const databaseQuery = async (
129
+ { table, where, data },
130
+ { databaseConnection }
131
+ ) => {
132
+ const values = Object.entries(data).map(([key, val]) => ({
133
+ path: key,
134
+ value: val
135
+ }))
136
+
137
+ const whereInQuery = where
138
+ .map(([key, operator, val]) => `${key} ${operator} ${sql`${val}`}`)
139
+ .join(' AND ')
140
+
141
+ const query = `
142
+ SELECT * FROM ${table}
143
+ WHERE ${whereInQuery};`
144
+
145
+ const [rows] = await databaseConnection.query(query)
146
+
147
+ if (rows.length === 0) {
148
+ const query2 = `INSERT INTO ${table}
149
+ (${[...where.map(([key]) => key), ...values.map((p) => p.path)].join(
150
+ ', '
151
+ )})
152
+ VALUES (${[
153
+ ...where.map(([, , val]) => sql`${val}`),
154
+ ...values.map((p) => sql`${p.value}`)
155
+ ].join(', ')});`
156
+
157
+ await databaseConnection.query(query2)
158
+
159
+ return true
160
+ }
161
+
162
+ const [row] = rows
163
+
164
+ const incorrectData = Object.entries(data).filter(
165
+ ([key, val]) => row[key] !== val
166
+ )
167
+
168
+ if (incorrectData.length > 0) {
169
+ await databaseConnection.query(
170
+ `UPDATE ${table}
171
+ SET ${incorrectData
172
+ .map(([key, val]) => `${key} = ${sql`${val}`}`)
173
+ .join(', ')}
174
+ WHERE ${whereInQuery};`
175
+ )
176
+
177
+ return true
178
+ }
179
+
180
+ return false
181
+ }
182
+
102
183
  module.exports = {
103
184
  updateTableValues,
104
- isTableExists
185
+ isTableExists,
186
+ databaseQuery
105
187
  }
@@ -24,7 +24,7 @@ const getInstanceMetadata = (ctx) => {
24
24
  ports,
25
25
  config: {
26
26
  magentoConfiguration,
27
- overridenConfiguration: { host, ssl }
27
+ overridenConfiguration: { ssl, storeDomains }
28
28
  }
29
29
  } = ctx
30
30
 
@@ -43,25 +43,22 @@ const getInstanceMetadata = (ctx) => {
43
43
  */
44
44
  const maildev = []
45
45
 
46
- const isNgrok = host.endsWith('ngrok.io')
46
+ frontend.push({
47
+ title: WEB_LOCATION_TITLE,
48
+ text: `${ssl.enabled ? 'https' : 'http'}://${storeDomains.admin}${
49
+ ssl.enabled || ports.sslTerminator === 80
50
+ ? ''
51
+ : `:${ports.sslTerminator}`
52
+ }/`
53
+ })
47
54
 
48
- if (isNgrok) {
49
- frontend.push({
50
- title: WEB_LOCAL_LOCATION_TITLE,
51
- text: `${ssl.enabled ? 'https' : 'http'}://localhost${
52
- ssl.enabled || ports.sslTerminator === 80
53
- ? ''
54
- : `:${ports.sslTerminator}`
55
- }/`
56
- })
57
- frontend.push({
58
- title: WEB_LOCATION_TITLE,
59
- text: `${ssl.enabled ? 'https' : 'http'}://${host}/`
60
- })
61
- } else {
55
+ for (const [storeCode, domain] of Object.entries(storeDomains)) {
56
+ if (storeCode === 'admin') {
57
+ continue
58
+ }
62
59
  frontend.push({
63
- title: WEB_LOCATION_TITLE,
64
- text: `${ssl.enabled ? 'https' : 'http'}://${host}${
60
+ title: `Frontend store ${logger.style.file(storeCode)} location`,
61
+ text: `${ssl.enabled ? 'https' : 'http'}://${domain}${
65
62
  ssl.enabled || ports.sslTerminator === 80
66
63
  ? ''
67
64
  : `:${ports.sslTerminator}`
@@ -87,7 +84,7 @@ const getInstanceMetadata = (ctx) => {
87
84
 
88
85
  maildev.push({
89
86
  title: WEB_MAILDEV_LOCATION_TITLE,
90
- text: `http://${host}:${ports.maildevWeb}/`
87
+ text: `http://localhost:${ports.maildevWeb}/`
91
88
  })
92
89
 
93
90
  return {
@@ -17,6 +17,7 @@ const matchFilesystem = async (cwd, structure) => {
17
17
 
18
18
  return ok
19
19
  }
20
+
20
21
  if (typeof structure === 'object') {
21
22
  const ok = (
22
23
  await Promise.all(
@@ -6,6 +6,7 @@ const { runPHPContainerCommand } = require('../tasks/php/php-container')
6
6
  * @param {import('../../typings/context').ListrContext} ctx
7
7
  * @param {String} command magento command
8
8
  * @param {Parameters<typeof import('../tasks/php/php-container')['runPHPContainerCommand']>[2] & { throwNonZeroCode?: boolean }} options
9
+ * @returns {Promise<{ code: number, result: string }>}
9
10
  */
10
11
  const runMagentoCommand = async (ctx, command, options = {}) => {
11
12
  const { throwNonZeroCode = true } = options
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Scripts and configuration used by CMA.",
4
4
  "homepage": "https://docs.create-magento-app.com/",
5
5
  "repository": "github:scandipwa/create-magento-app",
6
- "version": "2.1.4",
6
+ "version": "2.2.0-alpha.0",
7
7
  "main": "./index.js",
8
8
  "types": "./typings/index.d.ts",
9
9
  "license": "OSL-3.0",
@@ -58,5 +58,5 @@
58
58
  "devDependencies": {
59
59
  "@types/yargs": "^17.0.13"
60
60
  },
61
- "gitHead": "71b3bef6b620023fedca851dd529b60e22b113e0"
61
+ "gitHead": "f019bf2b569373558c7a90a036db5a4464ece57f"
62
62
  }
package/tsconfig.json CHANGED
@@ -12,7 +12,8 @@
12
12
  "moduleResolution": "Node",
13
13
  "types": [
14
14
  "./typings"
15
- ]
15
+ ],
16
+ "noEmit": true
16
17
  },
17
18
  "exclude": [
18
19
  "**/node_modules",
@@ -0,0 +1,53 @@
1
+ import { CMAConfiguration, ServiceWithImage } from "./index"
2
+ import { ListrContext } from "./context"
3
+
4
+ export type MagentoVersionConfigurationFunction = (args: ListrContext['config']['baseConfig']) => MagentoVersionConfiguration
5
+
6
+ export type MagentoVersionConfiguration = CMAConfigurationWithMySQL & {
7
+ magentoVersion: string
8
+ isDefault?: boolean
9
+ }
10
+
11
+ export type CMAConfigurationWithMySQL = Optional<CMAConfiguration, 'storeDomains' | 'host' | 'magento' | 'prefix' | 'ssl'> & {
12
+ configuration: {
13
+ mysql: Optional<ServiceWithImage, 'image'>
14
+ }
15
+ }
16
+
17
+ type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>
18
+
19
+ export interface ConfigPHPType {
20
+ modules: Record<string, number>
21
+ scopes?: {
22
+ websites: {
23
+ [websiteCode: string]: {
24
+ website_id: string
25
+ code: string
26
+ name: string
27
+ sort_order: string
28
+ default_group_id: string
29
+ is_default: string
30
+ }
31
+ }
32
+ groups: {
33
+ group_id: string
34
+ website_id: string
35
+ code: string
36
+ name: string
37
+ root_category_id: string
38
+ default_store_id: string
39
+ }[]
40
+ stores: {
41
+ [storeCode: string]: {
42
+ store_id: string
43
+ code: string
44
+ website_id: string
45
+ group_id: string
46
+ name: string
47
+ sort_order: string
48
+ is_active: string
49
+ }
50
+ }
51
+ }
52
+ system?: any
53
+ }
@@ -202,6 +202,11 @@ export interface PHPConfiguration {
202
202
  * Extensions for PHP
203
203
  */
204
204
  extensions: PHPExtensions
205
+
206
+ /**
207
+ * Environmental variables used for PHP container
208
+ */
209
+ env: Record<string, unknown>
205
210
  }
206
211
  export interface SSLConfiguration {
207
212
  /**
@@ -224,6 +229,32 @@ export interface SSLConfiguration {
224
229
  * `./ssl_certificate-key.pem`
225
230
  */
226
231
  ssl_certificate_key?: string
232
+
233
+ /**
234
+ * SSL external provider configuration
235
+ *
236
+ * Set to `true` if you don't need locally provided SSL certificates
237
+ *
238
+ * @default false
239
+ */
240
+ external_provider?: boolean
241
+ }
242
+
243
+ export interface NewRelicConfiguration {
244
+ /**
245
+ * Enables or disables New Relic in application
246
+ */
247
+ enabled: boolean
248
+
249
+ /**
250
+ * New Relic Agent version
251
+ */
252
+ agentVersion?: string
253
+
254
+ /**
255
+ * New Relic license key
256
+ */
257
+ licenseKey?: string
227
258
  }
228
259
 
229
260
  export interface CMAConfiguration {
@@ -271,6 +302,11 @@ export interface CMAConfiguration {
271
302
  */
272
303
  sslTerminator: SSLTerminatorConfiguration
273
304
 
305
+ /**
306
+ * New Relic configuration
307
+ */
308
+ newRelic?: NewRelicConfiguration
309
+
274
310
  /**
275
311
  * MailDev configuration
276
312
  */
@@ -316,9 +352,28 @@ export interface CMAConfiguration {
316
352
  /**
317
353
  * Custom host for website base url
318
354
  * @default 'localhost'
355
+ *
356
+ * @deprecated Use `storeDomains` instead, as follows: `storeDomains: { admin: 'localhost' }`
319
357
  */
320
358
  host: string
321
359
 
360
+ /**
361
+ * Custom domains for magento stores by store code
362
+ *
363
+ * Note: you can look up **scope_id** in `app/etc/config.php` in `scopes` section.
364
+ *
365
+ * @default { admin: 'localhost' }
366
+ *
367
+ * @example ```js
368
+ * storeDomains: {
369
+ * admin: 'localhost',
370
+ * custom_store_code: 'scandipwa.local',
371
+ * another_store_code: 'another-store.local'
372
+ * }
373
+ * ```
374
+ */
375
+ storeDomains: { admin: string } & Record<string, string>
376
+
322
377
  /**
323
378
  * SSL Configuration
324
379
  */