diff --git a/index.js b/index.js index f89584b..b73533b 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,6 @@ const fs = require('fs'); const path = require('path'); +const csscolors = require('css-color-names'); const exists = (file) => { try { @@ -10,14 +11,33 @@ const exists = (file) => { } } +const reValue = new RegExp([ + // ---- hex colors + '^#[0-9a-z]{3}$', // #def + '^#[0-9a-z]{4}$', // #def0 + '^#[0-9a-z]{6}$', // #ddeeff + '^#[0-9a-z]{8}$', // #ddeeff00 + // ---- numbers + '^[0-9]+(?:\\.[0-9]+)?(?:%|[a-z]+)?$', // 12.34 + unit + // ---- function calls + '^[a-z][a-z0-9-_]*\\(', // foo(...) +].join('|'), 'i'); + +const looksLikeString = (value) => { + return !reValue.test(value) || csscolors[value]; +} + const buildSassValue = (value) => { if (Array.isArray(value)) { - return `(${value.reduce((prev, cur) => prev + `"${cur}",`, '')})`; + return `(${value.reduce((prev, cur) => prev + `${buildSassValue(cur)},`, '')})`; } if (typeof value === "object") { return `(${buildSassMap(value)})`; } - return `"${value}"`; + if (looksLikeString(value)) { + return `"${value}"`; + } + return value; } const buildSassMap = (json) => { diff --git a/package.json b/package.json index 18da68a..c5770f4 100644 --- a/package.json +++ b/package.json @@ -24,5 +24,8 @@ "devDependencies": { "jest": "^23.4.0", "node-sass": "^4.9.2" + }, + "dependencies": { + "css-color-names": "0.0.4" } } diff --git a/tests/__snapshots__/index.test.js.snap b/tests/__snapshots__/index.test.js.snap index 311fc5e..2d19b34 100644 --- a/tests/__snapshots__/index.test.js.snap +++ b/tests/__snapshots__/index.test.js.snap @@ -1,5 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`json-importer async should not resolve Sass values to quoted strings 1`] = ` +"output { + contents: (\\"short-hex-color\\": #def, \\"short-hex-color-with-alpha\\": #def0, \\"long-hex-color\\": #ddeeff, \\"long-hex-color-with-alpha\\": #ddeeff00, \\"named-color\\": \\"red\\", \\"number\\": 16, \\"number-with-percentage\\": 16%, \\"number-with-word-unit\\": 16rem, \\"decimal\\": 12.34, \\"decimal-with-percentage\\": 12.34%, \\"decimal-with-word-unit\\": 12.34rem, \\"function-call\\": black, \\"string\\": \\"foo\\", \\"string-with-spaces\\": \\"who are you\\", \\"array\\": (16, 16px, 16%, 12.34, 12.34px, 12.34%, #def, black, \\"foo\\", \\"who are you\\"), \\"map\\": (\\"short-hex-color\\": #def, \\"short-hex-color-with-alpha\\": #def0, \\"string\\": \\"foo\\", \\"string-with-spaces\\": \\"who are you\\")); } +" +`; + exports[`json-importer async should resolve flat json strings as Sass map 1`] = ` "output { contents: (\\"color\\": \\"red\\", \\"size\\": \\"small\\"); } @@ -20,7 +26,13 @@ exports[`json-importer async should resolve json files in includePaths 1`] = ` exports[`json-importer async should resolve nested json strings as Sass map 1`] = ` "output { - contents: (\\"colors\\": (\\"red\\": \\"#f00\\", \\"blue\\": \\"#00f\\"), \\"sizes\\": (\\"small\\": \\"16px\\", \\"big\\": \\"30px\\")); } + contents: (\\"colors\\": (\\"red\\": #f00, \\"blue\\": #00f), \\"sizes\\": (\\"small\\": 16px, \\"big\\": 30px)); } +" +`; + +exports[`json-importer sync should not resolve Sass values to quoted strings 1`] = ` +"output { + contents: (\\"short-hex-color\\": #def, \\"short-hex-color-with-alpha\\": #def0, \\"long-hex-color\\": #ddeeff, \\"long-hex-color-with-alpha\\": #ddeeff00, \\"named-color\\": \\"red\\", \\"number\\": 16, \\"number-with-percentage\\": 16%, \\"number-with-word-unit\\": 16rem, \\"decimal\\": 12.34, \\"decimal-with-percentage\\": 12.34%, \\"decimal-with-word-unit\\": 12.34rem, \\"function-call\\": black, \\"string\\": \\"foo\\", \\"string-with-spaces\\": \\"who are you\\", \\"array\\": (16, 16px, 16%, 12.34, 12.34px, 12.34%, #def, black, \\"foo\\", \\"who are you\\"), \\"map\\": (\\"short-hex-color\\": #def, \\"short-hex-color-with-alpha\\": #def0, \\"string\\": \\"foo\\", \\"string-with-spaces\\": \\"who are you\\")); } " `; @@ -44,6 +56,6 @@ exports[`json-importer sync should resolve json files in includePaths 1`] = ` exports[`json-importer sync should resolve nested json strings as Sass map 1`] = ` "output { - contents: (\\"colors\\": (\\"red\\": \\"#f00\\", \\"blue\\": \\"#00f\\"), \\"sizes\\": (\\"small\\": \\"16px\\", \\"big\\": \\"30px\\")); } + contents: (\\"colors\\": (\\"red\\": #f00, \\"blue\\": #00f), \\"sizes\\": (\\"small\\": 16px, \\"big\\": 30px)); } " `; diff --git a/tests/fixtures/values.json b/tests/fixtures/values.json new file mode 100644 index 0000000..8fac3fa --- /dev/null +++ b/tests/fixtures/values.json @@ -0,0 +1,34 @@ +{ + "short-hex-color": "#def", + "short-hex-color-with-alpha": "#def0", + "long-hex-color": "#ddeeff", + "long-hex-color-with-alpha": "#ddeeff00", + "named-color": "red", + "number": "16", + "number-with-percentage": "16%", + "number-with-word-unit": "16rem", + "decimal": "12.34", + "decimal-with-percentage": "12.34%", + "decimal-with-word-unit": "12.34rem", + "function-call": "hsl(0,0,0)", + "string": "foo", + "string-with-spaces": "who are you", + "array": [ + 16, + "16px", + "16%", + 12.34, + "12.34px", + "12.34%", + "#def", + "hsl(0,0,0)", + "foo", + "who are you" + ], + "map": { + "short-hex-color": "#def", + "short-hex-color-with-alpha": "#def0", + "string": "foo", + "string-with-spaces": "who are you" + } +} diff --git a/tests/index.test.js b/tests/index.test.js index 6c454c5..4b180be 100644 --- a/tests/index.test.js +++ b/tests/index.test.js @@ -42,6 +42,10 @@ describe('json-importer', () => { func(generate('tests/fixtures/list.json')) .then(result => expect(result).toMatchSnapshot()) )); + it('should not resolve Sass values to quoted strings', () => ( + func(generate('tests/fixtures/values.json')) + .then(result => expect(result).toMatchSnapshot()) + )); it('should resolve json files in includePaths', () => ( func(generate('fixtures/flat.json'), { includePaths: ['tests']}) .then(result => expect(result).toMatchSnapshot())