UNPKG

3.85 kBJavaScriptView Raw
1'use strict';
2const _ = require('lodash'),
3 pluralize = require('pluralize'),
4 h = require('highland'),
5 yaml = require('js-yaml'),
6 getStdin = require('get-stdin'),
7 options = require('./cli-options'),
8 config = require('../lib/cmd/config'),
9 rest = require('../lib/rest'),
10 reporter = require('../lib/reporters'),
11 exporter = require('../lib/cmd/export'),
12 prefixes = require('../lib/prefixes');
13
14function builder(yargs) {
15 return yargs
16 .usage('Usage: $0 export [url]')
17 .example('$0 export --key prod domain.com > db_dump.clay', 'Export dispatches')
18 .example('$0 export --key prod --layout domain.com > db_dump.clay', 'Export pages with layouts')
19 .example('$0 export --key prod --yaml domain.com/_pages/foo > bootstrap.yml', 'Export bootstrap')
20 .option('k', options.key)
21 .option('s', options.size)
22 .option('l', options.layout)
23 .option('y', options.yaml)
24 .option('r', options.reporter);
25}
26
27/**
28 * log fatal errors and exit with non-zero status
29 * @param {Error} e
30 * @param {object} argv
31 */
32function fatalError(e, argv) {
33 reporter.logSummary(argv.reporter, 'export', () => ({ success: false, message: 'Unable to export' }))([{ type: 'error', message: e.url, details: e.message }]);
34 process.exit(1);
35}
36
37/**
38 * show progress as we export things
39 * @param {object} argv
40 */
41function handler(argv) {
42 const log = reporter.log(argv.reporter, 'export');
43
44 let url = config.get('url', argv.url),
45 isElasticPrefix, stream;
46
47 if (!url) {
48 fatalError({ url: 'URL is not defined!', message: 'Please specify a url to export from'}, argv);
49 }
50
51 log('Exporting items...');
52 stream = rest.isElasticPrefix(url).flatMap((isPrefix) => {
53 isElasticPrefix = isPrefix;
54 // if we're pointed at an elastic prefix, run a query to fetch pages
55 if (isPrefix) {
56 return h(getStdin()
57 .then(yaml.safeLoad)
58 .then((query) => {
59 return exporter.fromQuery(url, query, {
60 key: argv.key,
61 concurrency: argv.concurrency,
62 size: argv.size,
63 layout: argv.layout,
64 yaml: argv.yaml
65 });
66 })).flatten();
67 } else {
68 // export a single url
69 return exporter.fromURL(url, {
70 key: argv.key,
71 concurrency: argv.concurrency,
72 size: argv.size,
73 layout: argv.layout,
74 yaml: argv.yaml
75 });
76 }
77 });
78
79 stream
80 .stopOnError((e) => fatalError(e, argv))
81 .map((res) => {
82 const rootKey = Object.keys(res)[0], // could be unprefixed uri OR type of thing (if exporting a bootstrap)
83 str = argv.yaml ? yaml.safeDump(res) : `${JSON.stringify(res)}\n`;
84
85 process.stdout.write(str); // pipe stringified exported stuff to stdout
86 if (argv.yaml) {
87 return { type: 'success', message: _.tail(rootKey).join('') }; // e.g. components
88 } else if (isElasticPrefix) {
89 return { type: 'success', message: `${url}${rootKey}` }; // e.g. http://domain.com/_components/foo
90 } else {
91 return { type: 'success', message: `${prefixes.getFromUrl(url)}${rootKey}` }; // e.g. http://domain.com/_pages/foo
92 }
93 })
94 .errors((err, push) => {
95 push(null, { type: 'error', message: err.url, details: err.message }); // every url that errors out should be captured
96 })
97 .map(reporter.logAction(argv.reporter, 'export'))
98 .toArray(reporter.logSummary(argv.reporter, 'export', (successes) => {
99 const thing = argv.yaml ? 'bootstrap' : 'dispatch';
100
101 if (successes) {
102 return { success: true, message: `Exported ${pluralize(thing, successes, true)}` };
103 } else {
104 return { success: false, message: `Exported 0 ${thing}s (´°ω°\`)` };
105 }
106 }));
107}
108
109module.exports = {
110 command: 'export [url]',
111 describe: 'Export data from clay',
112 aliases: ['exporter', 'e'],
113 builder,
114 handler
115};