@automattic/vip 2.31.1-dev → 2.31.1-dev2

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 (36) hide show
  1. package/.editorconfig +11 -0
  2. package/.prettierignore +6 -0
  3. package/CONTRIBUTING.md +17 -13
  4. package/dist/bin/vip-app-list.js +12 -10
  5. package/dist/bin/vip-dev-env-start.js +1 -1
  6. package/dist/bin/vip-dev-env-sync-sql.js +1 -1
  7. package/dist/bin/vip-import-media-abort.js +3 -3
  8. package/dist/bin/vip-import-media.js +3 -3
  9. package/dist/bin/vip-import-sql.js +2 -1
  10. package/dist/bin/vip-sync.js +27 -13
  11. package/dist/bin/vip-validate-preflight.js +16 -14
  12. package/dist/bin/vip-wp.js +9 -9
  13. package/dist/commands/backup-db.js +6 -6
  14. package/dist/commands/export-sql.js +2 -2
  15. package/dist/lib/api/cache-purge.js +2 -10
  16. package/dist/lib/app-logs/app-logs.js +10 -4
  17. package/dist/lib/cli/format.js +2 -2
  18. package/dist/lib/config/software.js +10 -9
  19. package/dist/lib/constants/dev-environment.js +3 -6
  20. package/dist/lib/dev-environment/dev-environment-cli.js +3 -3
  21. package/dist/lib/dev-environment/dev-environment-core.js +52 -41
  22. package/dist/lib/dev-environment/dev-environment-lando.js +3 -1
  23. package/dist/lib/envvar/api-delete.js +2 -11
  24. package/dist/lib/envvar/api-get-all.js +3 -10
  25. package/dist/lib/envvar/api-list.js +3 -10
  26. package/dist/lib/envvar/api-set.js +2 -12
  27. package/dist/lib/media-import/status.js +18 -18
  28. package/dist/lib/validations/site-type.js +1 -1
  29. package/dist/lib/validations/sql.js +2 -1
  30. package/dist/lib/vip-import-validate-files.js +1 -0
  31. package/helpers/check-version.js +7 -5
  32. package/helpers/prepublishOnly.js +88 -0
  33. package/npm-shrinkwrap.json +101 -3167
  34. package/package.json +10 -10
  35. package/tsconfig.json +5 -9
  36. package/automattic-vip-2.31.1-dev.tgz +0 -0
package/.editorconfig ADDED
@@ -0,0 +1,11 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ indent_style = tab
7
+ insert_final_newline = true
8
+ trim_trailing_whitespace = true
9
+
10
+ [*.json,*.yaml,*.yml]
11
+ indent_style = space
@@ -0,0 +1,6 @@
1
+ *.generated.d.ts
2
+ /CHANGELOG.md
3
+ /__fixtures__/
4
+ /dist/
5
+ /flow-typed/
6
+ /src/graphqlTypes.d.ts
package/CONTRIBUTING.md CHANGED
@@ -35,35 +35,38 @@ Who doesn't like a good console.log for debugging?
35
35
  Well, sometimes it's insufficient, luckily it's not too complicated to use a debugger.
36
36
 
37
37
  1. First, make sure to run the `npm run build:watch`, this will generate source maps
38
- 2. Run the command you want via `node --inspect`, like so: `node --inspect ./dist/bin/vip-dev-env-import-sql.js`
38
+ 2. Run the command you want via `node --inspect`, like so: `node --inspect ./dist/bin/vip-dev-env-import-sql.js`
39
39
  3. Note the port the debugger is listening on:
40
+
40
41
  ```
41
42
  Debugger listening on ws://127.0.0.1:9229/db6c03e9-2585-4a08-a1c6-1fee0295c9ff
42
43
  For help, see: https://nodejs.org/en/docs/inspector
43
44
  ```
45
+
44
46
  4. In your editor of choice attach to the debugger. For VSCode: Hit 'Run and Debug' panel, hit the "gear" icon (open launch.json), make your `Attach` configuration entry to look like so:
45
- Make sure the `port` matches the port from step 3, and the `runtimeExecutable` matches the exact `node` executable you ran. If you use a version manager like `nvm`, its especially important to check this.
47
+ Make sure the `port` matches the port from step 3, and the `runtimeExecutable` matches the exact `node` executable you ran. If you use a version manager like `nvm`, its especially important to check this.
46
48
 
47
49
  ```json
48
- {
49
- "name": "Attach",
50
- "port": 9229,
51
- "request": "attach",
52
- "skipFiles": ["<node_internals>/**"],
53
- "type": "node",
54
- "runtimeExecutable": "/Users/user/.nvm/versions/node/v14.18.2/bin/node"
55
- }
50
+ {
51
+ "name": "Attach",
52
+ "port": 9229,
53
+ "request": "attach",
54
+ "skipFiles": [ "<node_internals>/**" ],
55
+ "type": "node",
56
+ "runtimeExecutable": "/Users/user/.nvm/versions/node/v14.18.2/bin/node"
57
+ }
56
58
  ```
57
59
 
58
60
  5. Set your breakpoints and whatnot, hit the play button.
59
61
  6. Confirm that you attached the debugger to continue command execution
60
62
  7. Squash them bugs 🐛🔨.
61
63
  8. [Optional but recommended] Pay it forward and implement a similar approach to other internal/external tooling.
64
+
62
65
  ### Adding commands
63
66
 
64
- * New command names should use the singular form (e.g. site vs sites).
65
- * Add new commands to `package.json#bin`.
66
- * Run `npm link` so that `arg` knows how to spawn the command locally. (Skipping this step will result in `Error: spawn vip-command ENOENT`.)
67
+ - New command names should use the singular form (e.g. site vs sites).
68
+ - Add new commands to `package.json#bin`.
69
+ - Run `npm link` so that `arg` knows how to spawn the command locally. (Skipping this step will result in `Error: spawn vip-command ENOENT`.)
67
70
 
68
71
  ### Adding libraries
69
72
 
@@ -83,6 +86,7 @@ Our release flow for VIP CLI follows this pattern:
83
86
  - Finally, release your changes as a new minor or major NPM version. Ping in the #vip-platform channel to notify folks of a new release, but please feel free to release your changes without any blockers from the team. Any team member that is part of the Automattic NPM organization can release a new version; if you aren't a member, generic credentials are available in the Secret Store.
84
87
 
85
88
  ### Changelogs
89
+
86
90
  Changelogs allow customers to keep up with all the changes happening across our VIP Platform. Changelogs for VIP CLI are posted to the [VIP Cloud Changelog P2](https://wpvipchangelog.wordpress.com/), along with the repository’s `README.md`.
87
91
 
88
92
  ## Releasing / Publishing
@@ -21,17 +21,19 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
21
21
  try {
22
22
  response = await api.query({
23
23
  // $FlowFixMe: gql template is not supported by flow
24
- query: (0, _graphqlTag.default)`query Apps( $first: Int, $after: String ) {
25
- apps( first: $first, after: $after ) {
26
- total,
27
- nextCursor
28
- edges {
29
- id,
30
- name,
31
- repo
32
- }
24
+ query: (0, _graphqlTag.default)`
25
+ query Apps($first: Int, $after: String) {
26
+ apps(first: $first, after: $after) {
27
+ total
28
+ nextCursor
29
+ edges {
30
+ id
31
+ name
32
+ repo
33
33
  }
34
- }`,
34
+ }
35
+ }
36
+ `,
35
37
  variables: {
36
38
  first: 100,
37
39
  after: null // TODO make dynamic
@@ -31,7 +31,7 @@ const examples = [{
31
31
  usage: `${_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND} start`,
32
32
  description: 'Starts a local dev environment'
33
33
  }];
34
- (0, _command.default)().option('slug', 'Custom name of the dev environment').option('skip-rebuild', 'Only start stopped services').option(['w', 'skip-wp-versions-check'], 'Skip propting for wordpress update if non latest').option('vscode', 'Open environment workspace in VSCode').examples(examples).argv(process.argv, async (arg, opt) => {
34
+ (0, _command.default)().option('slug', 'Custom name of the dev environment').option('skip-rebuild', 'Only start stopped services').option(['w', 'skip-wp-versions-check'], 'Skip prompt to update WordPress version if not on latest').option('vscode', 'Generate a Visual Studio Code Workspace file and open it').examples(examples).argv(process.argv, async (arg, opt) => {
35
35
  const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
36
36
  const lando = await (0, _devEnvironmentLando.bootstrapLando)();
37
37
  await (0, _devEnvironmentCli.validateDependencies)(lando, slug);
@@ -24,7 +24,7 @@ var _tracker = require("../lib/tracker");
24
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
25
  const examples = [{
26
26
  usage: `${_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND} sync sql @my-test.develop --slug=my_site`,
27
- description: 'Syncs with the `my-test` site\'s `develop` environment database into `my_site`'
27
+ description: "Syncs with the `my-test` site's `develop` environment database into `my_site`"
28
28
  }];
29
29
  const appQuery = `
30
30
  id,
@@ -41,8 +41,8 @@ const appQuery = `
41
41
  }
42
42
  `;
43
43
  const ABORT_IMPORT_MUTATION = (0, _graphqlTag.default)`
44
- mutation AbortMediaImport( $input: AppEnvironmentAbortMediaImportInput ) {
45
- abortMediaImport( input: $input ) {
44
+ mutation AbortMediaImport($input: AppEnvironmentAbortMediaImportInput) {
45
+ abortMediaImport(input: $input) {
46
46
  applicationId
47
47
  environmentId
48
48
  mediaImportStatusChange {
@@ -60,7 +60,7 @@ const ABORT_IMPORT_MUTATION = (0, _graphqlTag.default)`
60
60
  envContext: true,
61
61
  requiredArgs: 0,
62
62
  requireConfirm: `
63
- ${_chalk.default.red.bold('By running this command, the Media Import running on your App will stop and can\'t be resumed.')}
63
+ ${_chalk.default.red.bold("By running this command, the Media Import running on your App will stop and can't be resumed.")}
64
64
  ${_chalk.default.red.bold('Are you sure you want to abort this Media Import?')}
65
65
  `
66
66
  }).argv(process.argv, async (arg, {
@@ -38,8 +38,8 @@ const appQuery = `
38
38
  }
39
39
  `;
40
40
  const START_IMPORT_MUTATION = (0, _graphqlTag.default)`
41
- mutation StartMediaImport( $input: AppEnvironmentStartMediaImportInput ) {
42
- startMediaImport( input: $input ) {
41
+ mutation StartMediaImport($input: AppEnvironmentStartMediaImportInput) {
42
+ startMediaImport(input: $input) {
43
43
  applicationId
44
44
  environmentId
45
45
  mediaImportStatus {
@@ -83,7 +83,7 @@ function isSupportedUrl(urlToTest) {
83
83
  module: 'import-media',
84
84
  requiredArgs: 1,
85
85
  requireConfirm: `
86
- ${_chalk.default.red.bold('NOTE: If the provided archive\'s directory structure contains an `uploads/` directory,')}
86
+ ${_chalk.default.red.bold("NOTE: If the provided archive's directory structure contains an `uploads/` directory,")}
87
87
  ${_chalk.default.red.bold('only the files present inside that directory will be imported and the rest will be ignored.')}
88
88
  ${_chalk.default.red.bold('If no `uploads/` directory is found, all files will be imported, as is.')}
89
89
 
@@ -296,7 +296,8 @@ const displayPlaybook = ({
296
296
  if (wpSite.id === 1) {
297
297
  siteRegex = /^wp_[a-z]+/i;
298
298
  } else {
299
- siteRegex = new RegExp(`^wp_${wpSite.id}_[a-z]+`, 'i');
299
+ // eslint-disable-next-line security/detect-non-literal-regexp
300
+ siteRegex = new RegExp(`^wp_${parseInt(wpSite.id, 10)}_[a-z]+`, 'i');
300
301
  }
301
302
  const tableNamesInGroup = tableNames.filter(name => siteRegex.test(name));
302
303
  return {
@@ -35,14 +35,14 @@ const appQuery = `id,name,environments{
35
35
  await api.mutate({
36
36
  // $FlowFixMe: gql template is not supported by flow
37
37
  mutation: (0, _graphqlTag.default)`
38
- mutation SyncEnvironmentMutation($input: AppEnvironmentSyncInput){
39
- syncEnvironment(input: $input){
40
- environment{
41
- id
42
- }
43
- }
38
+ mutation SyncEnvironmentMutation($input: AppEnvironmentSyncInput) {
39
+ syncEnvironment(input: $input) {
40
+ environment {
41
+ id
44
42
  }
45
- `,
43
+ }
44
+ }
45
+ `,
46
46
  variables: {
47
47
  input: {
48
48
  id: opts.app.id,
@@ -106,15 +106,29 @@ const appQuery = `id,name,environments{
106
106
  // The rest of the iterations are just for moving the spinner
107
107
  api.query({
108
108
  // $FlowFixMe: gql template is not supported by flow
109
- query: (0, _graphqlTag.default)`query App( $id: Int, $sync: Int ) {
110
- app( id: $id ){
111
- id,name,environments{
112
- id,name,defaultDomain,branch,datacenter,syncProgress( sync: $sync ){
113
- status,sync,steps{name,status}
109
+ query: (0, _graphqlTag.default)`
110
+ query App($id: Int, $sync: Int) {
111
+ app(id: $id) {
112
+ id
113
+ name
114
+ environments {
115
+ id
116
+ name
117
+ defaultDomain
118
+ branch
119
+ datacenter
120
+ syncProgress(sync: $sync) {
121
+ status
122
+ sync
123
+ steps {
124
+ name
125
+ status
126
+ }
114
127
  }
115
128
  }
116
129
  }
117
- }`,
130
+ }
131
+ `,
118
132
  fetchPolicy: 'network-only',
119
133
  variables: {
120
134
  id: opts.app.id,
@@ -68,19 +68,20 @@ async function getBuildConfiguration(application, environment) {
68
68
  // Disable the global GraphQL error handling, so we can catch Unauthorized errors and recommend next steps.
69
69
  (0, _api.disableGlobalGraphQLErrorHandling)();
70
70
  const buildConfigQuery = (0, _graphqlTag.default)`
71
- query BuildConfig( $appId: Int, $envId: Int ) {
72
- app(id: $appId) {
73
- environments(id: $envId) {
74
- id,
75
- buildConfiguration {
76
- buildType
77
- nodeBuildDockerEnv,
78
- nodeJSVersion,
79
- npmToken,
80
- }
81
- }
82
- }
83
- }`;
71
+ query BuildConfig($appId: Int, $envId: Int) {
72
+ app(id: $appId) {
73
+ environments(id: $envId) {
74
+ id
75
+ buildConfiguration {
76
+ buildType
77
+ nodeBuildDockerEnv
78
+ nodeJSVersion
79
+ npmToken
80
+ }
81
+ }
82
+ }
83
+ }
84
+ `;
84
85
  try {
85
86
  const result = await api.query({
86
87
  query: buildConfigQuery,
@@ -122,7 +123,7 @@ async function vipValidatePreflightCommand(arg, opt) {
122
123
  };
123
124
  await (0, _tracker.trackEvent)('validate_preflight_command_execute', baseTrackingParams);
124
125
  logToConsole(' /\\ /\\__ _ _ __ _ __ ___ ___ _ __ (_) __ _ ');
125
- logToConsole(' / /_/ / _` | \'__| \'_ ` _ \\ / _ \\| \'_ \\| |/ _` |');
126
+ logToConsole(" / /_/ / _` | '__| '_ ` _ \\ / _ \\| '_ \\| |/ _` |");
126
127
  logToConsole('/ __ / (_| | | | | | | | | (_) | | | | | (_| |');
127
128
  logToConsole('\\/ /_/ \\__,_|_| |_| |_| |_|\\___/|_| |_|_|\\__,_|');
128
129
  logToConsole('VIP Harmonia - Application testing made easy\n');
@@ -155,6 +156,7 @@ async function vipValidatePreflightCommand(arg, opt) {
155
156
  const packageJSONfile = _path.default.resolve(opt.path, 'package.json');
156
157
  let packageJSON;
157
158
  try {
159
+ // eslint-disable-next-line security/detect-non-literal-require
158
160
  packageJSON = require(packageJSONfile);
159
161
  siteOptions.setPackageJSON(packageJSON);
160
162
  } catch (error) {
@@ -100,15 +100,15 @@ const getTokenForCommand = async (appId, envId, command) => {
100
100
  return api.mutate({
101
101
  // $FlowFixMe: gql template is not supported by flow
102
102
  mutation: (0, _graphqlTag.default)`
103
- mutation TriggerWPCLICommandMutation($input: AppEnvironmentTriggerWPCLICommandInput ){
104
- triggerWPCLICommandOnAppEnvironment( input: $input ) {
105
- inputToken
106
- command {
107
- guid
108
- }
103
+ mutation TriggerWPCLICommandMutation($input: AppEnvironmentTriggerWPCLICommandInput) {
104
+ triggerWPCLICommandOnAppEnvironment(input: $input) {
105
+ inputToken
106
+ command {
107
+ guid
109
108
  }
110
109
  }
111
- `,
110
+ }
111
+ `,
112
112
  variables: {
113
113
  input: {
114
114
  id: appId,
@@ -125,8 +125,8 @@ const cancelCommand = async guid => {
125
125
  return api.mutate({
126
126
  // $FlowFixMe: gql template is not supported by flow
127
127
  mutation: (0, _graphqlTag.default)`
128
- mutation cancelWPCLICommand($input: CancelWPCLICommandInput ){
129
- cancelWPCLICommand( input: $input ) {
128
+ mutation cancelWPCLICommand($input: CancelWPCLICommandInput) {
129
+ cancelWPCLICommand(input: $input) {
130
130
  command {
131
131
  id
132
132
  }
@@ -109,7 +109,7 @@ class BackupDBCommand {
109
109
  this.env = env;
110
110
  this.progressTracker = new _progress.ProgressTracker([{
111
111
  id: this.steps.PREPARE,
112
- name: 'Preparing'
112
+ name: 'Preparing for backup generation'
113
113
  }, {
114
114
  id: this.steps.GENERATE,
115
115
  name: 'Generating backup'
@@ -148,9 +148,9 @@ class BackupDBCommand {
148
148
  async run(silent = false) {
149
149
  var _this$job4;
150
150
  this.silent = silent;
151
- const readMoreMessage = '\nRead more about the limitations around database backups & exports here: https://docs.wpvip.com/technical-references/vip-dashboard/backups/ \n';
151
+ const readMoreMessage = '\nLearn more about the database backup limitations here: https://docs.wpvip.com/technical-references/vip-dashboard/backups/ \n';
152
152
  let noticeMessage = `\n${_chalk.default.yellow('NOTICE: ')}`;
153
- noticeMessage += 'A fresh database backup will be generated only if there hasn\'t one already been created recently, either by our automated system or by a user on your site';
153
+ noticeMessage += 'A new database backup will be created only if no recent backup is available, created by our automated system or manually by a user.';
154
154
  noticeMessage += readMoreMessage;
155
155
  this.log(noticeMessage);
156
156
  await this.loadBackupJob();
@@ -172,9 +172,9 @@ class BackupDBCommand {
172
172
  error_message: `Couldn't create a new database backup job: ${err === null || err === void 0 ? void 0 : err.message}`,
173
173
  stack: err === null || err === void 0 ? void 0 : err.stack
174
174
  });
175
- let errMessage = err.message.replace('Database backups limit reached', 'New database backup generation failed because there was already one created recently, either by our automated system or by a user on your site');
176
- errMessage = errMessage.replace('Retry after', '\nTo create a new backup, you can wait until:');
177
- errMessage += `\n\nYou can also export the latest backup using the ${_chalk.default.green('vip @app.env export sql')} command`;
175
+ let errMessage = err.message.replace('Database backups limit reached', 'Unable to create a new database backup as a recent backup already exists. This backup was created by our automated system or a user.');
176
+ errMessage = errMessage.replace('Retry after', '\nThe next possible backup attempt can be made on:');
177
+ errMessage += `\n\nYou can export the (existing) latest database backup with the command: ${_chalk.default.green('vip @app.env export sql')}`;
178
178
  errMessage += readMoreMessage;
179
179
  exit.withError(errMessage);
180
180
  }
@@ -32,7 +32,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
32
32
 
33
33
  const EXPORT_SQL_PROGRESS_POLL_INTERVAL = 1000;
34
34
  const BACKUP_AND_JOB_STATUS_QUERY = (0, _graphqlTag.default)`
35
- query AppBackupAndJobStatus( $appId: Int!, $envId: Int! ) {
35
+ query AppBackupAndJobStatus($appId: Int!, $envId: Int!) {
36
36
  app(id: $appId) {
37
37
  id
38
38
  environments(id: $envId) {
@@ -207,7 +207,7 @@ class ExportSQLCommand {
207
207
  this.generateBackup = options.generateBackup || false;
208
208
  this.progressTracker = new _progress.ProgressTracker([{
209
209
  id: this.steps.PREPARE,
210
- name: 'Preparing'
210
+ name: 'Preparing for backup copy creation'
211
211
  }, {
212
212
  id: this.steps.CREATE,
213
213
  name: 'Creating backup copy'
@@ -19,16 +19,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
19
19
  */
20
20
 
21
21
  const mutation = (0, _graphqlTag.default)`
22
- mutation PurgePageCacheMutation(
23
- $appId: Int!
24
- $envId: Int!
25
- $urls: [String!]!
26
- ) {
27
- purgePageCache( input: {
28
- appId: $appId
29
- environmentId: $envId
30
- urls: $urls
31
- } ) {
22
+ mutation PurgePageCacheMutation($appId: Int!, $envId: Int!, $urls: [String!]!) {
23
+ purgePageCache(input: { appId: $appId, environmentId: $envId, urls: $urls }) {
32
24
  success
33
25
  urls
34
26
  }
@@ -21,11 +21,17 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
21
21
  const LIMIT_MAX = 5000;
22
22
  exports.LIMIT_MAX = LIMIT_MAX;
23
23
  const QUERY_ENVIRONMENT_LOGS = (0, _graphqlTag.default)`
24
- query GetAppLogs( $appId: Int, $envId: Int, $type: AppEnvironmentLogType, $limit: Int, $after: String ) {
25
- app( id: $appId ) {
26
- environments( id: $envId ) {
24
+ query GetAppLogs(
25
+ $appId: Int
26
+ $envId: Int
27
+ $type: AppEnvironmentLogType
28
+ $limit: Int
29
+ $after: String
30
+ ) {
31
+ app(id: $appId) {
32
+ environments(id: $envId) {
27
33
  id
28
- logs( type: $type, limit: $limit, after: $after ) {
34
+ logs(type: $type, limit: $limit, after: $after) {
29
35
  nodes {
30
36
  timestamp
31
37
  message
@@ -94,8 +94,8 @@ function keyValue(values) {
94
94
  value
95
95
  } of values) {
96
96
  let formattedValue;
97
- switch (key.toLowerCase()) {
98
- // NOSONAR
97
+ switch (key.toLowerCase() // NOSONAR
98
+ ) {
99
99
  case 'environment':
100
100
  formattedValue = formatEnvironment(value);
101
101
  break;
@@ -91,16 +91,16 @@ const updateSoftwareMutation = (0, _graphqlTag.default)`
91
91
  }
92
92
  ) {
93
93
  php {
94
- ...Software
94
+ ...Software
95
95
  }
96
96
  wordpress {
97
- ...Software
97
+ ...Software
98
98
  }
99
99
  muplugins {
100
- ...Software
100
+ ...Software
101
101
  }
102
102
  nodejs {
103
- ...Software
103
+ ...Software
104
104
  }
105
105
  }
106
106
  }
@@ -108,9 +108,9 @@ const updateSoftwareMutation = (0, _graphqlTag.default)`
108
108
  `;
109
109
  const updateJobQuery = (0, _graphqlTag.default)`
110
110
  query UpdateJob($appId: Int!, $envId: Int!) {
111
- app(id: $appId ) {
111
+ app(id: $appId) {
112
112
  environments(id: $envId) {
113
- jobs (types:["upgrade_php", "upgrade_wordpress", "upgrade_muplugins", "upgrade_nodejs"]) {
113
+ jobs(types: ["upgrade_php", "upgrade_wordpress", "upgrade_muplugins", "upgrade_nodejs"]) {
114
114
  type
115
115
  completedAt
116
116
  createdAt
@@ -126,7 +126,8 @@ const updateJobQuery = (0, _graphqlTag.default)`
126
126
  }
127
127
  }
128
128
  }
129
- }`;
129
+ }
130
+ `;
130
131
  const COMPONENT_NAMES = {
131
132
  wordpress: 'WordPress',
132
133
  php: 'PHP',
@@ -236,9 +237,9 @@ const _processComponentVersion = (softwareSettings, component, userProvidedVersi
236
237
  const promptForUpdate = async (appTypeId, opts, softwareSettings) => {
237
238
  const component = await _processComponent(appTypeId, opts.component);
238
239
  const version = await _processComponentVersion(softwareSettings, component, opts.version);
239
-
240
+ const confirm =
240
241
  // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
241
- const confirm = opts.force || (await new _enquirer.Confirm({
242
+ opts.force || (await new _enquirer.Confirm({
242
243
  // NOSONAR
243
244
  message: `Are you sure you want to upgrade ${COMPONENT_NAMES[component]} to ${version}?`
244
245
  }).run().catch(() => {
@@ -30,11 +30,8 @@ const DEV_ENVIRONMENT_WORDPRESS_VERSION_TTL = 86400; // once per day
30
30
  exports.DEV_ENVIRONMENT_WORDPRESS_VERSION_TTL = DEV_ENVIRONMENT_WORDPRESS_VERSION_TTL;
31
31
  const DEV_ENVIRONMENT_PHP_VERSIONS = {
32
32
  '8.0': 'ghcr.io/automattic/vip-container-images/php-fpm:8.0',
33
- // eslint-disable-next-line quote-props
34
- '8.2': 'ghcr.io/automattic/vip-container-images/php-fpm:8.2',
35
- // eslint-disable-next-line quote-props
36
- '8.1': 'ghcr.io/automattic/vip-container-images/php-fpm:8.1',
37
- // eslint-disable-next-line quote-props -- flow does not support non-string keys
38
- '7.4': 'ghcr.io/automattic/vip-container-images/php-fpm:7.4'
33
+ 8.2: 'ghcr.io/automattic/vip-container-images/php-fpm:8.2',
34
+ 8.1: 'ghcr.io/automattic/vip-container-images/php-fpm:8.1',
35
+ 7.4: 'ghcr.io/automattic/vip-container-images/php-fpm:7.4'
39
36
  };
40
37
  exports.DEV_ENVIRONMENT_PHP_VERSIONS = DEV_ENVIRONMENT_PHP_VERSIONS;
@@ -712,10 +712,10 @@ async function postStart(slug, options) {
712
712
  const launchVSCode = slug => {
713
713
  const workspacePath = (0, _devEnvironmentCore.getVSCodeWorkspacePath)(slug);
714
714
  if (_fs.default.existsSync(workspacePath)) {
715
- console.log('VSCode workspace already exists, skipping creation.');
715
+ console.log('VS Code workspace already exists, skipping creation.');
716
716
  } else {
717
717
  (0, _devEnvironmentCore.generateVSCodeWorkspace)(slug);
718
- console.log('VSCode workspace generated');
718
+ console.log('VS Code workspace generated');
719
719
  }
720
720
  const vsCodeExecutable = getVSCodeExecutable();
721
721
  if (vsCodeExecutable) {
@@ -723,7 +723,7 @@ const launchVSCode = slug => {
723
723
  shell: process.platform === 'win32'
724
724
  });
725
725
  } else {
726
- console.log(`VSCode not detected in path, please open ${workspacePath} with VSCode`);
726
+ console.log(`VS Code was not detected in the expected path. VS Code Workspace file location:\n${workspacePath}`);
727
727
  }
728
728
  };
729
729
  const getVSCodeExecutable = () => {