sheetloaf 1.26.0 → 1.26.1-beta.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/dist/configs.js CHANGED
@@ -1,28 +1,26 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generateSassOptionsAsync = exports.generateSassOptions = exports.generatePostcssConfigFromUse = exports.generatePostcssConfigFromFile = void 0;
7
- const path_1 = __importDefault(require("path"));
8
- const fs_1 = __importDefault(require("fs"));
9
- const sass_embedded_1 = require("sass-embedded");
10
- function generatePostcssConfigFromFile(configPath = '') {
1
+ import path from "path";
2
+ import fs from "fs";
3
+ import {} from "postcss";
4
+ import { NodePackageImporter } from "sass-embedded";
5
+ import {} from "commander";
6
+ import { createRequire } from "module";
7
+ const require = createRequire(import.meta.url);
8
+ export function generatePostcssConfigFromFile(configPath = '') {
11
9
  let obj = {
12
10
  plugins: []
13
11
  };
14
- let configFileLoc = path_1.default.resolve(process.cwd(), configPath, 'postcss.config.js');
12
+ let configFileLoc = path.resolve(process.cwd(), configPath, 'postcss.config.js');
15
13
  try {
16
- fs_1.default.lstatSync(configFileLoc);
14
+ fs.lstatSync(configFileLoc);
17
15
  obj = require(configFileLoc);
18
16
  }
19
17
  catch (e) {
20
18
  console.log(`No postcss.config.js file found at location ${configPath}`);
19
+ // TODO
21
20
  }
22
21
  return obj;
23
22
  }
24
- exports.generatePostcssConfigFromFile = generatePostcssConfigFromFile;
25
- function generatePostcssConfigFromUse(useArg) {
23
+ export function generatePostcssConfigFromUse(useArg) {
26
24
  let obj = {
27
25
  plugins: []
28
26
  };
@@ -31,26 +29,24 @@ function generatePostcssConfigFromUse(useArg) {
31
29
  });
32
30
  return obj;
33
31
  }
34
- exports.generatePostcssConfigFromUse = generatePostcssConfigFromUse;
35
- function generateSassOptions(opts) {
32
+ export function generateSassOptions(opts) {
36
33
  return {
37
34
  style: opts.style,
38
35
  loadPaths: opts.loadPath ? opts.loadPath.split(',') : [],
39
36
  sourceMap: opts.sourceMap === false ? false : true,
40
37
  sourceMapIncludeSources: opts.sourceMap === false ? false : true,
41
- importers: opts.pkgImporter === 'node' ? [new sass_embedded_1.NodePackageImporter()] : [],
38
+ importers: opts.pkgImporter === 'node' ? [new NodePackageImporter()] : [],
42
39
  silenceDeprecations: opts.silenceDeprecation ? opts.silenceDeprecation.split(',') : []
43
40
  };
44
41
  }
45
- exports.generateSassOptions = generateSassOptions;
46
- function generateSassOptionsAsync(opts) {
42
+ export function generateSassOptionsAsync(opts) {
47
43
  return {
48
44
  style: opts.style,
49
45
  loadPaths: opts.loadPath ? opts.loadPath.split(',') : [],
50
46
  sourceMap: opts.sourceMap === false ? false : true,
51
47
  sourceMapIncludeSources: opts.sourceMap === false ? false : true,
52
- importers: opts.pkgImporter === 'node' ? [new sass_embedded_1.NodePackageImporter()] : [],
48
+ importers: opts.pkgImporter === 'node' ? [new NodePackageImporter()] : [],
53
49
  silenceDeprecations: opts.silenceDeprecation ? opts.silenceDeprecation.split(',') : []
54
50
  };
55
51
  }
56
- exports.generateSassOptionsAsync = generateSassOptionsAsync;
52
+ //# sourceMappingURL=configs.js.map
@@ -1,18 +1,13 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.buildDestinationPath = exports.getAllFilesPathsFromSources = void 0;
7
- const fs_1 = __importDefault(require("fs"));
8
- const path_1 = __importDefault(require("path"));
9
- const glob_1 = require("glob");
10
- function getAllFilesPathsFromSources(input, callback) {
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { globSync } from 'glob';
4
+ export function getAllFilesPathsFromSources(input, callback) {
11
5
  let sourcesCompleted = 0;
12
6
  let filePaths = [];
13
7
  for (let i = 0; i < input.length; i++) {
14
- const result = (0, glob_1.globSync)(input[i], { withFileTypes: true });
15
- if (result.length === 1 && result[0].isDirectory()) {
8
+ const result = globSync(input[i], { withFileTypes: true });
9
+ // If user has supplied a directory, we do an extra step and read all files from directory.
10
+ if (result.length === 1 && result[0] && result[0].isDirectory()) {
16
11
  try {
17
12
  getAllFilePathsInDir(input[i], (files) => {
18
13
  filePaths.push(...files);
@@ -29,7 +24,7 @@ function getAllFilesPathsFromSources(input, callback) {
29
24
  else {
30
25
  for (const entry of result) {
31
26
  if (entry.isFile()) {
32
- filePaths.push(path_1.default.normalize(entry.relative()));
27
+ filePaths.push(path.normalize(entry.relative()));
33
28
  }
34
29
  }
35
30
  sourcesCompleted++;
@@ -39,17 +34,16 @@ function getAllFilesPathsFromSources(input, callback) {
39
34
  }
40
35
  }
41
36
  }
42
- exports.getAllFilesPathsFromSources = getAllFilesPathsFromSources;
43
37
  function getAllFilePathsInDir(dir, callback) {
44
38
  let files = [];
45
- fs_1.default.readdir(dir, (err, nodes) => {
39
+ fs.readdir(dir, (err, nodes) => {
46
40
  if (err) {
47
41
  throw err;
48
42
  }
49
43
  else {
50
44
  nodes.forEach((file) => {
51
- let fullname = path_1.default.join(dir, file);
52
- if (!fs_1.default.lstatSync(fullname).isDirectory()) {
45
+ let fullname = path.join(dir, file);
46
+ if (!fs.lstatSync(fullname).isDirectory()) {
53
47
  files.push(fullname);
54
48
  }
55
49
  });
@@ -57,7 +51,13 @@ function getAllFilePathsInDir(dir, callback) {
57
51
  }
58
52
  });
59
53
  }
60
- function buildDestinationPath(fileName, outFile = '', dir = '', base = '', extension = '.css', usingStdin) {
54
+ // TODO: returning a blank string seems super messy, this could use a refactor.
55
+ /**
56
+ *
57
+ * @param filename
58
+ * @returns path, or a blank string if the combination of options provided does not give a valid path.
59
+ */
60
+ export function buildDestinationPath(fileName, outFile = '', dir = '', base = '', extension = '.css', usingStdin) {
61
61
  let destination = '';
62
62
  let mirror = '';
63
63
  if (usingStdin === true) {
@@ -71,9 +71,9 @@ function buildDestinationPath(fileName, outFile = '', dir = '', base = '', exten
71
71
  else {
72
72
  if (dir.length > 0) {
73
73
  if (base.length > 0) {
74
- mirror = path_1.default.dirname(fileName.replace(path_1.default.join(base, '/'), ''));
74
+ mirror = path.dirname(fileName.replace(path.join(base, '/'), ''));
75
75
  }
76
- destination = path_1.default.join(dir, mirror, path_1.default.basename(fileName, path_1.default.extname(fileName)) + extension);
76
+ destination = path.join(dir, mirror, path.basename(fileName, path.extname(fileName)) + extension);
77
77
  }
78
78
  else if (outFile.length > 0) {
79
79
  destination = outFile;
@@ -84,4 +84,4 @@ function buildDestinationPath(fileName, outFile = '', dir = '', base = '', exten
84
84
  }
85
85
  return destination;
86
86
  }
87
- exports.buildDestinationPath = buildDestinationPath;
87
+ //# sourceMappingURL=fileFinder.js.map
package/dist/index.js CHANGED
@@ -1,310 +1,279 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || function (mod) {
20
- if (mod && mod.__esModule) return mod;
21
- var result = {};
22
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
- __setModuleDefault(result, mod);
24
- return result;
25
- };
26
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
27
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
28
- return new (P || (P = Promise))(function (resolve, reject) {
29
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
30
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
31
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
32
- step((generator = generator.apply(thisArg, _arguments || [])).next());
33
- });
34
- };
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- const commander_1 = require("commander");
40
- const chokidar_1 = __importDefault(require("chokidar"));
41
- const picocolors_1 = __importDefault(require("picocolors"));
42
- const fs_1 = __importDefault(require("fs"));
43
- const path_1 = __importDefault(require("path"));
44
- const sass_embedded_1 = require("sass-embedded");
45
- const postcss_1 = __importDefault(require("postcss"));
46
- const configs = __importStar(require("./configs"));
47
- const fileFinder = __importStar(require("./fileFinder"));
48
- const sources = __importStar(require("./sources"));
49
- const glob_1 = require("glob");
50
- const sheetloaf = new commander_1.Command();
51
- sheetloaf.version("1.26.0", '-v, --version', 'Print the version of Sheetloaf.');
52
- let usingStdin = false;
2
+ import chokidar from 'chokidar';
3
+ import color from 'picocolors';
4
+ import { Command } from 'commander';
5
+ import fs from 'fs';
6
+ import { globSync } from 'glob';
7
+ import postcss from 'postcss';
8
+ import path from 'path';
9
+ import { initCompiler, initAsyncCompiler } from 'sass-embedded';
10
+ import * as configs from "./configs.js";
11
+ import * as fileFinder from "./fileFinder.js";
12
+ import * as sources from "./sources.js";
13
+ const sheetloaf = new Command();
14
+ sheetloaf.version("1.26.1", '-v, --version', 'Print the version of Sheetloaf.');
53
15
  let postcssConfig = {
54
16
  plugins: []
55
17
  };
56
- let sassCompiler;
57
- let sassAsyncCompiler;
58
- sheetloaf
59
- .arguments('[sources...]')
60
- .description('📃🍞 Compile Sass to CSS and transform the output using PostCSS, all in one command.')
61
- .action((source) => __awaiter(void 0, void 0, void 0, function* () {
62
- if (sheetloaf.opts().use) {
63
- postcssConfig = configs.generatePostcssConfigFromUse(sheetloaf.opts().use);
64
- }
65
- else {
66
- postcssConfig = configs.generatePostcssConfigFromFile(sheetloaf.opts().config);
67
- }
68
- if (sheetloaf.opts().async === true) {
69
- sassAsyncCompiler = yield (0, sass_embedded_1.initAsyncCompiler)();
18
+ class CompWrapper {
19
+ initialized = false;
20
+ usingStdin = false;
21
+ source;
22
+ entries;
23
+ options;
24
+ compiler = {};
25
+ init(options, source = "") {
26
+ this.options = options;
27
+ this.source = source;
28
+ return new Promise((resolve, reject) => {
29
+ if (this.source.length > 0) {
30
+ fileFinder.getAllFilesPathsFromSources(this.source.split(','), (entries) => {
31
+ this.entries = entries;
32
+ if (this.entries.length > 0 && this.entries[0]) {
33
+ this.usingStdin = false;
34
+ }
35
+ else {
36
+ this.usingStdin = true;
37
+ }
38
+ if (this.options.async === true) {
39
+ initAsyncCompiler().then((compiler) => {
40
+ this.compiler.async = compiler;
41
+ this.initialized = true;
42
+ resolve("Compiler initialized.");
43
+ }).catch((e) => {
44
+ reject(e);
45
+ });
46
+ }
47
+ else {
48
+ this.compiler.sync = initCompiler();
49
+ this.initialized = true;
50
+ resolve("Compiler initialized.");
51
+ }
52
+ });
53
+ }
54
+ });
70
55
  }
71
- else {
72
- sassCompiler = (0, sass_embedded_1.initCompiler)();
56
+ dispose() {
57
+ if (this.initialized) {
58
+ this.compiler.async?.dispose();
59
+ this.compiler.sync?.dispose();
60
+ }
61
+ else {
62
+ throw 'Compiler not initialized, therefore could not dispose.';
63
+ }
73
64
  }
74
- if (source.length > 0) {
75
- renderAllFiles(source);
76
- watch(source);
65
+ watch() {
66
+ if (this.source.length > 0) {
67
+ const toWatch = globSync(this.source.split(','));
68
+ chokidar
69
+ .watch(toWatch, {
70
+ usePolling: this.options.poll !== undefined,
71
+ interval: typeof this.options.poll === 'number' ? this.options.poll : 100,
72
+ ignoreInitial: true,
73
+ awaitWriteFinish: {
74
+ stabilityThreshold: 1500,
75
+ pollInterval: 100
76
+ }
77
+ })
78
+ .on('change', (changed) => {
79
+ console.log(`File changed: ${changed}`);
80
+ this.getFilesToRender(changed).then((filesToRender) => {
81
+ filesToRender.forEach((fileName) => {
82
+ this.render(fileName);
83
+ });
84
+ });
85
+ })
86
+ .on('add', (added) => {
87
+ console.log(`File added: ${added}`);
88
+ // Clear out old info.
89
+ sources.clearSourcesChecker();
90
+ this.renderAll();
91
+ });
92
+ }
77
93
  }
78
- else if (!process.stdin.isTTY) {
79
- let stdin = '';
80
- process.stdin.on('readable', () => {
81
- var chunk = process.stdin.read();
82
- if (chunk !== null) {
83
- stdin += chunk;
94
+ render(fileNameOrString = '') {
95
+ return new Promise((resolve, reject) => {
96
+ if (this.usingStdin === false) {
97
+ console.log(`Rendering ${fileNameOrString}...`);
84
98
  }
85
- });
86
- process.stdin.on('end', () => {
87
- usingStdin = true;
88
- renderSassFromStdin(stdin);
99
+ const destination = fileFinder.buildDestinationPath(fileNameOrString, this.options.output, this.options.dir, this.options.base, this.options.ext, this.usingStdin);
100
+ this.renderSass(fileNameOrString).then((sassResult) => {
101
+ this.renderPost(fileNameOrString, destination, sassResult).then((postedResult) => {
102
+ this.writeOut(postedResult, destination).then(() => {
103
+ resolve("File rendered and written successfully.");
104
+ });
105
+ }).catch((err) => {
106
+ if (destination !== '') {
107
+ console.log(color.red(err));
108
+ }
109
+ else {
110
+ process.stderr.write(err);
111
+ }
112
+ resolve("Error in file.");
113
+ });
114
+ }).catch((e) => {
115
+ this.sassErrorOut(e, destination);
116
+ resolve("Error in file.");
117
+ });
89
118
  });
90
119
  }
91
- }));
92
- sheetloaf
93
- .option('-o, --output <LOCATION>', 'Output file.')
94
- .option('--dir <LOCATION>', 'Output directory.')
95
- .option('--base <DIR>', 'Mirror the directory structure relative to this path in the output directory, for use with --dir.', '')
96
- .option('--ext <EXTENSION>', 'Override the output file extension; for use with --dir', '.css')
97
- .option('-s, --style <NAME>', 'Output style. ["expanded", "compressed"]', 'expanded')
98
- .option('--source-map', 'Generate a source map (this is the default option).')
99
- .option('--no-source-map', 'Do not generate a source map.')
100
- .option('--embed-source-map', 'Embed the contents of the source map file in the generated CSS, rather than creating a separate file and linking to it from the CSS.')
101
- .option('--embed-sources', 'Embed the entire contents of the Sass files that contributed to the generated CSS in the source map.')
102
- .option('--source-map-urls <TYPE>', 'Controls how the source maps that Sass generates link back to the Sass files that contributed to the generated CSS. ["relative", "absolute"]', 'relative')
103
- .option('--error-css', 'Emit a CSS file when an error occurs during compilation (this is the default option).')
104
- .option('--no-error-css', 'Do not emit a CSS file when an error occurs during compilation.')
105
- .option('--silence-deprecation <TYPE>', 'This option tells Sass to silence a particular type of deprecation.')
106
- .option('-I, --load-path <PATHS>', 'Adds an additional load path for Sass to look for stylesheets.')
107
- .option('-p, --pkg-importer <TYPE>', `Built-in importer(s) to use for pkg: URLs.\n[node] - Load files like Node.js package resolution.`)
108
- .option('-w, --watch', 'Watch stylesheets and recompile when they change.')
109
- .option('--config <LOCATION>', 'Set a custom directory to look for a postcss config file.')
110
- .option('--poll [DURATION]', 'Use polling for file watching. Can optionally pass polling interval; default 100 ms')
111
- .option('-u, --use <PLUGINS>', 'List of postcss plugins to use. Will cause sheetloaf to ignore any config files.')
112
- .option('--async', `Use sass' asynchronous API. This may be slower.`);
113
- sheetloaf.parse(process.argv);
114
- function renderAllFiles(source) {
115
- fileFinder.getAllFilesPathsFromSources(source[0].split(','), function (entries) {
116
- entries.forEach(function (fileName) {
117
- if (path_1.default.basename(fileName).charAt(0) !== '_') {
118
- renderSass(fileName);
119
- }
120
+ renderAll() {
121
+ return new Promise((resolve, reject) => {
122
+ const filesToRender = this.entries.filter((fileName) => path.basename(fileName).charAt(0) !== '_');
123
+ let rendered = 0;
124
+ filesToRender.forEach((fileName) => {
125
+ this.render(fileName).then(() => {
126
+ rendered++;
127
+ if (rendered == filesToRender.length) {
128
+ resolve("All files rendered");
129
+ }
130
+ });
131
+ });
120
132
  });
121
- });
122
- }
123
- function renderPartially(source, fileName) {
124
- if (path_1.default.basename(fileName).charAt(0) !== '_') {
125
- renderSass(fileName);
126
133
  }
127
- else {
128
- let partialExistsInSassSources = false;
129
- let ind = 0;
130
- while (ind < sources.getChecker().length) {
131
- const toCheck = sources.getChecker()[ind];
132
- if (toCheck.containsPartial(fileName)) {
133
- partialExistsInSassSources = true;
134
- renderSass(toCheck.getMain());
134
+ renderSass(fileNameOrString) {
135
+ return new Promise((resolve, reject) => {
136
+ if (this.compiler.async) {
137
+ const options = configs.generateSassOptionsAsync(this.options);
138
+ if (this.usingStdin === false) {
139
+ this.compiler.async.compileAsync(fileNameOrString, options).then((result) => {
140
+ sources.addResultToSourcesChecker(fileNameOrString, result);
141
+ resolve(result);
142
+ }).catch((err) => {
143
+ reject(err);
144
+ });
145
+ }
146
+ else {
147
+ this.compiler.async.compileStringAsync(fileNameOrString, options).then((result) => {
148
+ resolve(result);
149
+ }).catch((err) => {
150
+ reject(err);
151
+ });
152
+ }
135
153
  }
136
- ind = ind + 1;
137
- }
138
- if (partialExistsInSassSources === false) {
139
- sources.clearSourcesChecker();
140
- renderAllFiles(source);
141
- }
142
- }
143
- }
144
- function watch(source) {
145
- if (sheetloaf.opts().watch === true) {
146
- const toWatch = (0, glob_1.globSync)(source[0].split(','));
147
- chokidar_1.default
148
- .watch(toWatch, {
149
- usePolling: sheetloaf.opts().poll !== undefined,
150
- interval: typeof sheetloaf.opts().poll === 'number' ? sheetloaf.opts().poll : 100,
151
- ignoreInitial: true,
152
- awaitWriteFinish: {
153
- stabilityThreshold: 1500,
154
- pollInterval: 100
154
+ else if (this.compiler.sync) {
155
+ try {
156
+ const options = configs.generateSassOptions(this.options);
157
+ if (this.usingStdin === false) {
158
+ const result = this.compiler.sync.compile(fileNameOrString, options);
159
+ sources.addResultToSourcesChecker(fileNameOrString, result);
160
+ resolve(result);
161
+ }
162
+ else {
163
+ const result = this.compiler.sync.compile(fileNameOrString, options);
164
+ resolve(result);
165
+ }
166
+ }
167
+ catch (err) {
168
+ reject(err);
169
+ }
155
170
  }
156
- })
157
- .on('change', (changed) => {
158
- console.log(`File changed: ${changed}`);
159
- renderPartially(source, changed);
160
- })
161
- .on('add', (added) => {
162
- console.log(`File added: ${added}`);
163
- sources.clearSourcesChecker();
164
- renderAllFiles(source);
165
171
  });
166
172
  }
167
- }
168
- function renderSass(fileName) {
169
- return __awaiter(this, void 0, void 0, function* () {
170
- console.log(`Rendering ${fileName}...`);
171
- const destination = fileFinder.buildDestinationPath(fileName, sheetloaf.opts().output, sheetloaf.opts().dir, sheetloaf.opts().base, sheetloaf.opts().ext, usingStdin);
172
- try {
173
- if (sheetloaf.opts().async === true) {
174
- const options = configs.generateSassOptionsAsync(sheetloaf.opts());
175
- const result = yield sassAsyncCompiler.compileAsync(fileName, options);
176
- renderPost(fileName, destination, result);
177
- sources.addResultToSourcesChecker(fileName, result);
178
- }
179
- else {
180
- const options = configs.generateSassOptions(sheetloaf.opts());
181
- const result = sassCompiler.compile(fileName, options);
182
- renderPost(fileName, destination, result);
183
- sources.addResultToSourcesChecker(fileName, result);
173
+ renderPost(fileNameOrString, destination, sassResult) {
174
+ return new Promise((resolve, reject) => {
175
+ let postcssMapOptions = {
176
+ annotation: true,
177
+ prev: sassResult.sourceMap,
178
+ inline: this.options.embedSourceMap === true ? true : false,
179
+ absolute: this.options.sourceMapUrls === 'absolute' ? true : false,
180
+ sourcesContent: this.options.embedSources === true ? true : false,
181
+ };
182
+ if (this.usingStdin === true || this.options.sourceMap === false) {
183
+ postcssMapOptions = false;
184
184
  }
185
- }
186
- catch (e) {
187
- sassErrorCatcher(e, destination);
188
- }
189
- });
190
- }
191
- function renderSassFromStdin(text) {
192
- return __awaiter(this, void 0, void 0, function* () {
193
- const destination = fileFinder.buildDestinationPath('', sheetloaf.opts().output, sheetloaf.opts().dir, sheetloaf.opts().base, sheetloaf.opts().ext, usingStdin);
194
- try {
195
- if (sheetloaf.opts().async === true) {
196
- const options = configs.generateSassOptionsAsync(sheetloaf.opts());
197
- const result = yield sassAsyncCompiler.compileStringAsync(text, options);
198
- renderPost('', destination, result);
185
+ postcss(postcssConfig.plugins)
186
+ .process(sassResult.css.toString(), {
187
+ from: fileNameOrString,
188
+ to: destination,
189
+ map: postcssMapOptions
190
+ })
191
+ .then((postedResult) => {
192
+ resolve(postedResult);
193
+ })
194
+ .catch((err) => {
195
+ reject(err);
196
+ });
197
+ });
198
+ }
199
+ getFilesToRender(fileChanged) {
200
+ return new Promise((resolve, reject) => {
201
+ let filesToRender = [];
202
+ if (path.basename(fileChanged).charAt(0) !== '_') {
203
+ filesToRender.push(fileChanged);
204
+ resolve(filesToRender);
199
205
  }
200
206
  else {
201
- const options = configs.generateSassOptions(sheetloaf.opts());
202
- const result = sassCompiler.compileString(text, options);
203
- renderPost('', destination, result);
207
+ let partialExistsInSassSources = false;
208
+ let ind = 0;
209
+ while (ind < sources.getChecker().length) {
210
+ const toCheck = sources.getChecker()[ind];
211
+ if (toCheck?.containsPartial(fileChanged)) {
212
+ partialExistsInSassSources = true;
213
+ filesToRender.push(toCheck.getMain());
214
+ }
215
+ ind = ind + 1;
216
+ }
217
+ if (partialExistsInSassSources === false) {
218
+ // SassSources are built with sass's CompileResult object when
219
+ // sheetloaf initially runs. However, if compilation fails, the
220
+ // SassSource will not be generated for that particular file.
221
+ // That means if a partial is later fixed to not error out and
222
+ // it will not render at all.
223
+ // We therefore check for this condition and rebuild everything
224
+ // if it doesn't exist.
225
+ sources.clearSourcesChecker();
226
+ fileFinder.getAllFilesPathsFromSources(this.source.split(','), (entries) => {
227
+ entries.forEach((entry) => {
228
+ filesToRender.push(entry);
229
+ resolve(filesToRender);
230
+ });
231
+ });
232
+ }
233
+ else {
234
+ resolve(filesToRender);
235
+ }
204
236
  }
205
- }
206
- catch (e) {
207
- sassErrorCatcher(e, destination);
208
- }
209
- });
210
- }
211
- function renderPost(fileName, destination, sassResult) {
212
- let postcssMapOptions = {
213
- annotation: true,
214
- prev: sassResult.sourceMap,
215
- inline: sheetloaf.opts().embedSourceMap === true ? true : false,
216
- absolute: sheetloaf.opts().sourceMapUrls === 'absolute' ? true : false,
217
- sourcesContent: sheetloaf.opts().embedSources === true ? true : false,
218
- };
219
- if (usingStdin === true || sheetloaf.opts().sourceMap === false) {
220
- postcssMapOptions = false;
221
- }
222
- (0, postcss_1.default)(postcssConfig.plugins)
223
- .process(sassResult.css.toString(), {
224
- from: fileName,
225
- to: destination,
226
- map: postcssMapOptions
227
- })
228
- .then((postedResult) => {
229
- postedResult.warnings().forEach((warn) => {
230
- process.stderr.write(warn.toString());
231
237
  });
238
+ }
239
+ sassErrorOut(e, destination) {
232
240
  if (destination !== '') {
241
+ console.log(e.message);
233
242
  try {
234
- fs_1.default.mkdirSync(path_1.default.dirname(destination), {
243
+ fs.mkdirSync(path.dirname(destination), {
235
244
  recursive: true
236
245
  });
237
246
  }
238
- catch (err) {
239
- if (err.code !== 'EEXIST' || err.code !== 'EISDIR')
240
- throw err;
247
+ catch (mkDirErr) {
248
+ if (mkDirErr.code !== 'EEXIST' || mkDirErr.code !== 'EISDIR')
249
+ throw mkDirErr;
241
250
  }
242
- fs_1.default.writeFile(destination, postedResult.css, (err) => {
243
- if (err) {
244
- console.log(err);
245
- }
246
- else {
247
- console.log(picocolors_1.default.green(`Successfully written to ${destination}`));
248
- }
249
- });
250
- if (postedResult.map) {
251
- fs_1.default.writeFile(destination + '.map', postedResult.map.toString(), (err) => {
252
- if (err)
253
- throw err;
251
+ if (this.options.errorCss !== false) {
252
+ fs.writeFile(destination, this.emitSassError(e), (writeFileErr) => {
253
+ // throws an error, you could also catch it here
254
+ if (writeFileErr)
255
+ throw writeFileErr;
256
+ // success case, the file was saved
257
+ console.log(color.yellow(`Emitted error to ${destination}`));
254
258
  });
255
259
  }
256
260
  }
257
261
  else {
258
- process.stdout.write(postedResult.css);
259
- if (!sheetloaf.opts().watch) {
260
- process.exit();
261
- }
262
- }
263
- })
264
- .catch((err) => {
265
- if (destination !== '') {
266
- console.log(picocolors_1.default.red(err));
267
- }
268
- else {
269
- process.stderr.write(err);
270
- }
271
- if (!sheetloaf.opts().watch) {
272
- process.exit();
273
- }
274
- });
275
- }
276
- function sassErrorCatcher(e, destination) {
277
- if (destination !== '') {
278
- console.log(e.message);
279
- try {
280
- fs_1.default.mkdirSync(path_1.default.dirname(destination), {
281
- recursive: true
282
- });
262
+ process.stderr.write(e.message);
283
263
  }
284
- catch (mkDirErr) {
285
- if (mkDirErr.code !== 'EEXIST' || mkDirErr.code !== 'EISDIR')
286
- throw mkDirErr;
264
+ if (this.options.watch && (process.exitCode == null || process.exitCode === 0)) {
265
+ process.exitCode = 1;
287
266
  }
288
- if (sheetloaf.opts().errorCss !== false) {
289
- fs_1.default.writeFile(destination, emitSassError(e), (writeFileErr) => {
290
- if (writeFileErr)
291
- throw writeFileErr;
292
- console.log(picocolors_1.default.yellow(`Emitted error to ${destination}`));
293
- });
294
- }
295
- }
296
- else {
297
- process.stderr.write(e.message);
298
- }
299
- if (!sheetloaf.opts().watch && (process.exitCode == null || process.exitCode === 0)) {
300
- process.exitCode = 1;
301
- process.exit();
302
267
  }
303
- }
304
- function emitSassError(err) {
305
- const message = err.sassMessage.toString().replace(/"/g, "'").replace(/\n/g, " ");
306
- const context = err.span.context.toString().replace(/"/g, "'").replace(/\n/g, " ");
307
- let css = `
268
+ /**
269
+ * Build a new CSS file that contains the error and puts its content in the body.
270
+ * @param {*} err
271
+ */
272
+ emitSassError(err) {
273
+ // Sanitize message so that it fits in a content attribute.
274
+ const message = err.sassMessage.toString().replace(/"/g, "'").replace(/\n/g, " ");
275
+ const context = err.span.context.toString().replace(/"/g, "'").replace(/\n/g, " ");
276
+ let css = `
308
277
  body:before {
309
278
  content: "Error at line ${err.span.start.line} in ${err.span.url.pathname}";
310
279
  display: table;
@@ -327,5 +296,115 @@ function emitSassError(err) {
327
296
  }
328
297
  body * { display: none; }
329
298
  `;
330
- return css;
299
+ return css;
300
+ }
301
+ writeOut(postedResult, destination) {
302
+ return new Promise((resolve, reject) => {
303
+ postedResult.warnings().forEach((warn) => {
304
+ process.stderr.write(warn.toString());
305
+ });
306
+ if (destination !== '') {
307
+ try {
308
+ fs.mkdirSync(path.dirname(destination), {
309
+ recursive: true
310
+ });
311
+ }
312
+ catch (err) {
313
+ if (err.code !== 'EEXIST' || err.code !== 'EISDIR')
314
+ throw err;
315
+ }
316
+ fs.writeFile(destination, postedResult.css, (err) => {
317
+ if (err) {
318
+ console.log(err);
319
+ }
320
+ else {
321
+ // success case, the file was saved
322
+ console.log(color.green(`Successfully written to ${destination}`));
323
+ resolve("Written to file.");
324
+ }
325
+ });
326
+ if (postedResult.map) {
327
+ fs.writeFile(destination + '.map', postedResult.map.toString(), (err) => {
328
+ if (err) {
329
+ throw err;
330
+ }
331
+ else {
332
+ resolve("Written to file.");
333
+ }
334
+ ;
335
+ });
336
+ }
337
+ }
338
+ else {
339
+ process.stdout.write(postedResult.css);
340
+ resolve("Written to file.");
341
+ }
342
+ });
343
+ }
331
344
  }
345
+ sheetloaf
346
+ .arguments('[sources...]')
347
+ .description('📃🍞 Compile Sass to CSS and transform the output using PostCSS, all in one command.')
348
+ .action((source) => {
349
+ //If user specifies --use, we ignore postcss config files.
350
+ if (sheetloaf.opts().use) {
351
+ postcssConfig = configs.generatePostcssConfigFromUse(sheetloaf.opts().use);
352
+ }
353
+ else {
354
+ postcssConfig = configs.generatePostcssConfigFromFile(sheetloaf.opts().config);
355
+ }
356
+ const compiler = new CompWrapper();
357
+ // If source is provided, we ignore pipes.
358
+ if (source.length > 0 && source[0]) {
359
+ compiler.init(sheetloaf.opts(), source[0]).then(() => {
360
+ compiler.renderAll().then(() => {
361
+ if (sheetloaf.opts().watch) {
362
+ compiler.watch();
363
+ }
364
+ else {
365
+ compiler.dispose();
366
+ }
367
+ });
368
+ });
369
+ }
370
+ else if (!process.stdin.isTTY) {
371
+ compiler.init(sheetloaf.opts).then(() => {
372
+ //see github.com/tj/commander.js/issues/137
373
+ let stdin = '';
374
+ process.stdin.on('readable', () => {
375
+ var chunk = process.stdin.read();
376
+ if (chunk !== null) {
377
+ stdin += chunk;
378
+ }
379
+ });
380
+ process.stdin.on('end', () => {
381
+ compiler.render(stdin).then(() => {
382
+ compiler.dispose();
383
+ });
384
+ });
385
+ });
386
+ }
387
+ });
388
+ sheetloaf
389
+ .option('-o, --output <LOCATION>', 'Output file.')
390
+ .option('--dir <LOCATION>', 'Output directory.')
391
+ .option('--base <DIR>', 'Mirror the directory structure relative to this path in the output directory, for use with --dir.', '')
392
+ .option('--ext <EXTENSION>', 'Override the output file extension; for use with --dir', '.css')
393
+ .option('-s, --style <NAME>', 'Output style. ["expanded", "compressed"]', 'expanded')
394
+ .option('--source-map', 'Generate a source map (this is the default option).')
395
+ .option('--no-source-map', 'Do not generate a source map.')
396
+ .option('--embed-source-map', 'Embed the contents of the source map file in the generated CSS, rather than creating a separate file and linking to it from the CSS.')
397
+ .option('--embed-sources', 'Embed the entire contents of the Sass files that contributed to the generated CSS in the source map.')
398
+ .option('--source-map-urls <TYPE>', 'Controls how the source maps that Sass generates link back to the Sass files that contributed to the generated CSS. ["relative", "absolute"]', 'relative')
399
+ .option('--error-css', 'Emit a CSS file when an error occurs during compilation (this is the default option).')
400
+ .option('--no-error-css', 'Do not emit a CSS file when an error occurs during compilation.')
401
+ .option('--silence-deprecation <TYPE>', 'This option tells Sass to silence a particular type of deprecation.')
402
+ .option('-I, --load-path <PATHS>', 'Adds an additional load path for Sass to look for stylesheets.')
403
+ .option('-p, --pkg-importer <TYPE>', `Built-in importer(s) to use for pkg: URLs.\n[node] - Load files like Node.js package resolution.`)
404
+ .option('-w, --watch', 'Watch stylesheets and recompile when they change.')
405
+ .option('--config <LOCATION>', 'Set a custom directory to look for a postcss config file.')
406
+ .option('--poll [DURATION]', 'Use polling for file watching. Can optionally pass polling interval; default 100 ms')
407
+ .option('-u, --use <PLUGINS>', 'List of postcss plugins to use. Will cause sheetloaf to ignore any config files.')
408
+ .option('--async', `Use sass' asynchronous API. This may be slower.`);
409
+ sheetloaf.parse(process.argv);
410
+ //# sourceMappingURL=index.js.map
package/dist/sources.js CHANGED
@@ -1,29 +1,28 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.addResultToSourcesChecker = exports.clearSourcesChecker = exports.getChecker = exports.SassSources = void 0;
7
- const path_1 = __importDefault(require("path"));
8
- const url_1 = require("url");
1
+ import path from "path";
2
+ import {} from "sass-embedded";
3
+ import { fileURLToPath } from "url";
9
4
  let sourcesChecker = [];
10
- class SassSources {
5
+ export class SassSources {
6
+ absoluteMain;
7
+ main;
8
+ sources = [];
11
9
  constructor(fileName, sassResult) {
12
- this.sources = [];
13
10
  this.main = fileName;
14
- this.absoluteMain = path_1.default.resolve(fileName);
11
+ this.absoluteMain = path.resolve(fileName);
15
12
  this.setSources(sassResult.loadedUrls);
16
13
  }
17
14
  setSources(urls) {
18
15
  this.sources.splice(0, this.sources.length);
19
16
  urls.forEach(url => {
20
- if ((0, url_1.fileURLToPath)(url.href) !== this.absoluteMain) {
21
- this.sources.push((0, url_1.fileURLToPath)(url.href));
17
+ if (fileURLToPath(url.href) !== this.absoluteMain) {
18
+ this.sources.push(fileURLToPath(url.href));
22
19
  }
23
20
  });
24
21
  }
25
22
  containsPartial(filename) {
26
- if (this.sources.indexOf(path_1.default.resolve(filename)) >= 0) {
23
+ // FIXME: source paths are a little weird on windows which is making this check
24
+ // always return false.
25
+ if (this.sources.indexOf(path.resolve(filename)) >= 0) {
27
26
  return true;
28
27
  }
29
28
  else {
@@ -40,21 +39,18 @@ class SassSources {
40
39
  return this.main;
41
40
  }
42
41
  }
43
- exports.SassSources = SassSources;
44
- function getChecker() {
42
+ export function getChecker() {
45
43
  return sourcesChecker;
46
44
  }
47
- exports.getChecker = getChecker;
48
- function clearSourcesChecker() {
45
+ export function clearSourcesChecker() {
49
46
  sourcesChecker.splice(0, sourcesChecker.length);
50
47
  }
51
- exports.clearSourcesChecker = clearSourcesChecker;
52
- function addResultToSourcesChecker(fileName, result) {
48
+ export function addResultToSourcesChecker(fileName, result) {
53
49
  let resultExistsInChecker = false;
54
50
  let ind = 0;
55
51
  while (ind < sourcesChecker.length && resultExistsInChecker === false) {
56
- if (sourcesChecker[ind].getAbsoluteMain() === path_1.default.resolve(fileName)) {
57
- sourcesChecker[ind].setSources(result.loadedUrls);
52
+ if (sourcesChecker[ind]?.getAbsoluteMain() === path.resolve(fileName)) {
53
+ sourcesChecker[ind]?.setSources(result.loadedUrls);
58
54
  resultExistsInChecker = true;
59
55
  }
60
56
  ind = ind + 1;
@@ -63,4 +59,4 @@ function addResultToSourcesChecker(fileName, result) {
63
59
  sourcesChecker.push(new SassSources(fileName, result));
64
60
  }
65
61
  }
66
- exports.addResultToSourcesChecker = addResultToSourcesChecker;
62
+ //# sourceMappingURL=sources.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sheetloaf",
3
- "version": "1.26.0",
3
+ "version": "1.26.1-beta.0",
4
4
  "description": "freshmade stylesheets for the whole family.",
5
5
  "main": "./dist/index.js",
6
6
  "bin": {
@@ -21,12 +21,14 @@
21
21
  "files": [
22
22
  "dist/*.js"
23
23
  ],
24
+
24
25
  "keywords": [
25
26
  "scss",
26
27
  "css",
27
28
  "sass",
28
29
  "processor"
29
30
  ],
31
+ "type": "module",
30
32
  "author": "Benjamin Richardson",
31
33
  "license": "MIT",
32
34
  "bugs": {
@@ -42,7 +44,7 @@
42
44
  "postcss": "^8.5.15",
43
45
  "postcss-custom-properties": "^13.3.10",
44
46
  "ts-node": "^10.9.2",
45
- "typescript": "^4.7.4"
47
+ "typescript": "^6.0.3"
46
48
  },
47
49
  "peerDependencies": {
48
50
  "postcss": "^8.5.15"