@madebyseed/seed-cli-tools 1.0.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.
@@ -0,0 +1,211 @@
1
+ const chalk = require("chalk");
2
+ const log = require("fancy-log");
3
+ const _ = require('lodash');
4
+ const Promise = require('bluebird');
5
+ const { shopifyCLI } = require("../../utils");
6
+
7
+
8
+ let errors = [];
9
+
10
+ /**
11
+ * Utility and reusable functions used by our Gulp Tasks
12
+ *
13
+ * @summary a set of utility functions used within the gulp tasks of seed-cli
14
+ * @namespace seed-cli.utilities
15
+ * @memberof seed-cli
16
+ */
17
+ const utilities = {
18
+
19
+ /**
20
+ * Launches shopify theme serve command to serve files on ./dist folder
21
+ *
22
+ * @memberof seed-cli.utilities
23
+ * @returns {object} - ChildProcess
24
+ */
25
+ serveDist: () => {
26
+ return shopifyCLI.serve();
27
+ },
28
+
29
+ /**
30
+ * Launches shopify theme push command to deploy files on ./dist folder
31
+ * to a store's theme
32
+ *
33
+ * @memberof seed-cli.utilities
34
+ * @returns {object} - ChildProcess
35
+ */
36
+ deployDist: () => {
37
+ return shopifyCLI.push();
38
+ },
39
+
40
+ /**
41
+ * Handles the output for any errors that might have been captured
42
+ * during the build and zip Gulp tasks.
43
+ *
44
+ * @memberof seed-cli.utilities
45
+ */
46
+ outputErrors: () => {
47
+ if (!errors.length) {
48
+ return;
49
+ }
50
+
51
+ log(chalk.red(`There were errors during the build:\n`));
52
+
53
+ errors.forEach((err) => {
54
+ log(chalk.red(err));
55
+ });
56
+
57
+ errors = [];
58
+ },
59
+
60
+ /**
61
+ * Generic error handler for streams called in `watch` tasks (used by gulp-plumber).
62
+ * Any error that is thrown inside of a task is added to the errors array.
63
+ *
64
+ * @memberof seed-cli.utilities
65
+ * @param {Error} err
66
+ */
67
+ errorHandler: (err) => {
68
+ log(chalk.red(err));
69
+ errors.push(err);
70
+
71
+ this.emit('end');
72
+ },
73
+
74
+ /**
75
+ * Executes an array of promises in series
76
+ *
77
+ * @param promiseArrayFactory {Function} - an array of promise factories
78
+ * @returns {Promise} - promise.all() style array of results from each promise
79
+ */
80
+ promiseSeries: (promiseArrayFactory) => {
81
+ const results = [];
82
+
83
+ return Promise.each(promiseArrayFactory, (factory) => {
84
+ const result = factory();
85
+ results.push(result);
86
+ return result;
87
+ }).thenReturn(results).all();
88
+ },
89
+
90
+ /**
91
+ * Function passed to cheerio.run - adds aria tags & other accessibility
92
+ * based information to each svg element's markup...
93
+ *
94
+ * @memberof seed-cli.utilities
95
+ * @param {Function} $ - jQuery reference
96
+ * @param {fs} file - reference to current icon file?
97
+ */
98
+ processSvg: ($, file) => {
99
+ var $svg = $('svg'); // eslint-disable-line no-var
100
+ var $newSvg = $('<svg aria-hidden="true" focusable="false" role="presentation" class="icon" />'); // eslint-disable-line no-var
101
+ var fileName = file.relative.replace('.svg', ''); // eslint-disable-line no-var
102
+ var viewBoxAttr = $svg.attr('viewbox'); // eslint-disable-line no-var
103
+
104
+ // Add necessary attributes
105
+ if (viewBoxAttr) {
106
+ var width = parseInt(viewBoxAttr.split(' ')[2], 10); // eslint-disable-line no-var
107
+ var height = parseInt(viewBoxAttr.split(' ')[3], 10); // eslint-disable-line no-var
108
+ var widthToHeightRatio = width / height; // eslint-disable-line no-var
109
+ if (widthToHeightRatio >= 1.5) {
110
+ $newSvg.addClass('icon--wide');
111
+ }
112
+ $newSvg.attr('viewBox', viewBoxAttr);
113
+ }
114
+
115
+ // Add required classes to full color icons
116
+ if (file.relative.indexOf('-full-color') >= 0) {
117
+ $newSvg.addClass('icon--full-color');
118
+ }
119
+
120
+ $newSvg
121
+ .addClass(fileName)
122
+ .append($svg.contents());
123
+
124
+ $newSvg.append($svg.contents());
125
+ $svg.after($newSvg);
126
+ $svg.remove();
127
+ },
128
+
129
+ /**
130
+ * Factory for creating an event cache - used with a short debounce to batch any
131
+ * file changes that occur in rapid succession during Watch tasks.
132
+ *
133
+ * @memberof seed-cli.utilities
134
+ * @param {Object} options
135
+ * @returns {eventCache} see type definition for more robust documentation
136
+ */
137
+ createEventCache: (options) => {
138
+ _.defaults(options = options || {}, { // eslint-disable-line no-param-reassign
139
+ changeEvents: ['add', 'change'],
140
+ unlinkEvents: ['unlink'],
141
+ });
142
+
143
+ /**
144
+ * A cache object used for caching `[chokidar]{@link https://github.com/paulmillr/chokidar}`
145
+ * events - used with a short `debounce` to batch any file changes that occur in rapid
146
+ * succession during Watch tasks.
147
+ *
148
+ * @typedef {Object} eventCache
149
+ * @prop {Array} change - an array for caching `add` and `change` events
150
+ * @prop {Array} unlink - an array for caching `unlink` events
151
+ * @prop {Function} addEvent - a function to push events to the appropriate `cache` array
152
+ */
153
+ return {
154
+ change: [],
155
+ unlink: [],
156
+
157
+ /**
158
+ * Pushes events to upload & remove caches for later batch deployment
159
+ *
160
+ * @function addEvent
161
+ * @memberof eventCache
162
+ * @param {String} event - chokidar event type - only cares about `(add|change|unlink)`
163
+ * @param {String} path - relative path to file passed via event
164
+ */
165
+ addEvent: function(event, path) {
166
+ _.each(options.changeEvents, (eventType) => {
167
+ if (event === eventType) {
168
+ this.change.push(path);
169
+ }
170
+ });
171
+
172
+ _.each(options.unlinkEvents, (eventType) => {
173
+ if (event === eventType) {
174
+ this.unlink.push(path);
175
+ }
176
+ });
177
+ },
178
+ };
179
+ },
180
+
181
+ /**
182
+ * Debounced (320ms) delegator function passing an {@link eventCache} object
183
+ * through to a pair of custom functions for processing batch add/change or unlink events.
184
+ * Clears the appropriate cache array after a change/delete function has been
185
+ * called.
186
+ *
187
+ * Example:
188
+ * ```javascript
189
+ * // TODO:
190
+ * ```
191
+ *
192
+ * @memberof seed-cli.utilities
193
+ * @method
194
+ * @param {eventCache} cache - a specific cache object for tracking file events
195
+ * @param {Function} changeFn - a custom function to process the set of files that have changed
196
+ * @param {Function} delFn - a custom function to remove the set of files that have changed from the `dist` directory
197
+ */
198
+ processCache: _.debounce((cache, changeFn, delFn) => {
199
+ if (cache.change.length) {
200
+ changeFn(cache.change);
201
+ cache.change = [];
202
+ }
203
+
204
+ if (cache.unlink.length) {
205
+ delFn(cache.unlink);
206
+ cache.unlink = [];
207
+ }
208
+ }, 320),
209
+ };
210
+
211
+ module.exports = utilities;
@@ -0,0 +1,48 @@
1
+ // const { yellow } = require('chalk');
2
+ const gulp = require('gulp');
3
+ // const runSequence = require('gulp4-run-sequence');
4
+ // const _ = require('lodash');
5
+ // const debug = require('debug')('seed-tools:watchers');
6
+ // const chokidar = require('chokidar');
7
+ // const fs = require('fs');
8
+ // const themekit = require('@shopify/themekit');
9
+ // const Promise = require('bluebird');
10
+
11
+
12
+ // const config = require('./includes/config.js');
13
+ const utils = require('./includes/utilities.js');
14
+ // const messages = require('./includes/messages.js');
15
+
16
+ // const cache = utils.createEventCache();
17
+ // const environment = config.environment.split(/\s*,\s*|\s+/)[0];
18
+
19
+ /**
20
+ * Aggregate task watching for file changes in `src` and
21
+ * building/cleaning/updating `dist` accordingly. *Made up of individual tasks
22
+ * referenced in other files
23
+ *
24
+ * @function watch:src
25
+ * @memberof seed-cli.tasks.watch
26
+ * @static
27
+ */
28
+ gulp.task('watch:src', () => {
29
+ return gulp.parallel(
30
+ 'watch:css',
31
+ 'watch:js',
32
+ 'watch:assets',
33
+ 'watch:svg'
34
+ )()
35
+ });
36
+
37
+ /**
38
+ * Initiates shopify's cli command 'shopify theme serve' on the dist folder,
39
+ * watching files and uploading them to development store
40
+ *
41
+ * @function watch:dist
42
+ * @memberof seed-cli.tasks.watch
43
+ * @static
44
+ */
45
+ gulp.task('watch:dist', () => {
46
+ console.log("Running Shopify theme serve...")
47
+ return utils.serveDist();
48
+ })
package/src/utils.js ADDED
@@ -0,0 +1,90 @@
1
+ import spawn from "cross-spawn";
2
+ import { join } from "path";
3
+ import config from "./config"
4
+
5
+ /**
6
+ * Wrappers for Shopify CLI commands
7
+ *
8
+ * @summary a set of utility functions used to wrap shopify's CLI
9
+ * @namespace seed-cli.shopifyCLI
10
+ * @memberof seed-cli
11
+ */
12
+ export const shopifyCLI = {
13
+
14
+ /**
15
+ * shopify login
16
+ *
17
+ * @memberof seed-cli.shopifyCLI
18
+ * @param {string} store - store's myshopify domain name
19
+ * @param {boolean} async - login asynchronously
20
+ *
21
+ * @returns {object} - spawnSync object or, node's <ChildProcess> object if async
22
+ */
23
+ login: (store, async = false) => {
24
+ const args = ['login', '--store', store];
25
+ const options = {
26
+ env: process.env,
27
+ stdio: "inherit",
28
+ shell: true,
29
+ }
30
+
31
+ if (async)
32
+ return spawn('shopify', args, options);
33
+ else
34
+ return spawn.sync('shopify', args, options);
35
+ },
36
+
37
+ /**
38
+ * shopify theme serve
39
+ *
40
+ * @memberof seed-cli.shopifyCLI
41
+ * @returns {object} - node's ChildProcess
42
+ */
43
+ serve: () => {
44
+ return spawn('shopify theme', ['serve'], {
45
+ cwd: config.themeRoot + '/dist',
46
+ env: process.env,
47
+ stdio: "inherit",
48
+ shell: true,
49
+ })
50
+ },
51
+
52
+ /**
53
+ * shopify theme push
54
+ *
55
+ * @memberof seed-cli.shopifyCLI
56
+ * @returns {object} - node's ChildProcess
57
+ */
58
+ push: () => {
59
+ return spawn('shopify theme', ['push'], {
60
+ cwd: config.themeRoot + '/dist',
61
+ env: process.env,
62
+ stdio: "inherit",
63
+ shell: true,
64
+ })
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Get seed.config.js from project root dir
70
+ *
71
+ * @param {string} themeRoot - the path to theme root dir
72
+ */
73
+ export function getSeedConfig(themeRoot) {
74
+ return require(join(themeRoot, 'seed.config.js'));
75
+ }
76
+
77
+ /**
78
+ * Get store name from seed.config.js
79
+ *
80
+ * @param {string} themeRoot - the path to theme root dir
81
+ */
82
+ export function getStoreName(themeRoot) {
83
+ return getSeedConfig(themeRoot).store;
84
+ }
85
+
86
+
87
+
88
+
89
+
90
+