@madebyseed/seed-cli-tools 1.0.1 → 1.2.1

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.
@@ -1,11 +1,42 @@
1
- const gulp = require('gulp');
2
- const del = require('del');
3
- const zip = require('gulp-zip');
4
- const size = require('gulp-size');
5
- const plumber = require('gulp-plumber');
1
+ const gulp = require("gulp");
2
+ const gulpif = require("gulp-if");
3
+ const del = require("del");
4
+ const zip = require("gulp-zip");
5
+ const size = require("gulp-size");
6
+ const plumber = require("gulp-plumber");
6
7
 
7
- const config = require('./includes/config.js');
8
- const utils = require('./includes/utilities.js');
8
+ const config = require("./includes/config.js");
9
+ const utils = require("./includes/utilities.js");
10
+ const messages = require("./includes/messages.js");
11
+
12
+ const assetsPaths = [
13
+ config.src.assets,
14
+ config.src.templates,
15
+ config.src.sections,
16
+ config.src.snippets,
17
+ config.src.locales,
18
+ config.src.config,
19
+ config.src.layout,
20
+ ];
21
+
22
+ const themeSettingsAssets = [config.tmp.templates, config.tmp.config];
23
+
24
+ /**
25
+ * Copies files from one fold to another, creating a new dir if doesn't exists and
26
+ * overwriting if it does exist
27
+ *
28
+ * @param {Array} files - files to copy
29
+ * @param {Object} srcOptions - second param for gulp.src function
30
+ * @param {String} dest - destination dir
31
+ * @returns {Stream}
32
+ * @private
33
+ */
34
+ function copyFiles(files, srcOptions, dest, log = false) {
35
+ return gulp.src(files, srcOptions)
36
+ .pipe(plumber(utils.errorHandler))
37
+ .pipe(gulpif(log, size({ showFiles: true, pretty: true })))
38
+ .pipe(gulp.dest(dest));
39
+ }
9
40
 
10
41
  /**
11
42
  * Clean up build dirs/files whenever doing a full/clean (re)build.
@@ -14,8 +45,8 @@ const utils = require('./includes/utilities.js');
14
45
  * @memberof slate-cli.tasks.build
15
46
  * @static
16
47
  */
17
- gulp.task('clean', () => {
18
- return del(['upload', 'dist']);
48
+ gulp.task("clean", () => {
49
+ return del(["upload", "dist", "tmp"]);
19
50
  });
20
51
 
21
52
  /**
@@ -25,13 +56,39 @@ gulp.task('clean', () => {
25
56
  * @memberof slate-cli.tasks.deploy
26
57
  * @static
27
58
  */
28
- gulp.task('compress', () => {
59
+ gulp.task("compress", () => {
29
60
  const distFiles = `${config.dist.root}**/*`;
30
- const ignoreConfig = `!${config.dist.root}config.yml`;
31
61
 
32
- return gulp.src([distFiles, ignoreConfig])
62
+ return gulp.src([distFiles])
33
63
  .pipe(plumber(utils.errorHandler))
34
- .pipe(zip(`${config.packageJson.name}.zip` || 'theme.zip'))
35
- .pipe(size({showFiles: true, pretty: true}))
36
- .pipe(gulp.dest('./upload/'));
64
+ .pipe(zip(`${config.packageJson.name}.zip` || "theme.zip"))
65
+ .pipe(size({ showFiles: true, pretty: true }))
66
+ .pipe(gulp.dest("./upload/"));
67
+ });
68
+
69
+ /**
70
+ * Duplicates /src directory into a /tmp directory
71
+ *
72
+ * @function generate:tmp
73
+ * @memberof seed-cli.tasks.sync-settings
74
+ * @static
75
+ */
76
+ gulp.task("generate:tmp", () => {
77
+ messages.logProcessFiles('Generating tmp folder...')
78
+ return copyFiles(assetsPaths, { base: config.src.root }, config.tmp.root);
79
+ });
80
+
81
+ /**
82
+ * Syncronizes the theme settings of /tmp directory into our src directory
83
+ *
84
+ * @function sync-settings:tmp:src
85
+ * @memberof seed-cli.tasks.sync-settings
86
+ * @static
87
+ */
88
+ gulp.task("sync-settings:tmp:src", () => {
89
+ return copyFiles(
90
+ themeSettingsAssets,
91
+ { base: config.tmp.root },
92
+ config.src.root
93
+ );
37
94
  });
@@ -1,15 +1,17 @@
1
- const join = require('path').join;
2
- const logger = require('debug')('seed-tools');
3
- const findRoot = require('find-root');
4
- const autoprefixer = require('autoprefixer');
5
- const tailwindcss = require('tailwindcss');
6
- const argv = require('minimist')(process.argv.slice(2));
1
+ const join = require("path").join;
2
+ const logger = require("debug")("seed-tools");
3
+ const findRoot = require("find-root");
4
+ const autoprefixer = require("autoprefixer");
5
+ const tailwindcss = require("tailwindcss");
6
+ const cssnano = require("cssnano");
7
+ const argv = require("minimist")(process.argv.slice(2));
7
8
  const themeRoot = findRoot(process.cwd());
9
+ const tailwindConfig = 'tailwind.config.js'
8
10
 
9
11
  let pkg = {};
10
12
 
11
13
  try {
12
- pkg = require(join(themeRoot, 'package.json'));
14
+ pkg = require(join(themeRoot, "package.json"));
13
15
  } catch (err) {
14
16
  logger(err);
15
17
  }
@@ -31,65 +33,89 @@ try {
31
33
  * @memberof seed-cli
32
34
  * @summary Configuring seed-cli
33
35
  * @prop {String} environment - development | staging | production
34
- * @prop {String} tkconfig - path to themekit config file
35
- * @prop {String} scssLintConfig - path to scss-lint config file
36
36
  * @prop {String} deployLog - path to deploy log file
37
37
  * @prop {String} src - globs (multi-filename matching patterns) for various source files
38
+ * @prop {String} tmp - globs (multi-filename matching patterns) for various tmp files
38
39
  * @prop {Object} dist - paths to relevant folder locations in the distributable directory
39
40
  * @prop {Object} roots - array of "root" (entry point) JS & CSS files
40
41
  * @prop {Object} plugins - configuration objects passed to various plugins used in the task interface
41
42
  */
42
43
  const config = {
43
- environment: argv.enviroment || 'development',
44
+ environment: argv.environment || "development",
45
+ optimize: !argv["skip-optimizations"],
44
46
  themeRoot,
45
47
  packageJson: pkg,
46
48
 
47
- tkConfig: 'config.yml',
48
- deployLog: 'deploy.log',
49
+ tailwindConfig,
50
+
51
+ seedConfig: "seed.config.js",
52
+
49
53
 
50
54
  src: {
51
- root: 'src/',
52
- js: 'src/scripts/**/*.{js,js.liquid}',
53
- vendorJs: 'src/scripts/vendor/*.js',
54
- json: 'src/**/*.json',
55
- css: 'src/styles/**/*.{css,scss,scss.liquid}',
56
- cssLint: 'src/styles/**/*.{css,scss}',
57
- vendorCss: 'src/styles/vendor/*.{css,scss}',
58
- assets: 'src/assets/**/*',
59
- icons: 'src/icons/**/*.svg',
60
- templates: 'src/templates/**/*',
61
- snippets: 'src/snippets/*',
62
- sections: 'src/sections/*',
63
- locales: 'src/locales/*',
64
- config: 'src/config/*',
65
- layout: 'src/layout/*',
55
+ root: "src/",
56
+ js: "src/scripts/**/*.{js,js.liquid}",
57
+ vendorJs: "src/scripts/vendor/*.js",
58
+ json: "src/**/*.json",
59
+ css: "src/styles/**/*.{css,scss,scss.liquid}",
60
+ cssLint: "src/styles/**/*.{css,scss}",
61
+ vendorCss: "src/styles/vendor/*.{css,scss}",
62
+ assets: "src/assets/**/*",
63
+ icons: "src/icons/**/*.svg",
64
+ templates: "src/templates/**/*",
65
+ snippets: "src/snippets/*",
66
+ sections: "src/sections/*",
67
+ locales: "src/locales/*",
68
+ config: "src/config/*",
69
+ layout: "src/layout/*",
70
+ },
71
+
72
+ tmp: {
73
+ root: "tmp/",
74
+ js: "tmp/scripts/**/*.{js,js.liquid}",
75
+ vendorJs: "tmp/scripts/vendor/*.js",
76
+ json: "tmp/**/*.json",
77
+ css: "tmp/styles/**/*.{css,scss,scss.liquid}",
78
+ cssLint: "tmp/styles/**/*.{css,scss}",
79
+ vendorCss: "tmp/styles/vendor/*.{css,scss}",
80
+ assets: "tmp/assets/**/*",
81
+ icons: "tmp/icons/**/*.svg",
82
+ templates: "tmp/templates/**/*",
83
+ snippets: "tmp/snippets/*",
84
+ sections: "tmp/sections/*",
85
+ locales: "tmp/locales/*",
86
+ config: "tmp/config/*",
87
+ layout: "tmp/layout/*",
66
88
  },
67
89
 
68
90
  dist: {
69
- root: 'dist/',
70
- assets: 'dist/assets/',
71
- snippets: 'dist/snippets/',
72
- sections: 'dist/sections/',
73
- layout: 'dist/layout/',
74
- templates: 'dist/templates/',
75
- locales: 'dist/locales/',
91
+ root: "dist/",
92
+ assets: "dist/assets/",
93
+ snippets: "dist/snippets/",
94
+ sections: "dist/sections/",
95
+ layout: "dist/layout/",
96
+ templates: "dist/templates/",
97
+ locales: "dist/locales/",
76
98
  },
77
99
 
78
100
  roots: {
79
- js: 'src/scripts/*.{js,js.liquid}',
80
- vendorJs: 'src/scripts/vendor.js',
81
- css: 'src/styles/*.{css,scss}',
101
+ js: "src/scripts/*.{js,js.liquid}",
102
+ vendorJs: "src/scripts/vendor.js",
103
+ css: "src/styles/*.{css,scss}",
82
104
  },
83
105
 
84
106
  plugins: {
85
107
  cheerio: {
86
- run: require('./utilities.js').processSvg,
108
+ run: require("./utilities.js").processSvg,
87
109
  },
88
110
  postcss: [
89
- tailwindcss({ config: join(themeRoot, 'tailwind.config.js')}),
90
- autoprefixer(),
91
- ]
111
+ tailwindcss({ config: join(themeRoot, tailwindConfig) }),
112
+ autoprefixer(),
113
+ ],
92
114
  },
93
115
  };
94
116
 
117
+ if (config.optimize) {
118
+ config.plugins.postcss.push((cssnano({ preset: "default" })))
119
+ }
120
+
95
121
  module.exports = config;
@@ -52,7 +52,7 @@ const messages = {
52
52
  log('running task',
53
53
  chalk.bold('[child process]'),
54
54
  chalk.white('-'),
55
- chalk.cyan('theme', cmd),
55
+ chalk.cyan(cmd),
56
56
  );
57
57
  },
58
58
 
@@ -80,8 +80,8 @@ const messages = {
80
80
  },
81
81
 
82
82
  configChange: () => {
83
- return 'Changes to ThemeKit Config Detected: You may need to quit <slate watch>' +
84
- ' and run a full <slate deploy> as a result.';
83
+ return 'Changes to seed.config.js Detected: You may need to quit <seed watch>' +
84
+ ' and run a full <seed deploy> as a result.';
85
85
  },
86
86
 
87
87
  translationsFailed: () => {
@@ -91,13 +91,13 @@ const messages = {
91
91
  invalidThemeId: (themeId, env) => {
92
92
  log('Invalid theme id for',
93
93
  chalk.cyan(`${env}: ${themeId}`),
94
- chalk.yellow('`theme_id` must be an integer or "live".'),
94
+ chalk.yellow('`theme_id` must be a string.'),
95
95
  );
96
96
  },
97
97
 
98
98
  configError: () => {
99
99
  log('File missing:',
100
- chalk.yellow('`config.yml` does not exist. You need to add a config file before you can make changes to your Shopify store.'),
100
+ chalk.yellow('`seed.config.js` does not exist. You need to add a config file before you can make changes to your Shopify store.'),
101
101
  );
102
102
  },
103
103
 
@@ -1,9 +1,7 @@
1
1
  const chalk = require("chalk");
2
2
  const log = require("fancy-log");
3
- const _ = require('lodash');
4
- const Promise = require('bluebird');
5
- const { shopifyCLI } = require("../../utils");
6
-
3
+ const _ = require("lodash");
4
+ const Promise = require("bluebird");
7
5
 
8
6
  let errors = [];
9
7
 
@@ -15,28 +13,6 @@ let errors = [];
15
13
  * @memberof seed-cli
16
14
  */
17
15
  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
16
  /**
41
17
  * Handles the output for any errors that might have been captured
42
18
  * during the build and zip Gulp tasks.
@@ -68,7 +44,7 @@ const utilities = {
68
44
  log(chalk.red(err));
69
45
  errors.push(err);
70
46
 
71
- this.emit('end');
47
+ this.emit("end");
72
48
  },
73
49
 
74
50
  /**
@@ -84,7 +60,9 @@ const utilities = {
84
60
  const result = factory();
85
61
  results.push(result);
86
62
  return result;
87
- }).thenReturn(results).all();
63
+ })
64
+ .thenReturn(results)
65
+ .all();
88
66
  },
89
67
 
90
68
  /**
@@ -96,30 +74,30 @@ const utilities = {
96
74
  * @param {fs} file - reference to current icon file?
97
75
  */
98
76
  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
77
+ var $svg = $("svg"); // eslint-disable-line no-var
78
+ var $newSvg = $(
79
+ '<svg aria-hidden="true" focusable="false" role="presentation" class="icon" />'
80
+ ); // eslint-disable-line no-var
81
+ var fileName = file.relative.replace(".svg", ""); // eslint-disable-line no-var
82
+ var viewBoxAttr = $svg.attr("viewbox"); // eslint-disable-line no-var
103
83
 
104
84
  // Add necessary attributes
105
85
  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
86
+ var width = parseInt(viewBoxAttr.split(" ")[2], 10); // eslint-disable-line no-var
87
+ var height = parseInt(viewBoxAttr.split(" ")[3], 10); // eslint-disable-line no-var
108
88
  var widthToHeightRatio = width / height; // eslint-disable-line no-var
109
89
  if (widthToHeightRatio >= 1.5) {
110
- $newSvg.addClass('icon--wide');
90
+ $newSvg.addClass("icon--wide");
111
91
  }
112
- $newSvg.attr('viewBox', viewBoxAttr);
92
+ $newSvg.attr("viewBox", viewBoxAttr);
113
93
  }
114
94
 
115
95
  // Add required classes to full color icons
116
- if (file.relative.indexOf('-full-color') >= 0) {
117
- $newSvg.addClass('icon--full-color');
96
+ if (file.relative.indexOf("-full-color") >= 0) {
97
+ $newSvg.addClass("icon--full-color");
118
98
  }
119
99
 
120
- $newSvg
121
- .addClass(fileName)
122
- .append($svg.contents());
100
+ $newSvg.addClass(fileName).append($svg.contents());
123
101
 
124
102
  $newSvg.append($svg.contents());
125
103
  $svg.after($newSvg);
@@ -135,9 +113,10 @@ const utilities = {
135
113
  * @returns {eventCache} see type definition for more robust documentation
136
114
  */
137
115
  createEventCache: (options) => {
138
- _.defaults(options = options || {}, { // eslint-disable-line no-param-reassign
139
- changeEvents: ['add', 'change'],
140
- unlinkEvents: ['unlink'],
116
+ _.defaults((options = options || {}), {
117
+ // eslint-disable-line no-param-reassign
118
+ changeEvents: ["add", "change"],
119
+ unlinkEvents: ["unlink"],
141
120
  });
142
121
 
143
122
  /**
@@ -162,7 +141,7 @@ const utilities = {
162
141
  * @param {String} event - chokidar event type - only cares about `(add|change|unlink)`
163
142
  * @param {String} path - relative path to file passed via event
164
143
  */
165
- addEvent: function(event, path) {
144
+ addEvent: function (event, path) {
166
145
  _.each(options.changeEvents, (eventType) => {
167
146
  if (event === eventType) {
168
147
  this.change.push(path);
@@ -0,0 +1,100 @@
1
+ const gulp = require("gulp");
2
+
3
+ const {
4
+ shopifyCLI,
5
+ extractThemeId,
6
+ logChildProcessOutput,
7
+ getDevThemeID,
8
+ setDevThemeID,
9
+ getThemeID,
10
+ } = require("../utils");
11
+ const config = require("./includes/config");
12
+ const messages = require("./includes/messages")
13
+
14
+ /**
15
+ * Initiates shopify's cli command 'shopify theme serve' on the dist folder,
16
+ * watching files and uploading them to development store
17
+ *
18
+ * @function shopify:serve:dist
19
+ * @memberof seed-cli.tasks.watch
20
+ * @static
21
+ */
22
+ gulp.task("shopify:serve:dist", () => {
23
+ messages.logChildProcess("'shopify theme serve' on dist...");
24
+ const childProcess = shopifyCLI.serve({
25
+ stdio: ["inherit", "pipe", "inherit"],
26
+ });
27
+ childProcess.stdout.setEncoding("utf8");
28
+ logChildProcessOutput(childProcess);
29
+ persistDevThemeID(childProcess);
30
+ return childProcess;
31
+ });
32
+
33
+ /**
34
+ * Pulls theme files from the development theme specified in seed config into src
35
+ *
36
+ * @function shopify:pull:dev
37
+ * @memberof seed-cli.tasks.deploy
38
+ * @static
39
+ */
40
+ gulp.task("shopify:pull:dev", (done) => {
41
+ messages.logChildProcess("'shopify theme pull' on development theme...");
42
+ const devThemeId = getDevThemeID(config.themeRoot);
43
+ if (!devThemeId) {
44
+ return done();
45
+ }
46
+
47
+ return shopifyCLI.pull(devThemeId);
48
+ });
49
+
50
+ /**
51
+ * Pulls theme files from the development theme specified in seed config into tmp
52
+ *
53
+ * @function shopify:pull:dev:tmp
54
+ * @memberof seed-cli.tasks.deploy
55
+ * @static
56
+ */
57
+ gulp.task("shopify:pull:dev:tmp", (done) => {
58
+ messages.logChildProcess("'shopify theme pull' on tmp folder...");
59
+ const devThemeId = getDevThemeID(config.themeRoot);
60
+ if (!devThemeId) {
61
+ return done();
62
+ }
63
+
64
+ return shopifyCLI.pull(
65
+ devThemeId,
66
+ config.tmp.root
67
+ );
68
+ });
69
+
70
+ /**
71
+ * Initiates shopify's cli command 'shopify theme push' on the dist folder,
72
+ * pushing it to stores theme
73
+ *
74
+ * @function deploy:dist
75
+ * @memberof seed-cli.tasks.deploy
76
+ * @static
77
+ */
78
+ gulp.task("shopify:push:dist", () => {
79
+ messages.logChildProcess("'shopify theme push' on dist folder...");
80
+ return shopifyCLI.push(getThemeID(config.themeRoot, config.environment));
81
+ });
82
+
83
+ /**
84
+ * Takes the output of shopify cli serve, extracts dev theme ID and persists
85
+ * in seed.config.js
86
+ *
87
+ * @param {child_process} serveProcess shopify cli serve spawned child process
88
+ */
89
+ function persistDevThemeID(serveProcess) {
90
+ serveProcess.stdout.on("data", (data) => {
91
+ const devThemeId = extractThemeId(data.toString());
92
+ const currentDevThemeId = getDevThemeID(config.themeRoot);
93
+
94
+ // If we already have latest dev theme ID, we got nothing left to do
95
+ if (devThemeId === currentDevThemeId) return;
96
+
97
+ // Else, write dev theme ID into seed.config.js
98
+ setDevThemeID(devThemeId);
99
+ });
100
+ }
@@ -1,20 +1,12 @@
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');
1
+ const gulp = require("gulp");
2
+ const config = require("./includes/config");
3
+ const chokidar = require("chokidar");
4
+ const utils = require("./includes/utilities");
10
5
 
6
+ const messages = require("./includes/messages.js");
11
7
 
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];
8
+ const environment = config.environment.split(/\s*,\s*|\s+/)[0];
9
+ const cache = utils.createEventCache();
18
10
 
19
11
  /**
20
12
  * Aggregate task watching for file changes in `src` and
@@ -25,24 +17,27 @@ const utils = require('./includes/utilities.js');
25
17
  * @memberof seed-cli.tasks.watch
26
18
  * @static
27
19
  */
28
- gulp.task('watch:src', () => {
29
- return gulp.parallel(
30
- 'watch:css',
31
- 'watch:js',
32
- 'watch:assets',
33
- 'watch:svg'
34
- )()
20
+ gulp.task("watch:src", () => {
21
+ return gulp.parallel("watch:css", "watch:js", "watch:assets", "watch:svg")();
35
22
  });
36
23
 
37
24
  /**
38
- * Initiates shopify's cli command 'shopify theme serve' on the dist folder,
39
- * watching files and uploading them to development store
40
- *
25
+ * Watches for changes in the `./dist` folder and passes event data to the
26
+ * `cache` via {@link pushToCache}.
41
27
  * @function watch:dist
42
28
  * @memberof seed-cli.tasks.watch
43
29
  * @static
44
30
  */
45
- gulp.task('watch:dist', () => {
46
- console.log("Running Shopify theme serve...")
47
- return utils.serveDist();
48
- })
31
+ gulp.task("watch:dist", () => {
32
+ const watcher = chokidar.watch(["./"], {
33
+ cwd: config.dist.root,
34
+ ignored: /(^|[/\\])\../,
35
+ ignoreInitial: true,
36
+ });
37
+
38
+ watcher.on("all", (event, path) => {
39
+ messages.logFileEvent(event, path);
40
+ cache.addEvent(event, path);
41
+ messages.deployTo(environment);
42
+ });
43
+ });