Skip to content

Commit

Permalink
Revert Node.js API returned resolved object change (#7183)
Browse files Browse the repository at this point in the history
This commit does:
- reverts the `output` property change in Node.js API returned promise object
- deprecates the `output` property
- adds a new `report` property instead of `output`

Co-authored-by: Matt Wang <matt@matthewwang.me>
  • Loading branch information
ybiquitous and mattxwang committed Sep 27, 2023
1 parent ad2f4ab commit 37413b4
Show file tree
Hide file tree
Showing 22 changed files with 572 additions and 47 deletions.
5 changes: 5 additions & 0 deletions .changeset/stale-hotels-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"stylelint": minor
---

Deprecated: `output` property in a Node.js API returned object. Instead, `report`/`code` properties are recommended
5 changes: 5 additions & 0 deletions .changeset/wise-parents-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"stylelint": minor
---

Added: `report`/`code` properties to a Node.js API returned object
6 changes: 4 additions & 2 deletions docs/migration-guide/to-16.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ You should use the following or higher versions of Node.js:

We've changed the resolved object of the Promise returned by `stylelint.lint()` so that:

- the [`output`](../user-guide/node-api.md#output) property now only contains formatted problems
- a new [`report`](../user-guide/node-api.md#report) property contains the formatted problems
- a new [`code`](../user-guide/node-api.md#code-1) property contains the autofixed code
- the [`output`](../user-guide/node-api.md#output) property is now deprecated in favor of the new `report` and `code` properties and will be removed in the next major version

If you use `stylelint.lint()` to lint a source string and the `fix` option is `true`, the `output` property will contain the formatted problems and the `code` property will contain the fixed code.
If you use `stylelint.lint()` to lint a source string and the `fix` option is `true`, the `report` property will contain the formatted problems and the `code` property will contain the fixed code.

```diff js
async function lint() {
Expand All @@ -39,6 +40,7 @@ async function lint() {
fix: true
});
- const fixedCode = result.output;
+ const formattedProblems = result.report;
+ const fixedCode = result.code;
}
```
Expand Down
11 changes: 10 additions & 1 deletion docs/user-guide/node-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,21 @@ Boolean. If `true`, at least one rule with an "error"-level severity registered

### `output`

A string that contains the formatted problems (using the default formatter or whichever you passed).
> **Warning** This property is deprecated and will be removed in the next major version. Use [`report`](#report) or [`code`](#code-1) instead. See [the migration guide](../migration-guide/to-16.md).
A string that contains either the:

- formatted problems (using the default formatter or whichever you passed)
- or the autofixed code, if the `fix` option is set to `true`

### `postcssResults`

An array containing all the accumulated [PostCSS LazyResults](https://api.postcss.org/LazyResult.html).

### `report`

A string that contains the formatted problems (using the default formatter or whichever you passed).

### `results`

An array containing all the Stylelint result objects (the objects that formatters consume).
Expand Down
22 changes: 22 additions & 0 deletions lib/__tests__/standalone-deprecations.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,25 @@ describe('standalone with deprecations', () => {
expect(results[0].deprecations).toHaveLength(0);
});
});

describe('standalone with the `output` property deprecation', () => {
beforeEach(() => {
jest.spyOn(console, 'warn').mockImplementation(() => {});
});

it('warns when using the `output` property', async () => {
const result = await standalone({
code: 'a {}',
config: { rules: {} },
});

// Use multiple times
expect(result.output).toBeTruthy();
expect(result.output).toBeTruthy();

expect(console.warn).toHaveBeenCalledTimes(1);
expect(console.warn).toHaveBeenCalledWith(
'`output` is deprecated. Use `report` or `code` instead.',
);
});
});
49 changes: 27 additions & 22 deletions lib/__tests__/standalone-fix.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,25 @@ it('outputs fixed code when input is code string', async () => {
});

expect(result.code).toBe('a { color: #fff; }');
expect(result.output).toBe('');
expect(result.report).toBe('');
expect(result.output).toBe('a { color: #fff; }'); // TODO: Deprecated. Remove in the next major version.
});

it('fixes when enabled in config', async () => {
const config = {
fix: true,
rules: {
'color-hex-length': 'short',
},
};

const result = await standalone({
code: 'a { color: #ffffff; }',
config,
config: {
fix: true,
rules: {
'color-hex-length': 'short',
},
},
formatter: 'string',
});

expect(result.code).toBe('a { color: #fff; }');
expect(result.output).toBe('');
expect(result.report).toBe('');
expect(result.output).toBe('a { color: #fff; }'); // TODO: Deprecated. Remove in the next major version.
});

it("doesn't fix with stylelint-disable commands", async () => {
Expand All @@ -65,7 +65,8 @@ it("doesn't fix with stylelint-disable commands", async () => {
});

expect(result.code).toBe(code);
expect(result.output).toBe('');
expect(result.report).toBe('');
expect(result.output).toBe(code); // TODO: Deprecated. Remove in the next major version.
});

it("doesn't fix with scoped stylelint-disable commands", async () => {
Expand All @@ -85,7 +86,7 @@ it("doesn't fix with scoped stylelint-disable commands", async () => {
});

expect(result.code).toBe(code);
expect(result.output).toBe('');
expect(result.report).toBe('');
});

it("doesn't fix with multiple scoped stylelint-disable commands", async () => {
Expand All @@ -109,12 +110,15 @@ it("doesn't fix with multiple scoped stylelint-disable commands", async () => {
});

expect(result.code).toBe(code);
expect(result.output).toBe('');
expect(result.report).toBe('');
});

it("doesn't fix with a scoped stylelint-disable command, but does fix other rules", async () => {
const code =
'/* stylelint-disable declaration-block-no-duplicate-properties */ a { color: #ffffff; color: orange; }';

const result = await standalone({
code: '/* stylelint-disable declaration-block-no-duplicate-properties */ a { color: #ffffff; color: orange; }',
code,
config: {
rules: {
'color-hex-length': 'short',
Expand All @@ -128,7 +132,7 @@ it("doesn't fix with a scoped stylelint-disable command, but does fix other rule
expect(result.code).toBe(
'/* stylelint-disable declaration-block-no-duplicate-properties */ a { color: #fff; color: orange; }',
);
expect(result.output).toBe('');
expect(result.report).toBe('');
});

describe('writing fixes to files', () => {
Expand Down Expand Up @@ -167,13 +171,14 @@ describe('writing fixes to files', () => {
expect(fileContent).toBe(postcssResult.root.toString(postcssResult.opts.syntax));

expect(result.code).toBeUndefined();
expect(getCleanOutput(result.output)).toBe(stripIndent`
expect(getCleanOutput(result.report)).toBe(stripIndent`
stylesheet.css
1:1 × Unknown rule at-rule-name-case at-rule-name-case
7:1 × Unexpected empty comment comment-no-empty
2 problems (2 errors, 0 warnings)
`);
expect(result.output).toMatch('stylesheet.css'); // TODO: Deprecated. Remove in the next major version.
});

it("doesn't write to ignored file", async () => {
Expand All @@ -197,7 +202,7 @@ describe('writing fixes to files', () => {
expect(newFile).toBe(oldFile);

expect(result.code).toBeUndefined();
expect(getCleanOutput(result.output)).toBe('');
expect(getCleanOutput(result.report)).toBe('');
});

// eslint-disable-next-line jest/no-disabled-tests
Expand Down Expand Up @@ -245,7 +250,7 @@ it('one rule being disabled', async () => {

expect(result.results[0].errored).toBe(true);
expect(result.code).toBe(code);
expect(getCleanOutput(result.output)).toBe(stripIndent`
expect(getCleanOutput(result.report)).toBe(stripIndent`
test.css
3:11 × Expected "#ffffff" to be "#fff" color-hex-length
Expand Down Expand Up @@ -295,7 +300,7 @@ it('two rules being disabled', async () => {
),
).toBe(true);
expect(result.code).toBe(code);
expect(getCleanOutput(result.output)).toBe(stripIndent`
expect(getCleanOutput(result.report)).toBe(stripIndent`
test.css
2:3 × Unexpected duplicate selector "a", first used at line 2 no-duplicate-selectors
3:11 × Expected "#ffffff" to be "#fff" color-hex-length
Expand Down Expand Up @@ -345,7 +350,7 @@ it('one rule being disabled and another still autofixing', async () => {
a, a {
color: #fff;
}`);
expect(getCleanOutput(result.output)).toBe(stripIndent`
expect(getCleanOutput(result.report)).toBe(stripIndent`
test.css
2:3 × Unexpected duplicate selector "a", first used at line 2 no-duplicate-selectors
Expand All @@ -367,7 +372,7 @@ it("doesn't return the fixed code if the fix option is false", async () => {
});

expect(result.code).toBeUndefined();
expect(getCleanOutput(result.output)).toBe(stripIndent`
expect(getCleanOutput(result.report)).toBe(stripIndent`
test.css
1:12 × Expected "#ffffff" to be "#fff" color-hex-length
Expand All @@ -391,7 +396,7 @@ it('returns the original code if the fix option is true but the code is not fixa
});

expect(result.code).toBe(code);
expect(getCleanOutput(result.output)).toBe(stripIndent`
expect(getCleanOutput(result.report)).toBe(stripIndent`
test.css
1:12 × Unexpected invalid hex color "#y3" color-no-invalid-hex
Expand Down
6 changes: 6 additions & 0 deletions lib/__tests__/stylelintignore-test/stylelintignore.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ describe('stylelintignore', () => {
expect(data).toEqual({
cwd: expect.any(String),
errored: false,
report: '[]',
output: '[]',
reportedDisables: [],
results: [],
Expand Down Expand Up @@ -99,6 +100,7 @@ describe('stylelintignore', () => {
expect(data).toEqual({
cwd: expect.any(String),
errored: false,
report: '[]',
output: '[]',
reportedDisables: [],
results: [],
Expand All @@ -116,6 +118,7 @@ describe('stylelintignore', () => {
expect(data).toEqual({
cwd: expect.any(String),
errored: false,
report: '[]',
output: '[]',
reportedDisables: [],
results: [],
Expand Down Expand Up @@ -180,6 +183,7 @@ describe('stylelintignore with options.cwd', () => {
expect(data).toEqual({
cwd: expect.any(String),
errored: false,
report: '[]',
output: '[]',
reportedDisables: [],
results: [],
Expand Down Expand Up @@ -219,6 +223,7 @@ describe('stylelintignore with options.cwd', () => {
expect(data).toEqual({
cwd: expect.any(String),
errored: false,
report: '[]',
output: '[]',
reportedDisables: [],
results: [],
Expand All @@ -237,6 +242,7 @@ describe('stylelintignore with options.cwd', () => {
expect(data).toEqual({
cwd: expect.any(String),
errored: false,
report: '[]',
output: '[]',
reportedDisables: [],
results: [],
Expand Down
10 changes: 5 additions & 5 deletions lib/cli.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -505,21 +505,21 @@ export default async function main(argv) {
}

return standalone(options)
.then(({ output, code, errored, maxWarningsExceeded }) => {
if (!output && !code) {
.then(({ report, code, errored, maxWarningsExceeded }) => {
if (!report && !code) {
return;
}

if (code) {
process.stdout.write(code);
}

if (output) {
process.stderr.write(output);
if (report) {
process.stderr.write(report);
}

if (isString(outputFile)) {
writeOutputFile(output, outputFile).catch(handleError);
writeOutputFile(report, outputFile).catch(handleError);
}

Check warning on line 523 in lib/cli.mjs

View check run for this annotation

Codecov / codecov/patch

lib/cli.mjs#L522-L523

Added lines #L522 - L523 were not covered by tests

if (errored) {
Expand Down
20 changes: 18 additions & 2 deletions lib/prepareReturnValue.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,26 @@ function prepareReturnValue(stylelintResults, maxWarnings, formatter, cwd) {
cwd,
errored,
results: [],
output: '',
report: '',

// TODO: Deprecated. Remove in the next major version.
get output() {
if (!this._outputWarned) {
console.warn('`output` is deprecated. Use `report` or `code` instead.');
this._outputWarned = true;
}

return this._output ?? '';
},

reportedDisables: [],
ruleMetadata: getRuleMetadata(stylelintResults),
};

// TODO: Deprecated. Remove in the next major version.
Object.defineProperty(returnValue, '_output', { value: '', writable: true });
Object.defineProperty(returnValue, '_outputWarned', { value: false, writable: true });

if (maxWarnings !== undefined) {
const foundWarnings = stylelintResults.reduce((count, file) => count + file.warnings.length, 0);

Expand All @@ -55,7 +70,8 @@ function prepareReturnValue(stylelintResults, maxWarnings, formatter, cwd) {
}
}

returnValue.output = formatter(stylelintResults, returnValue);
returnValue.report = formatter(stylelintResults, returnValue);
returnValue._output = returnValue.report; // TODO: Deprecated. Remove in the next major version.
returnValue.results = stylelintResults;

return returnValue;
Expand Down
20 changes: 18 additions & 2 deletions lib/prepareReturnValue.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,26 @@ export default function prepareReturnValue(stylelintResults, maxWarnings, format
cwd,
errored,
results: [],
output: '',
report: '',

// TODO: Deprecated. Remove in the next major version.
get output() {
if (!this._outputWarned) {
console.warn('`output` is deprecated. Use `report` or `code` instead.');
this._outputWarned = true;
}

return this._output ?? '';
},

reportedDisables: [],
ruleMetadata: getRuleMetadata(stylelintResults),
};

// TODO: Deprecated. Remove in the next major version.
Object.defineProperty(returnValue, '_output', { value: '', writable: true });
Object.defineProperty(returnValue, '_outputWarned', { value: false, writable: true });

if (maxWarnings !== undefined) {
const foundWarnings = stylelintResults.reduce((count, file) => count + file.warnings.length, 0);

Expand All @@ -53,7 +68,8 @@ export default function prepareReturnValue(stylelintResults, maxWarnings, format
}
}

returnValue.output = formatter(stylelintResults, returnValue);
returnValue.report = formatter(stylelintResults, returnValue);
returnValue._output = returnValue.report; // TODO: Deprecated. Remove in the next major version.
returnValue.results = stylelintResults;

return returnValue;
Expand Down

0 comments on commit 37413b4

Please sign in to comment.