From 2035f9fb6f9817a94fc96e7fccc892c2d289ccbb Mon Sep 17 00:00:00 2001 From: Sonia Muzemil Date: Tue, 30 Jun 2020 14:17:09 -0500 Subject: [PATCH 1/9] feat(stylelint): wrote draft of rules --- package.json | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 1e7693bf5c..b78a15548d 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,38 @@ "extends": "stylelint-config-recommended-scss", "plugins": [ "stylelint-scss" - ] + ], + "rules": { + "declaration-property-unit-blacklist": [ + { + "font-size": [ + "em", + "px", + "pt" + ], + "margin": [ + "px", + "rem" + ] + }, + { + "severity": "error", + "message": "Please refer to the Carbon guidelines for the appropriate tokens to use: https://www.carbondesignsystem.com/" + } + ], + "declaration-property-value-blacklist": [ + { + "color": [ + "/^#/", + "/^rgb/" + ] + }, + { + "severity": "error", + "message": "Please refer to the Carbon guidelines for the appropriate tokens to use: https://www.carbondesignsystem.com/" + } + ] + } }, "husky": { "hooks": { From a1bd786ec865dfa7acc3d981a0d911a1471cffe1 Mon Sep 17 00:00:00 2001 From: Sonia Muzemil Date: Wed, 1 Jul 2020 13:46:18 -0500 Subject: [PATCH 2/9] feat(linter): custom formatter is finished --- package.json | 13 +++--- sass-msg-formatter.js | 102 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 sass-msg-formatter.js diff --git a/package.json b/package.json index b78a15548d..1bb62d2f07 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "format:diff": "prettier --list-different \"**/*.{scss,css,js,jsx,md,ts}\"", "lint": "yarn lint:javascript && yarn lint:stylelint", "lint:javascript": "eslint --ext .jsx --ext .js .", - "lint:stylelint": "stylelint './src/**/*.scss' --syntax scss --ignorePath .gitignore", + "lint:stylelint": "stylelint './src/**/*.scss' --syntax scss --ignorePath .gitignore --custom-formatter ./sass-msg-formatter.js", "prepare": "yarn build", "publish-npm": "yarn semantic-release", "start": "yarn test:engines && yarn storybook", @@ -60,11 +60,14 @@ "margin": [ "px", "rem" + ], + "transition": [ + "s", + "ms" ] }, { - "severity": "error", - "message": "Please refer to the Carbon guidelines for the appropriate tokens to use: https://www.carbondesignsystem.com/" + "severity": "error" } ], "declaration-property-value-blacklist": [ @@ -75,8 +78,7 @@ ] }, { - "severity": "error", - "message": "Please refer to the Carbon guidelines for the appropriate tokens to use: https://www.carbondesignsystem.com/" + "severity": "error" } ] } @@ -118,6 +120,7 @@ "carbon-components": "10.12.0", "carbon-components-react": "7.12.0", "carbon-icons": "^7.0.7", + "chalk": "^4.1.0", "classnames": "^2.2.5", "core-js": "3.6.5", "immutability-helper": "^2.9.0", diff --git a/sass-msg-formatter.js b/sass-msg-formatter.js new file mode 100644 index 0000000000..a48fda9f07 --- /dev/null +++ b/sass-msg-formatter.js @@ -0,0 +1,102 @@ +const chalk = require('chalk'); + +// colored text constants +const errorText = chalk.bold.red; +const warningText = chalk.yellow; +const urlText = chalk.underline.cyan; +const titleText = chalk.bgYellow; +const numberedText = chalk.dim; +const ruleNameText = chalk.bgWhite.black; + +/* + * filterForErrors: filters out elements in the results array that don't have errors + */ +function filterForErrors(result) { + return result.errored; +} + +/* + * generateErrorIcon: generates a custom error or warning text depending on the severity of the error + */ +function generateErrorIcon(severity) { + let errorIcon = ''; + switch (severity) { + case 'error': + errorIcon = errorText('ERROR'); + break; + case 'warning': + errorIcon = warningText('warning'); + break; + default: + errorIcon += ''; + break; + } + return errorIcon; +} + +/* + * formatTabbing: controls how many tabs are in between the location and the rule depending on how long the location is + */ +function formatTabbing(error) { + if (`${error.line}:${error.column}`.length < 6) { + return '\t \t'; + } + return '\t'; +} + +/* + * createCustomMessage: returns a custom message with a link to the carbon documentation depending on what the error is + */ +function createCustomMessage(text) { + let message; + if (text.includes('color"')) { + const url = urlText('https://www.carbondesignsystem.com/guidelines/color/usage'); + message = `\n\t${text}\n\t> Please refer to the Carbon documentation for proper color tokens: ${url}`; + } else if (text.includes('"margin') || text.includes('"padding')) { + const url = urlText('https://www.carbondesignsystem.com/guidelines/spacing#spacing-scale'); + message = `\n\t${text}\n\t> Please refer to the Carbon documentation for proper spacing values: ${url}`; + } else if (text.includes('"font')) { + const url = urlText('https://www.carbondesignsystem.com/guidelines/typography/productive'); + message = `\n\t${text}\n\t> Please refer to the Carbon productive typography documentation for proper font values: ${url}`; + } else if (text.includes('transition')) { + const url = urlText('https://www.carbondesignsystem.com/guidelines/motion/overview'); + message = `\n\t${text}\n\t> Please refer to the Carbon motion documentation for transitions: ${url}`; + } + return message; +} + +/* + * formatError: formats the error message + */ +function formatError(errors) { + let errorMsg = ''; + errors.forEach((error, i) => { + const number = numberedText(`${i + 1}.`); + errorMsg += `${number} \t${generateErrorIcon(error.severity)} \t ${error.line}:${ + error.column + } ${formatTabbing(error)} ${ruleNameText(error.rule)} \n \t${createCustomMessage( + error.text + )}\n\n`; + }); + + return errorMsg; +} + +/** + * @type {import('stylelint').Formatter} + */ +function formatter(results) { + let formattedMsg = titleText('\n!! WARNINGS !!\n\n'); + const filesWithErrors = results.filter(filterForErrors); + filesWithErrors.forEach(result => { + const errors = result.warnings; + const errorMessage = formatError(errors); + formattedMsg += chalk.bold('Source: '); + formattedMsg += `${result.source} \n`; + formattedMsg += `${errorMessage} \n `; + }); + + return formattedMsg; +} + +module.exports = formatter; From a9ec5079498c8fe31687a4a41f7f7f627c5d53a7 Mon Sep 17 00:00:00 2001 From: Sonia Muzemil Date: Wed, 1 Jul 2020 16:32:17 -0500 Subject: [PATCH 3/9] fix(linting): fixed linting errors --- sass-msg-formatter.js | 5 ++++- src/components/GaugeCard/_gauge-card.scss | 2 +- src/components/Header/_header.scss | 11 ++++++----- src/components/SideNav/SideNav.story.scss | 2 +- src/components/SideNav/_side-nav.scss | 3 ++- src/components/TableCard/_table-card.scss | 2 +- src/components/TileCatalog/_catalog-content.scss | 2 +- src/components/TileGallery/_tile-gallery.scss | 2 +- yarn.lock | 8 ++++++++ 9 files changed, 25 insertions(+), 12 deletions(-) diff --git a/sass-msg-formatter.js b/sass-msg-formatter.js index a48fda9f07..00fcbbedbc 100644 --- a/sass-msg-formatter.js +++ b/sass-msg-formatter.js @@ -86,8 +86,11 @@ function formatError(errors) { * @type {import('stylelint').Formatter} */ function formatter(results) { - let formattedMsg = titleText('\n!! WARNINGS !!\n\n'); + let formattedMsg = ''; const filesWithErrors = results.filter(filterForErrors); + if (filesWithErrors.length > 0) { + formattedMsg += titleText('\n!! WARNINGS !!\n\n'); + } filesWithErrors.forEach(result => { const errors = result.warnings; const errorMessage = formatError(errors); diff --git a/src/components/GaugeCard/_gauge-card.scss b/src/components/GaugeCard/_gauge-card.scss index f982866bfc..ae9493d686 100644 --- a/src/components/GaugeCard/_gauge-card.scss +++ b/src/components/GaugeCard/_gauge-card.scss @@ -32,7 +32,7 @@ stroke-dasharray: 0 var(--stroke-dash-array); transform: rotate(-90deg); transform-origin: center; - transition: all 0.2s ease-in; + transition: all $duration--moderate-01 ease-in; .#{$iot-prefix}--gauge__loaded & { stroke-dasharray: var(--stroke-dash) var(--stroke-dash-array); diff --git a/src/components/Header/_header.scss b/src/components/Header/_header.scss index 483b6f4d0a..9a99096e34 100644 --- a/src/components/Header/_header.scss +++ b/src/components/Header/_header.scss @@ -59,7 +59,7 @@ .#{$prefix}--header__menu .#{$prefix}--header__menu-item[role='menuitem'] { display: flex; align-items: center; - color: #c6c6c6; + color: $active-ui; height: 100%; font-size: 0.875rem; font-weight: 400; @@ -68,7 +68,8 @@ text-decoration: none; user-select: none; border: 2px solid #0000; - transition: background-color 110ms, border-color 110ms, color 110ms; + transition: background-color $duration--fast-02, border-color $duration--fast-02, + color $duration--fast-02; justify-content: center; padding: 0; width: 100%; @@ -100,10 +101,10 @@ // Used for links that are directly in the menubar to span the full height height: 100%; // Text styles - font-size: rem(14px); + font-size: carbon--type-scale(1); font-weight: 400; letter-spacing: 0; - line-height: rem(18px); + line-height: carbon--type-scale(3); // Reset link styles and make sure the text isn't selectable text-decoration: none; user-select: none; @@ -119,7 +120,7 @@ button.#{$prefix}--header__menu-item { &:focus { border-color: #fff; - color: #f4f4f4; + color: $ui-02; outline: none; } } diff --git a/src/components/SideNav/SideNav.story.scss b/src/components/SideNav/SideNav.story.scss index 8a8d098085..d843d7ce53 100644 --- a/src/components/SideNav/SideNav.story.scss +++ b/src/components/SideNav/SideNav.story.scss @@ -3,7 +3,7 @@ .#{$iot-prefix}--main-content { padding-top: 3rem; height: 100%; - transition: all 0.11s cubic-bezier(0.2, 0, 1, 0.9); + transition: all $duration--fast-02 cubic-bezier(0.2, 0, 1, 0.9); width: 100%; @media (min-width: 66em) { diff --git a/src/components/SideNav/_side-nav.scss b/src/components/SideNav/_side-nav.scss index 987f38857d..276c9ee164 100644 --- a/src/components/SideNav/_side-nav.scss +++ b/src/components/SideNav/_side-nav.scss @@ -43,7 +43,8 @@ padding: 0 $spacing-05; position: relative; text-decoration: none; - transition: color 110ms, background-color 110ms, outline 110ms; + transition: color $duration--fast-02, background-color $duration--fast-02, + outline $duration--fast-02; &:focus { outline: 2px solid $interactive-01; diff --git a/src/components/TableCard/_table-card.scss b/src/components/TableCard/_table-card.scss index 155b9d5b1d..02cfb9595a 100644 --- a/src/components/TableCard/_table-card.scss +++ b/src/components/TableCard/_table-card.scss @@ -27,7 +27,7 @@ p { margin-bottom: 8px; - font-size: 14px; + font-size: carbon--type-scale(1); font-weight: 600; } } diff --git a/src/components/TileCatalog/_catalog-content.scss b/src/components/TileCatalog/_catalog-content.scss index 6f87b2c24f..3d3fc4abe5 100644 --- a/src/components/TileCatalog/_catalog-content.scss +++ b/src/components/TileCatalog/_catalog-content.scss @@ -22,7 +22,7 @@ } .#{$iot-prefix}--sample-tile-title { - color: #3d70b2; + color: $inverse-support-04; text-overflow: ellipsis; white-space: nowrap; overflow-x: hidden; diff --git a/src/components/TileGallery/_tile-gallery.scss b/src/components/TileGallery/_tile-gallery.scss index bf6e9f358c..9247553f6b 100644 --- a/src/components/TileGallery/_tile-gallery.scss +++ b/src/components/TileGallery/_tile-gallery.scss @@ -169,7 +169,7 @@ transform: translate(-50%, -50%); width: 100%; height: 100%; - transition: 0.5s ease; + transition: $duration--slow-01 ease; opacity: 0; display: flex; align-items: center; diff --git a/yarn.lock b/yarn.lock index c233e8f7d3..a9ad937ad4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6225,6 +6225,14 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + change-emitter@^0.1.2: version "0.1.6" resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515" From efad16ae7eb6761f2725b96cd4ea957ebd10aada Mon Sep 17 00:00:00 2001 From: Sonia Muzemil Date: Tue, 7 Jul 2020 17:07:19 -0500 Subject: [PATCH 4/9] fix(linting): added tests and jdocs --- package.json | 6 +- sassMsgFormatter.js | 132 +++++++++++++++++++++++++++++++++++++++ sassMsgFormatter.test.js | 97 ++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 sassMsgFormatter.js create mode 100644 sassMsgFormatter.test.js diff --git a/package.json b/package.json index 1bb62d2f07..3fe2382132 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "format:diff": "prettier --list-different \"**/*.{scss,css,js,jsx,md,ts}\"", "lint": "yarn lint:javascript && yarn lint:stylelint", "lint:javascript": "eslint --ext .jsx --ext .js .", - "lint:stylelint": "stylelint './src/**/*.scss' --syntax scss --ignorePath .gitignore --custom-formatter ./sass-msg-formatter.js", + "lint:stylelint": "stylelint './src/**/*.scss' --syntax scss --ignorePath .gitignore --custom-formatter ./sassMsgFormatter.js", "prepare": "yarn build", "publish-npm": "yarn semantic-release", "start": "yarn test:engines && yarn storybook", @@ -61,6 +61,10 @@ "px", "rem" ], + "padding": [ + "px", + "rem" + ], "transition": [ "s", "ms" diff --git a/sassMsgFormatter.js b/sassMsgFormatter.js new file mode 100644 index 0000000000..94fc33f258 --- /dev/null +++ b/sassMsgFormatter.js @@ -0,0 +1,132 @@ +const chalk = require('chalk'); + +/** + * @constant + */ +const ERROR = chalk.bold.red; +const WARNING = chalk.yellow; +const URL = chalk.underline.cyan; +const TITLE = chalk.bgYellow; +const NUMBER = chalk.dim; +const RULE = chalk.bgWhite.black; + +/** + * returns the boolean representing whether a file has any errors for filtering purposes + * @param {Object} result - the object representing the result of a linting session + * @returns {Boolean} returns true or false depending on whether the file has errors or not + */ +function filterForErrors(result) { + return result.errored; +} + +/** + * creates colored text that describes the severity of a problem + * @param {String} severity - error.severity, the severity of the error + * @returns {String} returns colored error text depending on the severity + */ +function generateErrorIcon(severity) { + let errorIcon = ''; + switch (severity) { + case 'error': + errorIcon = ERROR('ERROR'); + break; + case 'warning': + errorIcon = WARNING('warning'); + break; + default: + errorIcon += ''; + break; + } + return errorIcon; +} + +/** + * indents a piece of text depending on the length of the previous block of text + * @param {Object} error - the specific error + * @returns {String} returns the appropriate amount of tab characters + */ +function formatTabbing(error) { + if (`${error.line}:${error.column}`.length < 6) { + return '\t \t'; + } + return '\t'; +} + +/** + * creates a message with a link to the carbon documentation depending on the individual error + * @param {String} text - the error.text property of an error message, the defaul error message stylelint produces + * @returns {String} returns a custom informational message for the type of error + */ +function createCustomMessage(text) { + let message = ''; + if (text) { + if (text.includes('color"')) { + const url = URL('https://www.carbondesignsystem.com/guidelines/color/usage'); + message = `\n\t${text}\n\t> Please refer to the Carbon documentation for proper color tokens: ${url}`; + } else if (text.includes('"margin') || text.includes('"padding')) { + const url = URL('https://www.carbondesignsystem.com/guidelines/spacing#spacing-scale'); + message = `\n\t${text}\n\t> Please refer to the Carbon documentation for proper spacing values: ${url}`; + } else if (text.includes('"font')) { + const url = URL('https://www.carbondesignsystem.com/guidelines/typography/productive'); + message = `\n\t${text}\n\t> Please refer to the Carbon productive typography documentation for proper font values: ${url}`; + } else if (text.includes('transition')) { + const url = URL('https://www.carbondesignsystem.com/guidelines/motion/overview'); + message = `\n\t${text}\n\t> Please refer to the Carbon motion documentation for transitions: ${url}`; + } + } + return message; +} + +/** + * formats the error message + * @param {Array} errors - an array of all the errors in the linting session + * @returns {String} returns a formatted error message + */ + +function formatError(errors) { + let errorMsg = ''; + errors.forEach((error, i) => { + const number = NUMBER(`${i + 1}.`); + errorMsg += `${number} \t${generateErrorIcon(error.severity)} \t ${error.line}:${ + error.column + } ${formatTabbing(error)} ${RULE(error.rule)}\n \t${createCustomMessage(error.text)}\n\n`; + }); + + return errorMsg; +} + +/** + * formats the message and is sent to the stylelint call + * @param {Array} results - the results from linting + * @returns {String} returns the formatted message + */ + +/** + * @type {import('stylelint').Formatter} + */ +function formatter(results) { + let formattedMsg = ''; + if (results) { + const filesWithErrors = results.filter(filterForErrors); + if (filesWithErrors.length > 0) { + formattedMsg += TITLE('\n!! WARNINGS !!\n\n'); + } + filesWithErrors.forEach(result => { + const errors = result.warnings; + const errorMessage = formatError(errors); + formattedMsg += chalk.bold('Source: '); + formattedMsg += `${result.source}\n`; + formattedMsg += `${errorMessage}\n`; + }); + } + return formattedMsg; +} + +module.exports = { + filterForErrors, + generateErrorIcon, + formatTabbing, + createCustomMessage, + formatError, + formatter, +}; diff --git a/sassMsgFormatter.test.js b/sassMsgFormatter.test.js new file mode 100644 index 0000000000..b1f027a2b6 --- /dev/null +++ b/sassMsgFormatter.test.js @@ -0,0 +1,97 @@ +import { + filterForErrors, + generateErrorIcon, + formatTabbing, + createCustomMessage, + formatError, + formatter, +} from './sassMsgFormatter'; + +const chalk = require('chalk'); + +const ERROR = chalk.bold.red; +const WARNING = chalk.yellow; +const URL = chalk.underline.cyan; +const TITLE = chalk.bgYellow; + +const exampleOne = { + source: 'test1.js', + errored: true, + warnings: [ + { + severity: 'error', + line: 21, + column: 33, + rule: 'declaration-property-unit-blacklist', + text: 'Unexpected value in property "color"', + }, + ], +}; +const exampleTwo = { + source: 'test2.js', + errored: true, + warnings: [ + { + severity: 'error', + line: 123, + column: 76, + rule: 'declaration-property-value-blacklist', + text: 'Unexpected value in "font-family"', + }, + ], +}; + +describe('sass-msg-formatter', () => { + it('filters for errors', () => { + // this function should return false unless errored is equal to true + expect(filterForErrors({ errored: undefined })).toBeFalsy(); + expect(filterForErrors({ errored: true })).toBeTruthy(); + expect(filterForErrors({ errored: false })).toBeFalsy(); + expect(filterForErrors({ errored: null })).toBeFalsy(); + }); + it('generates error icons', () => { + // expect(generateErrorIcon('error')).toEqual(ERROR('ERROR')); + expect(generateErrorIcon('error')).toContain('ERROR'); + expect(generateErrorIcon('warning')).toContain('warning'); + expect(generateErrorIcon(undefined)).toHaveLength(0); + }); + it('formats tabbing', () => { + expect(formatTabbing({ line: 121, column: 23 })).toHaveLength(1); + expect(formatTabbing({ line: 1, column: 123 })).toHaveLength(3); + expect(formatTabbing({ line: 14, column: 23 })).toHaveLength(3); + }); + it('creates custom message', () => { + console.log(exampleOne.warnings[0].text); + expect(createCustomMessage(exampleOne.warnings[0].text)).toContain( + URL('https://www.carbondesignsystem.com/guidelines/color/usage') + ); + expect(createCustomMessage(exampleTwo.warnings[0].text)).toContain( + URL('https://www.carbondesignsystem.com/guidelines/typography/productive') + ); + expect(createCustomMessage(null)).toHaveLength(0); + }); + it('formats errors', () => { + expect(formatError(exampleOne.warnings)).toContain(ERROR('ERROR')); + expect(formatError(exampleTwo.warnings)).toContain(ERROR('ERROR')); + expect( + formatError([ + { + severity: 'warning', + line: 123, + column: 45, + rule: 'insert-rule-here', + text: 'error text', + }, + ]) + ).toContain(WARNING('warning')); + }); + it('formats message', () => { + const resultsTest = [exampleOne, exampleTwo, { errored: false, warnings: undefined }]; + expect(resultsTest.filter(filterForErrors)).toHaveLength(2); + expect(formatter(resultsTest)).toContain(TITLE('\n!! WARNINGS !!\n\n')); + expect(formatter(resultsTest)).toContain(formatError(exampleOne.warnings)); + expect(formatter(resultsTest)).toContain(formatError(exampleTwo.warnings)); + expect(formatter([{ errored: false, warnings: undefined }])).toMatch(''); + expect(formatter(null)).toHaveLength(0); + }); +}); From c3208d596bebe681115b2c27b5b3b08fd4e5080b Mon Sep 17 00:00:00 2001 From: Sonia Muzemil Date: Wed, 8 Jul 2020 11:39:34 -0500 Subject: [PATCH 5/9] fix(linting): fixed errors --- sassMsgFormatter.js | 17 +-- sassMsgFormatter.test.js | 6 +- sassMsgFormatterFunctions.js | 103 ++++++++++++++++++ .../TileCatalog/_catalog-content.scss | 2 +- src/components/TileCatalog/_tile-group.scss | 2 +- .../TileCatalogNew/_tile-catalog.scss | 2 +- src/components/WizardModal/_wizard-modal.scss | 2 +- 7 files changed, 112 insertions(+), 22 deletions(-) create mode 100644 sassMsgFormatterFunctions.js diff --git a/sassMsgFormatter.js b/sassMsgFormatter.js index 94fc33f258..ed13cacbee 100644 --- a/sassMsgFormatter.js +++ b/sassMsgFormatter.js @@ -3,10 +3,10 @@ const chalk = require('chalk'); /** * @constant */ +const TITLE = chalk.bgYellow; const ERROR = chalk.bold.red; const WARNING = chalk.yellow; const URL = chalk.underline.cyan; -const TITLE = chalk.bgYellow; const NUMBER = chalk.dim; const RULE = chalk.bgWhite.black; @@ -95,12 +95,6 @@ function formatError(errors) { return errorMsg; } -/** - * formats the message and is sent to the stylelint call - * @param {Array} results - the results from linting - * @returns {String} returns the formatted message - */ - /** * @type {import('stylelint').Formatter} */ @@ -122,11 +116,4 @@ function formatter(results) { return formattedMsg; } -module.exports = { - filterForErrors, - generateErrorIcon, - formatTabbing, - createCustomMessage, - formatError, - formatter, -}; +module.exports = formatter; diff --git a/sassMsgFormatter.test.js b/sassMsgFormatter.test.js index b1f027a2b6..d699491e55 100644 --- a/sassMsgFormatter.test.js +++ b/sassMsgFormatter.test.js @@ -1,11 +1,11 @@ +import formatter from './sassMsgFormatter'; import { filterForErrors, generateErrorIcon, formatTabbing, createCustomMessage, formatError, - formatter, -} from './sassMsgFormatter'; +} from './sassMsgFormatterFunctions'; const chalk = require('chalk'); @@ -41,7 +41,7 @@ const exampleTwo = { ], }; -describe('sass-msg-formatter', () => { +describe('sassMsgFormatter', () => { it('filters for errors', () => { // this function should return false unless errored is equal to true expect(filterForErrors({ errored: undefined })).toBeFalsy(); diff --git a/sassMsgFormatterFunctions.js b/sassMsgFormatterFunctions.js new file mode 100644 index 0000000000..dbc393e09b --- /dev/null +++ b/sassMsgFormatterFunctions.js @@ -0,0 +1,103 @@ +const chalk = require('chalk'); + +/** + * @constant + */ +const ERROR = chalk.bold.red; +const WARNING = chalk.yellow; +const URL = chalk.underline.cyan; +const NUMBER = chalk.dim; +const RULE = chalk.bgWhite.black; + +/** + * returns the boolean representing whether a file has any errors for filtering purposes + * @param {Object} result - the object representing the result of a linting session + * @returns {Boolean} returns true or false depending on whether the file has errors or not + */ +function filterForErrors(result) { + return result.errored; +} + +/** + * creates colored text that describes the severity of a problem + * @param {String} severity - error.severity, the severity of the error + * @returns {String} returns colored error text depending on the severity + */ +function generateErrorIcon(severity) { + let errorIcon = ''; + switch (severity) { + case 'error': + errorIcon = ERROR('ERROR'); + break; + case 'warning': + errorIcon = WARNING('warning'); + break; + default: + errorIcon += ''; + break; + } + return errorIcon; +} + +/** + * indents a piece of text depending on the length of the previous block of text + * @param {Object} error - the specific error + * @returns {String} returns the appropriate amount of tab characters + */ +function formatTabbing(error) { + if (`${error.line}:${error.column}`.length < 6) { + return '\t \t'; + } + return '\t'; +} + +/** + * creates a message with a link to the carbon documentation depending on the individual error + * @param {String} text - the error.text property of an error message, the defaul error message stylelint produces + * @returns {String} returns a custom informational message for the type of error + */ +function createCustomMessage(text) { + let message = ''; + if (text) { + if (text.includes('color"')) { + const url = URL('https://www.carbondesignsystem.com/guidelines/color/usage'); + message = `\n\t${text}\n\t> Please refer to the Carbon documentation for proper color tokens: ${url}`; + } else if (text.includes('"margin') || text.includes('"padding')) { + const url = URL('https://www.carbondesignsystem.com/guidelines/spacing#spacing-scale'); + message = `\n\t${text}\n\t> Please refer to the Carbon documentation for proper spacing values: ${url}`; + } else if (text.includes('"font')) { + const url = URL('https://www.carbondesignsystem.com/guidelines/typography/productive'); + message = `\n\t${text}\n\t> Please refer to the Carbon productive typography documentation for proper font values: ${url}`; + } else if (text.includes('transition')) { + const url = URL('https://www.carbondesignsystem.com/guidelines/motion/overview'); + message = `\n\t${text}\n\t> Please refer to the Carbon motion documentation for transitions: ${url}`; + } + } + return message; +} + +/** + * formats the error message + * @param {Array} errors - an array of all the errors in the linting session + * @returns {String} returns a formatted error message + */ + +function formatError(errors) { + let errorMsg = ''; + errors.forEach((error, i) => { + const number = NUMBER(`${i + 1}.`); + errorMsg += `${number} \t${generateErrorIcon(error.severity)} \t ${error.line}:${ + error.column + } ${formatTabbing(error)} ${RULE(error.rule)}\n \t${createCustomMessage(error.text)}\n\n`; + }); + + return errorMsg; +} + +module.exports = { + filterForErrors, + generateErrorIcon, + formatTabbing, + createCustomMessage, + formatError, +}; diff --git a/src/components/TileCatalog/_catalog-content.scss b/src/components/TileCatalog/_catalog-content.scss index 3d3fc4abe5..159fa93eb5 100644 --- a/src/components/TileCatalog/_catalog-content.scss +++ b/src/components/TileCatalog/_catalog-content.scss @@ -39,7 +39,7 @@ .#{$iot-prefix}--sample-tile-contents { display: flex; flex-flow: column nowrap; - padding: 0 1rem; + padding: 0 $spacing-05; align-self: flex-start; } diff --git a/src/components/TileCatalog/_tile-group.scss b/src/components/TileCatalog/_tile-group.scss index b373bf7dea..3859571bd1 100644 --- a/src/components/TileCatalog/_tile-group.scss +++ b/src/components/TileCatalog/_tile-group.scss @@ -21,7 +21,7 @@ flex: 1 1 33.33%; display: none; min-height: 0px; - padding: 0px; + padding: 0; border-top: 0px; border-bottom: 0px; @media screen and (min-width: $two-pane) { diff --git a/src/components/TileCatalogNew/_tile-catalog.scss b/src/components/TileCatalogNew/_tile-catalog.scss index 24a217ce92..a5abb848de 100644 --- a/src/components/TileCatalogNew/_tile-catalog.scss +++ b/src/components/TileCatalogNew/_tile-catalog.scss @@ -43,7 +43,7 @@ svg { height: 2.5rem; width: 2.5rem; - padding: 0.75rem; + padding: $spacing-04; } } } diff --git a/src/components/WizardModal/_wizard-modal.scss b/src/components/WizardModal/_wizard-modal.scss index 19318d9804..5afdb11c69 100644 --- a/src/components/WizardModal/_wizard-modal.scss +++ b/src/components/WizardModal/_wizard-modal.scss @@ -7,7 +7,7 @@ .#{$prefix}--progress { /* need to pad some space for the focus outlines*/ - padding: 3px; + padding: $spacing-09; } .#{$prefix}--progress-step { max-width: 150px; From e7b139de4fb18955973a6d39f66a5fbea6c56745 Mon Sep 17 00:00:00 2001 From: Sonia Muzemil Date: Mon, 13 Jul 2020 13:08:38 -0500 Subject: [PATCH 6/9] fix(lint): deleted extra file + moved used files --- .../stylelint/sassMsgFormatter.js | 0 .../stylelint/sassMsgFormatter.test.js | 0 .../stylelint/sassMsgFormatterFunctions.js | 0 package.json | 2 +- sass-msg-formatter.js | 105 ------------------ 5 files changed, 1 insertion(+), 106 deletions(-) rename sassMsgFormatter.js => config/stylelint/sassMsgFormatter.js (100%) rename sassMsgFormatter.test.js => config/stylelint/sassMsgFormatter.test.js (100%) rename sassMsgFormatterFunctions.js => config/stylelint/sassMsgFormatterFunctions.js (100%) delete mode 100644 sass-msg-formatter.js diff --git a/sassMsgFormatter.js b/config/stylelint/sassMsgFormatter.js similarity index 100% rename from sassMsgFormatter.js rename to config/stylelint/sassMsgFormatter.js diff --git a/sassMsgFormatter.test.js b/config/stylelint/sassMsgFormatter.test.js similarity index 100% rename from sassMsgFormatter.test.js rename to config/stylelint/sassMsgFormatter.test.js diff --git a/sassMsgFormatterFunctions.js b/config/stylelint/sassMsgFormatterFunctions.js similarity index 100% rename from sassMsgFormatterFunctions.js rename to config/stylelint/sassMsgFormatterFunctions.js diff --git a/package.json b/package.json index 3fe2382132..12c3101d5c 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "format:diff": "prettier --list-different \"**/*.{scss,css,js,jsx,md,ts}\"", "lint": "yarn lint:javascript && yarn lint:stylelint", "lint:javascript": "eslint --ext .jsx --ext .js .", - "lint:stylelint": "stylelint './src/**/*.scss' --syntax scss --ignorePath .gitignore --custom-formatter ./sassMsgFormatter.js", + "lint:stylelint": "stylelint './src/**/*.scss' --syntax scss --ignorePath .gitignore --custom-formatter ./config/stylelint/sassMsgFormatter.js", "prepare": "yarn build", "publish-npm": "yarn semantic-release", "start": "yarn test:engines && yarn storybook", diff --git a/sass-msg-formatter.js b/sass-msg-formatter.js deleted file mode 100644 index 00fcbbedbc..0000000000 --- a/sass-msg-formatter.js +++ /dev/null @@ -1,105 +0,0 @@ -const chalk = require('chalk'); - -// colored text constants -const errorText = chalk.bold.red; -const warningText = chalk.yellow; -const urlText = chalk.underline.cyan; -const titleText = chalk.bgYellow; -const numberedText = chalk.dim; -const ruleNameText = chalk.bgWhite.black; - -/* - * filterForErrors: filters out elements in the results array that don't have errors - */ -function filterForErrors(result) { - return result.errored; -} - -/* - * generateErrorIcon: generates a custom error or warning text depending on the severity of the error - */ -function generateErrorIcon(severity) { - let errorIcon = ''; - switch (severity) { - case 'error': - errorIcon = errorText('ERROR'); - break; - case 'warning': - errorIcon = warningText('warning'); - break; - default: - errorIcon += ''; - break; - } - return errorIcon; -} - -/* - * formatTabbing: controls how many tabs are in between the location and the rule depending on how long the location is - */ -function formatTabbing(error) { - if (`${error.line}:${error.column}`.length < 6) { - return '\t \t'; - } - return '\t'; -} - -/* - * createCustomMessage: returns a custom message with a link to the carbon documentation depending on what the error is - */ -function createCustomMessage(text) { - let message; - if (text.includes('color"')) { - const url = urlText('https://www.carbondesignsystem.com/guidelines/color/usage'); - message = `\n\t${text}\n\t> Please refer to the Carbon documentation for proper color tokens: ${url}`; - } else if (text.includes('"margin') || text.includes('"padding')) { - const url = urlText('https://www.carbondesignsystem.com/guidelines/spacing#spacing-scale'); - message = `\n\t${text}\n\t> Please refer to the Carbon documentation for proper spacing values: ${url}`; - } else if (text.includes('"font')) { - const url = urlText('https://www.carbondesignsystem.com/guidelines/typography/productive'); - message = `\n\t${text}\n\t> Please refer to the Carbon productive typography documentation for proper font values: ${url}`; - } else if (text.includes('transition')) { - const url = urlText('https://www.carbondesignsystem.com/guidelines/motion/overview'); - message = `\n\t${text}\n\t> Please refer to the Carbon motion documentation for transitions: ${url}`; - } - return message; -} - -/* - * formatError: formats the error message - */ -function formatError(errors) { - let errorMsg = ''; - errors.forEach((error, i) => { - const number = numberedText(`${i + 1}.`); - errorMsg += `${number} \t${generateErrorIcon(error.severity)} \t ${error.line}:${ - error.column - } ${formatTabbing(error)} ${ruleNameText(error.rule)} \n \t${createCustomMessage( - error.text - )}\n\n`; - }); - - return errorMsg; -} - -/** - * @type {import('stylelint').Formatter} - */ -function formatter(results) { - let formattedMsg = ''; - const filesWithErrors = results.filter(filterForErrors); - if (filesWithErrors.length > 0) { - formattedMsg += titleText('\n!! WARNINGS !!\n\n'); - } - filesWithErrors.forEach(result => { - const errors = result.warnings; - const errorMessage = formatError(errors); - formattedMsg += chalk.bold('Source: '); - formattedMsg += `${result.source} \n`; - formattedMsg += `${errorMessage} \n `; - }); - - return formattedMsg; -} - -module.exports = formatter; From cc10a1861e8a2396ac9c44ef0f19fa928ebff563 Mon Sep 17 00:00:00 2001 From: Sonia Muzemil Date: Mon, 13 Jul 2020 14:30:33 -0500 Subject: [PATCH 7/9] fix(linting): fixed suggested changes --- package.json | 2 +- src/components/Header/_header.scss | 6 +----- src/components/TableCard/_table-card.scss | 2 +- src/components/TileCatalog/_catalog-content.scss | 2 +- src/components/WizardModal/_wizard-modal.scss | 4 ---- 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 8c60dce76e..77a33ed8de 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,6 @@ "carbon-components": "10.12.0", "carbon-components-react": "7.12.0", "carbon-icons": "^7.0.7", - "chalk": "^4.1.0", "classnames": "^2.2.5", "core-js": "3.6.5", "downshift": "^1.31.14", @@ -201,6 +200,7 @@ "babel-plugin-require-context-hook": "^1.0.0", "babel-plugin-styled-components": "^1.10.7", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", + "chalk": "^4.1.0", "check-node-version": "^4.0.3", "coveralls": "^3.0.2", "cross-env": "^6.0.3", diff --git a/src/components/Header/_header.scss b/src/components/Header/_header.scss index 9a99096e34..ef47446d11 100644 --- a/src/components/Header/_header.scss +++ b/src/components/Header/_header.scss @@ -1,4 +1,5 @@ @import '~carbon-components/scss/globals/scss/vars'; +@include carbon--type-style('body-short-01'); .#{$prefix}--header { .#{$prefix}--skip-to-content:focus { @@ -100,11 +101,6 @@ padding: 0 mini-units(2); // Used for links that are directly in the menubar to span the full height height: 100%; - // Text styles - font-size: carbon--type-scale(1); - font-weight: 400; - letter-spacing: 0; - line-height: carbon--type-scale(3); // Reset link styles and make sure the text isn't selectable text-decoration: none; user-select: none; diff --git a/src/components/TableCard/_table-card.scss b/src/components/TableCard/_table-card.scss index 02cfb9595a..c619000e67 100644 --- a/src/components/TableCard/_table-card.scss +++ b/src/components/TableCard/_table-card.scss @@ -27,7 +27,7 @@ p { margin-bottom: 8px; - font-size: carbon--type-scale(1); + font-size: carbon--type-scale(2); font-weight: 600; } } diff --git a/src/components/TileCatalog/_catalog-content.scss b/src/components/TileCatalog/_catalog-content.scss index 159fa93eb5..04d68db0fb 100644 --- a/src/components/TileCatalog/_catalog-content.scss +++ b/src/components/TileCatalog/_catalog-content.scss @@ -22,7 +22,7 @@ } .#{$iot-prefix}--sample-tile-title { - color: $inverse-support-04; + color: $link-01; text-overflow: ellipsis; white-space: nowrap; overflow-x: hidden; diff --git a/src/components/WizardModal/_wizard-modal.scss b/src/components/WizardModal/_wizard-modal.scss index 5afdb11c69..37f3de81a4 100644 --- a/src/components/WizardModal/_wizard-modal.scss +++ b/src/components/WizardModal/_wizard-modal.scss @@ -5,10 +5,6 @@ min-width: 410px; } - .#{$prefix}--progress { - /* need to pad some space for the focus outlines*/ - padding: $spacing-09; - } .#{$prefix}--progress-step { max-width: 150px; } From 23b9d3d9e56c295f0309f091a3336c63cfe3c6fa Mon Sep 17 00:00:00 2001 From: Sonia Muzemil Date: Mon, 13 Jul 2020 14:57:22 -0500 Subject: [PATCH 8/9] fix(linting): tests should pass now --- src/components/Header/_header.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Header/_header.scss b/src/components/Header/_header.scss index ef47446d11..81d1d33a20 100644 --- a/src/components/Header/_header.scss +++ b/src/components/Header/_header.scss @@ -1,5 +1,4 @@ @import '~carbon-components/scss/globals/scss/vars'; -@include carbon--type-style('body-short-01'); .#{$prefix}--header { .#{$prefix}--skip-to-content:focus { @@ -101,6 +100,8 @@ padding: 0 mini-units(2); // Used for links that are directly in the menubar to span the full height height: 100%; + // Text styles + @include carbon--type-style('body-short-01'); // Reset link styles and make sure the text isn't selectable text-decoration: none; user-select: none; From f2ecdba0308cbe7e4a1e4e5bacfcf096dc4e987a Mon Sep 17 00:00:00 2001 From: Sonia Muzemil Date: Tue, 14 Jul 2020 13:02:41 -0500 Subject: [PATCH 9/9] fix(linting): deleted extra file --- config/stylelint/sassMsgFormatter.js | 8 +- config/stylelint/sassMsgFormatter.test.js | 36 +++--- config/stylelint/sassMsgFormatterFunctions.js | 103 ------------------ 3 files changed, 20 insertions(+), 127 deletions(-) delete mode 100644 config/stylelint/sassMsgFormatterFunctions.js diff --git a/config/stylelint/sassMsgFormatter.js b/config/stylelint/sassMsgFormatter.js index ed13cacbee..2c42f00406 100644 --- a/config/stylelint/sassMsgFormatter.js +++ b/config/stylelint/sassMsgFormatter.js @@ -3,7 +3,6 @@ const chalk = require('chalk'); /** * @constant */ -const TITLE = chalk.bgYellow; const ERROR = chalk.bold.red; const WARNING = chalk.yellow; const URL = chalk.underline.cyan; @@ -116,4 +115,9 @@ function formatter(results) { return formattedMsg; } -module.exports = formatter; +const formatterModule = (module.exports = formatter); +formatterModule.filterForErrors = filterForErrors; +formatterModule.generateErrorIcon = generateErrorIcon; +formatterModule.formatTabbing = formatTabbing; +formatterModule.createCustomMessage = createCustomMessage; +formatterModule.formatError = formatError; diff --git a/config/stylelint/sassMsgFormatter.test.js b/config/stylelint/sassMsgFormatter.test.js index d699491e55..b8b7076105 100644 --- a/config/stylelint/sassMsgFormatter.test.js +++ b/config/stylelint/sassMsgFormatter.test.js @@ -1,12 +1,4 @@ -import formatter from './sassMsgFormatter'; -import { - filterForErrors, - generateErrorIcon, - formatTabbing, - createCustomMessage, - formatError, -} from './sassMsgFormatterFunctions'; - +const formatter = require('./sassMsgFormatter'); const chalk = require('chalk'); const ERROR = chalk.bold.red; @@ -44,21 +36,21 @@ const exampleTwo = { describe('sassMsgFormatter', () => { it('filters for errors', () => { // this function should return false unless errored is equal to true - expect(filterForErrors({ errored: undefined })).toBeFalsy(); - expect(filterForErrors({ errored: true })).toBeTruthy(); - expect(filterForErrors({ errored: false })).toBeFalsy(); - expect(filterForErrors({ errored: null })).toBeFalsy(); + expect(formatter.filterForErrors({ errored: undefined })).toBeFalsy(); + expect(formatter.filterForErrors({ errored: true })).toBeTruthy(); + expect(formatter.filterForErrors({ errored: false })).toBeFalsy(); + expect(formatter.filterForErrors({ errored: null })).toBeFalsy(); }); it('generates error icons', () => { // expect(generateErrorIcon('error')).toEqual(ERROR('ERROR')); - expect(generateErrorIcon('error')).toContain('ERROR'); - expect(generateErrorIcon('warning')).toContain('warning'); - expect(generateErrorIcon(undefined)).toHaveLength(0); + expect(formatter.generateErrorIcon('error')).toContain('ERROR'); + expect(formatter.generateErrorIcon('warning')).toContain('warning'); + expect(formatter.generateErrorIcon(undefined)).toHaveLength(0); }); it('formats tabbing', () => { - expect(formatTabbing({ line: 121, column: 23 })).toHaveLength(1); - expect(formatTabbing({ line: 1, column: 123 })).toHaveLength(3); - expect(formatTabbing({ line: 14, column: 23 })).toHaveLength(3); + expect(formatter.formatTabbing({ line: 121, column: 23 })).toHaveLength(1); + expect(formatter.formatTabbing({ line: 1, column: 123 })).toHaveLength(3); + expect(formatter.formatTabbing({ line: 14, column: 23 })).toHaveLength(3); }); it('creates custom message', () => { console.log(exampleOne.warnings[0].text); @@ -71,8 +63,8 @@ describe('sassMsgFormatter', () => { expect(createCustomMessage(null)).toHaveLength(0); }); it('formats errors', () => { - expect(formatError(exampleOne.warnings)).toContain(ERROR('ERROR')); - expect(formatError(exampleTwo.warnings)).toContain(ERROR('ERROR')); + expect(formatter.formatError(exampleOne.warnings)).toContain(ERROR('ERROR')); + expect(formatter.formatError(exampleTwo.warnings)).toContain(ERROR('ERROR')); expect( formatError([ { @@ -87,7 +79,7 @@ describe('sassMsgFormatter', () => { }); it('formats message', () => { const resultsTest = [exampleOne, exampleTwo, { errored: false, warnings: undefined }]; - expect(resultsTest.filter(filterForErrors)).toHaveLength(2); + expect(resultsTest.filter(formatter.filterForErrors)).toHaveLength(2); expect(formatter(resultsTest)).toContain(TITLE('\n!! WARNINGS !!\n\n')); expect(formatter(resultsTest)).toContain(formatError(exampleOne.warnings)); expect(formatter(resultsTest)).toContain(formatError(exampleTwo.warnings)); diff --git a/config/stylelint/sassMsgFormatterFunctions.js b/config/stylelint/sassMsgFormatterFunctions.js deleted file mode 100644 index dbc393e09b..0000000000 --- a/config/stylelint/sassMsgFormatterFunctions.js +++ /dev/null @@ -1,103 +0,0 @@ -const chalk = require('chalk'); - -/** - * @constant - */ -const ERROR = chalk.bold.red; -const WARNING = chalk.yellow; -const URL = chalk.underline.cyan; -const NUMBER = chalk.dim; -const RULE = chalk.bgWhite.black; - -/** - * returns the boolean representing whether a file has any errors for filtering purposes - * @param {Object} result - the object representing the result of a linting session - * @returns {Boolean} returns true or false depending on whether the file has errors or not - */ -function filterForErrors(result) { - return result.errored; -} - -/** - * creates colored text that describes the severity of a problem - * @param {String} severity - error.severity, the severity of the error - * @returns {String} returns colored error text depending on the severity - */ -function generateErrorIcon(severity) { - let errorIcon = ''; - switch (severity) { - case 'error': - errorIcon = ERROR('ERROR'); - break; - case 'warning': - errorIcon = WARNING('warning'); - break; - default: - errorIcon += ''; - break; - } - return errorIcon; -} - -/** - * indents a piece of text depending on the length of the previous block of text - * @param {Object} error - the specific error - * @returns {String} returns the appropriate amount of tab characters - */ -function formatTabbing(error) { - if (`${error.line}:${error.column}`.length < 6) { - return '\t \t'; - } - return '\t'; -} - -/** - * creates a message with a link to the carbon documentation depending on the individual error - * @param {String} text - the error.text property of an error message, the defaul error message stylelint produces - * @returns {String} returns a custom informational message for the type of error - */ -function createCustomMessage(text) { - let message = ''; - if (text) { - if (text.includes('color"')) { - const url = URL('https://www.carbondesignsystem.com/guidelines/color/usage'); - message = `\n\t${text}\n\t> Please refer to the Carbon documentation for proper color tokens: ${url}`; - } else if (text.includes('"margin') || text.includes('"padding')) { - const url = URL('https://www.carbondesignsystem.com/guidelines/spacing#spacing-scale'); - message = `\n\t${text}\n\t> Please refer to the Carbon documentation for proper spacing values: ${url}`; - } else if (text.includes('"font')) { - const url = URL('https://www.carbondesignsystem.com/guidelines/typography/productive'); - message = `\n\t${text}\n\t> Please refer to the Carbon productive typography documentation for proper font values: ${url}`; - } else if (text.includes('transition')) { - const url = URL('https://www.carbondesignsystem.com/guidelines/motion/overview'); - message = `\n\t${text}\n\t> Please refer to the Carbon motion documentation for transitions: ${url}`; - } - } - return message; -} - -/** - * formats the error message - * @param {Array} errors - an array of all the errors in the linting session - * @returns {String} returns a formatted error message - */ - -function formatError(errors) { - let errorMsg = ''; - errors.forEach((error, i) => { - const number = NUMBER(`${i + 1}.`); - errorMsg += `${number} \t${generateErrorIcon(error.severity)} \t ${error.line}:${ - error.column - } ${formatTabbing(error)} ${RULE(error.rule)}\n \t${createCustomMessage(error.text)}\n\n`; - }); - - return errorMsg; -} - -module.exports = { - filterForErrors, - generateErrorIcon, - formatTabbing, - createCustomMessage, - formatError, -};