create-stylelint 0.4.0 → 0.6.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.
Files changed (3) hide show
  1. package/README.md +4 -2
  2. package/package.json +32 -25
  3. package/src/index.mjs +134 -41
package/README.md CHANGED
@@ -3,11 +3,13 @@
3
3
  [![npm version](https://img.shields.io/npm/v/create-stylelint)](https://www.npmjs.com/package/create-stylelint)
4
4
  [![Testing](https://github.com/stylelint/create-stylelint/actions/workflows/testing.yml/badge.svg)](https://github.com/stylelint/create-stylelint/actions/workflows/testing.yml)
5
5
 
6
- The [`npm init`](https://docs.npmjs.com/cli/v9/commands/npm-init) script for [Stylelint](https://github.com/stylelint/stylelint).
6
+ The [`create`](https://docs.npmjs.com/cli/commands/npm-init) script for [Stylelint](https://github.com/stylelint/stylelint).
7
7
 
8
8
  ## Usage
9
9
 
10
- Run `npm init stylelint`
10
+ Run `npm create stylelint`
11
+
12
+ (Also compatible with the Bun, pnpm, and Yarn package managers.)
11
13
 
12
14
  ## Contributing
13
15
 
package/package.json CHANGED
@@ -1,16 +1,22 @@
1
1
  {
2
2
  "name": "create-stylelint",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "The npm init script for Stylelint.",
5
5
  "keywords": [
6
6
  "stylelint",
7
7
  "npm init"
8
8
  ],
9
9
  "repository": "stylelint/create-stylelint",
10
- "funding": {
11
- "type": "opencollective",
12
- "url": "https://opencollective.com/stylelint"
13
- },
10
+ "funding": [
11
+ {
12
+ "type": "opencollective",
13
+ "url": "https://opencollective.com/stylelint"
14
+ },
15
+ {
16
+ "type": "github",
17
+ "url": "https://github.com/sponsors/stylelint"
18
+ }
19
+ ],
14
20
  "license": "MIT",
15
21
  "author": "stylelint",
16
22
  "main": "create-stylelint.mjs",
@@ -24,7 +30,7 @@
24
30
  "format": "prettier . --write --cache",
25
31
  "lint": "npm-run-all --parallel --continue-on-error lint:*",
26
32
  "lint:formatting": "prettier . --check --cache",
27
- "lint:js": "eslint . --cache --max-warnings=0 --ext .js,.mjs",
33
+ "lint:js": "eslint",
28
34
  "lint:md": "remark . --quiet --frail",
29
35
  "lint:packagejson": "npmPkgJsonLint .",
30
36
  "lint:types": "tsc",
@@ -34,12 +40,6 @@
34
40
  "release": "np --no-release-draft"
35
41
  },
36
42
  "prettier": "@stylelint/prettier-config",
37
- "eslintConfig": {
38
- "extends": [
39
- "stylelint"
40
- ],
41
- "root": true
42
- },
43
43
  "npmpackagejsonlint": {
44
44
  "extends": "@stylelint/npm-package-json-lint-config"
45
45
  },
@@ -49,28 +49,35 @@
49
49
  ]
50
50
  },
51
51
  "dependencies": {
52
+ "@inquirer/confirm": "^5.1.16",
52
53
  "cosmiconfig": "^9.0.0",
53
- "execa": "^8.0.1",
54
- "ora": "^7.0.1",
55
- "picocolors": "^1.0.0",
56
- "semver": "^7.5.4",
54
+ "execa": "^9.6.0",
55
+ "ora": "^8.1.1",
56
+ "picocolors": "^1.1.1",
57
+ "semver": "^7.7.2",
57
58
  "strip-indent": "^4.0.0",
58
59
  "which-pm-runs": "^1.1.0"
59
60
  },
60
61
  "devDependencies": {
61
- "@stylelint/npm-package-json-lint-config": "^4.0.0",
62
+ "@stylelint/npm-package-json-lint-config": "^5.1.0",
62
63
  "@stylelint/prettier-config": "^3.0.0",
63
- "@stylelint/remark-preset": "^5.0.0",
64
+ "@stylelint/remark-preset": "^5.1.1",
64
65
  "@types/which-pm-runs": "^1.0.2",
65
- "eslint": "^8.55.0",
66
- "eslint-config-stylelint": "^20.0.0",
67
- "np": "^9.1.0",
66
+ "eslint": "^9.34.0",
67
+ "eslint-config-stylelint": "^25.0.0",
68
+ "np": "^10.2.0",
68
69
  "npm-run-all": "^4.1.5",
69
- "remark-cli": "^12.0.0",
70
- "typescript": "^5.3.3",
71
- "vitest": "^1.0.2"
70
+ "prettier": "^3.6.2",
71
+ "remark-cli": "^12.0.1",
72
+ "typescript": "^5.9.2",
73
+ "vitest": "^3.2.4"
74
+ },
75
+ "optionalDependencies": {
76
+ "@rollup/rollup-darwin-x64": "*",
77
+ "@rollup/rollup-linux-x64-gnu": "*",
78
+ "@rollup/rollup-win32-x64-msvc": "*"
72
79
  },
73
80
  "engines": {
74
- "node": ">=18.12.0"
81
+ "node": ">=20.19.0"
75
82
  }
76
83
  }
package/src/index.mjs CHANGED
@@ -5,19 +5,27 @@ import * as fs from 'node:fs';
5
5
  import * as path from 'node:path';
6
6
  import process from 'node:process';
7
7
 
8
- import { cosmiconfigSync } from 'cosmiconfig';
8
+ import confirm from '@inquirer/confirm';
9
+ import { cosmiconfig } from 'cosmiconfig';
9
10
  import detectPackageManager from 'which-pm-runs';
10
11
  import { execa } from 'execa';
11
12
  import ora from 'ora';
12
- import picocolors from 'picocolors';
13
+ import pc from 'picocolors';
13
14
  import stripIndent from 'strip-indent';
14
15
 
15
- const DEFAULT_CONFIG_FILE = '.stylelintrc.json';
16
+ const DEFAULT_CONFIG_FILE = 'stylelint.config.mjs';
17
+ const DEFAULT_CONFIG_CONTENT = `/** @type {import("stylelint").Config} */
18
+ export default {
19
+ "extends": ["stylelint-config-standard"]
20
+ };`;
16
21
 
17
- function getExistingConfigInDirectory() {
18
- const explorer = cosmiconfigSync('stylelint');
22
+ const ADD_COMMAND = 'add -D stylelint stylelint-config-standard';
19
23
 
20
- return explorer.search();
24
+ async function getExistingConfigInDirectory() {
25
+ const explorer = cosmiconfig('stylelint');
26
+ const result = await explorer.search();
27
+
28
+ return result;
21
29
  }
22
30
 
23
31
  /**
@@ -27,78 +35,162 @@ function directoryHasPackageJson(dir) {
27
35
  return fs.readdirSync(dir).some((file) => file === 'package.json');
28
36
  }
29
37
 
38
+ /**
39
+ * @param {string} pkgManager
40
+ * @return {string} The command
41
+ */
42
+ function getExecuteCommand(pkgManager) {
43
+ switch (pkgManager) {
44
+ case 'npm':
45
+ return 'npx';
46
+ case 'bun':
47
+ return 'bunx';
48
+ case 'pnpm':
49
+ case 'yarn':
50
+ return `${pkgManager} dlx`;
51
+ default:
52
+ throw new Error(`"${pkgManager}" package manager is not supported`);
53
+ }
54
+ }
55
+
56
+ /**
57
+ * @param {string} errorMessage
58
+ */
59
+ function cancelSetup(errorMessage = '') {
60
+ console.error(
61
+ stripIndent(`
62
+ ${pc.red(pc.bold('Setup canceled!'))}
63
+ `),
64
+ );
65
+
66
+ if (errorMessage) {
67
+ console.error(
68
+ stripIndent(`${errorMessage}
69
+ `),
70
+ );
71
+ }
72
+
73
+ process.exit(1);
74
+ }
75
+
30
76
  /**
31
77
  * @param {string} pkgManager
32
78
  */
33
- function getInstallCommand(pkgManager) {
34
- return pkgManager === 'npm' ? 'install' : 'add';
79
+ async function showPrompt(pkgManager) {
80
+ console.info(
81
+ stripIndent(`
82
+ We'll create a ${pc.cyan(DEFAULT_CONFIG_FILE)} file containing:
83
+ `),
84
+ );
85
+
86
+ console.info(
87
+ pc.dim(
88
+ DEFAULT_CONFIG_CONTENT.split('\n')
89
+ .map((line) => ` ${line}`)
90
+ .join('\n'),
91
+ ),
92
+ );
93
+
94
+ console.info(
95
+ stripIndent(`
96
+ Then add the related dependencies using:
97
+
98
+ ${pc.dim(`${pkgManager} ${ADD_COMMAND}`)}
99
+ `),
100
+ );
101
+
102
+ let proceed;
103
+
104
+ try {
105
+ proceed = await confirm({
106
+ message: 'Continue?',
107
+ });
108
+ } catch (error) {
109
+ if (error instanceof Error && error.name === 'ExitPromptError') {
110
+ // silence
111
+ } else {
112
+ throw error;
113
+ }
114
+ }
115
+
116
+ if (!proceed) {
117
+ cancelSetup();
118
+ }
35
119
  }
36
120
 
37
121
  /**
38
122
  * @param {string} cwd
39
123
  * @param {string} pkgManager
40
124
  */
41
- function createConfig(cwd, pkgManager) {
125
+ async function createConfig(cwd, pkgManager) {
42
126
  const spinner = ora('Creating config...').start();
43
- const existingConfig = getExistingConfigInDirectory();
127
+ const existingConfig = await getExistingConfigInDirectory();
44
128
 
45
129
  if (existingConfig !== null) {
46
130
  const basename = path.basename(existingConfig.filepath);
47
131
  const failureMessage =
48
132
  basename === 'package.json'
49
- ? 'The "stylelint" config in "package.json" already exists.'
50
- : `The "${basename}" config already exists.`;
133
+ ? 'A "stylelint" config in "package.json" already exists.'
134
+ : `A "${basename}" config already exists.`;
51
135
 
52
- spinner.fail(`Failed to create config:\n${failureMessage} Remove it and then try again.`);
53
- process.exit(1);
136
+ spinner.fail();
137
+ cancelSetup(`${failureMessage} Remove it and then try again.`);
54
138
  }
55
139
 
56
140
  if (!directoryHasPackageJson(cwd)) {
57
- spinner.fail(
58
- `Failed to create config:\npackage.json was not found. Run "${pkgManager} init" and then try again.`,
59
- );
60
- process.exit(1);
141
+ spinner.fail();
142
+ cancelSetup(`A "package.json" was not found. Run "${pkgManager} init" and then try again.`);
61
143
  }
62
144
 
63
145
  try {
64
- fs.writeFileSync(DEFAULT_CONFIG_FILE, '{ "extends": ["stylelint-config-standard"] }');
146
+ fs.writeFileSync(DEFAULT_CONFIG_FILE, `${DEFAULT_CONFIG_CONTENT}\n`);
65
147
  } catch (error) {
66
- spinner.fail(`Failed to create config:\n${error}`);
67
- process.exit(1);
148
+ spinner.fail();
149
+ cancelSetup(error instanceof Error ? error.message : String(error));
68
150
  }
69
151
 
70
- spinner.succeed(`Created ${DEFAULT_CONFIG_FILE}.`);
152
+ spinner.succeed('Created config file');
71
153
  }
72
154
 
73
155
  /**
74
156
  * @param {string} cwd
75
157
  * @param {string} pkgManager
76
158
  */
77
- async function installPackages(cwd, pkgManager) {
78
- const spinner = ora('Installing packages...').start();
159
+ async function addDependencies(cwd, pkgManager) {
160
+ const spinner = ora('Adding dependencies...').start();
79
161
 
80
162
  try {
81
- await execa(
82
- pkgManager,
83
- [`${getInstallCommand(pkgManager)}`, '-D', 'stylelint', 'stylelint-config-standard'],
84
- { cwd },
85
- );
163
+ await execa(pkgManager, [...ADD_COMMAND.split(' ')], {
164
+ cwd,
165
+ });
86
166
  } catch (error) {
87
- spinner.fail(`Failed to install packages:\n${error}`);
88
- process.exit(1);
167
+ spinner.fail();
168
+ cancelSetup(error instanceof Error ? error.message : String(error));
89
169
  }
90
170
 
91
- spinner.succeed('Installed packages.');
171
+ spinner.succeed('Added dependencies');
92
172
  }
93
173
 
94
- function showNextSteps() {
95
- console.log(
174
+ /**
175
+ * @param {string} pkgManager
176
+ */
177
+ function showNextSteps(pkgManager) {
178
+ console.info(
96
179
  stripIndent(`
97
- ${picocolors.green(`You can now lint your CSS files using:
98
- npx stylelint "**/*.css"`)}
180
+ ${pc.green(pc.bold('Setup complete!'))}
181
+
182
+ Lint your CSS files with:
183
+
184
+ ${pc.dim(`${getExecuteCommand(pkgManager)} stylelint "**/*.css"`)}
185
+
186
+ Next steps? Customize your config: ${pc.underline(
187
+ pc.blue('https://stylelint.io/user-guide/customize'),
188
+ )}
189
+
190
+ If you benefit from Stylelint, please consider sponsoring the project at:
99
191
 
100
- ${picocolors.dim(`We recommend customizing Stylelint:
101
- https://stylelint.io/user-guide/customize/`)}
192
+ - ${pc.underline(pc.blue('https://github.com/sponsors/stylelint'))}
193
+ - ${pc.underline(pc.blue('https://opencollective.com/stylelint'))}
102
194
  `),
103
195
  );
104
196
  }
@@ -107,7 +199,8 @@ export async function main() {
107
199
  const pkgManager = detectPackageManager()?.name ?? 'npm';
108
200
  const cwd = './';
109
201
 
110
- createConfig(cwd, pkgManager);
111
- await installPackages(cwd, pkgManager);
112
- showNextSteps();
202
+ await showPrompt(pkgManager);
203
+ await createConfig(cwd, pkgManager);
204
+ await addDependencies(cwd, pkgManager);
205
+ showNextSteps(pkgManager);
113
206
  }