@caweb/cli 1.11.2 → 1.12.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.
@@ -15,7 +15,7 @@ import { confirm, input, password } from '@inquirer/prompts';
15
15
  * Internal dependencies
16
16
  */
17
17
  import {
18
- appPath,
18
+ appPath,
19
19
  getTaxonomies,
20
20
  createTaxonomies
21
21
  } from '../../lib/index.js';
@@ -28,9 +28,6 @@ import {
28
28
  promptForSync,
29
29
  promptForId
30
30
  } from './prompts.js';
31
- import { get } from 'http';
32
- import { connect } from 'http2';
33
- import { create } from 'domain';
34
31
 
35
32
  const errors = [];
36
33
  const configFile = path.join(appPath, 'caweb.json');
@@ -171,9 +168,10 @@ function getStaticNavItems(navJson, destUrl){
171
168
  * @param {Array} options.include Include specific IDs only.
172
169
  */
173
170
  export default async function sync({
174
- spinner,
175
- debug,
176
- target,
171
+ spinner,
172
+ debug,
173
+ config,
174
+ target,
177
175
  dest,
178
176
  interactive,
179
177
  tax,
@@ -189,7 +187,7 @@ export default async function sync({
189
187
  // read caweb configuration file.
190
188
  let serviceConfig = fs.existsSync(configFile) ? JSON.parse( fs.readFileSync(configFile) ) : { sync: {} };
191
189
 
192
- process.env.WP_CLI_CONFIG_PATH = path.join(workDirectoryPath, 'config.yml');
190
+ // process.env.WP_CLI_CONFIG_PATH = path.join(workDirectoryPath, 'config.yml');
193
191
 
194
192
  target = serviceConfig.sync[target];
195
193
  dest = serviceConfig.sync[dest];
@@ -294,6 +292,7 @@ export default async function sync({
294
292
  // we create a taxonomies object based off of the static data.
295
293
  if( 'static' === target.url ){
296
294
  let mediaPath = serviceConfig.media;
295
+ let cawebSettings = [];
297
296
 
298
297
  // iterate over pages and create a pages object.
299
298
  for( let page of serviceConfig.pages ){
@@ -334,13 +333,14 @@ export default async function sync({
334
333
 
335
334
  }
336
335
 
336
+ let currentDate = new Date();
337
+ let uploadDir = path.join(
338
+ 'wp-content', 'uploads',
339
+ currentDate.getFullYear().toString(), (currentDate.getMonth() + 1).toString().padStart(2, '0')
340
+ );
341
+
337
342
  // if the media path exists
338
343
  if( fs.existsSync(mediaPath) ){
339
- let currentDate = new Date();
340
- let uploadDir = path.join(
341
- 'wp-content', 'uploads',
342
- currentDate.getFullYear().toString(), (currentDate.getMonth() + 1).toString().padStart(2, '0')
343
- );
344
344
 
345
345
  // we read all the files in the media directory and create a media object.
346
346
  fs.readdirSync(mediaPath, {recursive: true}).forEach( (file) => {
@@ -376,8 +376,50 @@ export default async function sync({
376
376
  });
377
377
  }
378
378
  })
379
+
379
380
  }
380
381
 
382
+ // Favicon is one level up from the media path.
383
+ let icoFile = path.join(mediaPath, '..', 'favicon.ico');
384
+
385
+ if( fs.existsSync(icoFile) && fs.statSync(icoFile).isFile() ){
386
+ // read the file and create a media object.
387
+ let icoBlob = fs.readFileSync(icoFile);
388
+
389
+ // and new media object
390
+ media.push({
391
+ source_url: icoFile,
392
+ title: 'favicon.ico',
393
+ alt_text: 'Fav Icon',
394
+ media_details:{},
395
+ date: currentDate.toISOString(),
396
+ data: new Blob([icoBlob])
397
+ });
398
+ }
399
+
400
+ // Default Organization Logo.
401
+ // since all files in the media path are copied to the uploads directory,
402
+ // we only do the default one if the user hasn't added their own logo.
403
+ // the default logo is usually stored one level up from the media path.
404
+ // and in the caweb/template/media/logo.png
405
+ if( ! fs.existsSync(path.join(mediaPath, 'logo.png')) ){
406
+ let logoFile = path.join(mediaPath, '..', 'caweb', 'template', 'media', 'logo.png');
407
+
408
+ // read the file and create a media object.
409
+ let logoBlob = fs.readFileSync(logoFile);
410
+
411
+ // and new media object
412
+ media.push({
413
+ source_url: logoFile,
414
+ title: path.basename(logoFile),
415
+ alt_text: 'Organization Logo',
416
+ media_details:{},
417
+ date: currentDate.toISOString(),
418
+ data: new Blob([logoBlob])
419
+ });
420
+
421
+ }
422
+
381
423
  // Settings
382
424
  settings[0] = {
383
425
  title: serviceConfig?.site?.title,
@@ -657,7 +699,6 @@ export default async function sync({
657
699
  }
658
700
  }
659
701
  }
660
-
661
702
 
662
703
  /**
663
704
  * Now we have all the data we can begin to create the taxonomies on the target.
@@ -687,7 +728,7 @@ export default async function sync({
687
728
  spinner.text = `Creating all pages to ${dest.url}`;
688
729
  createdPages = await createTaxonomies( pages, destOptions, 'pages', spinner );
689
730
  }
690
-
731
+
691
732
  // Posts.
692
733
  if( posts ){
693
734
  spinner.text = `Creating all posts to ${dest.url}`;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { select } from 'inquirer-select-pro';
5
+ import chalk from 'chalk';
6
+ import { writeLine, clearLine } from '../lib/index.js';
7
+
8
+ // since we are in a spinner,
9
+ // we have to silence all the cancellation errors when using prompts
10
+ // .catch(() => {process.exit(1);})
11
+ import { confirm, input, password } from '@inquirer/prompts';
12
+
13
+
14
+ const bullet = chalk.yellow('-');
15
+ const info = chalk.cyan('i');
16
+
17
+ /**
18
+ * Prompt for General Site Information
19
+ *
20
+ * - Site Title
21
+ *
22
+ * @param {string} title Site title default.
23
+ * @returns {object}
24
+ */
25
+ async function promptForDivi(){
26
+ writeLine('CAWebPublishing requires that Divi be installed in order to function properly', { char: '#', borderColor: 'blue'});
27
+ writeLine('Divi Credentials', {color: 'magenta', char: '#', borderColor: 'magenta'});
28
+ writeLine('The following credentials are required to download and install Divi.', {color: 'cyan', prefix: 'i'});
29
+ writeLine('By not providing appropriate credentials, you may encounter issues.', {color: 'cyan', prefix: 'i'});
30
+ let info = {
31
+ ET_USERNAME: await input({
32
+ message: 'Elegant Themes Username:',
33
+ },
34
+ {
35
+ clearPromptOnDone: true,
36
+ },
37
+ ).catch(() => {
38
+ // clear lines.
39
+ clearLine(8);
40
+ process.exit(1);
41
+ }),
42
+ ET_API_KEY: await password({
43
+ message: 'Elegant Themes API Key:',
44
+ },
45
+ {
46
+ clearPromptOnDone: true,
47
+ },
48
+ ).catch(() => {
49
+ // clear lines.
50
+ clearLine(8);
51
+ process.exit(1);
52
+ })
53
+ };
54
+
55
+ // clear lines.
56
+ clearLine(8);
57
+ return info;
58
+ }
59
+
60
+ export {
61
+ bullet,
62
+ info,
63
+ promptForDivi,
64
+ }
package/configs/wp-env.js CHANGED
@@ -8,58 +8,55 @@ import fs from 'fs';
8
8
  * Internal Dependencies
9
9
  */
10
10
  import {
11
+ appPath,
11
12
  projectPath
12
13
  } from '../lib/helpers.js';
14
+ import { promptForDivi } from './prompts.js';
15
+ import { config, env } from 'process';
13
16
 
14
17
  const localFile = path.join(projectPath, 'package.json');
15
18
  const pkg = JSON.parse( fs.readFileSync(localFile) );
16
19
 
20
+ const cawebJson = fs.existsSync( path.join(appPath, 'caweb.json') ) ?
21
+ JSON.parse(fs.readFileSync(path.join(appPath, 'caweb.json')))
22
+ : {};
23
+
17
24
  /**
18
25
  * Build .wp-env.json
19
26
  *
20
27
  * @param {boolean} bare True if excluding any CAWeb Configurations.
21
28
  * @param {boolean} multisite True if converting to multisite.
29
+ * @param {boolean} subdomain True if converting to multisite subdomain.
22
30
  * @param {boolean} plugin True if root directory is a plugin.
23
31
  * @param {boolean} theme True if root directory is a theme.
24
32
  *
25
33
  * @returns object
26
34
  */
27
- export default function wpEnvConfig ( bare, multisite, plugin, theme ) {
35
+ function wpEnvConfig ( bare, multisite, subdomain, plugin, theme ) {
28
36
  let themes = [];
29
37
  let plugins = [];
30
-
31
- let config = {
38
+
39
+ let envConfig = {
32
40
  core: `WordPress/WordPress#${pkg.config.WP_VER}`,
33
41
  phpVersion: `${pkg.config.PHP_VER}`,
34
- config: {
35
- ...pkg.config.DEFAULTS
42
+ multisite,
43
+ env: {
44
+ development: { port: 8888, config: {} },
45
+ tests: { port: 8889, config: {} }
36
46
  }
37
47
  }
38
48
 
39
- // if not bare.
40
- if( ! bare ){
41
- // include our theme
42
- themes.push('CAWebPublishing/CAWeb')
43
-
44
- // include our dev plugin
45
- plugins.push('CAWebPublishing/caweb-dev')
49
+ if( multisite && subdomain ){
50
+ pkg.config.DEFAULTS.SUBDOMAIN_INSTALL= true;
46
51
  }
47
52
 
53
+ envConfig.config = pkg.config.DEFAULTS
54
+
48
55
  // if root directory is a theme
49
56
  if( theme ){
50
57
  themes.push( '.' );
51
58
  }
52
59
 
53
- // if is multisite
54
- if( multisite ){
55
- config.config['WP_ALLOW_MULTISITE'] = true;
56
-
57
- // set CAWeb as Default Theme if it was downloaded
58
- if( ! bare ){
59
- config.config['WP_DEFAULT_THEME'] = 'CAWeb';
60
- }
61
- }
62
-
63
60
  // if root directory is a plugin
64
61
  if( plugin ){
65
62
  plugins.push( '.' );
@@ -67,14 +64,106 @@ export default function wpEnvConfig ( bare, multisite, plugin, theme ) {
67
64
 
68
65
  // add plugins if sources were added
69
66
  if( plugins.length ){
70
- config['plugins'] = plugins;
67
+ envConfig['plugins'] = plugins;
71
68
  }
72
69
 
73
70
  // add themes if sources were added
74
71
  if( themes.length ){
75
- config['themes'] = themes;
72
+ envConfig['themes'] = themes;
76
73
  }
77
74
 
78
- return config;
75
+ // lets add some configurations from the caweb.json file
76
+ if( cawebJson ){
77
+ let siteDomain = new URL('http://localhost');
78
+ let currentDate = new Date();
79
+ let uploadDir = path.join(
80
+ 'wp-content', 'uploads',
81
+ currentDate.getFullYear().toString(), (currentDate.getMonth() + 1).toString().padStart(2, '0')
82
+ );
83
+
84
+
85
+ // add siteurl and home
86
+ if( cawebJson?.site?.domain ){
87
+ siteDomain = new URL(cawebJson.site.domain);
88
+
89
+ if( 'localhost' !== siteDomain.host ){
90
+ // Global configurations
91
+ envConfig.config['WP_SITEURL'] = `${cawebJson.site.domain}`;
92
+ envConfig.config['WP_HOME'] = `${cawebJson.site.domain}`;
93
+
94
+ // dev configurations
95
+ envConfig.env.development.port = '' !== siteDomain.port ? siteDomain.port : envConfig.env.development.port;
96
+
97
+ // tests configurations
98
+ }
99
+ }
100
+
101
+ // add caweb logo
102
+ if( cawebJson?.logo ){
103
+ // dev configurations
104
+ envConfig.env.development.config['CAWEB_ORG_LOGO'] = `${envConfig.config['WP_SITEURL']}/` + path.join(
105
+ uploadDir,
106
+ path.basename(cawebJson.logo) + // add the port
107
+ ('80' !== envConfig.env.development.port ? `:${envConfig.env.development.port}` : '')
108
+ ).replace(/\\/g, '/');
109
+
110
+ // tests configurations
111
+ envConfig.env.tests.config['CAWEB_ORG_LOGO'] = `${envConfig.config['WP_SITEURL']}/` + path.join(
112
+ uploadDir,
113
+ path.basename(cawebJson.logo) + // add the port
114
+ ('80' !== envConfig.env.tests.port ? `:${envConfig.env.tests.port}` : '')
115
+ ).replace(/\\/g, '/');
116
+ }
117
+
118
+ // add caweb favicon
119
+ if( cawebJson?.favicon ){
120
+ // dev configurations
121
+ envConfig.env.development.config['CAWEB_FAV_ICON'] = `${envConfig.config['WP_SITEURL']}/` + path.join(
122
+ uploadDir,
123
+ path.basename(cawebJson.favicon) + // add the port
124
+ ('80' !== envConfig.env.development.port ? `:${envConfig.env.development.port}` : '')
125
+ ).replace(/\\/g, '/');
126
+
127
+ // tests configurations
128
+ envConfig.env.tests.config['CAWEB_FAV_ICON'] = `${envConfig.config['WP_SITEURL']}/` + path.join(
129
+ uploadDir,
130
+ path.basename(cawebJson.favicon) + // add the port
131
+ ('80' !== envConfig.env.tests.port ? `:${envConfig.env.tests.port}` : '')
132
+ ).replace(/\\/g, '/');
133
+
134
+ }
135
+
136
+ }
137
+
138
+ return envConfig;
79
139
 
140
+ }
141
+
142
+
143
+ /**
144
+ * Build .wp-env.override.json
145
+ *
146
+ * @param {boolean} bare True if excluding any CAWeb Configurations.
147
+ * @param {boolean} multisite True if converting to multisite.
148
+ * @param {boolean} subdomain True if converting to multisite subdomain.
149
+ * @param {boolean} plugin True if root directory is a plugin.
150
+ * @param {boolean} theme True if root directory is a theme.
151
+ *
152
+ * @returns object
153
+ */
154
+ async function wpEnvOverrideConfig(){
155
+ let divi = await promptForDivi();
156
+
157
+ let config = {
158
+ config: {
159
+ ...divi
160
+ }
161
+ }
162
+
163
+ return config;
164
+ }
165
+
166
+ export {
167
+ wpEnvConfig,
168
+ wpEnvOverrideConfig
80
169
  }
package/lib/cli.js CHANGED
@@ -52,13 +52,13 @@ function addWebpackCmds(){
52
52
  .allowUnknownOption(true)
53
53
  .allowExcessArguments(true)
54
54
  .action(env.webpack)
55
-
56
-
55
+
56
+
57
57
  // Serve Command.
58
58
  program.command('serve')
59
- .description('Serves the current project using CAWebPublishing templates.')
60
- .addOption(new Option('--template <template>', 'Serves the project using templating.').choices(['default', 'blank']).default('default'))
61
- .addOption(new Option('--scheme <scheme>', 'Serves the project using template colorscheme.').choices([
59
+ .description('Serves the current project using CAWebPublishing templates.')
60
+ .addOption(new Option('--template <template>', 'Serves the project using templating.').choices(['default', 'blank']).default('default'))
61
+ .addOption(new Option('--scheme <scheme>', 'Serves the project using template colorscheme.').choices([
62
62
  'delta',
63
63
  'eureka',
64
64
  'mono',
@@ -73,74 +73,74 @@ function addWebpackCmds(){
73
73
  'trinity',
74
74
  'false'
75
75
  ]).default('oceanside'))
76
- .option( '--no-audit', 'Skips WordPress CSS-Audit.', false )
77
- .option( '--no-a11y', 'Skips IBM Accessibility Checker.', false )
78
- .option( '--no-jshint', 'Skips JSHint.', false )
79
- .allowUnknownOption(true)
76
+ .option( '--no-audit', 'Skips WordPress CSS-Audit.', false )
77
+ .option( '--no-a11y', 'Skips IBM Accessibility Checker.', false )
78
+ .option( '--no-jshint', 'Skips JSHint.', false )
79
+ .allowUnknownOption(true)
80
80
  .allowExcessArguments(true)
81
- .action(env.webpack)
81
+ .action(env.webpack)
82
82
 
83
83
  // a11y Command.
84
84
  program.command('a11y')
85
- .description('Runs accessibility checks.')
86
- .addArgument(new Argument('<url>', 'URL to scan for accessibility checks.'))
87
- .option( '--rule-archive <rule>', 'Specify the rule archive.', 'latest')
88
- .option( '--policies <policy...>', 'Specify one or many policies to scan.', ['WCAG_2_1'])
89
- .option( '--fail-levels <levels...>', 'Specify one or many violation levels on which to fail the test.', [
90
- 'violation',
91
- 'potentialviolation'
92
- ])
93
- .option( '--report-levels <levels...>', 'Specify one or many violation levels that should be reported.', [
94
- 'violation',
95
- 'potentialviolation',
96
- 'recommendation',
97
- 'potentialrecommendation',
98
- 'manual',
99
- 'pass'
100
- ])
101
- .option( '--labels <label...>', 'Specify labels that you would like associated to your scan.', [])
102
- .option( '--output-format <format>', 'In which formats should the results be output.', ['html'])
103
- .option( '--output-filename <name>', 'Filename for the scan results.', 'a11y')
104
- .option( '--output-folder <folder>', 'Where the scan results should be saved.', 'a11y')
105
- .option( '--output-filename-timestamp', 'Should the timestamp be included in the filename of the reports?', false)
106
- .allowUnknownOption(true)
85
+ .description('Runs accessibility checks.')
86
+ .addArgument(new Argument('<url>', 'URL to scan for accessibility checks.'))
87
+ .option( '--rule-archive <rule>', 'Specify the rule archive.', 'latest')
88
+ .option( '--policies <policy...>', 'Specify one or many policies to scan.', ['WCAG_2_1'])
89
+ .option( '--fail-levels <levels...>', 'Specify one or many violation levels on which to fail the test.', [
90
+ 'violation',
91
+ 'potentialviolation'
92
+ ])
93
+ .option( '--report-levels <levels...>', 'Specify one or many violation levels that should be reported.', [
94
+ 'violation',
95
+ 'potentialviolation',
96
+ 'recommendation',
97
+ 'potentialrecommendation',
98
+ 'manual',
99
+ 'pass'
100
+ ])
101
+ .option( '--labels <label...>', 'Specify labels that you would like associated to your scan.', [])
102
+ .option( '--output-format <format>', 'In which formats should the results be output.', ['html'])
103
+ .option( '--output-filename <name>', 'Filename for the scan results.', 'a11y')
104
+ .option( '--output-folder <folder>', 'Where the scan results should be saved.', 'a11y')
105
+ .option( '--output-filename-timestamp', 'Should the timestamp be included in the filename of the reports?', false)
106
+ .allowUnknownOption(true)
107
107
  .allowExcessArguments(true)
108
- .action(env.a11y)
108
+ .action(env.a11y)
109
109
 
110
-
110
+
111
111
  // audit Command.
112
112
  program.command('audit')
113
- .description('Runs WordPress CSS Audit tool against projects.')
114
- .addArgument(new Argument('[files...]', 'Files or directory path to CSS files.').default(['./build']))
115
- .option('--format [format]', 'Format to use for displaying report.', 'html' )
116
- .option('--filename [name]', 'If using a format that outputs to a file, specify the file name.', 'css-audit' )
117
- .option('--colors', 'Runs colors audit.', true )
118
- .addOption(new Option('--no-colors', 'Skips colors audit.', false ).hideHelp())
119
- .option('--important', 'Runs !important audit.', true )
120
- .addOption(new Option('--no-important', 'Skips !important audit.', false ).hideHelp())
121
- .option('--display-none', 'Runs display: none audit.', true )
122
- .addOption(new Option('--no-display-none', 'Skips display: none audit.', false ).hideHelp())
123
- .option('--selectors', 'Runs selectors audit.', true )
124
- .addOption(new Option('--no-selectors', 'Skips selectors audit.', false ).hideHelp())
125
- .option('--media-queries', 'Runs media queries audit.', true )
126
- .addOption(new Option('--no-media-queries', 'Skips media queries audit.', false ).hideHelp())
127
- .option('--typography', 'Runs typography audit.', true )
128
- .addOption(new Option('--no-typography', 'Skips typography audit.', false ).hideHelp())
129
- .option('--property-values <values...>', 'Runs property value audit.', ['font-size', 'padding,padding-top,padding-bottom,padding-right,padding-left', 'margin,margin-top,marin-bottom,marin-right,marin-left'] )
130
- .addOption(new Option('--no-property-values', 'Skips property values audit.', false ).hideHelp())
131
- .allowUnknownOption(true)
113
+ .description('Runs WordPress CSS Audit tool against projects.')
114
+ .addArgument(new Argument('[files...]', 'Files or directory path to CSS files.').default(['./build']))
115
+ .option('--format [format]', 'Format to use for displaying report.', 'html' )
116
+ .option('--filename [name]', 'If using a format that outputs to a file, specify the file name.', 'css-audit' )
117
+ .option('--colors', 'Runs colors audit.', true )
118
+ .addOption(new Option('--no-colors', 'Skips colors audit.', false ).hideHelp())
119
+ .option('--important', 'Runs !important audit.', true )
120
+ .addOption(new Option('--no-important', 'Skips !important audit.', false ).hideHelp())
121
+ .option('--display-none', 'Runs display: none audit.', true )
122
+ .addOption(new Option('--no-display-none', 'Skips display: none audit.', false ).hideHelp())
123
+ .option('--selectors', 'Runs selectors audit.', true )
124
+ .addOption(new Option('--no-selectors', 'Skips selectors audit.', false ).hideHelp())
125
+ .option('--media-queries', 'Runs media queries audit.', true )
126
+ .addOption(new Option('--no-media-queries', 'Skips media queries audit.', false ).hideHelp())
127
+ .option('--typography', 'Runs typography audit.', true )
128
+ .addOption(new Option('--no-typography', 'Skips typography audit.', false ).hideHelp())
129
+ .option('--property-values <values...>', 'Runs property value audit.', ['font-size', 'padding,padding-top,padding-bottom,padding-right,padding-left', 'margin,margin-top,marin-bottom,marin-right,marin-left'] )
130
+ .addOption(new Option('--no-property-values', 'Skips property values audit.', false ).hideHelp())
131
+ .allowUnknownOption(true)
132
132
  .allowExcessArguments(true)
133
- .action(env.audit)
133
+ .action(env.audit)
134
134
 
135
135
  // JSHint Command.
136
136
  program.command('jshint')
137
- .description('Runs JSHint tool against projects.')
138
- .addArgument(new Argument('[files...]', 'Files or directory path to JS files.').default(['./src']))
139
- .option( '--output-filename <name>', 'Filename for the scan results.', 'jshint')
140
- .option( '--output-folder <folder>', 'Where the hint results should be saved.', 'jshint')
141
- .allowUnknownOption(true)
137
+ .description('Runs JSHint tool against projects.')
138
+ .addArgument(new Argument('[files...]', 'Files or directory path to JS files.').default(['./src']))
139
+ .option( '--output-filename <name>', 'Filename for the scan results.', 'jshint')
140
+ .option( '--output-folder <folder>', 'Where the hint results should be saved.', 'jshint')
141
+ .allowUnknownOption(true)
142
142
  .allowExcessArguments(true)
143
- .action(env.hint)
143
+ .action(env.hint)
144
144
  }
145
145
 
146
146
 
@@ -170,6 +170,11 @@ function addWPEnvCommands(){
170
170
  'Execute any configured lifecycle scripts.',
171
171
  true
172
172
  )
173
+ .option(
174
+ '--sync',
175
+ 'Will attempt to sync changes from a CAWebPublishing static site to this WordPress instance.',
176
+ false
177
+ )
173
178
  .option(
174
179
  '--bare',
175
180
  'True if excluding any downloads from CAWeb, use this if you want to use a local version of the CAWeb Theme, Configurations will still be applied.',
@@ -293,7 +298,7 @@ function addWPEnvCommands(){
293
298
  */
294
299
  function addWPInstanceCommands(){
295
300
  // Update Plugins Command.
296
- program.command('update-plugins')
301
+ program.command('update-plugins')
297
302
  .description('Updates all plugins in the WordPress environment.')
298
303
  .argument('[slug]', 'Plugin slug to update.', 'all')
299
304
  .addOption(new Option('--environment <env>', 'Which environment to use.').choices(['development', 'tests']).default('development'))
@@ -416,30 +421,37 @@ export default function cli() {
416
421
  })
417
422
  .helpCommand(false)
418
423
 
419
- // Add Webpack specific commands.
424
+ // Add Scripts command.
425
+ program.command('gen-scripts')
426
+ .description('Adds some general basic scripts commonly used in most projects to your package.json.')
427
+ .allowUnknownOption(true)
428
+ .allowExcessArguments(true)
429
+ .action( withSpinner(env.genScripts) )
430
+
431
+ // Add Webpack specific commands.
420
432
  addWebpackCmds()
421
433
 
422
- // Add wp-env specific commands.
423
- addWPEnvCommands();
434
+ // Add wp-env specific commands.
435
+ addWPEnvCommands();
424
436
 
425
437
  // Add wp-env specific commands.
426
- addWPInstanceCommands()
438
+ addWPInstanceCommands()
427
439
 
428
440
  // Add block specific commands.
429
- addBlockCommands()
441
+ addBlockCommands()
430
442
 
431
443
  // Add site specific commands.
432
- addSiteCommands()
444
+ addSiteCommands()
433
445
 
434
-
446
+
435
447
  // Test Command.
436
448
  // Ensure this is commented out.
437
449
  /*program.command('test')
438
- .description('Test commands on a WordPress environment')
439
- //.addArgument(envArg)
440
- .allowUnknownOption(true)
450
+ .description('Test commands on a WordPress environment')
451
+ //.addArgument(envArg)
452
+ .allowUnknownOption(true)
441
453
  .allowExcessArguments(true)
442
- .action(withSpinner(env.test))
454
+ .action(withSpinner(env.test))
443
455
  */
444
456
 
445
457
  return program;
@@ -5,6 +5,7 @@ import path from 'path';
5
5
  import axios from 'axios';
6
6
  import terminalLink from 'terminal-link';
7
7
  import axiosRetry from 'axios-retry';
8
+ import { stat } from 'fs';
8
9
 
9
10
  /**
10
11
  * Internal dependencies
@@ -187,12 +188,12 @@ async function createTaxonomies( taxData, request, tax = 'pages', spinner ){
187
188
  if( ! request.method ){
188
189
  request.method = 'POST'
189
190
  }
191
+ // endpoint url.
192
+ let url = `${request.url}${endpoint}/${tax}`;
190
193
 
191
194
  let collection = [];
192
195
 
193
196
  for( let obj of taxData ){
194
- // endpoint url.
195
- let url = `${request.url}${endpoint}/${tax}`;
196
197
  let existingID = obj.id ? obj.id : false;
197
198
 
198
199
  // process object properties.
@@ -212,7 +213,7 @@ async function createTaxonomies( taxData, request, tax = 'pages', spinner ){
212
213
  delete obj[prop];
213
214
  }
214
215
  }
215
-
216
+
216
217
  // The REST API doesn't allow passing the id, in order to maintain ID's we make an additional request to our plugin endpoint.
217
218
  if( obj.id ){
218
219
  // first we check if the ID exist
@@ -269,16 +270,23 @@ async function createTaxonomies( taxData, request, tax = 'pages', spinner ){
269
270
  // return the JSON object.
270
271
  return JSON.parse(res.data.substring(res.data.indexOf('{')))
271
272
  }
272
- //console.log( res.data );
273
273
  return res.data;
274
274
  } ).catch( async (error) => {
275
275
  let { data, status } = error.response;
276
- let msg = data.message || 'An unknown error occurred.';
277
-
278
- if( 401 === status ){
279
- msg += `\nPlease check your ${terminalLink('Application Password', 'https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/')}`;
280
- } else if( 403 === status ){
281
- msg = 'Forbidden Request: A potentially unsafe operation has been detected in your request to this site';
276
+ let msg = '';
277
+
278
+ switch( status ){
279
+ case 401:
280
+ msg = `${data.message}\nPlease check your ${terminalLink('Application Password', 'https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/')}`;
281
+ break;
282
+ case 403:
283
+ msg = `Forbidden Request: A potentially unsafe operation has been detected in your request to this site`;
284
+ break;
285
+ case 404:
286
+ msg = `The requested URL was not found on this server.`;
287
+ break;
288
+ default:
289
+ msg = data.message || 'An unknown error occurred.';
282
290
  }
283
291
 
284
292
  spinner.fail( msg )