@kitschpatrol/stylelint-config 7.1.0 → 7.2.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/bin/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{cosmiconfig as e}from"cosmiconfig";import{TypeScriptLoader as t}from"cosmiconfig-typescript-loader";import{execa as n}from"execa";import r from"fs-extra";import i from"node:fs";import a from"node:path";import{PassThrough as o,Transform as s}from"node:stream";import{fileURLToPath as c}from"node:url";import{packageUp as l,packageUpSync as u}from"package-up";import d from"picocolors";import f from"yargs";import{hideBin as p}from"yargs/helpers";import m from"@pinojs/json-colorizer";import h from"decircular";import g from"deepmerge";import _ from"json-stringify-pretty-compact";import{findWorkspacesRoot as v}from"find-workspaces";import y from"node:fs/promises";import{stripVTControlCharacters as b}from"node:util";import x from"stylelint";var S=`7.1.0`;function C(e){return e instanceof Error&&`exitCode`in e&&typeof e.exitCode==`number`}function w(e){return m(_(h(e),{indent:2,replacer(e,t){return typeof t==`function`?t.name:t}}),{colors:{BRACKET:`gray`}})}const T=(e,t,n)=>{let r=[...e];for(let[i,a]of t.entries())r[i]===void 0?r[i]=n.cloneUnlessOtherwiseSpecified(a,n):n.isMergeableObject(a)?r[i]=E(e[i],a,n):e.includes(a)||r.push(a);return r};function E(e,t,n={arrayMerge:T}){return g(e,t,n)}function D(){let e=u();if(e===void 0)throw Error(`No package.json found.`);return a.dirname(e)}function O(){let e=v();return e===null?D():a.resolve(e.location)}function k(e){let t=a.join(O(),e);if(r.existsSync(t))return t}function A(e){if(e===`workspace-root`)return O();if(e===`package-dir`)return D();if(typeof e==`string`){if(!r.pathExistsSync(e))throw Error(`Custom cwd directory does not exist: ${e}`);return e}return process.cwd()}async function j(e,t){try{let{default:n}=await import(`prettier`),r=await n.resolveConfig(e),i=await n.format(t,{filepath:e,...r});await y.writeFile(e,i,`utf8`)}catch{console.warn(`Skipped formatting ${e} since Prettier is not installed.`)}}async function M(e){try{await j(e,await y.readFile(e,`utf8`))}catch{}}const N=/\r?\n/;function P(e){return new s({transform(t,n,r){let i=t.toString().split(N).filter(t=>t.trim()!==``&&!e(b(t))).join(`
2
+ import{cosmiconfig as e}from"cosmiconfig";import{TypeScriptLoader as t}from"cosmiconfig-typescript-loader";import{execa as n}from"execa";import r from"fs-extra";import i from"node:fs";import a from"node:path";import{PassThrough as o,Transform as s}from"node:stream";import{fileURLToPath as c}from"node:url";import{packageUp as l,packageUpSync as u}from"package-up";import d from"picocolors";import f from"yargs";import{hideBin as p}from"yargs/helpers";import m from"@pinojs/json-colorizer";import h from"decircular";import g from"deepmerge";import _ from"json-stringify-pretty-compact";import{findWorkspacesRoot as v}from"find-workspaces";import y from"node:fs/promises";import{stripVTControlCharacters as b}from"node:util";import x from"stylelint";var S=`7.2.0`;function C(e){return e instanceof Error&&`exitCode`in e&&typeof e.exitCode==`number`}function w(e){return m(_(h(e),{indent:2,replacer(e,t){return typeof t==`function`?t.name:t}}),{colors:{BRACKET:`gray`}})}const T=(e,t,n)=>{let r=[...e];for(let[i,a]of t.entries())r[i]===void 0?r[i]=n.cloneUnlessOtherwiseSpecified(a,n):n.isMergeableObject(a)?r[i]=E(e[i],a,n):e.includes(a)||r.push(a);return r};function E(e,t,n={arrayMerge:T}){return g(e,t,n)}function D(){let e=u();if(e===void 0)throw Error(`No package.json found.`);return a.dirname(e)}function O(){let e=v();return e===null?D():a.resolve(e.location)}function k(e){let t=a.join(O(),e);if(r.existsSync(t))return t}function A(e){if(e===`workspace-root`)return O();if(e===`package-dir`)return D();if(typeof e==`string`){if(!r.pathExistsSync(e))throw Error(`Custom cwd directory does not exist: ${e}`);return e}return process.cwd()}async function j(e,t){try{let{default:n}=await import(`prettier`),r=await n.resolveConfig(e),i=await n.format(t,{filepath:e,...r});await y.writeFile(e,i,`utf8`)}catch{console.warn(`Skipped formatting ${e} since Prettier is not installed.`)}}async function M(e){try{await j(e,await y.readFile(e,`utf8`))}catch{}}const N=/\r?\n/;function P(e){return new s({transform(t,n,r){let i=t.toString().split(N).filter(t=>t.trim()!==``&&!e(b(t))).join(`
3
3
  `);this.push(i+`
4
4
  `),r()}})}function F(e,t){return new s({transform(n,r,i){let a=n.toString().split(N).filter(e=>e.trim().length>0).map(n=>`${e?t===void 0?e:d[t](e):``} ${n}\n`).join(``);this.push(a),i()}})}async function I(e){let t=[];return new Promise((n,r)=>{e.on(`data`,e=>t.push(e)),e.on(`error`,e=>{r(e)}),e.on(`end`,()=>{n(Buffer.concat(t).toString(`utf8`))})})}function L(e,t){return t===1?e:e+`s`}async function R(e,t,n,r,i){let a=1,o;if(r.logPrefix===void 0)o=e;else{let t=F(r.logPrefix,r.logColor);t.pipe(e),o=t}i&&o.write(d.bold(`Running: "${r.name}() with Positional arguments: ${String(t)} and Option flags: ${String(n)}"`));try{a=await r.execute(o,t,n)}catch(e){console.error(String(e)),a=1}return a}async function z(e,t,r,i,a){let s=1,c;if(i.logPrefix===void 0)c=e;else{let t=F(i.logPrefix,i.logColor);t.pipe(e),c=t}let l=i.subcommands??[],u=[...i.receivePositionalArguments?t:[],...i.positionalArguments??[]],d=[...i.receiveOptionFlags?r:[],...i.optionFlags??[]],f=[...l,...d,...u],p=A(i.cwdOverride);a&&c.write(`Running: "${i.name} ${f.join(` `)}"`);let m=i.prettyJsonOutput?new o:c;try{let e=n(i.name,f,{cwd:p,env:{...process.env.NO_COLOR===void 0?{FORCE_COLOR:`true`}:{}},preferLocal:!0,reject:!1,stdin:`inherit`});if(i.outputFilter){let t=P(i.outputFilter),n=P(i.outputFilter);e.stdout.pipe(t).pipe(m,{end:!1}),e.stderr.pipe(n).pipe(m,{end:!1})}else e.stdout.pipe(m,{end:!1}),e.stderr.pipe(m,{end:!1});if(await e,i.prettyJsonOutput){m.end();let e=await I(m),t=w(JSON.parse(e)).split(`
5
5
  `);for(let e of t)c.write(`${e}\n`)}s=e.exitCode??1}catch(e){console.error(`${i.name} failed with error:`),console.error(e),C(e)&&(s=typeof e.exitCode==`number`?e.exitCode:1)}return s}function B(e){return`execute`in e}const V=/^ksc-/;function H(e){return e.replace(V,``)}function U(e){return e===void 0||e.length===0?[]:e.flatMap(e=>e.split(`,`)).map(e=>H(e.trim()))}function W(e){return e.option(`skip`,{array:!0,describe:`Tool names to skip (with or without "ksc-" prefix).`,type:`string`})}async function G(e,t,n,r,i,a,o){let s=o??[],c=[],l=[];for(let e of r)s.length>0&&s.includes(H(e.name))?l.push(e):c.push(e);if(s.length>0){let t=new Set(l.map(e=>H(e.name))),n=s.filter(e=>!t.has(e));if(n.length>0){let t=r.map(e=>H(e.name)).join(`, `);e.write(`⚠️ ${d.yellow(`Unrecognized --skip ${L(`value`,n.length)}: ${n.join(`, `)}. Available: ${t}`)}\n`)}}let u=[];for(let r of c){let a=await(B(r)?R(e,t,n,r,i):z(e,t,n,r,i));u.push({exitCode:a,name:r.name})}let f=r.length;if(l.length>0){let t=l.map(({name:e})=>e);e.write(`⏭️ ${d.dim(d.bold(`${t.length} / ${f} ${L(`Command`,t.length)} Skipped:`))} ${d.dim(t.join(`, `))}\n`)}if(a){let t=u.filter(({exitCode:e})=>e===0).map(({name:e})=>e),n=u.filter(({exitCode:e})=>e!==0).map(({name:e})=>e);t.length>0&&e.write(`✅ ${d.green(d.bold(`${t.length} / ${f} ${L(`Command`,t.length)} Succeeded:`))} ${d.green(t.join(`, `))}\n`),n.length>0&&e.write(`❌ ${d.red(d.bold(`${n.length} / ${f} ${L(`Command`,n.length)} Failed:`))} ${d.red(n.join(`, `))}\n`)}return u.every(({exitCode:e})=>e===0)?0:1}async function K(e,t,n,o){let s=await l();if(s===void 0)throw Error("The `init` command must be used in a directory with a package.json file");let u=await l({cwd:c(import.meta.url)});if(u===void 0)return e.write(`Error: The script being called was not in a package, weird.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { Config } from "stylelint";
1
+ import { Config, Config as StylelintConfig } from "stylelint";
2
2
 
3
- //#region src/index.d.ts
3
+ //#region src/config.d.ts
4
4
  declare const sharedStylelintConfig: Config;
5
5
  /**
6
6
  * **@Kitschpatrol's Shared Stylelint Configuration**
@@ -22,4 +22,38 @@ declare const sharedStylelintConfig: Config;
22
22
  */
23
23
  declare function stylelintConfig(config?: Config): Config;
24
24
  //#endregion
25
- export { sharedStylelintConfig as default, stylelintConfig };
25
+ //#region src/api.d.ts
26
+ /**
27
+ * File extension or filepath hint for syntax inference. Accepts a bare
28
+ * extension (e.g. `'scss'`), a virtual filename (e.g. `'file.scss'`), or a full
29
+ * path. Known extensions supported by the default shared config are offered as
30
+ * autocomplete suggestions.
31
+ */
32
+ type FileType = 'astro' | 'css' | 'html' | 'jsx' | 'php' | 'sass' | 'scss' | 'svelte' | 'tsx' | 'vue' | (string & {});
33
+ /**
34
+ * Lint and fix a CSS source string using the shared Stylelint configuration.
35
+ *
36
+ * @param source - The CSS source code to lint and fix.
37
+ * @param fileTypeOrConfig - A file extension (e.g. `'scss'`), virtual filepath
38
+ * (e.g. `'file.scss'`), or a `StylelintConfig` object for overrides. Defaults
39
+ * to `'css'`.
40
+ * @param config - Optional `StylelintConfig` overrides when a file type is
41
+ * provided as the second argument.
42
+ *
43
+ * @returns The fixed CSS source string.
44
+ */
45
+ declare function fix(source: string, fileTypeOrConfig?: FileType | StylelintConfig, config?: StylelintConfig): Promise<string>;
46
+ /**
47
+ * Lint and fix a CSS file in place using the shared Stylelint configuration.
48
+ *
49
+ * @param filePath - Path to the file to lint and fix.
50
+ * @param config - Optional `StylelintConfig` overrides.
51
+ */
52
+ declare function fixFile(filePath: string, config?: StylelintConfig): Promise<void>;
53
+ /**
54
+ * Clear the cached Stylelint module. Subsequent calls to `fix` or `fixFile`
55
+ * will re-import Stylelint.
56
+ */
57
+ declare function clearCache(): void;
58
+ //#endregion
59
+ export { type FileType, type StylelintConfig, clearCache, sharedStylelintConfig as default, sharedStylelintConfig, fix, fixFile, stylelintConfig };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{propertyGroups as e}from"stylelint-config-clean-order";const t=e.map(e=>({emptyLineBefore:`never`,noEmptyLineBetween:!0,properties:e})),n={extends:[`stylelint-config-standard`,`stylelint-config-clean-order`,`stylelint-config-html`],overrides:[{files:[`*.astro`],rules:{"no-empty-source":null}}],rules:{"color-hex-length":null,"comment-empty-line-before":null,"declaration-empty-line-before":null,"order/properties-order":[t,{severity:`error`,unspecified:`bottomAlphabetical`}],"selector-class-pattern":null,"selector-pseudo-class-no-unknown":[!0,{ignorePseudoClasses:[`global`]}]}};function r(e){return{extends:`@kitschpatrol/stylelint-config`,...e}}export{n as default,r as stylelintConfig};
1
+ import e from"node:fs/promises";import t from"node:path";import{propertyGroups as n}from"stylelint-config-clean-order";const r=n.map(e=>({emptyLineBefore:`never`,noEmptyLineBetween:!0,properties:e})),i={extends:[`stylelint-config-standard`,`stylelint-config-clean-order`,`stylelint-config-html`],overrides:[{files:[`*.astro`],rules:{"no-empty-source":null}}],rules:{"color-hex-length":null,"comment-empty-line-before":null,"declaration-empty-line-before":null,"order/properties-order":[r,{severity:`error`,unspecified:`bottomAlphabetical`}],"selector-class-pattern":null,"selector-pseudo-class-no-unknown":[!0,{ignorePseudoClasses:[`global`]}]}};function a(e){return{extends:`@kitschpatrol/stylelint-config`,...e}}const o=/[./\\]/;function s(e){return o.test(e)?e:`file.${e}`}let c;async function l(){return c||=(await import(`stylelint`)).default,c}async function u(e,t,n){let r=`file.css`,a=n;typeof t==`string`?r=s(t):t!==void 0&&(a=t);let{lint:o}=await l();return(await o({code:e,codeFilename:r,config:a?{...i,...a,rules:{...i.rules,...a.rules}}:i,fix:!0})).code??e}async function d(n,r){let a=await e.readFile(n,`utf8`),{lint:o}=await l(),s=await o({code:a,codeFilename:t.basename(n),config:r?{...i,...r,rules:{...i.rules,...r.rules}}:i,fix:!0});s.code!==void 0&&await e.writeFile(n,s.code,`utf8`)}function f(){c=void 0}export{f as clearCache,i as default,i as sharedStylelintConfig,u as fix,d as fixFile,a as stylelintConfig};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitschpatrol/stylelint-config",
3
- "version": "7.1.0",
3
+ "version": "7.2.0",
4
4
  "description": "Stylelint configuration for @kitschpatrol/shared-config.",
5
5
  "keywords": [
6
6
  "stylelint-config",
@@ -67,6 +67,7 @@
67
67
  },
68
68
  "scripts": {
69
69
  "build": "tsdown",
70
- "cli": "node ./bin/cli.js"
70
+ "cli": "node ./bin/cli.js",
71
+ "test": "vitest run"
71
72
  }
72
73
  }
package/readme.md CHANGED
@@ -225,6 +225,36 @@ ksc-stylelint print-config [file]
225
225
 
226
226
  <!-- /cli-help -->
227
227
 
228
+ ### API
229
+
230
+ The package also exports `fix`, `fixFile` functions for linting and fixing CSS programmatically, pre-configured with the shared Stylelint configuration.
231
+
232
+ ```typescript
233
+ import { clearCache, fix, fixFile } from '@kitschpatrol/stylelint-config'
234
+
235
+ // Fix a CSS string
236
+ const fixed = await fix('a { color: rgb(0, 0, 0); }\n')
237
+
238
+ // Fix with a bare file extension for syntax inference
239
+ const scss = await fix(source, 'scss')
240
+
241
+ // Fix with config overrides
242
+ const withOverrides = await fix(source, { rules: { 'color-hex-length': 'long' } })
243
+
244
+ // Both file type and config overrides
245
+ const both = await fix(source, 'scss', { rules: { 'color-hex-length': 'long' } })
246
+
247
+ // Fix a file in place
248
+ await fixFile('./src/styles.css')
249
+
250
+ // Clear cached Stylelint module
251
+ clearCache()
252
+ ```
253
+
254
+ Config is resolved in priority order: shared defaults < per-call overrides.
255
+
256
+ The Stylelint module is cached internally for performance across multiple calls. Use `clearCache()` to force re-initialization.
257
+
228
258
  <!-- license -->
229
259
 
230
260
  ## License