@adamlui/scss-to-css 1.12.0 → 2.0.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.
package/LICENSE.md ADDED
@@ -0,0 +1,9 @@
1
+ # 🏛️ MIT License
2
+
3
+ **Copyright © 2024 [Adam Lui](https://github.com/adamlui) & contributors**
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ <a id="top"></a>
2
+
1
3
  <table align="center">
2
4
  <td align="center" width=1000>
3
5
  <h6>
@@ -6,19 +8,19 @@
6
8
  <img height=14 src="https://assets.scsstocss.org/images/icons/earth/black/icon32.svg?v=7e4a141">
7
9
  </picture>
8
10
  &nbsp;English |
9
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/zh-cn#readme">简体中文</a> |
10
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/zh-tw#readme">繁體中文</a> |
11
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/ja#readme">日本語</a> |
12
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/hi#readme">हिंदी</a> |
13
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/bn#readme">বাংলা</a> |
14
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/mr#readme">मराठी</a> |
15
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/pa#readme">ਪੰਜਾਬੀ</a> |
16
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/de#readme">Deutsch</a> |
17
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/es#readme">Español</a> |
18
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/fr#readme">Français</a> |
19
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/it#readme">Italiano</a> |
20
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/nl#readme">Nederlands</a> |
21
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/pt#readme">Português</a>
11
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/zh-cn#readme">简体中文</a> |
12
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/zh-tw#readme">繁體中文</a> |
13
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/ja#readme">日本語</a> |
14
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/hi#readme">हिंदी</a> |
15
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/bn#readme">বাংলা</a> |
16
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/mr#readme">मराठी</a> |
17
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/pa#readme">ਪੰਜਾਬੀ</a> |
18
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/de#readme">Deutsch</a> |
19
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/es#readme">Español</a> |
20
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/fr#readme">Français</a> |
21
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/it#readme">Italiano</a> |
22
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/nl#readme">Nederlands</a> |
23
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/pt#readme">Português</a>
22
24
  </h6>
23
25
  </td>
24
26
  </table>
@@ -30,15 +32,15 @@
30
32
  <a href="https://www.npmjs.com/package/@adamlui/scss-to-css">
31
33
  <img height=31 src="https://img.shields.io/npm/dm/%40adamlui%2Fscss-to-css?logo=npm&color=af68ff&logoColor=white&labelColor=464646&style=for-the-badge"></a>
32
34
  <a href="#%EF%B8%8F-mit-license">
33
- <img height=31 src="https://img.shields.io/badge/License-MIT-fc4f2d.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
34
- <a href="https://github.com/adamlui/js-utils/releases/tag/scss-to-css-1.12.0">
35
- <img height=31 src="https://img.shields.io/badge/Latest_Build-1.12.0-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
35
+ <img height=31 src="https://img.shields.io/badge/License-MIT-orange.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
36
+ <a href="https://github.com/adamlui/js-utils/releases/tag/scss-to-css-2.0.1">
37
+ <img height=31 src="https://img.shields.io/badge/Latest_Build-2.0.1-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
36
38
  <a href="https://www.npmjs.com/package/@adamlui/scss-to-css?activeTab=code">
37
39
  <img height=31 src="https://img.shields.io/npm/unpacked-size/%40adamlui%2Fscss-to-css?style=for-the-badge&logo=ebox&logoColor=white&color=blue&labelColor=464646"></a>
38
- <a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_scss-to-css:node.js/src/scss-to-css.js">
39
- <img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_scss-to-css%3Anode.js%2Fsrc%2Fscss-to-css.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=Vulnerabilities&color=gold"></a>
40
+ <a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_scss-to-css:src/scss-to-css.js">
41
+ <img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_scss-to-css%3Asrc%2Fscss-to-css.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=Vulnerabilities&color=gold"></a>
40
42
  <a href="https://github.com/toolleeo/cli-apps#conversion">
41
- <img height=31 src="https://img.shields.io/badge/Mentioned_in-Awesome-c4a2bd?logo=awesomelists&logoColor=white&labelColor=464646&style=for-the-badge"></a>
43
+ <img height=31 src="https://img.shields.io/badge/Mentioned_in-Awesome-ff69b4?logo=awesomelists&logoColor=white&labelColor=464646&style=for-the-badge"></a>
42
44
 
43
45
  <img height=6px width="100%" src="https://assets.scsstocss.org/images/separators/aqua-gradient.png?v=7e4a141">
44
46
 
@@ -91,7 +93,7 @@ $ scss-to-css [input_path] [output_path]
91
93
  ```
92
94
 
93
95
  - `[input_path]`: Path to SCSS file or directory containing SCSS files to be compiled, relative to the current working directory.
94
- - `[output_path]`: Path to file or directory where CSS + source map files will be stored, relative to original file location (if not provided, `css/` is used).
96
+ - `[output_path]`: Path to file or directory where CSS + source map files will be stored, relative to input root (if not provided, `css/` is used).
95
97
 
96
98
  **📝 Note:** If folders are passed, files will be processed recursively unless `-R` or `--no-recursion` is passed.
97
99
 
@@ -117,13 +119,13 @@ Compile all SCSS files in the **current directory** (outputs to `css/`):
117
119
  $ scss-to-css
118
120
  ```
119
121
 
120
- Compile all SCSS files in a **specific directory** (outputs to `path/to/your/directory/css/`):
122
+ Compile all SCSS files in a **specific directory** (outputs to `css/path/to/your/directory/`):
121
123
 
122
124
  ```
123
125
  $ scss-to-css path/to/your/directory
124
126
  ```
125
127
 
126
- Compile a **specific file** (outputs to `path/to/your/css/file.min.css`):
128
+ Compile a **specific file** (outputs to `css/path/to/your/file.min.css`):
127
129
 
128
130
  ```
129
131
  $ scss-to-css path/to/your/file.scss
@@ -149,14 +151,14 @@ Boolean options:
149
151
  -S, --no-source-maps Prevent source maps from being generated.
150
152
  -M, --no-minify Disable minification of output CSS.
151
153
  -R, --no-recursion Disable recursive file searching.
152
- -C, --clone-folders Preserve folder structure in output directory
154
+ -r, --relative-output Output files relative to each source file instead of to input root.
153
155
  -c, --copy Copy compiled CSS to clipboard instead of
154
156
  writing to file if single source file is
155
157
  processed.
156
158
  -q, --quiet Suppress all logging except errors.
157
159
 
158
160
  Parameter options:
159
- --ignore-files="file1.scss,file2.scss" Files to exclude from
161
+ --ignores="dir/,file1.scss,file2.scss" Files/directories to exclude from
160
162
  compilation.
161
163
  --comment="comment" Prepend header comment to
162
164
  compiled CSS. Separate by
@@ -183,7 +185,7 @@ import scssToCSS from '@adamlui/scss-to-css';
183
185
  #### CJS:
184
186
 
185
187
  ```js
186
- const scssToCSS = require('@adamlui/scss-to-css');
188
+ const scssToCSS = require('@adamlui/scss-to-css')
187
189
  ```
188
190
 
189
191
  ###### _*Node.js version 14 or higher required_
@@ -198,10 +200,10 @@ If **source code** is passed, it is directly compiled, then an object containing
198
200
 
199
201
  ```js
200
202
  const srcCode = 'h1 { font-size: 40px ; code { font-face: Roboto Mono }}',
201
- compileResult = scssToCSS.compile(srcCode);
203
+ compileResult = scssToCSS.compile(srcCode)
202
204
 
203
- console.log(compileResult.error); // outputs runtime error, or `undefined` if no error
204
- console.log(compileResult.code); // outputs minified CSS: 'h1{font-size:40px}h1 code{font-face:Roboto Mono}'
205
+ console.log(compileResult.error) // outputs runtime error, or `undefined` if no error
206
+ console.log(compileResult.code) // outputs minified CSS: 'h1{font-size:40px}h1 code{font-face:Roboto Mono}'
205
207
  ```
206
208
 
207
209
  If a **file path** is passed, the file's code is loaded then compiled to CSS, returning an object like above.
@@ -210,32 +212,32 @@ If a **directory path** is passed, SCSS files are searched for (recursively by d
210
212
 
211
213
  ```js
212
214
  // Outputs paths to SCSS files in working directory + all nested directories
213
- const compileResults = scssToCSS.compile('.');
214
- compileResults.forEach(result => console.log(result.srcPath));
215
+ const compileResults = scssToCSS.compile('.')
216
+ compileResults.forEach(result => console.log(result.srcPath))
215
217
 
216
218
  // Outputs compiled CSS from 2nd SCSS file if found, or `undefined` if not found
217
- console.log(compileResults[1].code);
219
+ console.log(compileResults[1].code)
218
220
  ```
219
221
 
220
222
  Options are boolean, passed as object properties. For example:
221
223
 
222
224
  ```js
223
225
  // Returns array of data objects where `.code` contains unminified CSS
224
- scssToCSS.compile(inputDir, { minify: false });
226
+ scssToCSS.compile(inputDir, { minify: false })
225
227
  ```
226
228
 
227
229
  Available parameters (and their default settings) are:
228
230
 
229
- Name | Type | Desciption | Default value
230
- ---------------|---------|-------------------------------------------------------------------------|---------------
231
- `recursive` | Boolean | Recursively search for nested files if dir path passed. | `true`
232
- `verbose` | Boolean | Show logging in console/terminal. | `true`
233
- `dotFolders` | Boolean | Include dotfolders in file search. | `false`
234
- `minify` | Boolean | Minify output CSS. | `true`
235
- `sourceMaps` | Boolean | Generate CSS source maps. | `true`
236
- `cloneFolders` | Boolean | Preserve folder structure in output dir | `false`
237
- `ignoreFiles` | Array | Files (by name) to exclude from compilation. | `[]`
238
- `comment` | String | Header comment to prepend to compiled CSS. Separate by line using '\n'. | `''`
231
+ Name | Type | Desciption | Default value
232
+ -----------------|---------|-------------------------------------------------------------------------|---------------
233
+ `recursive` | Boolean | Recursively search for nested files if dir path passed. | `true`
234
+ `verbose` | Boolean | Show logging in console/terminal. | `true`
235
+ `dotFolders` | Boolean | Include dotfolders in file search. | `false`
236
+ `minify` | Boolean | Minify output CSS. | `true`
237
+ `sourceMaps` | Boolean | Generate CSS source maps. | `true`
238
+ `relativeOutput` | Boolean | Output files relative to each source file instead of to input root. | `false`
239
+ `ignores` | Array | Files/dirs to exclude from compilation. | `[]`
240
+ `comment` | String | Header comment to prepend to compiled CSS. Separate by line using '\n'. | `''`
239
241
 
240
242
  #
241
243
 
@@ -247,8 +249,8 @@ Options are boolean, passed as object properties. For example:
247
249
 
248
250
  ```js
249
251
  // Search for SCSS files in exactly assets/scss
250
- const searchResults = scssToCSS.findSCSS('assets/scss', { recursive: false });
251
- console.log(searchResults);
252
+ const searchResults = scssToCSS.findSCSS('assets/scss', { recursive: false })
253
+ console.log(searchResults)
252
254
 
253
255
  /* sample output:
254
256
 
@@ -269,7 +271,7 @@ Name | Type | Desciption
269
271
  `recursive` | Boolean | Recursively search for nested files in searchDir passed. | `true`
270
272
  `verbose` | Boolean | Show logging in console/terminal. | `true`
271
273
  `dotFolders` | Boolean | Include dotfolders in file search. | `false`
272
- `ignoreFiles` | Array | Files (by name) to exclude from search results. | `[]`
274
+ `ignores` | Array | Files/dirs to exclude from search results. | `[]`
273
275
 
274
276
  <br>
275
277
 
@@ -291,12 +293,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
291
293
 
292
294
  ## 🛠️ Related utilities
293
295
 
294
- ### [🖼️ img-to-webp](https://github.com/adamlui/js-utils/tree/main/img-to-webp)
295
-
296
- > Recursively compress all images to WEBPs.
297
- <br>[Download](https://cdn.jsdelivr.net/gh/adamlui/js-utils/img-to-webp/img-to-webp.js) /
298
- [Discuss](https://github.com/adamlui/js-utils/discussions)
299
-
300
296
  ### [</> minify.js](https://minify-js.org) &nbsp;<a href="https://github.com/toolleeo/cli-apps#programming"><img height=18 src="https://assets.scsstocss.org/images/badges/awesome/badge.svg?v=7e4a141"></a>
301
297
 
302
298
  > Recursively minify all JavaScript files.
@@ -312,4 +308,4 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
312
308
 
313
309
  <picture><source media="(prefers-color-scheme: dark)" srcset="https://assets.scsstocss.org/images/icons/home/white/icon32x27.png?v=7e4a141"><img height=13 src="https://assets.scsstocss.org/images/icons/home/dark-gray/icon32x27.png?v=7e4a141"></picture> <a href="https://js-utils.org">**More JavaScript utilities**</a> /
314
310
  <a href="https://github.com/adamlui/scss-to-css/discussions">Discuss</a> /
315
- <a href="#--scss-to-css">Back to top ↑</a>
311
+ <a href="#top">Back to top ↑</a>
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * © 2024 Adam Lui & contributors under the MIT license.
4
+ * Source: https://github.com/adamlui/scss-to-css/tree/main/src
5
+ * Documentation: https://github.com/adamlui/scss-to-css/tree/main/docs
6
+ */
7
+ (()=>{globalThis.env={devMode:__dirname.match(/[\\/]src/)};let i=require("node-clipboardy"),t=require("fs"),l=require("path"),f=require(`./lib/print${env.devMode?"":".min"}.js`),r=require(`../scss-to-css${env.devMode?"":".min"}.js`);if(Object.assign(globalThis.app??={},require(`../${env.devMode?"../":"./data/"}app.json`)),app.urls.docs+="/#-command-line-usage",app.colors={nc:"",br:"",by:"",bg:"",bw:"",blk:"",tlBG:""},app.regex={flags:{dryRun:/^--?(?:n|dry-?run)$/,includeDotFolders:/^--?(?:dd?|(?:include-?)?dot-?(?:folder|dir(?:ector(?:y|ie))?)s?=?(?:true|1)?)$/,noSourceMaps:/^--?(?:S|(?:exclude|disable|no)-?so?u?rce?-?maps?|so?u?rce?-?maps?=(?:false|0))$/,noRecursion:/^--?(?:R|(?:disable|no)-?recursi(?:on|ve)|recursi(?:on|ve)=(?:false|0))$/,noMinify:/^--?(?:M|(?:disable|no)-?minif(?:y|ication)|minif(?:y|ication)=(?:false|0))$/,relativeOutput:/^--?(?:r|relative-?output?=?(?:true|1)?)$/,copy:/^--?c(?:opy)?$/,quietMode:/^--?q(?:uiet)?(?:-?mode)?$/},paramOptions:{ignores:/^--?(?:ignores?|(?:ignore|skip|exclude)(?:d?-?files?)?)(?:=.*|$)/,comment:/^--?comments?(?:=.*|$)/},infoCmds:{help:/^--?h(?:elp)?$/,version:/^--?ve?r?s?i?o?n?$/},version:/^[~^>=]?\d+\.\d+\.\d+$/},app.config={},process.argv.forEach(o=>{var e,s,i;o.startsWith("-")&&(e=Object.keys(app.regex.paramOptions).find(e=>app.regex.paramOptions[e].test(o)),i=Object.keys(app.regex.flags).find(e=>app.regex.flags[e].test(o)),s=Object.keys(app.regex.infoCmds).find(e=>app.regex.infoCmds[e].test(o)),i?app.config[i]=!0:e?(/=.+/.test(o)||(console.error(`
8
+ ${app.colors.br}ERROR: Arg [--${o.replace(/-/g,"")}] requires '=' followed by a value.`+app.colors.nc),f.helpCmdAndDocURL(),process.exit(1)),i=o.split("=")[1],app.config[e]=parseInt(i)||i):s||(console.error(`
9
+ ${app.colors.br}ERROR: Arg [${o}] not recognized.`+app.colors.nc),console.info(`
10
+ ${app.colors.by}Valid arguments are below.`+app.colors.nc),f.help(["flags","paramOptions","infoCmds"]),process.exit(1)))}),process.argv.some(e=>app.regex.infoCmds.help.test(e)))f.help();else if(process.argv.some(e=>app.regex.infoCmds.version.test(e)))f.version();else{let[c="",a=""]=process.argv.slice(2).filter(e=>!e.startsWith("-")).map(e=>e.replace(/^\/*/,"")),o=l.resolve(process.cwd(),c);c&&!t.existsSync(o)&&(n=o+".scss",t.existsSync(n)?o=n:(console.error(`
11
+ ${app.colors.br}Error: First argument can only be an existing file or directory.`,`
12
+ '${o}' does not exist.`+app.colors.nc),console.info(`
13
+ ${app.colors.bg}Example valid command:
14
+ » scss-to-css . output.min.css`+app.colors.nc),f.helpCmdAndDocURL(),process.exit(1)));var p,n=o.endsWith(".scss")&&!t.statSync(o).isDirectory()?[o]:r.findSCSS(o,{recursive:!app.config.noRecursion,verbose:!app.config.quietMode,ignores:(app.config.ignores?.split(",")??[]).map(e=>e.trim())});if(app.config.dryRun)n.length?(console.info(`
15
+ ${app.colors.by}SCSS files to be compiled:`+app.colors.nc),n.forEach(e=>console.info(e))):console.info(app.colors.by+`
16
+ No SCSS files will be compiled.`+app.colors.nc);else{let s=[],e=[];!app.config.relativeOutput&&t.statSync(o).isDirectory()?(p=r.compile(o,{verbose:!app.config.quietMode,minify:!app.config.noMinify,comment:app.config.comment?.replace(/\\n/g,"\n"),relativeOutput:!1,recursive:!app.config.noRecursion,dotFolders:!!app.config.includeDotFolders,sourceMaps:!app.config.noSourceMaps,ignores:app.config.ignores?app.config.ignores.split(",").map(e=>e.trim()):[]}),Array.isArray(p)&&(e=p),p&&(p.error?s.push(o):e=[].concat(p))):e=n.map(e=>{var o=r.compile(e,{verbose:!app.config.quietMode,minify:!app.config.noMinify,sourceMaps:!app.config.noSourceMaps,comment:app.config.comment?.replace(/\\n/g,"\n")});return o.error&&s.push(e),o}).filter(e=>!e.error),e?.length?(p=1<e.length?"s":"",f.ifNotQuiet(`
17
+ ${app.colors.bg}Compilation complete!`+app.colors.nc),f.ifNotQuiet(""+app.colors.bw+e.length+" CSS file"+p+(app.config.noSourceMaps?"":` + ${e.length} source map`+p)+" generated."+app.colors.nc)):f.ifNotQuiet(`
18
+ ${app.colors.by}No SCSS files processed.`+app.colors.nc),s.length&&(f.ifNotQuiet(`
19
+ `+app.colors.br+s.length+" file"+(1<s.length?"s":"")+" failed to compile:"+app.colors.nc),s.forEach(e=>f.ifNotQuiet(e))),e?.length&&(app.config.copy&&1==e?.length?(console.log(`
20
+ `+app.colors.bw+e[0].code+app.colors.nc),f.ifNotQuiet("\nCopying to clipboard..."),i.writeSync(e[0].code)):(f.ifNotQuiet(`
21
+ Writing to file${1<e?.length?"s":""}...`),e?.forEach(({code:e,srcMap:o,srcPath:s,relPath:i})=>{let r,p;if(!app.config.relativeOutput&&i){let e=l.resolve(process.cwd(),a||"css"),o=l.dirname(i);r="."!=o?l.join(e,o):e,p=l.basename(s,".scss")+`${app.config.noMinify?"":".min"}.css`}else r=l.join(l.dirname(s),a.endsWith(".css")?l.dirname(a):a||"css"),p=`${a.endsWith(".css")&&c.endsWith(".scss")?l.basename(a).replace(/(\.min)?\.css$/,""):l.basename(s,".scss")}.min.css`;let n=l.join(r,p);t.existsSync(r)||t.mkdirSync(r,{recursive:!0}),t.writeFileSync(n,e,"utf8"),f.ifNotQuiet(` ${app.colors.bg}✓${app.colors.nc} `+l.relative(process.cwd(),n)),app.config.noSourceMaps||t.writeFileSync(n+".map",JSON.stringify(o),"utf8"),f.ifNotQuiet(` ${app.colors.bg}✓${app.colors.nc} `+l.relative(process.cwd(),n))})))}}})();
@@ -0,0 +1,17 @@
1
+ /**
2
+ * © 2024 Adam Lui & contributors under the MIT license.
3
+ * Source: https://github.com/adamlui/scss-to-css/tree/main/src
4
+ * Documentation: https://github.com/adamlui/scss-to-css/tree/main/docs
5
+ */
6
+ module.exports={help(e=["header","usage","pathArgs","flags","paramOptions","infoCmds"]){app.prefix=""+app.colors.tlBG+app.colors.blk+` ${app.name.replace(/^@[^/]+\//,"")} ${app.colors.nc} `;let o={header:[`
7
+ ├ ${app.prefix}© ${app.copyrightYear} ${app.author} under the ${app.license} license.`,app.prefix+"Source: "+app.urls.src],usage:[`
8
+ ${app.colors.bw}o Usage:`+app.colors.nc,` ${app.colors.bw}» `+app.colors.bg+app.cmdFormat+app.colors.nc],pathArgs:[`
9
+ ${app.colors.bw}o Path arguments:`+app.colors.nc," [inputPath] Path to SCSS file or directory containing SCSS files to be compiled, relative to the current working directory."," [outputPath] Path to file or directory where CSS + sourcemap files will be stored, relative to input root (if not provided, css/ is used)."],flags:[`
10
+ ${app.colors.bw}o Boolean options:`+app.colors.nc," -n, --dry-run Don't actually compile the file(s), just show if they will be processed."," -d, --include-dotfolders Include dotfolders in file search."," -S, --no-source-maps Prevent source maps from being generated."," -M, --no-minify Disable minification of output CSS."," -R, --no-recursion Disable recursive file searching."," -r, --relative-output Output files relative to each source file instead of to input root."," -c, --copy Copy compiled CSS to clipboard instead of writing to file if single source file is processed."," -q, --quiet Suppress all logging except errors."],paramOptions:[`
11
+ ${app.colors.bw}o Parameter options:`+app.colors.nc,'--ignores="dir/,file1.scss,file2.scss" Files/directories to exclude from compilation.',"--comment=\"comment\" Prepend header comment to compiled CSS. Separate by line using '\\n'."],infoCmds:[`
12
+ ${app.colors.bw}o Info commands:`+app.colors.nc," -h, --help Display help screen."," -v, --version Show version number."]};e.forEach(a=>o[a]?.forEach(o=>{{var i=/header|usage/.test(a)?1:41;let r=process.stdout.columns||80,s=[],e=o.match(/\S+|\s+/g),p="";e.forEach(e=>{var o=r-(s.length?i:0);p.length+"| ".length+e.length>o&&(s.push(s.length?p.trimStart():p),p=""),p+=e}),s.push(s.length?p.trimStart():p),s.forEach((e,o)=>console.info("| "+(0==o?e:" ".repeat(i)+e)))}})),console.info(`
13
+ For more help, please visit: `+app.colors.bw+app.urls.docs+app.colors.nc)},helpCmdAndDocURL(){console.info(`
14
+ For more help, type 'scss-to-css --help' or visit
15
+ `+app.colors.bw+app.urls.docs+app.colors.nc)},ifNotQuiet(e){app.config.quietMode||console.info(e)},version(){var e=require("path"),o=require("child_process").execSync(`npm view ${JSON.stringify(app.name)} version`).toString().trim()||"none";let r,s=process.cwd();for(;"/"!=s;){var p=e.join(s,"package.json");if(require("fs").existsSync(p)){p=require(p);r=(p.dependencies?.[app.name]||p.devDependencies?.[app.name])?.match(/^[~^>=]?\d+\.\d+\.\d+$/)[1]||"none";break}s=e.dirname(s)}console.info(`
16
+ Global version: ${o}
17
+ Local version: `+r)}};
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "@adamlui/scss-to-css",
3
+ "author": "Adam Lui & contributors",
4
+ "license": "MIT",
5
+ "copyrightYear": "2024–2026",
6
+ "cmdFormat": "scss-to-css [inputPath] [outputPath] [options]",
7
+ "urls": {
8
+ "docs": "https://github.com/adamlui/scss-to-css/tree/main/docs",
9
+ "github": "https://github.com/adamlui/scss-to-css",
10
+ "jsdelivr": "https://cdn.jsdelivr.net/gh/adamlui/scss-to-css",
11
+ "npm": "https://www.npmjs.com/package/@adamlui/scss-to-css",
12
+ "src": "https://github.com/adamlui/scss-to-css/tree/main/src"
13
+ }
14
+ }
@@ -1,18 +1,9 @@
1
- let fs=require("fs"),path=require("path"),sass=require("sass");function findSCSS(r,i={}){var e="https://docs.scsstocss.org/node.js/#findscsssearchdir-options",s={recursive:!0,verbose:!0,dotFolders:!1,ignoreFiles:[]};if("string"!=typeof r)console.error("findSCSS() » ERROR: 1st arg <searchDir> must be a string."),console.info("findSCSS() » For more help, please visit "+e);else{var o=path.resolve(process.cwd(),r);if(fs.existsSync(o)){if(validateOptions(i,s,e,"findSCSS('assets/scss', { verbose: false, dotFolders: true })")){i={...s,...i};let e=fs.readdirSync(r),o=[];return i.verbose&&!i.isRecursing&&console.info("findSCSS() » Searching for SCSS files..."),e.forEach(e=>{var s=path.resolve(r,e);fs.statSync(s).isDirectory()&&"node_modules"!=e&&i.recursive&&(i.dotFolders||!e.startsWith("."))?o.push(...findSCSS(s,{...i,isRecursing:!0})):e.endsWith(".scss")&&!i.ignoreFiles.includes(e)?o.push(s):i.verbose&&i.ignoreFiles.includes(e)&&console.info(`findSCSS() » ** ${e} ignored due to [options.ignoreFiles]`)}),i.verbose&&!i.isRecursing&&(console.info("findSCSS() » Search complete! "+(0==o.length?"No":o.length)+` file${1==o.length?"":"s"} found.`),"compile"!=findSCSS.caller?.name)&&"undefined"!=typeof window&&console.info("findSCSS() » Check returned array."),i.isRecursing||o.length?o:[]}}else console.error("findSCSS() » ERROR: 1st arg <searchDir> must be an existing directory."),console.error(`findSCSS() » ${o} does not exist.`),console.info("findSCSS() » For more help, please visit "+e)}}function compile(i,n={}){var e="https://docs.scsstocss.org/node.js/#compileinput-options",s={recursive:!0,verbose:!0,dotFolders:!1,minify:!0,sourceMaps:!0,cloneFolders:!1,ignoreFiles:[],comment:""};if("string"!=typeof i)console.error("compile() » ERROR: 1st arg <input> must be a string."),console.info("compile() » For more help, please visit "+e);else if(validateOptions(n,s,e,"compile('assets/scss', { recursive: false, minify: false })")){let r={style:(n={...s,...n}).minify?"compressed":"expanded",sourceMap:n.sourceMaps,charset:!1};if(fs.existsSync(i)){if(!i.endsWith(".scss"))return e=findSCSS(i,{recursive:n.recursive,verbose:n.verbose,dotFolders:n.dotFolders,ignoreFiles:n.ignoreFiles})?.map(s=>{n.verbose&&console.info(`compile() » ** Compiling ${s}...`);try{var o=sass.compile(s,r);let e;return n.cloneFolders&&(e=path.relative(path.resolve(process.cwd(),i),s)),n.comment&&(o.css=t(o.css,n.comment)),{code:o.css,srcMap:o.sourceMap,srcPath:s,relPath:e,error:void 0}}catch(e){return console.error(`
2
- compile() » ERROR: ${e.message}
3
- `),{code:void 0,srcMap:void 0,srcPath:void 0,error:e}}}).filter(e=>!e.error),n.verbose&&(e.length&&"undefined"!=typeof window?console.info("compile() » Compilation complete! Check returned object."):console.info("compile() » No SCSS files processed.")),e;n.verbose&&console.info(`compile() » ** Compiling ${i}...`);try{var o=sass.compile(i,r);return n.comment&&(o.css=t(o.css,n.comment)),n.verbose&&"undefined"!=typeof window&&console.info("compile() » Compilation complete! Check returned object."),{code:o.css,srcMap:o.sourceMap,srcPath:path.resolve(process.cwd(),i),error:void 0}}catch(e){return console.error(`
4
- compile() » ERROR: ${e.message}
5
- `),{code:void 0,srcMap:void 0,srcPath:void 0,error:e}}}else{n.verbose&&console.info("compile() » ** Compiling passed source code...");try{var c=sass.compileString(i,r);return n.comment&&(c.css=t(c.css,n.comment)),{code:c.css,srcMap:c.sourceMap,srcPath:void 0,error:void 0}}catch(e){return console.error(`
6
- compile() » ERROR: ${e.message}
7
- `),{code:void 0,srcMap:void 0,srcPath:void 0,error:e}}}function t(e,s){var s=s.split("\n").map(e=>" * "+e).join("\n"),o=e.indexOf("#!");return 0<=o?(o=e.indexOf("\n",o)+1,e.slice(0,o)+`/**
8
1
  /**
9
2
  * © 2024 Adam Lui & contributors under the MIT license.
10
- * Source: https://code.scsstocss.org/node.js
11
- * Documentation: https://docs.scsstocss.org/node.js
3
+ * Source: https://github.com/adamlui/scss-to-css/tree/main/src
4
+ * Documentation: https://github.com/adamlui/scss-to-css/tree/main/docs
12
5
  */
13
- ${s}
6
+ let fs=require("fs"),path=require("path"),sass=require("sass");function findSCSS(r,i={}){var e="https://github.com/adamlui/scss-to-css/tree/main/docs/#findscsssearchdir-options",o={recursive:!0,verbose:!0,dotFolders:!1,ignores:[]};if(log.prefix="findSCSS()","string"!=typeof r)return log.error("1st arg <searchDir> must be a string."),log.helpURL(e);var s=path.resolve(process.cwd(),r);if(!fs.existsSync(s))return log.error("1st arg <searchDir> must be an existing directory."),log.error(s+" does not exist."),log.helpURL(e);if(validateOptions({options:i,defaultOptions:o,helpURL:e,exampleCall:"findSCSS('assets/scss', { verbose: false, dotFolders: true })"})){(i={...o,...i}).ignoreFiles&&(i.ignores=[...i.ignores,...i.ignoreFiles]);let e=fs.readdirSync(r),s=[];return i.verbose&&!i.isRecursing&&log.info("Searching for SCSS files..."),e.forEach(e=>{let o=path.resolve(r,e);i.ignores.some(s=>s.endsWith("/")?o.split(path.sep).some(e=>e==s.replace(/\/$/,"")):e==s)?i.verbose&&log.info(`** ${e} ignored`):fs.statSync(o).isDirectory()&&"node_modules"!=e&&i.recursive&&(i.dotFolders||!e.startsWith("."))?s.push(...findSCSS(o,{...i,isRecursing:!0})):e.endsWith(".scss")&&s.push(o)}),i.verbose&&!i.isRecursing&&(log.info("Search complete!",`${s.length||"No"} file${1==s.length?"":"s"} found.`),"compile"!=findSCSS.caller?.name)&&"undefined"!=typeof window&&log.info("Check returned array."),i.isRecursing||s.length?s:[]}}function compile(i,t={}){var e="https://github.com/adamlui/scss-to-css/tree/main/docs/#compileinput-options",s={recursive:!0,verbose:!0,dotFolders:!1,minify:!0,sourceMaps:!0,relativeOutput:!1,ignores:[],comment:""};if(log.prefix="compile()","string"!=typeof i)return log.error("1st arg <input> must be a string."),log.helpURL(e);if(validateOptions({options:t,defaultOptions:s,helpURL:e,exampleCall:"compile('assets/scss', { recursive: false, minify: false })"})){(t={...s,...t}).ignoreFiles&&(t.ignores=[...t.ignores,...t.ignoreFiles]);let r={style:t.minify?"compressed":"expanded",sourceMap:t.sourceMaps,charset:!1};if(fs.existsSync(i)){if(!i.endsWith(".scss")||!fs.statSync(i).isFile())return e=findSCSS(i,t)?.map(e=>{t.verbose&&log.info(`** Compiling ${e}...`);try{var s=sass.compile(e,r),o=t.relativeOutput?void 0:path.relative(path.resolve(process.cwd(),i),e);return t.comment&&(s.css=prependComment(s.css,t.comment)),{code:s.css,srcMap:s.sourceMap,srcPath:e,relPath:o,error:void 0}}catch(e){return log.error(e.message),{code:void 0,srcMap:void 0,srcPath:void 0,error:e}}}).filter(e=>!e.error),t.verbose&&(e.length&&"undefined"!=typeof window?log.info("Compilation complete! Check returned object."):log.info("No SCSS files processed.")),e;t.verbose&&log.info(`** Compiling ${i}...`);try{var o=sass.compile(i,r);return t.comment&&(o.css=prependComment(o.css,t.comment)),t.verbose&&"undefined"!=typeof window&&log.info("Compilation complete! Check returned object."),{code:o.css,srcMap:o.sourceMap,srcPath:path.resolve(process.cwd(),i),error:void 0}}catch(e){return log.error(e.message),{code:void 0,srcMap:void 0,srcPath:void 0,error:e}}}else{t.verbose&&log.info("** Compiling passed source code...");try{var n=sass.compileString(i,r);return t.comment&&(n.css=prependComment(n.css,t.comment)),{code:n.css,srcMap:n.sourceMap,srcPath:void 0,error:void 0}}catch(e){return log.error(e.message),{code:void 0,srcMap:void 0,srcPath:void 0,error:e}}}}}function prependComment(e,s){var o=e.match(/^#!.*\n/);let r="";return o&&(r=o[0],e=e.slice(r.length)),`${r}/**
7
+ ${s.split("\n").map(e=>" * "+e).join("\n")}
14
8
  */
15
- `+e.slice(o)):`/**
16
- ${s}
17
- */
18
- `+e}}}function validateOptions(e,s,o,r){let i=JSON.stringify(s,void 0,2).replace(/"([^"]+)":/g,"$1:").replace(/"/g,"'").replace(/\n\s*/g," "),n=Object.keys(s).join(", "),c=Object.keys(s).filter(e=>"boolean"==typeof s[e]),t=Object.keys(s).filter(e=>Number.isInteger(s[e])),l=Object.keys(s).filter(e=>Array.isArray(s[e])),a=`${validateOptions.caller?.name||"validateOptions"}() » `;var d,p=r.split(",").findIndex(e=>e.trim().startsWith("{"))+1,f=(p+=["st","nd","rd"][p-1]||"th",()=>{console.info(a+`Valid options: [ ${n} ]`),console.info(a+"If omitted, default settings are: "+i)}),m=()=>{console.info(a+"For more help, please visit "+o)};if("object"!=typeof e)return console.error(a+`ERROR: ${"0th"==p?"[O":p+" arg [o"}ptions] can only be an object of key/values.`),console.info(a+"Example valid call: "+r),f(),m(),!1;for(d in e){if("isRecursing"!=d&&!Object.prototype.hasOwnProperty.call(s,d))return console.error(a+`ERROR: \`${d}\` is an invalid option.`),f(),m(),!1;if(c.includes(d)&&"boolean"!=typeof e[d])return console.error(a+`ERROR: [${d}] option can only be \`true\` or \`false\`.`),m(),!1;if(t.includes(d)){if(e[d]=parseInt(e[d],10),isNaN(e[d])||e[d]<1)return console.error(a+`ERROR: [${d}] option can only be an integer > 0.`),m(),!1}else if(l.includes(d))if("string"!=typeof e[d]||e[d].includes(",")){if(!Array.isArray(e[d]))return console.error(a+`ERROR: [${d}] option can only be an array.`),m(),!1}else e[d]=[e[d]]}return!0}let stcAliases={compile:["build","Build","Compile","compress","Compress","minify","Minify"],findSCSS:["find","Find","findscss","findScss","Findscss","FindScss","FindSCSS","search","Search"]};module.exports={compile:compile,findSCSS:findSCSS};for(let s in stcAliases)stcAliases[s].forEach(e=>module.exports[e]=module.exports[s]);
9
+ `+e}function validateOptions({options:e,defaultOptions:s,helpURL:o,exampleCall:r}){var i,t,n=Object.keys(s).filter(e=>"boolean"==typeof s[e]),l=Object.keys(s).filter(e=>Number.isInteger(s[e]));if("object"!=typeof e)return i=r.split(",").findIndex(e=>e.trim().startsWith("{"))+1,i+=["st","nd","rd"][i-1]||"th",log.error(`${"0th"==i?"[O":i+" arg [o"}ptions] can only be an object of key/vals.`),log.info("Example valid call:",r),log.validOptions(s),log.helpURL(o),!1;for(t in e)if("isRecursing"!=t&&Object.prototype.hasOwnProperty.call(s,t)){if(n.includes(t)&&"boolean"!=typeof e[t])return log.error(`[${t}] option can only be \`true\` or \`false\`.`),log.helpURL(o),!1;if(l.includes(t)&&(e[t]=parseInt(e[t],10),isNaN(e[t])||e[t]<1))return log.error(`[${t}] option can only be an integer > 0.`),log.helpURL(o),!1}return!0}Object.assign(globalThis.app??={},require(`${__dirname.match(/[\\/]src/)?"../":"./data/"}app.json`)),app.aliases={compile:["build","Build","Compile","compress","Compress","minify","Minify"],findSCSS:["find","Find","findscss","findScss","Findscss","FindScss","FindSCSS","search","Search"]};let log={prefix:app.name,error(...e){console.error(this.prefix+" » ERROR:",...e)},helpURL(e=app.urls?.docs){this.info("For more help, please visit",e)},info(...e){console.info(this.prefix+" »",...e)},validOptions(e){var s=Object.keys(e).join(", "),e=JSON.stringify(e,void 0,2).replace(/"([^"]+)":/g,"$1:").replace(/"/g,"'").replace(/\n\s*/g," ");this.info(`Valid options: [${s}]`),this.info("If omitted, default settings are: "+e)}};module.exports={compile:compile,findSCSS:findSCSS};for(let s in app.aliases)app.aliases[s].forEach(e=>module.exports[e]=module.exports[s]);
package/docs/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ <a id="top"></a>
2
+
1
3
  <table align="center">
2
4
  <td align="center" width=1000>
3
5
  <h6>
@@ -6,19 +8,19 @@
6
8
  <img height=14 src="https://assets.scsstocss.org/images/icons/earth/black/icon32.svg?v=7e4a141">
7
9
  </picture>
8
10
  &nbsp;English |
9
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/zh-cn#readme">简体中文</a> |
10
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/zh-tw#readme">繁體中文</a> |
11
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/ja#readme">日本語</a> |
12
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/hi#readme">हिंदी</a> |
13
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/bn#readme">বাংলা</a> |
14
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/mr#readme">मराठी</a> |
15
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/pa#readme">ਪੰਜਾਬੀ</a> |
16
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/de#readme">Deutsch</a> |
17
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/es#readme">Español</a> |
18
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/fr#readme">Français</a> |
19
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/it#readme">Italiano</a> |
20
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/nl#readme">Nederlands</a> |
21
- <a href="https://github.com/adamlui/scss-to-css/tree/main/node.js/docs/pt#readme">Português</a>
11
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/zh-cn#readme">简体中文</a> |
12
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/zh-tw#readme">繁體中文</a> |
13
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/ja#readme">日本語</a> |
14
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/hi#readme">हिंदी</a> |
15
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/bn#readme">বাংলা</a> |
16
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/mr#readme">मराठी</a> |
17
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/pa#readme">ਪੰਜਾਬੀ</a> |
18
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/de#readme">Deutsch</a> |
19
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/es#readme">Español</a> |
20
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/fr#readme">Français</a> |
21
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/it#readme">Italiano</a> |
22
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/nl#readme">Nederlands</a> |
23
+ <a href="https://github.com/adamlui/scss-to-css/tree/main/docs/pt#readme">Português</a>
22
24
  </h6>
23
25
  </td>
24
26
  </table>
@@ -30,15 +32,15 @@
30
32
  <a href="https://www.npmjs.com/package/@adamlui/scss-to-css">
31
33
  <img height=31 src="https://img.shields.io/npm/dm/%40adamlui%2Fscss-to-css?logo=npm&color=af68ff&logoColor=white&labelColor=464646&style=for-the-badge"></a>
32
34
  <a href="#%EF%B8%8F-mit-license">
33
- <img height=31 src="https://img.shields.io/badge/License-MIT-fc4f2d.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
34
- <a href="https://github.com/adamlui/js-utils/releases/tag/scss-to-css-1.12.0">
35
- <img height=31 src="https://img.shields.io/badge/Latest_Build-1.12.0-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
35
+ <img height=31 src="https://img.shields.io/badge/License-MIT-orange.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
36
+ <a href="https://github.com/adamlui/js-utils/releases/tag/scss-to-css-2.0.1">
37
+ <img height=31 src="https://img.shields.io/badge/Latest_Build-2.0.1-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
36
38
  <a href="https://www.npmjs.com/package/@adamlui/scss-to-css?activeTab=code">
37
39
  <img height=31 src="https://img.shields.io/npm/unpacked-size/%40adamlui%2Fscss-to-css?style=for-the-badge&logo=ebox&logoColor=white&color=blue&labelColor=464646"></a>
38
- <a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_scss-to-css:node.js/src/scss-to-css.js">
39
- <img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_scss-to-css%3Anode.js%2Fsrc%2Fscss-to-css.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=Vulnerabilities&color=gold"></a>
40
+ <a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_scss-to-css:src/scss-to-css.js">
41
+ <img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_scss-to-css%3Asrc%2Fscss-to-css.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=Vulnerabilities&color=gold"></a>
40
42
  <a href="https://github.com/toolleeo/cli-apps#conversion">
41
- <img height=31 src="https://img.shields.io/badge/Mentioned_in-Awesome-c4a2bd?logo=awesomelists&logoColor=white&labelColor=464646&style=for-the-badge"></a>
43
+ <img height=31 src="https://img.shields.io/badge/Mentioned_in-Awesome-ff69b4?logo=awesomelists&logoColor=white&labelColor=464646&style=for-the-badge"></a>
42
44
 
43
45
  <img height=6px width="100%" src="https://assets.scsstocss.org/images/separators/aqua-gradient.png?v=7e4a141">
44
46
 
@@ -91,7 +93,7 @@ $ scss-to-css [input_path] [output_path]
91
93
  ```
92
94
 
93
95
  - `[input_path]`: Path to SCSS file or directory containing SCSS files to be compiled, relative to the current working directory.
94
- - `[output_path]`: Path to file or directory where CSS + source map files will be stored, relative to original file location (if not provided, `css/` is used).
96
+ - `[output_path]`: Path to file or directory where CSS + source map files will be stored, relative to input root (if not provided, `css/` is used).
95
97
 
96
98
  **📝 Note:** If folders are passed, files will be processed recursively unless `-R` or `--no-recursion` is passed.
97
99
 
@@ -117,13 +119,13 @@ Compile all SCSS files in the **current directory** (outputs to `css/`):
117
119
  $ scss-to-css
118
120
  ```
119
121
 
120
- Compile all SCSS files in a **specific directory** (outputs to `path/to/your/directory/css/`):
122
+ Compile all SCSS files in a **specific directory** (outputs to `css/path/to/your/directory/`):
121
123
 
122
124
  ```
123
125
  $ scss-to-css path/to/your/directory
124
126
  ```
125
127
 
126
- Compile a **specific file** (outputs to `path/to/your/css/file.min.css`):
128
+ Compile a **specific file** (outputs to `css/path/to/your/file.min.css`):
127
129
 
128
130
  ```
129
131
  $ scss-to-css path/to/your/file.scss
@@ -149,14 +151,14 @@ Boolean options:
149
151
  -S, --no-source-maps Prevent source maps from being generated.
150
152
  -M, --no-minify Disable minification of output CSS.
151
153
  -R, --no-recursion Disable recursive file searching.
152
- -C, --clone-folders Preserve folder structure in output directory
154
+ -r, --relative-output Output files relative to each source file instead of to input root.
153
155
  -c, --copy Copy compiled CSS to clipboard instead of
154
156
  writing to file if single source file is
155
157
  processed.
156
158
  -q, --quiet Suppress all logging except errors.
157
159
 
158
160
  Parameter options:
159
- --ignore-files="file1.scss,file2.scss" Files to exclude from
161
+ --ignores="dir/,file1.scss,file2.scss" Files/directories to exclude from
160
162
  compilation.
161
163
  --comment="comment" Prepend header comment to
162
164
  compiled CSS. Separate by
@@ -183,7 +185,7 @@ import scssToCSS from '@adamlui/scss-to-css';
183
185
  #### CJS:
184
186
 
185
187
  ```js
186
- const scssToCSS = require('@adamlui/scss-to-css');
188
+ const scssToCSS = require('@adamlui/scss-to-css')
187
189
  ```
188
190
 
189
191
  ###### _*Node.js version 14 or higher required_
@@ -198,10 +200,10 @@ If **source code** is passed, it is directly compiled, then an object containing
198
200
 
199
201
  ```js
200
202
  const srcCode = 'h1 { font-size: 40px ; code { font-face: Roboto Mono }}',
201
- compileResult = scssToCSS.compile(srcCode);
203
+ compileResult = scssToCSS.compile(srcCode)
202
204
 
203
- console.log(compileResult.error); // outputs runtime error, or `undefined` if no error
204
- console.log(compileResult.code); // outputs minified CSS: 'h1{font-size:40px}h1 code{font-face:Roboto Mono}'
205
+ console.log(compileResult.error) // outputs runtime error, or `undefined` if no error
206
+ console.log(compileResult.code) // outputs minified CSS: 'h1{font-size:40px}h1 code{font-face:Roboto Mono}'
205
207
  ```
206
208
 
207
209
  If a **file path** is passed, the file's code is loaded then compiled to CSS, returning an object like above.
@@ -210,32 +212,32 @@ If a **directory path** is passed, SCSS files are searched for (recursively by d
210
212
 
211
213
  ```js
212
214
  // Outputs paths to SCSS files in working directory + all nested directories
213
- const compileResults = scssToCSS.compile('.');
214
- compileResults.forEach(result => console.log(result.srcPath));
215
+ const compileResults = scssToCSS.compile('.')
216
+ compileResults.forEach(result => console.log(result.srcPath))
215
217
 
216
218
  // Outputs compiled CSS from 2nd SCSS file if found, or `undefined` if not found
217
- console.log(compileResults[1].code);
219
+ console.log(compileResults[1].code)
218
220
  ```
219
221
 
220
222
  Options are boolean, passed as object properties. For example:
221
223
 
222
224
  ```js
223
225
  // Returns array of data objects where `.code` contains unminified CSS
224
- scssToCSS.compile(inputDir, { minify: false });
226
+ scssToCSS.compile(inputDir, { minify: false })
225
227
  ```
226
228
 
227
229
  Available parameters (and their default settings) are:
228
230
 
229
- Name | Type | Desciption | Default value
230
- ---------------|---------|-------------------------------------------------------------------------|---------------
231
- `recursive` | Boolean | Recursively search for nested files if dir path passed. | `true`
232
- `verbose` | Boolean | Show logging in console/terminal. | `true`
233
- `dotFolders` | Boolean | Include dotfolders in file search. | `false`
234
- `minify` | Boolean | Minify output CSS. | `true`
235
- `sourceMaps` | Boolean | Generate CSS source maps. | `true`
236
- `cloneFolders` | Boolean | Preserve folder structure in output dir | `false`
237
- `ignoreFiles` | Array | Files (by name) to exclude from compilation. | `[]`
238
- `comment` | String | Header comment to prepend to compiled CSS. Separate by line using '\n'. | `''`
231
+ Name | Type | Desciption | Default value
232
+ -----------------|---------|-------------------------------------------------------------------------|---------------
233
+ `recursive` | Boolean | Recursively search for nested files if dir path passed. | `true`
234
+ `verbose` | Boolean | Show logging in console/terminal. | `true`
235
+ `dotFolders` | Boolean | Include dotfolders in file search. | `false`
236
+ `minify` | Boolean | Minify output CSS. | `true`
237
+ `sourceMaps` | Boolean | Generate CSS source maps. | `true`
238
+ `relativeOutput` | Boolean | Output files relative to each source file instead of to input root. | `false`
239
+ `ignores` | Array | Files/dirs to exclude from compilation. | `[]`
240
+ `comment` | String | Header comment to prepend to compiled CSS. Separate by line using '\n'. | `''`
239
241
 
240
242
  #
241
243
 
@@ -247,8 +249,8 @@ Options are boolean, passed as object properties. For example:
247
249
 
248
250
  ```js
249
251
  // Search for SCSS files in exactly assets/scss
250
- const searchResults = scssToCSS.findSCSS('assets/scss', { recursive: false });
251
- console.log(searchResults);
252
+ const searchResults = scssToCSS.findSCSS('assets/scss', { recursive: false })
253
+ console.log(searchResults)
252
254
 
253
255
  /* sample output:
254
256
 
@@ -269,7 +271,7 @@ Name | Type | Desciption
269
271
  `recursive` | Boolean | Recursively search for nested files in searchDir passed. | `true`
270
272
  `verbose` | Boolean | Show logging in console/terminal. | `true`
271
273
  `dotFolders` | Boolean | Include dotfolders in file search. | `false`
272
- `ignoreFiles` | Array | Files (by name) to exclude from search results. | `[]`
274
+ `ignores` | Array | Files/dirs to exclude from search results. | `[]`
273
275
 
274
276
  <br>
275
277
 
@@ -291,12 +293,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
291
293
 
292
294
  ## 🛠️ Related utilities
293
295
 
294
- ### [🖼️ img-to-webp](https://github.com/adamlui/js-utils/tree/main/img-to-webp)
295
-
296
- > Recursively compress all images to WEBPs.
297
- <br>[Download](https://cdn.jsdelivr.net/gh/adamlui/js-utils/img-to-webp/img-to-webp.js) /
298
- [Discuss](https://github.com/adamlui/js-utils/discussions)
299
-
300
296
  ### [</> minify.js](https://minify-js.org) &nbsp;<a href="https://github.com/toolleeo/cli-apps#programming"><img height=18 src="https://assets.scsstocss.org/images/badges/awesome/badge.svg?v=7e4a141"></a>
301
297
 
302
298
  > Recursively minify all JavaScript files.
@@ -312,4 +308,4 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
312
308
 
313
309
  <picture><source media="(prefers-color-scheme: dark)" srcset="https://assets.scsstocss.org/images/icons/home/white/icon32x27.png?v=7e4a141"><img height=13 src="https://assets.scsstocss.org/images/icons/home/dark-gray/icon32x27.png?v=7e4a141"></picture> <a href="https://js-utils.org">**More JavaScript utilities**</a> /
314
310
  <a href="https://github.com/adamlui/scss-to-css/discussions">Discuss</a> /
315
- <a href="#--scss-to-css">Back to top ↑</a>
311
+ <a href="#top">Back to top ↑</a>
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@adamlui/scss-to-css",
3
- "version": "1.12.0",
3
+ "version": "2.0.1",
4
4
  "description": "Recursively compile all SCSS files into minified CSS",
5
5
  "author": {
6
6
  "name": "Adam Lui",
7
7
  "email": "adam@kudoai.com",
8
8
  "url": "https://github.com/adamlui"
9
9
  },
10
- "homepage": "https://scsstocss.org",
10
+ "homepage": "https://github.com/adamlui/scss-to-css",
11
11
  "license": "MIT",
12
12
  "funding": [
13
13
  {
@@ -29,18 +29,24 @@
29
29
  ],
30
30
  "main": "dist/scss-to-css.min.js",
31
31
  "files": [
32
+ "dist/",
32
33
  "docs/",
33
34
  "!docs/*/"
34
35
  ],
35
36
  "bin": {
36
- "scsstocss": "dist/cli.min.js",
37
- "scss-to-css": "dist/cli.min.js"
37
+ "scsstocss": "dist/cli/index.min.js",
38
+ "scss-to-css": "dist/cli/index.min.js"
38
39
  },
39
40
  "directories": {
40
41
  "lib": "./dist",
41
42
  "doc": "./docs"
42
43
  },
43
44
  "scripts": {
45
+ "prepare": "husky",
46
+ "lint": "eslint . --cache",
47
+ "lint:all": "eslint .",
48
+ "lint:fix": "eslint . --fix --cache",
49
+ "lint:fix-all": "eslint . --fix",
44
50
  "build": "bash utils/build.sh",
45
51
  "bump:patch": "bash utils/bump.sh patch",
46
52
  "bump:minor": "bash utils/bump.sh minor",
@@ -61,13 +67,20 @@
61
67
  "stylesheets"
62
68
  ],
63
69
  "bugs": {
64
- "url": "https://support.scsstocss.org"
70
+ "url": "https://github.com/adamlui/scss-to-css/issues"
65
71
  },
66
72
  "dependencies": {
67
73
  "node-clipboardy": "^1.0.3",
68
- "sass": "^1.97.2"
74
+ "sass": "^1.97.3"
69
75
  },
70
76
  "devDependencies": {
71
- "@adamlui/minify.js": "^1.9.0"
77
+ "@adamlui/minify.js": "^2.1.4",
78
+ "@eslint/json": "^1.0.0",
79
+ "@eslint/markdown": "^7.5.1",
80
+ "@stylistic/eslint-plugin": "^5.7.1",
81
+ "eslint": "^9.39.2",
82
+ "eslint-plugin-import": "^2.32.0",
83
+ "eslint-plugin-regexp": "^3.0.0",
84
+ "husky": "^9.1.7"
72
85
  }
73
86
  }
package/dist/cli.min.js DELETED
@@ -1,30 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * © 2024 Adam Lui & contributors under the MIT license.
4
- * Source: https://code.scsstocss.org/node.js
5
- * Documentation: https://docs.scsstocss.org/node.js
6
- */
7
- (()=>{let i="@adamlui/scss-to-css",r="https://docs.scsstocss.org/node.js/#-command-line-usage",n=require(__dirname.match(/src/)?"./scss-to-css":"./scss-to-css.min"),a=require("fs"),m=require("path"),t=require("node-clipboardy"),o=require("child_process").execSync,d="",p="",f="",u="",h="",g={},c={flags:{dryRun:/^--?(?:n|dry-?run)$/,includeDotFolders:/^--?(?:dd?|(?:include-?)?dot-?(?:folder|dir(?:ector(?:y|ie))?)s?=?(?:true|1)?)$/,noSourceMaps:/^--?(?:S|(?:exclude|disable|no)-?so?u?rce?-?maps?|so?u?rce?-?maps?=(?:false|0))$/,noRecursion:/^--?(?:R|(?:disable|no)-?recursi(?:on|ve)|recursi(?:on|ve)=(?:false|0))$/,noMinify:/^--?(?:M|(?:disable|no)-?minif(?:y|ication)|minif(?:y|ication)=(?:false|0))$/,cloneFolders:/^--?(?:C|clone-?folders?=?(?:true|1)?)$/,copy:/^--?c(?:opy)?$/,quietMode:/^--?q(?:uiet)?(?:-?mode)?$/},paramOptions:{ignoreFiles:/^--?(?:ignore|skip|exclude)(?:d?-?files?)?(?:=.*|$)/,comment:/^--?comments?(?:=.*|$)/},infoCmds:{help:/^--?h(?:elp)?$/,version:/^--?ve?r?s?i?o?n?$/}};if(process.argv.forEach(s=>{var e,o,i;s.startsWith("-")&&(i=Object.keys(c.flags).find(e=>c.flags[e].test(s)),e=Object.keys(c.paramOptions).find(e=>c.paramOptions[e].test(s)),o=Object.keys(c.infoCmds).find(e=>c.infoCmds[e].test(s)),i?g[i]=!0:e?(/=.+/.test(s)||(console.error(`
8
- ${p}ERROR: Arg [--${s.replace(/-/g,"")}] requires '=' followed by a value.`),$(),process.exit(1)),i=s.split("=")[1],g[e]=parseInt(i)||i):o||(console.error(`
9
- ${p}ERROR: Arg [${s}] not recognized.`),console.info(`
10
- ${f}Valid arguments are below.`),v(["flags","paramOptions","infoCmds"]),process.exit(1)))}),process.argv.some(e=>c.infoCmds.help.test(e)))v();else if(process.argv.some(e=>c.infoCmds.version.test(e))){var S=o(`npm view ${i} version`).toString().trim()||"none";let e,s=process.cwd();for(;"/"!=s;){var l=m.join(s,"package.json");if(a.existsSync(l)){l=require(l);e=(l.dependencies?.[i]||l.devDependencies?.[i])?.match(/(\d+\.\d+\.\d+)/)[0]||"none";break}s=m.dirname(s)}console.info(`
11
- Global version: `+S),console.info("Local version: "+e)}else{let[c="",l=""]=process.argv.slice(2).filter(e=>!e.startsWith("-")).map(e=>e.replace(/^\/*/,"")),s=m.resolve(process.cwd(),c);c&&!a.existsSync(s)&&(S=s+".scss",a.existsSync(S)?s=S:(console.error(`
12
- ${p}Error: First argument can only be an existing file or directory.`+`
13
- '${s}' does not exist.`),console.info(`
14
- ${u}Example valid command:
15
- » scss-to-css . output.min.css`),$(),process.exit(1)));var y,S=s.endsWith(".scss")&&!a.statSync(s).isDirectory()?[s]:n.findSCSS(s,{recursive:!g.noRecursion,verbose:!g.quietMode,ignoreFiles:(g.ignoreFiles?.split(",")??[]).map(e=>e.trim())});if(g.dryRun)S.length?(console.info(`
16
- ${f}SCSS files to be compiled:`),S.forEach(e=>console.info(e))):console.info(f+`
17
- No SCSS files will be compiled.`);else{let o=[],e=[];g.cloneFolders&&a.statSync(s).isDirectory()?(y=n.compile(s,{verbose:!g.quietMode,minify:!g.noMinify,comment:g.comment?.replace(/\\n/g,"\n"),cloneFolders:!0,recursive:!g.noRecursion,dotFolders:!!g.includeDotFolders,sourceMaps:!g.noSourceMaps,ignoreFiles:g.ignoreFiles?g.ignoreFiles.split(",").map(e=>e.trim()):[]}),Array.isArray(y)?e=y:y&&y.error?o.push(s):y&&(e=[y])):e=S.map(e=>{var s=n.compile(e,{verbose:!g.quietMode,minify:!g.noMinify,sourceMaps:!g.noSourceMaps,comment:g.comment?.replace(/\\n/g,"\n")});return s.error&&o.push(e),s}).filter(e=>!e.error),e?.length?(y=1<e.length?"s":"",b(`
18
- ${u}Compilation complete!`),b(h+e.length+" CSS file"+y+(g.noSourceMaps?"":` + ${e.length} source map`+y)+" generated."+d)):b(`
19
- ${f}No SCSS files processed.`),o.length&&(b(`
20
- `+p+o.length+" file"+(1<o.length?"s":"")+" failed to compile:"),o.forEach(e=>b(e))),0==e?.length&&process.exit(0),g.copy&&1==e?.length?(console.log(`
21
- `+h+e[0].code+d),b("\nCopying to clipboard..."),t.writeSync(e[0].code)):(b(`
22
- Writing to file${1<e?.length?"s":""}...`),e?.forEach(({code:e,srcMap:s,srcPath:o,relPath:i})=>{let r,n;if(g.cloneFolders&&i&&l){let e=m.resolve(process.cwd(),l),s=m.dirname(i);r="."!=s?m.join(e,s):e,n=m.basename(o,".scss")+`${g.noMinify?"":".min"}.css`}else r=m.join(m.dirname(o),/(?:src|s[ac]ss)$/.test(m.dirname(o))?"../"+(l||"css"):l.endsWith(".css")?m.dirname(l):l||"css"),n=(l.endsWith(".css")&&c.endsWith(".scss")?m.basename(l).replace(/(\.min)?\.css$/,""):m.basename(o,".scss"))+".min.css";let t=m.join(r,n);a.existsSync(r)||a.mkdirSync(r,{recursive:!0}),a.writeFileSync(t,e,"utf8"),b(` ${u}✓ `+m.relative(process.cwd(),t)),g.noSourceMaps||a.writeFileSync(t+".map",JSON.stringify(s),"utf8"),b(` ${u}✓ `+m.relative(process.cwd(),t))}))}}function v(e=["header","usage","pathArgs","flags","paramOptions","infoCmds"]){var s=` ${i.replace(/^@[^/]+\//,"")}  `;let o={header:[`
23
- ├ `+s+"© 2024–2026 Adam Lui & contributors under the MIT license.",s+"Source: https://code.scsstocss.org/node.js"],usage:[`
24
- ${h}o Usage:`,` ${h}» `+u+"scss-to-css [inputPath] [outputPath] [options]"+d],pathArgs:[`
25
- ${h}o Path arguments:`," [inputPath] Path to SCSS file or directory containing SCSS files to be compiled, relative to the current working directory."," [outputPath] Path to file or directory where CSS + sourcemap files will be stored, relative to original file location (if not provided, css/ is used)."],flags:[`
26
- ${h}o Boolean options:`," -n, --dry-run Don't actually compile the file(s), just show if they will be processed."," -d, --include-dotfolders Include dotfolders in file search."," -S, --no-source-maps Prevent source maps from being generated."," -M, --no-minify Disable minification of output CSS."," -R, --no-recursion Disable recursive file searching."," -C, --clone-folders Preserve folder structure in output directory."," -c, --copy Copy compiled CSS to clipboard instead of writing to file if single source file is processed."," -q, --quiet Suppress all logging except errors."],paramOptions:[`
27
- ${h}o Parameter options:`,'--ignore-files="file1.scss,file2.scss" Files to exclude from compilation.',"--comment=\"comment\" Prepend header comment to compiled CSS. Separate by line using '\\n'."],infoCmds:[`
28
- ${h}o Info commands:`," -h, --help Display help screen."," -v, --version Show version number."]};e.forEach(t=>o[t]?.forEach(s=>{{var n=/header|usage/.test(t)?1:41;let o=process.stdout.columns||80,i=[],e=s.match(/\S+|\s+/g),r="";e.forEach(e=>{var s=o-(i.length?n:0);r.length+"| ".length+e.length>s&&(i.push(i.length?r.trimStart():r),r=""),r+=e}),i.push(i.length?r.trimStart():r),i.forEach((e,s)=>console.info("| "+(0==s?e:" ".repeat(n)+e)))}})),console.info("\nFor more help, please visit: "+h+r+d)}function $(){console.info(`
29
- For more help, type 'scss-to-css --help' or visit
30
- `+h+r+d)}function b(e){g.quietMode||console.info(e)}})();