@plumeria/eslint-plugin 19.10.1 → 19.10.3

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/README.md CHANGED
@@ -34,12 +34,14 @@ export default [plumeria.configs.recommended];
34
34
 
35
35
  ## Configuring the styling prop
36
36
 
37
- Both `custom-props-require-import` and `no-mixed-styling-props` need to know which JSX
37
+ `custom-props-require-import`, `no-inline-object`, `no-mixed-styling-props`,
38
+ `no-style-prop-relay` and `no-unresolved-composition` need to know which JSX
38
39
  prop carries styles. It is `classStyle` unless you changed it, so most projects
39
40
  configure nothing.
40
41
 
41
42
  If you did rename it — via `styleProp` on `withPlumeria` or on the unplugin
42
- options — tell the plugin the same name. ESLint cannot read it from your bundler
43
+ options — tell the plugin the same name. The lint the bundler plugins run in the
44
+ build is given that name already. ESLint cannot read it from your bundler
43
45
  config, so set it once in `settings` and every rule picks it up:
44
46
 
45
47
  ```js
@@ -257,6 +259,16 @@ plumerialint
257
259
  The process exits with a non-zero status code if any errors or warnings are found,
258
260
  making it suitable for use in CI and build pipelines.
259
261
 
262
+ ### Styling prop
263
+
264
+ If the styling prop is renamed, pass the name with `--style-prop`. Without the
265
+ flag, `plumerialint` asks ESLint for `settings.plumeria.styleProp` when ESLint
266
+ and a flat config are installed, and uses `classStyle` otherwise:
267
+
268
+ ```bash
269
+ plumerialint --style-prop sx
270
+ ```
271
+
260
272
  ### Aborting Builds on Lint Errors (Parallel Pipeline)
261
273
 
262
274
  You can run `plumerialint` in parallel with your build command (e.g. `next build` or `vite build`) using the `--` separator:
package/bin/oxlint.js CHANGED
@@ -3,6 +3,7 @@
3
3
  const { spawn } = require('child_process');
4
4
  const process = require('process');
5
5
  const path = require('path');
6
+ const fs = require('fs');
6
7
  const oxlintConfig = path.join(__dirname, '..', 'oxlint.json');
7
8
  const oxlintBin = path.join(
8
9
  path.dirname(require.resolve('oxlint/package.json')),
@@ -10,49 +11,73 @@ const oxlintBin = path.join(
10
11
  'oxlint',
11
12
  );
12
13
 
14
+ const { cliOverrides } = require('../dist/cli.js');
15
+ const { lintConfig, lowerPriority } = require('../dist/guard.js');
16
+
13
17
  const doubleDashIndex = process.argv.indexOf('--');
14
- let oxlintExtraArgs = [];
18
+ let cliArgs = [];
15
19
  let buildCommand = null;
16
20
  let buildArgs = [];
17
21
 
18
22
  if (doubleDashIndex !== -1) {
19
- oxlintExtraArgs = process.argv.slice(2, doubleDashIndex);
23
+ cliArgs = process.argv.slice(2, doubleDashIndex);
20
24
  if (doubleDashIndex + 1 < process.argv.length) {
21
25
  buildCommand = process.argv[doubleDashIndex + 1];
22
26
  buildArgs = process.argv.slice(doubleDashIndex + 2);
23
27
  }
24
28
  } else {
25
- oxlintExtraArgs = process.argv.slice(2);
29
+ cliArgs = process.argv.slice(2);
26
30
  }
27
31
 
28
- const oxlintArgs = [
29
- oxlintBin,
30
- '-c',
31
- oxlintConfig,
32
- '--deny-warnings',
33
- '--no-error-on-unmatched-pattern',
34
- ...oxlintExtraArgs,
35
- ];
32
+ async function startOxlint() {
33
+ const { overrides, rest } = await cliOverrides(cliArgs, process.cwd());
34
+ const config = lintConfig(overrides);
35
+ const child = spawn(
36
+ process.execPath,
37
+ [
38
+ oxlintBin,
39
+ '-c',
40
+ config,
41
+ '--deny-warnings',
42
+ '--no-error-on-unmatched-pattern',
43
+ ...(rest.some((arg) => arg.startsWith('--threads'))
44
+ ? []
45
+ : ['--threads=2']),
46
+ ...rest,
47
+ ],
48
+ { stdio: 'inherit' },
49
+ );
50
+ lowerPriority(child.pid);
51
+ if (config !== oxlintConfig) {
52
+ child.on('close', () => fs.rmSync(config, { force: true }));
53
+ }
54
+ return child;
55
+ }
36
56
 
37
57
  function handleOxlintError(err) {
38
58
  console.error('Error running oxlint:', err.message);
39
59
  process.exit(1);
40
60
  }
41
61
 
62
+ function fail(err) {
63
+ console.error(`✖ [plumerialint] ${err.message}`);
64
+ process.exit(1);
65
+ }
66
+
42
67
  if (!buildCommand) {
43
- const child = spawn(process.execPath, oxlintArgs, { stdio: 'inherit' });
44
- child.on('error', handleOxlintError);
45
- child.on('close', (code) => {
46
- process.exit(code || 0);
47
- });
68
+ startOxlint().then((child) => {
69
+ child.on('error', handleOxlintError);
70
+ child.on('close', (code) => {
71
+ process.exit(code || 0);
72
+ });
73
+ }, fail);
48
74
  } else {
49
75
  let oxlintExited = false;
50
76
  let oxlintCode = null;
51
77
  let buildExited = false;
52
78
  let buildCode = null;
53
79
  let aborted = false;
54
-
55
- const oxlintChild = spawn(process.execPath, oxlintArgs, { stdio: 'inherit' });
80
+ let oxlintChild = null;
56
81
 
57
82
  const fullBuildCommand =
58
83
  buildArgs.length > 0
@@ -78,16 +103,12 @@ if (!buildCommand) {
78
103
  } else if (failedSource === 'build') {
79
104
  console.error(`\n✖ [plumerialint] Build failed. Aborting lint...`);
80
105
  try {
81
- oxlintChild.kill();
106
+ if (oxlintChild) oxlintChild.kill();
82
107
  } catch (e) {}
83
108
  process.exit(exitCode || 1);
84
109
  }
85
110
  }
86
111
 
87
- oxlintChild.on('error', (err) => {
88
- handleOxlintError(err);
89
- });
90
-
91
112
  buildChild.on('error', (err) => {
92
113
  console.error(
93
114
  `Error running build command "${buildCommand}":`,
@@ -96,16 +117,6 @@ if (!buildCommand) {
96
117
  abort(1, 'build');
97
118
  });
98
119
 
99
- oxlintChild.on('close', (code) => {
100
- oxlintExited = true;
101
- oxlintCode = code;
102
- if (code !== 0) {
103
- abort(code, 'lint');
104
- } else if (buildExited) {
105
- process.exit(buildCode || 0);
106
- }
107
- });
108
-
109
120
  buildChild.on('close', (code) => {
110
121
  buildExited = true;
111
122
  buildCode = code;
@@ -115,4 +126,22 @@ if (!buildCommand) {
115
126
  process.exit(oxlintCode || 0);
116
127
  }
117
128
  });
129
+
130
+ startOxlint().then((child) => {
131
+ if (aborted) {
132
+ child.kill();
133
+ return;
134
+ }
135
+ oxlintChild = child;
136
+ child.on('error', handleOxlintError);
137
+ child.on('close', (code) => {
138
+ oxlintExited = true;
139
+ oxlintCode = code;
140
+ if (code !== 0) {
141
+ abort(code, 'lint');
142
+ } else if (buildExited) {
143
+ process.exit(buildCode || 0);
144
+ }
145
+ });
146
+ }, fail);
118
147
  }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { type LintOverrides } from './guard';
2
+ export declare function takeStyleProp(args: string[]): {
3
+ styleProp?: string;
4
+ rest: string[];
5
+ };
6
+ export declare function stylePropFromESLint(cwd: string): Promise<string | undefined>;
7
+ export declare function cliOverrides(args: string[], cwd: string): Promise<{
8
+ overrides: LintOverrides;
9
+ rest: string[];
10
+ }>;
package/dist/cli.js ADDED
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.takeStyleProp = takeStyleProp;
37
+ exports.stylePropFromESLint = stylePropFromESLint;
38
+ exports.cliOverrides = cliOverrides;
39
+ const path = __importStar(require("path"));
40
+ const guard_1 = require("./guard");
41
+ const STYLE_PROP_FLAG = '--style-prop';
42
+ const PROBED_FILES = ['src/index.tsx', 'app/page.tsx', 'index.tsx', 'index.js'];
43
+ function takeStyleProp(args) {
44
+ const rest = [];
45
+ let styleProp;
46
+ for (let i = 0; i < args.length; i++) {
47
+ const arg = args[i];
48
+ if (arg === STYLE_PROP_FLAG) {
49
+ styleProp = args[++i];
50
+ if (!styleProp)
51
+ throw new Error(`${STYLE_PROP_FLAG} needs a prop name`);
52
+ }
53
+ else if (arg.startsWith(`${STYLE_PROP_FLAG}=`)) {
54
+ styleProp = arg.slice(STYLE_PROP_FLAG.length + 1);
55
+ if (!styleProp)
56
+ throw new Error(`${STYLE_PROP_FLAG} needs a prop name`);
57
+ }
58
+ else {
59
+ rest.push(arg);
60
+ }
61
+ }
62
+ return { styleProp, rest };
63
+ }
64
+ async function stylePropFromESLint(cwd) {
65
+ let eslint;
66
+ try {
67
+ eslint = require(require.resolve('eslint', { paths: [cwd] }));
68
+ }
69
+ catch {
70
+ return undefined;
71
+ }
72
+ try {
73
+ const ESLint = eslint.loadESLint
74
+ ? await eslint.loadESLint({ useFlatConfig: true })
75
+ : eslint.ESLint;
76
+ const instance = new ESLint({ cwd });
77
+ for (const file of PROBED_FILES) {
78
+ const config = (await instance.calculateConfigForFile(path.join(cwd, file)));
79
+ const styleProp = config?.settings?.plumeria?.styleProp;
80
+ if (typeof styleProp === 'string')
81
+ return styleProp;
82
+ }
83
+ }
84
+ catch {
85
+ return undefined;
86
+ }
87
+ return undefined;
88
+ }
89
+ async function cliOverrides(args, cwd) {
90
+ const { styleProp, rest } = takeStyleProp(args);
91
+ return {
92
+ overrides: (0, guard_1.lintOverrides)({
93
+ styleProp: styleProp ?? (await stylePropFromESLint(cwd)),
94
+ }),
95
+ rest,
96
+ };
97
+ }
package/dist/guard.d.ts CHANGED
@@ -1,10 +1,21 @@
1
1
  type Spelling = boolean | {
2
2
  sizes?: boolean;
3
3
  } | undefined;
4
- interface SpellingOptions {
4
+ interface LintOptions {
5
5
  withoutLogicalProperties?: Spelling;
6
6
  withoutPhysicalProperties?: Spelling;
7
+ styleProp?: string;
7
8
  }
8
- export declare function spellingRules(options: SpellingOptions): Record<string, unknown>;
9
- export declare function startLintGuard(rules?: Record<string, unknown>): boolean;
9
+ export interface LintOverrides {
10
+ rules?: Record<string, unknown>;
11
+ settings?: {
12
+ plumeria: {
13
+ styleProp: string;
14
+ };
15
+ };
16
+ }
17
+ export declare function lintOverrides(options: LintOptions): LintOverrides;
18
+ export declare function lintConfig(overrides: LintOverrides): string;
19
+ export declare function lowerPriority(pid: number | undefined): boolean;
20
+ export declare function startLintGuard(overrides?: LintOverrides): boolean;
10
21
  export {};
package/dist/guard.js CHANGED
@@ -33,7 +33,9 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.spellingRules = spellingRules;
36
+ exports.lintOverrides = lintOverrides;
37
+ exports.lintConfig = lintConfig;
38
+ exports.lowerPriority = lowerPriority;
37
39
  exports.startLintGuard = startLintGuard;
38
40
  const child_process_1 = require("child_process");
39
41
  const fs = __importStar(require("fs"));
@@ -48,7 +50,8 @@ function spellingRule(spelling) {
48
50
  ? ['error', { sizes: true }]
49
51
  : 'error';
50
52
  }
51
- function spellingRules(options) {
53
+ function lintOverrides(options) {
54
+ const overrides = {};
52
55
  const rules = {};
53
56
  const logical = spellingRule(options.withoutLogicalProperties);
54
57
  const physical = spellingRule(options.withoutPhysicalProperties);
@@ -56,27 +59,45 @@ function spellingRules(options) {
56
59
  rules['@plumeria/no-logical-properties'] = logical;
57
60
  if (physical)
58
61
  rules['@plumeria/no-physical-properties'] = physical;
59
- return rules;
62
+ if (logical || physical)
63
+ overrides.rules = rules;
64
+ if (options.styleProp) {
65
+ overrides.settings = { plumeria: { styleProp: options.styleProp } };
66
+ }
67
+ return overrides;
60
68
  }
61
- function lintConfig(rules) {
62
- if (Object.keys(rules).length === 0)
69
+ function lintConfig(overrides) {
70
+ if (!overrides.rules && !overrides.settings)
63
71
  return BASE_CONFIG;
64
72
  const file = path.join(os.tmpdir(), `plumeria-oxlint-${process.pid}.json`);
65
- fs.writeFileSync(file, JSON.stringify({ extends: [BASE_CONFIG], rules }));
73
+ fs.writeFileSync(file, JSON.stringify({ extends: [BASE_CONFIG], ...overrides }));
66
74
  return file;
67
75
  }
68
- function startLintGuard(rules = {}) {
76
+ function lowerPriority(pid) {
77
+ if (!pid)
78
+ return false;
79
+ try {
80
+ os.setPriority(pid, os.constants.priority.PRIORITY_LOW);
81
+ return true;
82
+ }
83
+ catch {
84
+ return false;
85
+ }
86
+ }
87
+ function startLintGuard(overrides = {}) {
69
88
  if (process.env[GUARD_ENV])
70
89
  return false;
71
90
  process.env[GUARD_ENV] = '1';
72
- const config = lintConfig(rules);
91
+ const config = lintConfig(overrides);
73
92
  const child = (0, child_process_1.spawn)(process.execPath, [
74
93
  path.join(path.dirname(require.resolve('oxlint/package.json')), 'bin', 'oxlint'),
75
94
  '-c',
76
95
  config,
77
96
  '--deny-warnings',
78
97
  '--no-error-on-unmatched-pattern',
98
+ '--threads=2',
79
99
  ], { stdio: 'inherit' });
100
+ lowerPriority(child.pid);
80
101
  const exit = process.exit.bind(process);
81
102
  let lintCode = null;
82
103
  let pendingCode = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/eslint-plugin",
3
- "version": "19.10.1",
3
+ "version": "19.10.3",
4
4
  "description": "Plumeria ESLint plugin",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -59,7 +59,7 @@
59
59
  "known-css-properties": "^0.37.0",
60
60
  "oxlint": "1.87.0",
61
61
  "zss-engine": "2.9.1",
62
- "@plumeria/compiler": "19.10.1"
62
+ "@plumeria/compiler": "19.10.3"
63
63
  },
64
64
  "scripts": {
65
65
  "build": "rimraf dist && pnpm cjs",