diff --git a/.changeset/stale-hotels-sniff.md b/.changeset/stale-hotels-sniff.md new file mode 100644 index 0000000000..1c0b7bcf80 --- /dev/null +++ b/.changeset/stale-hotels-sniff.md @@ -0,0 +1,5 @@ +--- +"stylelint": minor +--- + +Deprecated: `output` property in a Node.js API returned object. Instead, `report`/`code` properties are recommended diff --git a/.changeset/wise-parents-rule.md b/.changeset/wise-parents-rule.md new file mode 100644 index 0000000000..a40f19ee3e --- /dev/null +++ b/.changeset/wise-parents-rule.md @@ -0,0 +1,5 @@ +--- +"stylelint": minor +--- + +Added: `report`/`code` properties to a Node.js API returned object diff --git a/docs/migration-guide/to-16.md b/docs/migration-guide/to-16.md index f970f6294e..f5af9ed9c8 100644 --- a/docs/migration-guide/to-16.md +++ b/docs/migration-guide/to-16.md @@ -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() { @@ -39,6 +40,7 @@ async function lint() { fix: true }); - const fixedCode = result.output; ++ const formattedProblems = result.report; + const fixedCode = result.code; } ``` diff --git a/docs/user-guide/node-api.md b/docs/user-guide/node-api.md index 9133705b52..f5b99eb124 100644 --- a/docs/user-guide/node-api.md +++ b/docs/user-guide/node-api.md @@ -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). diff --git a/lib/__tests__/standalone-deprecations.test.mjs b/lib/__tests__/standalone-deprecations.test.mjs index b471a15638..bb36b4c2fd 100644 --- a/lib/__tests__/standalone-deprecations.test.mjs +++ b/lib/__tests__/standalone-deprecations.test.mjs @@ -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.', + ); + }); +}); diff --git a/lib/__tests__/standalone-fix.test.mjs b/lib/__tests__/standalone-fix.test.mjs index c724e56297..0f7cb9f682 100644 --- a/lib/__tests__/standalone-fix.test.mjs +++ b/lib/__tests__/standalone-fix.test.mjs @@ -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 () => { @@ -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 () => { @@ -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 () => { @@ -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', @@ -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', () => { @@ -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 () => { @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/lib/__tests__/stylelintignore-test/stylelintignore.test.mjs b/lib/__tests__/stylelintignore-test/stylelintignore.test.mjs index 4c0e6ad4b7..95bcd716b6 100644 --- a/lib/__tests__/stylelintignore-test/stylelintignore.test.mjs +++ b/lib/__tests__/stylelintignore-test/stylelintignore.test.mjs @@ -62,6 +62,7 @@ describe('stylelintignore', () => { expect(data).toEqual({ cwd: expect.any(String), errored: false, + report: '[]', output: '[]', reportedDisables: [], results: [], @@ -99,6 +100,7 @@ describe('stylelintignore', () => { expect(data).toEqual({ cwd: expect.any(String), errored: false, + report: '[]', output: '[]', reportedDisables: [], results: [], @@ -116,6 +118,7 @@ describe('stylelintignore', () => { expect(data).toEqual({ cwd: expect.any(String), errored: false, + report: '[]', output: '[]', reportedDisables: [], results: [], @@ -180,6 +183,7 @@ describe('stylelintignore with options.cwd', () => { expect(data).toEqual({ cwd: expect.any(String), errored: false, + report: '[]', output: '[]', reportedDisables: [], results: [], @@ -219,6 +223,7 @@ describe('stylelintignore with options.cwd', () => { expect(data).toEqual({ cwd: expect.any(String), errored: false, + report: '[]', output: '[]', reportedDisables: [], results: [], @@ -237,6 +242,7 @@ describe('stylelintignore with options.cwd', () => { expect(data).toEqual({ cwd: expect.any(String), errored: false, + report: '[]', output: '[]', reportedDisables: [], results: [], diff --git a/lib/cli.mjs b/lib/cli.mjs index 4273fd44da..dc2dfdd401 100644 --- a/lib/cli.mjs +++ b/lib/cli.mjs @@ -505,8 +505,8 @@ 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; } @@ -514,12 +514,12 @@ export default async function main(argv) { 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); } if (errored) { diff --git a/lib/prepareReturnValue.cjs b/lib/prepareReturnValue.cjs index 13a5baf500..fa45e89dc4 100644 --- a/lib/prepareReturnValue.cjs +++ b/lib/prepareReturnValue.cjs @@ -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); @@ -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; diff --git a/lib/prepareReturnValue.mjs b/lib/prepareReturnValue.mjs index 62ea9fe481..fcefa430a2 100644 --- a/lib/prepareReturnValue.mjs +++ b/lib/prepareReturnValue.mjs @@ -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); @@ -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; diff --git a/lib/standalone.cjs b/lib/standalone.cjs index 38e20aa6f3..5ff9a23164 100644 --- a/lib/standalone.cjs +++ b/lib/standalone.cjs @@ -8,6 +8,7 @@ const fastGlob = require('fast-glob'); const globby = require('globby'); const normalizePath = require('normalize-path'); const writeFileAtomic = require('write-file-atomic'); +const validateTypes = require('./utils/validateTypes.cjs'); const allFilesIgnoredError = require('./utils/allFilesIgnoredError.cjs'); const noFilesFoundError = require('./utils/noFilesFoundError.cjs'); const createPartialStylelintResult = require('./createPartialStylelintResult.cjs'); @@ -59,9 +60,9 @@ async function standalone({ }) { const startTime = Date.now(); - const isValidCode = typeof code === 'string'; + const hasOneValidInput = (files && !validateTypes.isString(code)) || (!files && validateTypes.isString(code)); - if ((!files && !isValidCode) || (files && (code || isValidCode))) { + if (!hasOneValidInput) { return Promise.reject( new Error('You must pass stylelint a `files` glob or a `code` string, though not both'), ); @@ -107,6 +108,8 @@ async function standalone({ }); if (!files) { + validateTypes.assertString(code); + const absoluteCodeFilename = codeFilename !== undefined && !node_path.isAbsolute(codeFilename) ? node_path.join(cwd, codeFilename) @@ -145,6 +148,7 @@ async function standalone({ postcssResult.root.toString(postcssResult.opts.syntax) : // If the writing of the fix is disabled, the input code is returned as-is code; + returnValue._output = returnValue.code; // TODO: Deprecated. Remove in the next major version. } return returnValue; diff --git a/lib/standalone.mjs b/lib/standalone.mjs index cd6a8f483e..d4d1c58596 100644 --- a/lib/standalone.mjs +++ b/lib/standalone.mjs @@ -10,6 +10,7 @@ import globby from 'globby'; import normalizePath from 'normalize-path'; import writeFileAtomic from 'write-file-atomic'; +import { assertString, isString } from './utils/validateTypes.mjs'; import AllFilesIgnoredError from './utils/allFilesIgnoredError.mjs'; import NoFilesFoundError from './utils/noFilesFoundError.mjs'; import createPartialStylelintResult from './createPartialStylelintResult.mjs'; @@ -59,9 +60,9 @@ export default async function standalone({ }) { const startTime = Date.now(); - const isValidCode = typeof code === 'string'; + const hasOneValidInput = (files && !isString(code)) || (!files && isString(code)); - if ((!files && !isValidCode) || (files && (code || isValidCode))) { + if (!hasOneValidInput) { return Promise.reject( new Error('You must pass stylelint a `files` glob or a `code` string, though not both'), ); @@ -107,6 +108,8 @@ export default async function standalone({ }); if (!files) { + assertString(code); + const absoluteCodeFilename = codeFilename !== undefined && !isAbsolute(codeFilename) ? join(cwd, codeFilename) @@ -145,6 +148,7 @@ export default async function standalone({ postcssResult.root.toString(postcssResult.opts.syntax) : // If the writing of the fix is disabled, the input code is returned as-is code; + returnValue._output = returnValue.code; // TODO: Deprecated. Remove in the next major version. } return returnValue; diff --git a/system-tests/001/__snapshots__/fs.test.mjs.snap b/system-tests/001/__snapshots__/fs.test.mjs.snap index 7d53ad80f9..816c6afcc7 100644 --- a/system-tests/001/__snapshots__/fs.test.mjs.snap +++ b/system-tests/001/__snapshots__/fs.test.mjs.snap @@ -10,6 +10,17 @@ exports[`fs - valid sanitize.css and their config 1`] = ` "errored": false, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", + "warnings": [], + }, + ], + "report": [ + { + "deprecations": [], + "errored": false, + "invalidOptionWarnings": [], + "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [], }, ], @@ -21,6 +32,7 @@ exports[`fs - valid sanitize.css and their config 1`] = ` "ignored": undefined, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [], }, ], diff --git a/system-tests/001/__snapshots__/no-fs.test.mjs.snap b/system-tests/001/__snapshots__/no-fs.test.mjs.snap index 191729442e..6b24c018cc 100644 --- a/system-tests/001/__snapshots__/no-fs.test.mjs.snap +++ b/system-tests/001/__snapshots__/no-fs.test.mjs.snap @@ -10,6 +10,17 @@ exports[`no-fs - valid sanitize.css and their config 1`] = ` "errored": false, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", + "warnings": [], + }, + ], + "report": [ + { + "deprecations": [], + "errored": false, + "invalidOptionWarnings": [], + "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [], }, ], @@ -21,6 +32,7 @@ exports[`no-fs - valid sanitize.css and their config 1`] = ` "ignored": undefined, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [], }, ], diff --git a/system-tests/002/__snapshots__/fs.test.mjs.snap b/system-tests/002/__snapshots__/fs.test.mjs.snap index e070e13da9..2f270e8e00 100644 --- a/system-tests/002/__snapshots__/fs.test.mjs.snap +++ b/system-tests/002/__snapshots__/fs.test.mjs.snap @@ -10,6 +10,45 @@ exports[`fs - invalid twbs buttons and their config 1`] = ` "errored": true, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", + "warnings": [ + { + "column": 10, + "endColumn": 15, + "endLine": 79, + "line": 79, + "rule": "color-named", + "severity": "error", + "text": "Unexpected named color "white" (color-named)", + }, + { + "column": 1, + "endColumn": 12, + "endLine": 118, + "line": 118, + "rule": "selector-no-qualifying-type", + "severity": "error", + "text": "Unexpected qualifying type selector "a.btn-block" (selector-no-qualifying-type)", + }, + { + "column": 3, + "endColumn": 4, + "endLine": 125, + "line": 123, + "rule": "selector-no-qualifying-type", + "severity": "error", + "text": "Unexpected qualifying type selector "a.btn-block" (selector-no-qualifying-type)", + }, + ], + }, + ], + "report": [ + { + "deprecations": [], + "errored": true, + "invalidOptionWarnings": [], + "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 10, @@ -49,6 +88,7 @@ exports[`fs - invalid twbs buttons and their config 1`] = ` "ignored": undefined, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 10, diff --git a/system-tests/002/__snapshots__/no-fs.test.mjs.snap b/system-tests/002/__snapshots__/no-fs.test.mjs.snap index d8f3d3bb18..124456bb72 100644 --- a/system-tests/002/__snapshots__/no-fs.test.mjs.snap +++ b/system-tests/002/__snapshots__/no-fs.test.mjs.snap @@ -10,6 +10,45 @@ exports[`no-fs - invalid twbs buttons and their config 1`] = ` "errored": true, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", + "warnings": [ + { + "column": 10, + "endColumn": 15, + "endLine": 79, + "line": 79, + "rule": "color-named", + "severity": "error", + "text": "Unexpected named color "white" (color-named)", + }, + { + "column": 1, + "endColumn": 12, + "endLine": 118, + "line": 118, + "rule": "selector-no-qualifying-type", + "severity": "error", + "text": "Unexpected qualifying type selector "a.btn-block" (selector-no-qualifying-type)", + }, + { + "column": 3, + "endColumn": 4, + "endLine": 125, + "line": 123, + "rule": "selector-no-qualifying-type", + "severity": "error", + "text": "Unexpected qualifying type selector "a.btn-block" (selector-no-qualifying-type)", + }, + ], + }, + ], + "report": [ + { + "deprecations": [], + "errored": true, + "invalidOptionWarnings": [], + "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 10, @@ -49,6 +88,7 @@ exports[`no-fs - invalid twbs buttons and their config 1`] = ` "ignored": undefined, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 10, diff --git a/system-tests/003/__snapshots__/fs.test.mjs.snap b/system-tests/003/__snapshots__/fs.test.mjs.snap index 48bf0e1c06..d0355846d4 100644 --- a/system-tests/003/__snapshots__/fs.test.mjs.snap +++ b/system-tests/003/__snapshots__/fs.test.mjs.snap @@ -10,6 +10,27 @@ exports[`fs - zen garden CSS with standard config 1`] = ` "errored": true, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", + "warnings": [ + { + "column": 25, + "endColumn": 32, + "endLine": 102, + "line": 102, + "rule": "font-family-no-missing-generic-family-keyword", + "severity": "error", + "text": "Unexpected missing generic font family (font-family-no-missing-generic-family-keyword)", + }, + ], + }, + ], + "report": [ + { + "deprecations": [], + "errored": true, + "invalidOptionWarnings": [], + "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 25, @@ -31,6 +52,7 @@ exports[`fs - zen garden CSS with standard config 1`] = ` "ignored": undefined, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 25, diff --git a/system-tests/003/__snapshots__/no-fs.test.mjs.snap b/system-tests/003/__snapshots__/no-fs.test.mjs.snap index e79c2a729e..8c98eb9897 100644 --- a/system-tests/003/__snapshots__/no-fs.test.mjs.snap +++ b/system-tests/003/__snapshots__/no-fs.test.mjs.snap @@ -216,12 +216,225 @@ footer a:link, footer a:visited { ", "cwd": "", "errored": true, - "output": [ + "output": "/* css Zen Garden default style v1.02 */ + +/* css released under Creative Commons License - http://creativecommons.org/licenses/by-nc-sa/1.0/ */ + +/* This file based on 'Tranquille' by Dave Shea */ + +/* You may use this file as a foundation for any new work, but you may find it easier to start from scratch. */ + +/* Not all elements are defined in this file, so you'll most likely want to refer to the xhtml as well. */ + +/* Your images should be linked as if the CSS file sits in the same folder as the images. ie. no paths. */ + + +/* basic elements */ +html { + margin: 0; + padding: 0; + } + +body { + font: 75% georgia, sans-serif; + line-height: 1.88889; + color: #555753; + background: #fff url(http://csszengarden.com/001/blossoms.jpg) no-repeat bottom right; + margin: 0; + padding: 0; + } + +p { + margin-top: 0; + text-align: justify; + } + +h3 { + font: italic normal 1.4em georgia, sans-serif; + letter-spacing: 1px; + margin-bottom: 0; + color: #7D775C; + } + +a:link { + font-weight: bold; + text-decoration: none; + color: #B7A5DF; + } + +a:visited { + font-weight: bold; + text-decoration: none; + color: #D4CDDC; + } + +a:hover, a:focus, a:active { + text-decoration: underline; + color: #9685BA; + } + +abbr { + border-bottom: none; + } + + +/* specific divs */ +.page-wrapper { + background: url(http://csszengarden.com/001/zen-bg.jpg) no-repeat top left; + padding: 0 175px 0 110px; + margin: 0; + position: relative; + } + +.intro { + min-width: 470px; + width: 100%; + } + +header h1 { + background: transparent url(http://csszengarden.com/001/h1.gif) no-repeat top left; + margin-top: 10px; + display: block; + width: 219px; + height: 87px; + float: left; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + } + +header h2 { + background: transparent url(http://csszengarden.com/001/h2.gif) no-repeat top left; + margin-top: 58px; + margin-bottom: 40px; + width: 200px; + height: 18px; + float: right; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + } + +header { + padding-top: 20px; + height: 87px; +} + +.summary { + clear: both; + margin: 20px 20px 20px 10px; + width: 160px; + float: left; + } + +.summary p { + font: italic 1.1em/2.2 georgia; + text-align: center; + } + +.preamble { + clear: right; + padding: 0 10px 0; + } + +.supporting { + padding-left: 10px; + margin-bottom: 40px; + } + +footer { + text-align: center; + } + +footer a:link, footer a:visited { + margin-right: 20px; + } + +.sidebar { + margin-left: 600px; + position: absolute; + top: 0; + right: 0; + } + +.sidebar .wrapper { + font: 10px verdana, sans-serif; + background: transparent url(http://csszengarden.com/001/paper-bg.jpg) top left repeat-y; + padding: 10px; + margin-top: 150px; + width: 130px; + } + +.sidebar h3.select { + background: transparent url(http://csszengarden.com/001/h3.gif) no-repeat top left; + margin: 10px 0 5px; + width: 97px; + height: 16px; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + } + +.sidebar h3.archives { + background: transparent url(http://csszengarden.com/001/h5.gif) no-repeat top left; + margin: 25px 0 5px; + width:57px; + height: 14px; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + } + +.sidebar h3.resources { + background: transparent url(http://csszengarden.com/001/h6.gif) no-repeat top left; + margin: 25px 0 5px; + width:63px; + height: 10px; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + } + + +.sidebar ul { + margin: 0; + padding: 0; + } + +.sidebar li { + line-height: 1.3em; + background: transparent url(http://csszengarden.com/001/cr1.gif) no-repeat top center; + display: block; + padding-top: 5px; + margin-bottom: 5px; + list-style-type: none; + } + +.sidebar li a:link { + color: #988F5E; + } + +.sidebar li a:visited { + color: #B3AE94; + } + + +.extra1 { + background: transparent url(http://csszengarden.com/001/cr2.gif) top left no-repeat; + position: absolute; + top: 40px; + right: 0; + width: 148px; + height: 110px; + } +", + "report": [ { "deprecations": [], "errored": true, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 25, @@ -243,6 +456,7 @@ footer a:link, footer a:visited { "ignored": undefined, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 25, diff --git a/system-tests/004/__snapshots__/fs.test.mjs.snap b/system-tests/004/__snapshots__/fs.test.mjs.snap index b2128f5163..76fea68f3d 100644 --- a/system-tests/004/__snapshots__/fs.test.mjs.snap +++ b/system-tests/004/__snapshots__/fs.test.mjs.snap @@ -10,6 +10,27 @@ exports[`fs - errored state for reportNeedlessDisables 1`] = ` "errored": true, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", + "warnings": [ + { + "column": 1, + "endColumn": 38, + "endLine": 1, + "line": 1, + "rule": "--report-needless-disables", + "severity": "error", + "text": "Needless disable for "block-no-empty"", + }, + ], + }, + ], + "report": [ + { + "deprecations": [], + "errored": true, + "invalidOptionWarnings": [], + "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 1, @@ -31,6 +52,7 @@ exports[`fs - errored state for reportNeedlessDisables 1`] = ` "ignored": undefined, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 1, @@ -62,6 +84,17 @@ exports[`fs - no errored state 1`] = ` "errored": false, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", + "warnings": [], + }, + ], + "report": [ + { + "deprecations": [], + "errored": false, + "invalidOptionWarnings": [], + "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [], }, ], @@ -73,6 +106,7 @@ exports[`fs - no errored state 1`] = ` "ignored": undefined, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [], }, ], diff --git a/system-tests/004/__snapshots__/no-fs.test.mjs.snap b/system-tests/004/__snapshots__/no-fs.test.mjs.snap index 3e7fa5636d..a62c390883 100644 --- a/system-tests/004/__snapshots__/no-fs.test.mjs.snap +++ b/system-tests/004/__snapshots__/no-fs.test.mjs.snap @@ -10,6 +10,27 @@ exports[`no-fs - errored state for reportNeedlessDisables 1`] = ` "errored": true, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", + "warnings": [ + { + "column": 1, + "endColumn": 38, + "endLine": 1, + "line": 1, + "rule": "--report-needless-disables", + "severity": "error", + "text": "Needless disable for "block-no-empty"", + }, + ], + }, + ], + "report": [ + { + "deprecations": [], + "errored": true, + "invalidOptionWarnings": [], + "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 1, @@ -31,6 +52,7 @@ exports[`no-fs - errored state for reportNeedlessDisables 1`] = ` "ignored": undefined, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [ { "column": 1, @@ -62,6 +84,17 @@ exports[`no-fs - no errored state 1`] = ` "errored": false, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", + "warnings": [], + }, + ], + "report": [ + { + "deprecations": [], + "errored": false, + "invalidOptionWarnings": [], + "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [], }, ], @@ -73,6 +106,7 @@ exports[`no-fs - no errored state 1`] = ` "ignored": undefined, "invalidOptionWarnings": [], "parseErrors": [], + "source": "/path/to/dummy.css", "warnings": [], }, ], diff --git a/system-tests/systemTestUtils.mjs b/system-tests/systemTestUtils.mjs index 541270bb41..e211e5a422 100644 --- a/system-tests/systemTestUtils.mjs +++ b/system-tests/systemTestUtils.mjs @@ -37,27 +37,34 @@ export async function caseFilesForFix(caseNumber, ext = 'css') { return tempPath; } -export function prepForSnapshot({ results, cwd, output, ...rest }) { +export function prepForSnapshot({ results, cwd, output, report, ...rest }) { // If output isn't fixed code if (output.startsWith('[')) { // The `source` of each file varies between platforms or if a tmp file is used - output = JSON.parse(output).map((warning) => { - delete warning.source; + output = JSON.parse(output).map((warning) => ({ + ...warning, + source: '/path/to/dummy.css', + })); + } - return warning; - }); + if (report) { + // The `source` of each file varies between platforms or if a tmp file is used + report = JSON.parse(report).map((warning) => ({ + ...warning, + source: '/path/to/dummy.css', + })); } return { cwd: path.relative(process.cwd(), cwd), // The _postcssResult object is not part of our API and is huge results: results.map((result) => { - delete result.source; delete result._postcssResult; - return result; + return { ...result, source: '/path/to/dummy.css' }; }), - output, + output, // TODO: Deprecated. Remove in the next major version. + report, ...rest, }; } diff --git a/types/stylelint/index.d.ts b/types/stylelint/index.d.ts index e5fc7ddfaf..598affdbdf 100644 --- a/types/stylelint/index.d.ts +++ b/types/stylelint/index.d.ts @@ -386,7 +386,23 @@ declare namespace stylelint { cwd: string; results: LintResult[]; errored: boolean; + /** + * @deprecated Use `report` for the formatted problems, or use `code` + * for the autofixed code instead. This will be removed in the next major version. + */ output: string; + /** @internal To show the deprecation warning. */ + _output?: string; + /** @internal To show the deprecation warning. */ + _outputWarned?: boolean; + /** + * A string that contains the formatted problems. + */ + report: string; + /** + * A string that contains the autofixed code, if the `fix` option is set to `true` + * and the `code` option is provided. + */ code?: string; maxWarningsExceeded?: { maxWarnings: number;