@caweb/cli 1.2.0 → 1.3.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.
- package/README.md +1 -1
- package/bin/caweb +1 -1
- package/bin/wp-cli.phar +0 -0
- package/commands/a11y.js +74 -0
- package/{lib/commands → commands}/blocks/create-block.js +7 -8
- package/{lib/commands → commands}/blocks/update-block.js +3 -9
- package/commands/build.js +73 -0
- package/{lib/commands → commands/env}/destroy.js +15 -22
- package/{lib/commands → commands/env}/start.js +26 -27
- package/{lib/commands → commands/env}/stop.js +4 -10
- package/{lib/commands → commands}/index.js +51 -43
- package/commands/serve.js +78 -0
- package/commands/sync.js +498 -0
- package/{lib/commands → commands}/tasks/update-plugins.js +2 -2
- package/commands/test.js +100 -0
- package/configs/aceconfig.js +28 -0
- package/{lib/configs.js → configs/docker-compose.js} +30 -83
- package/configs/webpack.config.js +119 -0
- package/configs/wp-env.js +76 -0
- package/gen/parser.js +166 -0
- package/gen/site-generator.js +111 -0
- package/lib/admin.js +1 -1
- package/lib/cli.js +105 -63
- package/lib/helpers.js +109 -0
- package/lib/index.js +28 -0
- package/lib/spinner.js +10 -7
- package/lib/{caweb.js → wordpress/caweb.js} +1 -1
- package/lib/{divi.js → wordpress/divi.js} +1 -1
- package/lib/{download-sources.js → wordpress/download-sources.js} +74 -78
- package/lib/wordpress/index.js +16 -0
- package/lib/{wordpress.js → wordpress/wordpress.js} +4 -8
- package/package.json +41 -27
- package/lib/commands/test.js +0 -46
- package/lib/utils.js +0 -150
- /package/{lib/commands → commands/tasks}/shell.js +0 -0
- /package/lib/{options.js → wordpress/options.js} +0 -0
- /package/{lib/template → template}/assets/css/popover.css +0 -0
- /package/{lib/template → template}/assets/js/popover.js +0 -0
- /package/{lib/template → template}/block/edit.js.mustache +0 -0
- /package/{lib/template → template}/block/editor.scss.mustache +0 -0
- /package/{lib/template → template}/block/index.js.mustache +0 -0
- /package/{lib/template → template}/block/save.js.mustache +0 -0
- /package/{lib/template → template}/block/style.scss.mustache +0 -0
- /package/{lib/template → template}/index.cjs +0 -0
- /package/{lib/template → template}/plugin/$slug.php.mustache +0 -0
- /package/{lib/template → template}/plugin/core/cdec-api.php.mustache +0 -0
- /package/{lib/template → template}/plugin/core/filters.php.mustache +0 -0
- /package/{lib/template → template}/plugin/core/functions.php.mustache +0 -0
- /package/{lib/template → template}/plugin/inc/renderer.php.mustache +0 -0
package/commands/sync.js
ADDED
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import axios from 'axios';
|
|
7
|
+
import terminalLink from 'terminal-link';
|
|
8
|
+
import loadConfig from '@wordpress/env/lib/config/load-config.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Internal dependencies
|
|
12
|
+
*/
|
|
13
|
+
import {
|
|
14
|
+
appPath,
|
|
15
|
+
projectPath,
|
|
16
|
+
runCmd
|
|
17
|
+
} from '../lib/index.js';
|
|
18
|
+
|
|
19
|
+
const endpoint = '/wp-json/wp/v2';
|
|
20
|
+
const requestDelay = 1000; // we wait 1 second between requests
|
|
21
|
+
|
|
22
|
+
const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));
|
|
23
|
+
|
|
24
|
+
function processData( data ){
|
|
25
|
+
/**
|
|
26
|
+
* If wpautop is enabled and data contains Divi shortcodes,
|
|
27
|
+
* WordPress will automatically add an opening/closing p tag that needs to be removed.
|
|
28
|
+
* @link https://developer.wordpress.org/reference/functions/wpautop/
|
|
29
|
+
*/
|
|
30
|
+
if( data.includes('et_pb_section') &&
|
|
31
|
+
data.startsWith('<p>') &&
|
|
32
|
+
data.endsWith('</p>\n')
|
|
33
|
+
){
|
|
34
|
+
data = data.substring(3, data.length - 5)
|
|
35
|
+
}
|
|
36
|
+
return data
|
|
37
|
+
.replace(/(”)|(″)|(“)/g, '') // replace double encoding
|
|
38
|
+
.replace(/(\s{2,})/g, ' ') // replace misc spacing // “
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function getTaxonomies( request, tax = 'pages', limit = 5000 ){
|
|
43
|
+
const fields = request.fields ? request.fields : [
|
|
44
|
+
'id',
|
|
45
|
+
'type',
|
|
46
|
+
'alt_text',
|
|
47
|
+
'caption',
|
|
48
|
+
'slug',
|
|
49
|
+
'title',
|
|
50
|
+
'source_url',
|
|
51
|
+
'mime_type',
|
|
52
|
+
'content',
|
|
53
|
+
'date',
|
|
54
|
+
'date_gmt',
|
|
55
|
+
'status',
|
|
56
|
+
'featured_media',
|
|
57
|
+
'comment_status',
|
|
58
|
+
'ping_status',
|
|
59
|
+
'template',
|
|
60
|
+
'format',
|
|
61
|
+
'categories',
|
|
62
|
+
'tags',
|
|
63
|
+
'meta'
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
let urlParams = [
|
|
67
|
+
'per_page=100',
|
|
68
|
+
`_fields=${ fields.join(',')}`,
|
|
69
|
+
'order=asc'
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
// if no request is added default to GET
|
|
73
|
+
if( ! request.method ){
|
|
74
|
+
request.method = 'GET'
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// if parent argument
|
|
78
|
+
if( request.parent ){
|
|
79
|
+
urlParams.push( `parent=` + ( Array === typeof request.parent ? request.parent.join(',') : request.parent ))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// if include argument
|
|
83
|
+
if( request.include ){
|
|
84
|
+
urlParams.push( `include=` + ( Array === typeof request.include ? request.include.join(',') : request.include ))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let collection = [];
|
|
88
|
+
|
|
89
|
+
for( let i = 1; i < limit / 100; i++ ){
|
|
90
|
+
// make requests for each page
|
|
91
|
+
urlParams.push(`page=${i}`)
|
|
92
|
+
|
|
93
|
+
let results = await axios.request(
|
|
94
|
+
{
|
|
95
|
+
...request,
|
|
96
|
+
url: `${request.url}${endpoint}/${tax}?` + urlParams.join('&')
|
|
97
|
+
}
|
|
98
|
+
).then(
|
|
99
|
+
(res) => {
|
|
100
|
+
return res.data
|
|
101
|
+
}).catch(
|
|
102
|
+
(error) => {return false}
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
// if no more results stop making requests
|
|
107
|
+
if( ! results ){
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// add results to collection
|
|
112
|
+
collection = collection.concat( results );
|
|
113
|
+
|
|
114
|
+
// lets wait requestDelay between requests.
|
|
115
|
+
await sleep( requestDelay );
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return collection;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function createTaxonomies( taxData, request, tax = 'pages', spinner ){
|
|
122
|
+
// if no request is added default to POST
|
|
123
|
+
if( ! request.method ){
|
|
124
|
+
request.method = 'POST'
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let collection = [];
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
for( let obj of taxData ){
|
|
131
|
+
// endpoint url.
|
|
132
|
+
let url = `${request.url}${endpoint}/${tax}`;
|
|
133
|
+
let existingID = false;
|
|
134
|
+
|
|
135
|
+
// in order to maintain ID's, we have to use the cli, the REST API doesn't allow passing the id.
|
|
136
|
+
if( obj.id ){
|
|
137
|
+
// first we check if the ID exist
|
|
138
|
+
let idExists = await axios.request(
|
|
139
|
+
{
|
|
140
|
+
...request,
|
|
141
|
+
method: 'GET',
|
|
142
|
+
url: `${url}/${ obj.id }`
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
.then((res) => { return res.data.id })
|
|
146
|
+
.catch(error => {return false;})
|
|
147
|
+
|
|
148
|
+
// for menus if ID doesn't exist we also check for matching slug
|
|
149
|
+
// if a menu with a matching slug exists we return that id instead.
|
|
150
|
+
if( 'menus' === tax && ! idExists ){
|
|
151
|
+
idExists = await axios.request(
|
|
152
|
+
{
|
|
153
|
+
...request,
|
|
154
|
+
method: 'GET',
|
|
155
|
+
url: `${url}/?slug=${ obj.slug }`
|
|
156
|
+
}
|
|
157
|
+
)
|
|
158
|
+
.then((res) => { return res.data[0].id })
|
|
159
|
+
.catch(error => {return false;})
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* if the ID doesn't exist we save it so we can update via CLI later on.
|
|
165
|
+
* if it does exist update endpoint url so we update the existing item.
|
|
166
|
+
*/
|
|
167
|
+
if( ! idExists ){
|
|
168
|
+
existingID = obj.id;
|
|
169
|
+
}else{
|
|
170
|
+
url = `${url}/${ obj.id }`;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// id has to be deleted.
|
|
174
|
+
delete obj.id;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// process properties
|
|
178
|
+
if( obj.content ){
|
|
179
|
+
obj.content = processData(obj.content.rendered);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if( obj.title ){
|
|
183
|
+
obj.title = processData(obj.title.rendered);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if( obj.caption ){
|
|
187
|
+
obj.caption = processData(obj.caption.rendered);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// make WordPress REST API request.
|
|
191
|
+
let results = await axios.request({
|
|
192
|
+
...request,
|
|
193
|
+
data: 'media' === tax ? createMediaItem(obj) : obj,
|
|
194
|
+
url
|
|
195
|
+
})
|
|
196
|
+
.then( async (res) => { return res.data; }, axiosErrorHandler )
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* if the obj had an existing ID that didn't exist
|
|
201
|
+
*/
|
|
202
|
+
if( existingID ){
|
|
203
|
+
|
|
204
|
+
let post_tbl = `wp_posts`;
|
|
205
|
+
let post_meta_tbl = `wp_postmeta`;
|
|
206
|
+
let term_taxonomy_tbl = `wp_term_taxonomy`;
|
|
207
|
+
|
|
208
|
+
const cmd = [
|
|
209
|
+
path.join(projectPath, 'bin', 'wp-cli.phar'),
|
|
210
|
+
`--ssh=${request.ssh}`,
|
|
211
|
+
'--skip-themes',
|
|
212
|
+
'--skip-column-names',
|
|
213
|
+
`--url=${new URL(request.url).origin}`
|
|
214
|
+
];
|
|
215
|
+
|
|
216
|
+
// if taxonomy is page/post/media.
|
|
217
|
+
if( ['pages', 'posts', 'media'].includes(tax) ){
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Since the REST API doesn't detected trashed posts/pages.
|
|
222
|
+
* We have to do a drop before we can do an update.
|
|
223
|
+
* Since trashed posts/pages stay in the database
|
|
224
|
+
*/
|
|
225
|
+
// drop post
|
|
226
|
+
await runCmd(
|
|
227
|
+
'php',
|
|
228
|
+
[
|
|
229
|
+
...cmd,
|
|
230
|
+
`db query 'DELETE FROM ${post_tbl} WHERE ID=${existingID}'`,
|
|
231
|
+
]
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
// drop post meta.
|
|
235
|
+
await runCmd(
|
|
236
|
+
'php',
|
|
237
|
+
[
|
|
238
|
+
...cmd,
|
|
239
|
+
`db query 'DELETE FROM ${post_meta_tbl} WHERE post_id=${existingID}'`,
|
|
240
|
+
]
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
// now we can update the new ID with the existing ID.
|
|
244
|
+
await runCmd(
|
|
245
|
+
'php',
|
|
246
|
+
[
|
|
247
|
+
...cmd,
|
|
248
|
+
`db query 'UPDATE ${post_tbl} SET ID=${existingID} WHERE ID=${results.id}'`,
|
|
249
|
+
]
|
|
250
|
+
)
|
|
251
|
+
// update post meta.
|
|
252
|
+
await runCmd(
|
|
253
|
+
'php',
|
|
254
|
+
[
|
|
255
|
+
...cmd,
|
|
256
|
+
`db query 'UPDATE ${post_meta_tbl} SET post_id=${existingID} WHERE post_id=${results.id}'`,
|
|
257
|
+
]
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
// if taxonomy is menu.
|
|
261
|
+
}else if( 'menus' === tax ){
|
|
262
|
+
// update the term taxonomy table.
|
|
263
|
+
await runCmd(
|
|
264
|
+
'php',
|
|
265
|
+
[
|
|
266
|
+
...cmd,
|
|
267
|
+
`db query 'UPDATE ${term_taxonomy_tbl} SET term_taxonomy_id=${existingID},term_id=${existingID} WHERE term_id=${results.id}'`,
|
|
268
|
+
]
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// update the API results ID, back to the existing ID from earlier.
|
|
274
|
+
results.id = existingID;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// add results to collection
|
|
278
|
+
collection = collection.concat( results );
|
|
279
|
+
|
|
280
|
+
// We wait requestDelay seconds between requests.
|
|
281
|
+
await sleep( requestDelay );
|
|
282
|
+
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function createMediaItem( media ){
|
|
289
|
+
|
|
290
|
+
let fd = new FormData();
|
|
291
|
+
let featureMediaFile = new File(
|
|
292
|
+
[
|
|
293
|
+
media.data
|
|
294
|
+
],
|
|
295
|
+
media.source_url.split('/').pop(),
|
|
296
|
+
{
|
|
297
|
+
type: media.mime_type
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
fd.append('file', featureMediaFile );
|
|
301
|
+
fd.append('title', media.title);
|
|
302
|
+
fd.append('caption', media.caption);
|
|
303
|
+
fd.append('alt_text', media.alt_text);
|
|
304
|
+
fd.append('date', media.date);
|
|
305
|
+
|
|
306
|
+
return fd;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function axiosErrorHandler( error ){
|
|
310
|
+
|
|
311
|
+
if (error.response) {
|
|
312
|
+
// The request was made and the server responded with a status code
|
|
313
|
+
// that falls out of the range of 2xx
|
|
314
|
+
let { data, status } = error.response;
|
|
315
|
+
|
|
316
|
+
switch( status ){
|
|
317
|
+
case 401: // Invalid Credentials
|
|
318
|
+
data.message += `\nPlease check your ${terminalLink('Application Password', 'https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/')}`;
|
|
319
|
+
case 404: // Not Found
|
|
320
|
+
//spinner.fail( `${data.message}` )
|
|
321
|
+
//console.log('Error', `${data.message}`);
|
|
322
|
+
//console.log('Error', `${data}`);
|
|
323
|
+
//process.exit(1)
|
|
324
|
+
default:
|
|
325
|
+
console.log('Error', error.response);
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
} else if (error.request) {
|
|
329
|
+
// The request was made but no response was received
|
|
330
|
+
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
|
331
|
+
// http.ClientRequest in node.js
|
|
332
|
+
console.log(error.request);
|
|
333
|
+
} else {
|
|
334
|
+
// Something happened in setting up the request that triggered an Error
|
|
335
|
+
console.log('Error', error.message);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Sync Environments.
|
|
341
|
+
*
|
|
342
|
+
* @param {Object} options
|
|
343
|
+
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
344
|
+
* @param {boolean} options.from Remote Site URL with current changes.
|
|
345
|
+
* @param {boolean} options.to Destination Site URL that should be synced.
|
|
346
|
+
* @param {boolean} options.debug True if debug mode is enabled.
|
|
347
|
+
*/
|
|
348
|
+
export default async function sync({
|
|
349
|
+
spinner,
|
|
350
|
+
debug,
|
|
351
|
+
from,
|
|
352
|
+
to
|
|
353
|
+
} ) {
|
|
354
|
+
|
|
355
|
+
const localFile = path.join(appPath, 'caweb.json');
|
|
356
|
+
const {workDirectoryPath} = await loadConfig(path.resolve('.'));
|
|
357
|
+
|
|
358
|
+
process.env.WP_CLI_CONFIG_PATH = path.join(workDirectoryPath, 'config.yml');
|
|
359
|
+
|
|
360
|
+
// if caweb.json file doesn't exist we don't do anything
|
|
361
|
+
if( ! fs.existsSync(localFile) ){
|
|
362
|
+
spinner.fail('caweb.json file not found.')
|
|
363
|
+
process.exit(1)
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// read configuration file
|
|
367
|
+
const serviceConfig = JSON.parse( fs.readFileSync(localFile) );
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* make sure instances are in the file.
|
|
371
|
+
* must have sync property
|
|
372
|
+
* each instance has to have a url, user, pwd property
|
|
373
|
+
*/
|
|
374
|
+
if(
|
|
375
|
+
! serviceConfig.sync ||
|
|
376
|
+
! serviceConfig.sync[from] ||
|
|
377
|
+
! serviceConfig.sync[from].url ||
|
|
378
|
+
! serviceConfig.sync[from].user ||
|
|
379
|
+
! serviceConfig.sync[from].pwd ||
|
|
380
|
+
! serviceConfig.sync[to] ||
|
|
381
|
+
! serviceConfig.sync[to].url ||
|
|
382
|
+
! serviceConfig.sync[to].user ||
|
|
383
|
+
! serviceConfig.sync[to].pwd
|
|
384
|
+
){
|
|
385
|
+
spinner.fail(`caweb.json is not configured properly for ${from} and ${to}.`);
|
|
386
|
+
process.exit(1)
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// get instance data
|
|
390
|
+
from = serviceConfig.sync[from];
|
|
391
|
+
let fromOptions = {
|
|
392
|
+
url: from.url,
|
|
393
|
+
headers: {
|
|
394
|
+
Authorization: 'Basic ' + Buffer.from(`${from.user}:${from.pwd}`).toString('base64')
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
let ssh = 'local' !== to ? to : `docker:${path.basename(workDirectoryPath)}-cli-1`;
|
|
399
|
+
|
|
400
|
+
to = serviceConfig.sync[to];
|
|
401
|
+
|
|
402
|
+
let toOptions = {
|
|
403
|
+
url: to.url,
|
|
404
|
+
ssh,
|
|
405
|
+
headers: {
|
|
406
|
+
Authorization: 'Basic ' + Buffer.from(`${to.user}:${to.pwd}`).toString('base64'),
|
|
407
|
+
'content-type': 'multipart/form-data',
|
|
408
|
+
'accept': '*/*'
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
// get all pages/posts
|
|
414
|
+
spinner.text = `Gathering all pages from ${from.url}`;
|
|
415
|
+
let pages = await getTaxonomies(fromOptions);
|
|
416
|
+
|
|
417
|
+
// data display
|
|
418
|
+
//spinner.info();
|
|
419
|
+
|
|
420
|
+
let posts = await getTaxonomies(fromOptions, 'posts');
|
|
421
|
+
|
|
422
|
+
// create all pages/posts
|
|
423
|
+
spinner.text = `Creating all pages to ${to.url}`;
|
|
424
|
+
await createTaxonomies( pages, toOptions, 'pages', spinner );
|
|
425
|
+
await createTaxonomies( posts, toOptions, 'posts', spinner );
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Media Library Handling
|
|
429
|
+
* 1) attached media items by default are only possible on pages.
|
|
430
|
+
* 2) featured media by default are only possible on posts.
|
|
431
|
+
*/
|
|
432
|
+
const mediaFields = [
|
|
433
|
+
'id',
|
|
434
|
+
'source_url',
|
|
435
|
+
'title',
|
|
436
|
+
'caption',
|
|
437
|
+
'alt_text',
|
|
438
|
+
'date',
|
|
439
|
+
'mime_type'
|
|
440
|
+
];
|
|
441
|
+
|
|
442
|
+
let attachedMedia = await getTaxonomies({
|
|
443
|
+
...fromOptions,
|
|
444
|
+
fields: mediaFields,
|
|
445
|
+
parent: pages.map((p) => { return p.id })
|
|
446
|
+
},
|
|
447
|
+
'media'
|
|
448
|
+
);
|
|
449
|
+
|
|
450
|
+
let featuredMedia = await getTaxonomies({
|
|
451
|
+
...fromOptions,
|
|
452
|
+
fields: mediaFields,
|
|
453
|
+
include: posts.map((p) => { if(p.featured_media){return p.featured_media } })
|
|
454
|
+
},
|
|
455
|
+
'media'
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
// before we can upload media files.
|
|
459
|
+
for( let mediaObj of [].concat( attachedMedia, featuredMedia ) ){
|
|
460
|
+
// generate a blob from the media object source_url.
|
|
461
|
+
const mediaBlob = await axios.request(
|
|
462
|
+
{
|
|
463
|
+
...fromOptions,
|
|
464
|
+
url: mediaObj.source_url,
|
|
465
|
+
responseType: 'arraybuffer'
|
|
466
|
+
}
|
|
467
|
+
).then( (img) => { return new Blob([img.data]) });
|
|
468
|
+
|
|
469
|
+
mediaObj.data = mediaBlob;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// create media attachments
|
|
473
|
+
spinner.text = `Uploading media files to ${to.url}`;
|
|
474
|
+
//await createTaxonomies([].concat( attachedMedia, featuredMedia ), toOptions, 'media', spinner)
|
|
475
|
+
|
|
476
|
+
// get all menus
|
|
477
|
+
let menus = await getTaxonomies({
|
|
478
|
+
...fromOptions,
|
|
479
|
+
fields: [
|
|
480
|
+
'id',
|
|
481
|
+
'description',
|
|
482
|
+
'name',
|
|
483
|
+
'slug',
|
|
484
|
+
'meta',
|
|
485
|
+
'locations'
|
|
486
|
+
]
|
|
487
|
+
}, 'menus').then((navs) =>{
|
|
488
|
+
// filter out any menus not assigned to a location.
|
|
489
|
+
return navs.filter((menu) => {
|
|
490
|
+
return menu.locations.length
|
|
491
|
+
});
|
|
492
|
+
})
|
|
493
|
+
|
|
494
|
+
// create menus
|
|
495
|
+
await createTaxonomies(menus, toOptions, 'menus', spinner);
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import path from '
|
|
4
|
+
import path from 'path';
|
|
5
5
|
import loadConfig from '@wordpress/env/lib/config/load-config.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Internal dependencies
|
|
9
9
|
*/
|
|
10
|
-
import {runCLICmds} from '../../
|
|
10
|
+
import {runCLICmds} from '../../lib/index.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Promisified dependencies
|
package/commands/test.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import axios from 'axios';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import loadConfig from '@wordpress/env/lib/config/load-config.js';
|
|
8
|
+
import cp from 'child_process';
|
|
9
|
+
|
|
10
|
+
//var WP = require('wp-cli');
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
import { runCLICmds, runCmd, projectPath } from '../lib/index.js';
|
|
15
|
+
/*
|
|
16
|
+
import generateOverridesMD from '../admin.js';
|
|
17
|
+
import { CAWEB_OPTIONS, DIVI_OPTIONS } from '../options.js';
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Promisified dependencies
|
|
21
|
+
*/
|
|
22
|
+
import os from 'os';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Test code.
|
|
26
|
+
*
|
|
27
|
+
* @param {Object} options
|
|
28
|
+
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
29
|
+
* @param {boolean} options.environment Which environment to test in.
|
|
30
|
+
* @param {boolean} options.debug True if debug mode is enabled.
|
|
31
|
+
*/
|
|
32
|
+
export default async function test({
|
|
33
|
+
spinner,
|
|
34
|
+
debug,
|
|
35
|
+
environment
|
|
36
|
+
} ) {
|
|
37
|
+
|
|
38
|
+
spinner.text = "Testing Code Functionality";
|
|
39
|
+
const config = await loadConfig(path.resolve('.'));
|
|
40
|
+
|
|
41
|
+
process.env.WP_CLI_CONFIG_PATH = path.join(config.workDirectoryPath, 'config.yml');
|
|
42
|
+
// update post meta.
|
|
43
|
+
let id = 35;
|
|
44
|
+
let newId = 30
|
|
45
|
+
let tbl = `wp_term_taxonomy`;
|
|
46
|
+
|
|
47
|
+
let result = await runCmd(
|
|
48
|
+
'php',
|
|
49
|
+
[
|
|
50
|
+
path.join(projectPath, 'bin', 'wp-cli.phar'),
|
|
51
|
+
'--ssh=docker:' + path.basename(config.workDirectoryPath) + '-cli-1',
|
|
52
|
+
`db query 'UPDATE ${tbl} SET term_taxonomy_id=${newId},term_id=${newId} WHERE term_id=${id}'`,
|
|
53
|
+
]
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
console.log( result );
|
|
57
|
+
/*
|
|
58
|
+
let q = `UPDATE wp_posts SET id=1 WHERE id=10 `;
|
|
59
|
+
let u = 'http://danny.com/wp-json/wp/v2/pages/2827';
|
|
60
|
+
let result = await axios.request({
|
|
61
|
+
url: u,
|
|
62
|
+
method: 'POST',
|
|
63
|
+
data: {
|
|
64
|
+
title: 'Audio',
|
|
65
|
+
meta: {
|
|
66
|
+
_et_pb_use_builder: 'on'
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
headers: {
|
|
70
|
+
Authorization: 'Basic ' + Buffer.from(`admin:9RUG nPuo u581 cY2A uSJd FE2P`).toString('base64')
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
.then( async (res) => { return res.data; } )
|
|
74
|
+
.catch( async (err) => { return err; } )
|
|
75
|
+
|
|
76
|
+
*/
|
|
77
|
+
/*
|
|
78
|
+
let result = await runCmd(
|
|
79
|
+
'php',
|
|
80
|
+
[
|
|
81
|
+
//'-r',
|
|
82
|
+
path.join(projectPath, 'bin', 'wp-cli.phar'),
|
|
83
|
+
'--ssh=' + `docker:${path.basename(config.workDirectoryPath)}-cli-1`,
|
|
84
|
+
//'@dev',
|
|
85
|
+
//`db query '${q}'`,
|
|
86
|
+
'post list',
|
|
87
|
+
//'--info',
|
|
88
|
+
'--skip-themes',
|
|
89
|
+
//`--url=${new URL(u).origin}`
|
|
90
|
+
// '--format=json'
|
|
91
|
+
//'--skip-column-names',
|
|
92
|
+
//'post list path=/nas/content/live/cawebdev/ --http=https://dev.sites.ca.gov --url=https://dev.sites.ca.gov',
|
|
93
|
+
],
|
|
94
|
+
config
|
|
95
|
+
)*/
|
|
96
|
+
|
|
97
|
+
//console.log( 'Result', result.toString() );
|
|
98
|
+
//console.log( 'Output', result.stdout.toString() );
|
|
99
|
+
//console.log( 'Error', result.stderr.toString() );
|
|
100
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for Accessibility Checker
|
|
3
|
+
* @link https://www.npmjs.com/package/accessibility-checker
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
ruleArchive: "latest",
|
|
8
|
+
policies: [
|
|
9
|
+
'WCAG_2_1'
|
|
10
|
+
],
|
|
11
|
+
failLevels: [
|
|
12
|
+
'violation',
|
|
13
|
+
'potentialviolation'
|
|
14
|
+
],
|
|
15
|
+
reportLevels: [
|
|
16
|
+
'violation',
|
|
17
|
+
'potentialviolation',
|
|
18
|
+
'recommendation',
|
|
19
|
+
'potentialrecommendation',
|
|
20
|
+
'manual',
|
|
21
|
+
'pass'
|
|
22
|
+
],
|
|
23
|
+
outputFolder: "a11y",
|
|
24
|
+
outputFormat: [
|
|
25
|
+
'html'
|
|
26
|
+
],
|
|
27
|
+
outputFilenameTimestamp: false
|
|
28
|
+
}
|