stylus-supremacy
Advanced tools
Comparing version 2.16.0 to 2.16.1
@@ -9,3 +9,6 @@ // Place your settings in this file to overwrite default and user settings. | ||
"docs/*.js": true | ||
} | ||
}, | ||
"cSpell.words": [ | ||
"stylint" | ||
] | ||
} |
@@ -5,5 +5,6 @@ const fs = require('fs') | ||
const glob = require('glob') | ||
const _ = require('lodash') | ||
const JSON5 = require('json5') | ||
const YAML = require('js-yaml') | ||
const difference = require('lodash/difference') | ||
const compact = require('lodash/compact') | ||
@@ -28,7 +29,4 @@ const format = require('./format') | ||
const inputFiles = _.chain(params) | ||
.difference(optionFilePathParams, outputDirectoryParams, replaceOriginalParams) | ||
.map(path => glob.sync(path)) | ||
.flatten() | ||
.value() | ||
const inputFiles = difference(params, optionFilePathParams, outputDirectoryParams, replaceOriginalParams) | ||
.flatMap(path => glob.sync(path)) | ||
if (inputFiles.length === 0) { | ||
@@ -70,48 +68,48 @@ Console.log('No input files found.') | ||
return _.chain(inputFiles) | ||
.reject(path => checkIfFilePathIsIgnored(path, ps.cwd(), formattingOptions)) | ||
.map(path => { | ||
if (inputFiles.length > 1) { | ||
Console.log() | ||
Console.log('»', path) | ||
} | ||
return compact( | ||
inputFiles | ||
.filter(path => !checkIfFilePathIsIgnored(path, ps.cwd(), formattingOptions)) | ||
.map(path => { | ||
if (inputFiles.length > 1) { | ||
Console.log() | ||
Console.log('»', path) | ||
} | ||
try { | ||
const inputContent = fs.readFileSync(path, 'utf8') | ||
const outputContent = format(inputContent, formattingOptions) | ||
try { | ||
const inputContent = fs.readFileSync(path, 'utf8') | ||
const outputContent = format(inputContent, formattingOptions) | ||
if (dryRunParams.length > 0) { | ||
// Do nothing | ||
if (dryRunParams.length > 0) { | ||
// Do nothing | ||
} else if (outputDirectoryParams.length > 0) { | ||
if (fs.existsSync(fp.resolve(outputDirectoryParams[1])) === false) { | ||
fs.mkdirSync(fp.resolve(outputDirectoryParams[1])) | ||
} | ||
} else if (outputDirectoryParams.length > 0) { | ||
if (fs.existsSync(fp.resolve(outputDirectoryParams[1])) === false) { | ||
fs.mkdirSync(fp.resolve(outputDirectoryParams[1])) | ||
} | ||
fs.writeFileSync(fp.resolve(outputDirectoryParams[1], fp.basename(path)), outputContent) | ||
fs.writeFileSync(fp.resolve(outputDirectoryParams[1], fp.basename(path)), outputContent) | ||
} else if (replaceOriginalParams.length > 0) { | ||
if (inputContent !== outputContent) { | ||
fs.writeFileSync(path, outputContent) | ||
} | ||
} else if (replaceOriginalParams.length > 0) { | ||
if (inputContent !== outputContent) { | ||
fs.writeFileSync(path, outputContent) | ||
} | ||
} else if (compareOriginalParams.length > 0) { | ||
const error = compareContent(inputContent, outputContent) | ||
if (error) { | ||
Console.log(error) | ||
return error | ||
} else if (compareOriginalParams.length > 0) { | ||
const error = compareContent(inputContent, outputContent) | ||
if (error) { | ||
Console.log(error) | ||
return error | ||
} | ||
} else { | ||
Console.log(outputContent) | ||
} | ||
} else { | ||
Console.log(outputContent) | ||
} catch (error) { | ||
Console.log(error) | ||
return error | ||
} | ||
}) | ||
) | ||
} catch (error) { | ||
Console.log(error) | ||
return error | ||
} | ||
}) | ||
.compact() | ||
.value() | ||
} else { | ||
@@ -118,0 +116,0 @@ throw new Error(`Command "${command}" was not recognized.`) |
@@ -1,7 +0,5 @@ | ||
const _ = require('lodash') | ||
const createComparableLines = text => text | ||
.replace(/\r/g, '¶') | ||
.replace(/\t/g, '→') | ||
.replace(/^\s+/gm, spaces => _.repeat('·', spaces.length)) | ||
.replace(/^\s+/gm, spaces => '·'.repeat(spaces.length)) | ||
.split('\n') | ||
@@ -8,0 +6,0 @@ |
@@ -1,2 +0,2 @@ | ||
const _ = require('lodash') | ||
const escape = require('lodash/escape') | ||
@@ -6,3 +6,3 @@ function createCodeForHTML(code) { | ||
.split(/\r?\n/) | ||
.map(_.escape) | ||
.map(line => escape(line)) | ||
// Escape white-spaces | ||
@@ -9,0 +9,0 @@ .map(line => line |
@@ -1,35 +0,33 @@ | ||
const _ = require('lodash') | ||
const isObject = require('lodash/isObject') | ||
const isInteger = require('lodash/isInteger') | ||
const uniq = require('lodash/uniq') | ||
const schema = require('./schema') | ||
function createFormattingOptions(options = {}) { | ||
if (_.isEmpty(options)) { | ||
return _.reduce(schema, (hash, info, name) => { | ||
hash[name] = info.default | ||
return hash | ||
}, {}) | ||
const hash = {} | ||
for (const name in schema) { | ||
try { | ||
// Support "stylusSupremacy." prefix for Visual Studio Code setting compatibility since v2.4 | ||
const normalProjection = options[name] | ||
const prefixProjection = options['stylusSupremacy.' + name] | ||
const data = prefixProjection !== undefined ? prefixProjection : normalProjection | ||
} else { | ||
return _.reduce(schema, (hash, info, name) => { | ||
try { | ||
// Support "stylusSupremacy." prefix for Visual Studio Code setting compatibility since v2.4 | ||
const data = options['stylusSupremacy.' + name] !== undefined ? options['stylusSupremacy.' + name] : options[name] | ||
if (data === undefined) { | ||
hash[name] = schema[name].default | ||
if (data === undefined) { | ||
hash[name] = info.default | ||
} else if (verify(data, info)) { | ||
hash[name] = data | ||
} | ||
} catch (ex) { | ||
throw new Error(ex.message + ` at "${name}".`) | ||
} else if (verify(data, schema[name])) { | ||
hash[name] = data | ||
} | ||
return hash | ||
}, {}) | ||
} catch (ex) { | ||
throw new Error(ex.message + ` at "${name}".`) | ||
} | ||
} | ||
return hash | ||
} | ||
function verify(data, info) { | ||
if (_.some(info.enum)) { | ||
return _.some(info.enum, item => { | ||
if (_.isObject(item)) { | ||
if (Array.isArray(info.enum)) { | ||
return info.enum.some(item => { | ||
if (isObject(item)) { | ||
return verify(data, item) | ||
@@ -43,3 +41,3 @@ } else { | ||
const matchAnyValue = info.oneOf.some(item => { | ||
if (_.isObject(item)) { | ||
if (isObject(item)) { | ||
try { | ||
@@ -59,3 +57,3 @@ return verify(data, item) | ||
} else if (info.type === 'integer') { | ||
if (_.isInteger(data) === false) { | ||
if (isInteger(data) === false) { | ||
throw new Error(`Expected ${data} to be an integer`) | ||
@@ -69,7 +67,7 @@ } else if (info.minimum !== undefined && data < info.minimum) { | ||
} else if (info.type === 'array') { | ||
if (_.isArray(data) === false) { | ||
if (Array.isArray(data) === false) { | ||
throw new Error(`Expected ${data} to be an array`) | ||
} else if (info.items !== undefined && _.some(data, item => verify(item, info.items) === false)) { | ||
} else if (info.items !== undefined && data.some(item => verify(item, info.items) === false)) { | ||
throw new Error(`Expected ${data} to have items of ${JSON.stringify(info.items)}`) | ||
} else if (info.uniqueItems === true && _.size(data) !== _.uniq(data).length) { | ||
} else if (info.uniqueItems === true && data.length !== uniq(data).length) { | ||
throw new Error(`Expected ${data} to have unique items`) | ||
@@ -76,0 +74,0 @@ } |
@@ -1,2 +0,7 @@ | ||
const _ = require('lodash') | ||
const isObject = require('lodash/isObject') | ||
const difference = require('lodash/difference') | ||
const omitBy = require('lodash/omitBy') | ||
const chunk = require('lodash/chunk') | ||
const identity = require('lodash/identity') | ||
const schema = require('./schema') | ||
@@ -15,3 +20,3 @@ | ||
extendPref: ['alwaysUseExtends', value => value === '@extends'], | ||
indentPref: ['tabStopChar', value => value > 0 ? _.repeat(' ', value) : undefined], | ||
indentPref: ['tabStopChar', value => value > 0 ? ' '.repeat(value) : undefined], | ||
leadingZero: ['insertLeadingZeroBeforeFraction', createAdapterForAlwaysNeverFalse], | ||
@@ -26,31 +31,25 @@ parenSpace: ['insertSpaceInsideParenthesis', createAdapterForAlwaysNeverFalse], | ||
const usedFormattingOptionNames = _.chain(stylintOptionMap) | ||
.values() | ||
.flatten() | ||
.chunk(2) | ||
.map('0') | ||
.flatten() | ||
.value() | ||
const usedFormattingOptionNames = chunk(Object.values(stylintOptionMap).flat(), 2) | ||
.flatMap(([name]) => name) | ||
const complementaryOptionMap = _.chain(schema) | ||
.keys() | ||
.difference(usedFormattingOptionNames) // Prevent conflicts by removing the formatting options that can be specified via Stylint above | ||
.reduce((hash, name) => { | ||
hash['stylusSupremacy.' + name] = [name, _.identity] | ||
return hash | ||
}, {}) | ||
.value() | ||
// Prevent conflicts by removing the formatting options that can be specified via Stylint above | ||
const complementaryOptionMap = Object.fromEntries( | ||
difference(Object.keys(schema), usedFormattingOptionNames) | ||
.map(name => ['stylusSupremacy.' + name, [name, identity]]) | ||
) | ||
const universalOptionMap = _.assign({}, stylintOptionMap, complementaryOptionMap) | ||
const universalOptionMap = { | ||
...stylintOptionMap, | ||
...complementaryOptionMap | ||
} | ||
function createFormattingOptionsFromStylint(stylintOptions = {}) { | ||
return _.chain(stylintOptions) | ||
.omitBy((rule, name) => universalOptionMap[name] === undefined) | ||
return omitBy(stylintOptions, (rule, name) => universalOptionMap[name] === undefined) | ||
.reduce((hash, rule, name) => { | ||
const value = _.isObject(rule) && rule.expect !== undefined ? rule.expect : rule | ||
const value = isObject(rule) && rule.expect !== undefined ? rule.expect : rule | ||
_.chunk(universalOptionMap[name], 2).forEach(pair => { | ||
const result = pair[1](value) | ||
chunk(universalOptionMap[name], 2).forEach(([name, convert]) => { | ||
const result = convert(value) | ||
if (result !== undefined) { | ||
hash['stylusSupremacy.' + pair[0]] = result | ||
hash['stylusSupremacy.' + name] = result | ||
} | ||
@@ -61,3 +60,2 @@ }) | ||
}, {}) | ||
.value() | ||
} | ||
@@ -64,0 +62,0 @@ |
@@ -1,15 +0,15 @@ | ||
const _ = require('lodash') | ||
const clone = require('lodash/clone') | ||
const uniq = require('lodash/uniq') | ||
const ordering = require('stylint/src/data/ordering.json') | ||
module.exports = function () { | ||
const list = _.clone(ordering.grouped) | ||
const list = clone(ordering.grouped) | ||
function insert(/* props */) { | ||
const args = _.toArray(arguments) | ||
function insert(...items) { | ||
return { | ||
before: function (prop) { | ||
Array.prototype.splice.apply(list, [list.indexOf(prop), 0].concat(args)) | ||
list.splice(list.indexOf(prop), 0, ...items) | ||
}, | ||
after: function (prop) { | ||
Array.prototype.splice.apply(list, [list.indexOf(prop) + 1, 0].concat(args)) | ||
list.splice(list.indexOf(prop) + 1, 0, ...items) | ||
} | ||
@@ -19,3 +19,3 @@ } | ||
// https://github.com/tj/nib/blob/master/docs/README.md | ||
// See https://github.com/tj/nib/blob/master/docs/README.md | ||
insert('fixed', 'absolute', 'relative').before('position') | ||
@@ -31,3 +31,3 @@ insert('clearfix').before('clear') | ||
return _.uniq(list) | ||
return uniq(list) | ||
} |
@@ -1,2 +0,2 @@ | ||
const _ = require('lodash') | ||
const isObject = require('lodash/isObject') | ||
@@ -14,7 +14,7 @@ function findChildNodes(inputNode, condition, results = [] /* Internal */, visited = [] /* Internal */) { | ||
const prop = inputNode[name] | ||
if (_.isArray(prop)) { | ||
_.forEach(prop, node => { | ||
if (Array.isArray(prop)) { | ||
prop.forEach(node => { | ||
findChildNodes(node, condition, results, visited) | ||
}) | ||
} else if (_.isObject(prop)) { | ||
} else if (isObject(prop)) { | ||
findChildNodes(prop, condition, results, visited) | ||
@@ -21,0 +21,0 @@ } |
const Stylus = require('stylus') | ||
const _ = require('lodash') | ||
const get = require('lodash/get') | ||
const first = require('lodash/first') | ||
const last = require('lodash/last') | ||
const findLast = require('lodash/findLast') | ||
const compact = require('lodash/compact') | ||
const difference = require('lodash/difference') | ||
const sortBy = require('lodash/sortBy') | ||
const uniq = require('lodash/uniq') | ||
const partition = require('lodash/partition') | ||
const takeRightWhile = require('lodash/takeRightWhile') | ||
const min = require('lodash/min') | ||
const maxBy = require('lodash/maxBy') | ||
const escapeRegExp = require('lodash/escapeRegExp') | ||
const trimStart = require('lodash/trimStart') | ||
const trimEnd = require('lodash/trimEnd') | ||
const isObject = require('lodash/isObject') | ||
const isPlainObject = require('lodash/isPlainObject') | ||
const isString = require('lodash/isString') | ||
const isInteger = require('lodash/isInteger') | ||
const isBoolean = require('lodash/isBoolean') | ||
@@ -17,3 +36,3 @@ const schema = require('./schema') | ||
// Consolidate the formatting options | ||
options = _.assign({ wrapMode: !!options.wrapMode }, createFormattingOptions(options)) | ||
options = Object.assign({ wrapMode: !!options.wrapMode }, createFormattingOptions(options)) | ||
@@ -36,13 +55,14 @@ // Prepare the artifacts | ||
modifiedContent = 'wrap\n\t' + content.trim() | ||
originalBaseIndent = _.get(content.match(/^(\s|\t)*/g), '0', null) | ||
originalBaseIndent = get(content.match(/^(\s|\t)*/g), '0', null) | ||
} else { | ||
// Determine an original tab stop character | ||
const twoShortestIndent = _.chain(originalLines) | ||
.filter(line => line.trim().length > 0) | ||
.map(line => _.get(line.match(/^(\s|\t)*/g), '0', '')) | ||
.uniq() | ||
.sortBy(text => text.length) | ||
.take(2) | ||
.value() | ||
const twoShortestIndent = sortBy( | ||
uniq( | ||
originalLines | ||
.filter(line => line.trim().length > 0) | ||
.map(line => get(line.match(/^(\s|\t)*/g), '0', '')) | ||
), | ||
text => text.length | ||
).slice(0, 2) | ||
if (twoShortestIndent.length === 2) { | ||
@@ -78,11 +98,11 @@ originalTabStopChar = twoShortestIndent[1].substring(twoShortestIndent[0].length) | ||
// Check argument type | ||
if (!(_.isObject(parentNode) || parentNode === null && inputNode instanceof Stylus.nodes.Root)) { | ||
if (!(isObject(parentNode) || parentNode === null && inputNode instanceof Stylus.nodes.Root)) { | ||
throw new Error(`Found a parent node of ${JSON.stringify(parentNode)}`) | ||
} else if (!(_.isObject(inputNode))) { | ||
} else if (!(isObject(inputNode))) { | ||
throw new Error(`Found an input node of ${JSON.stringify(inputNode)}` + (parentNode ? `, which had a parent node of ${JSON.stringify(parentNode)}` : '')) | ||
} else if (!(_.isInteger(indentLevel) && indentLevel >= 0)) { | ||
} else if (!(isInteger(indentLevel) && indentLevel >= 0)) { | ||
throw new Error(`Found an indent level of ${JSON.stringify(indentLevel)}`) | ||
} else if (!(_.isBoolean(insideExpression))) { | ||
} else if (!(isBoolean(insideExpression))) { | ||
throw new Error(`Found an expression flag of ${JSON.stringify(insideExpression)}`) | ||
} else if (!(_.isPlainObject(data))) { | ||
} else if (!(isPlainObject(data))) { | ||
throw new Error(`Found an additional data object of ${JSON.stringify(data)}`) | ||
@@ -95,3 +115,3 @@ } | ||
// Prepare the indentation from the current indent level | ||
const indent = _.repeat(options.tabStopChar, indentLevel) | ||
const indent = options.tabStopChar.repeat(indentLevel) | ||
@@ -122,3 +142,3 @@ // Store an output string for the current node | ||
// Insert single-line comment(s) | ||
const topCommentNodes = tryGetSingleLineCommentNodesOnTheTopOf(_.first(inputNode.nodes)) | ||
const topCommentNodes = tryGetSingleLineCommentNodesOnTheTopOf(first(inputNode.nodes)) | ||
if (topCommentNodes.length > 0) { | ||
@@ -137,3 +157,3 @@ outputBuffer.append(topCommentNodes.map(node => travel(inputNode.parent, node, indentLevel)).join('')) | ||
outputBuffer.append(travel(inputNode, inputNode.block, indentLevel, false, { potentialCommentNodeInsideTheBlock: _.last(inputNode.nodes) })) | ||
outputBuffer.append(travel(inputNode, inputNode.block, indentLevel, false, { potentialCommentNodeInsideTheBlock: last(inputNode.nodes) })) | ||
@@ -150,3 +170,3 @@ } else if (inputNode instanceof Stylus.nodes.Root || inputNode instanceof Stylus.nodes.Block) { | ||
inputNode.nodes.forEach(node => { | ||
const lastGroup = _.last(groupOfCommentNodes) | ||
const lastGroup = last(groupOfCommentNodes) | ||
if (node instanceof Stylus.nodes.Comment) { | ||
@@ -159,7 +179,10 @@ lastGroup.push(node) | ||
}) | ||
if (_.last(groupOfCommentNodes).length === 0) { | ||
if (last(groupOfCommentNodes).length === 0) { | ||
groupOfCommentNodes.pop() | ||
} | ||
const unsortedNonCommentNodes = _.difference(inputNode.nodes, _.flatten(groupOfCommentNodes)) | ||
const unsortedNonCommentNodes = difference( | ||
inputNode.nodes, | ||
groupOfCommentNodes.flat() | ||
) | ||
@@ -199,3 +222,3 @@ // Insert a comment on the right of the last selector | ||
} else { | ||
_.last(groupOfUnsortedNonCommentNodes).push(node) | ||
last(groupOfUnsortedNonCommentNodes).push(node) | ||
} | ||
@@ -208,3 +231,3 @@ }) | ||
if (options.sortProperties === 'alphabetical') { | ||
return _.sortBy(nodes, node => { | ||
return sortBy(nodes, node => { | ||
const propertyName = node.segments.map(segment => segment.name).join('') | ||
@@ -219,3 +242,3 @@ if (propertyName.startsWith('-')) { | ||
} else if (options.sortProperties === 'grouped') { | ||
return _.sortBy(nodes, node => { | ||
return sortBy(nodes, node => { | ||
const propertyName = node.segments.map(segment => segment.name).join('') | ||
@@ -230,4 +253,4 @@ const propertyRank = sortedProperties.indexOf(propertyName) | ||
} else if (_.isArray(options.sortProperties) && _.some(options.sortProperties)) { | ||
return _.sortBy(nodes, node => { | ||
} else if (Array.isArray(options.sortProperties) && options.sortProperties.length > 0) { | ||
return sortBy(nodes, node => { | ||
const propertyName = node.segments.map(segment => segment.name).join('') | ||
@@ -248,3 +271,3 @@ const propertyRank = options.sortProperties.indexOf(propertyName) | ||
// Note that do not mutate this | ||
const sortedNonCommentNodes = _.flatten(groupOfSortedNonCommentNodes) | ||
const sortedNonCommentNodes = groupOfSortedNonCommentNodes.flat() | ||
@@ -265,7 +288,7 @@ // Put single-line comment(s) to the relevant node | ||
groupOfCommentNodes.forEach(commentNodes => { | ||
const [rightCommentNodes, lineCommentNodes] = _.partition(commentNodes, commentNode => sortedNonCommentNodes.some(node => node.lineno === commentNode.lineno && node.column < commentNode.column)) | ||
const [rightCommentNodes, lineCommentNodes] = partition(commentNodes, commentNode => sortedNonCommentNodes.some(node => node.lineno === commentNode.lineno && node.column < commentNode.column)) | ||
// Put the column-consecutive comment(s) on the right of the inner node | ||
rightCommentNodes.forEach(commentNode => { | ||
const leftNode = _.findLast(sortedNonCommentNodes, node => node.lineno === commentNode.lineno && node.column < commentNode.column) | ||
const leftNode = findLast(sortedNonCommentNodes, node => node.lineno === commentNode.lineno && node.column < commentNode.column) | ||
if (leftNode.commentsOnRight === undefined) { | ||
@@ -277,3 +300,3 @@ leftNode.commentsOnRight = [] | ||
const index = inputNode.nodes.indexOf(_.last(lineCommentNodes)) | ||
const index = inputNode.nodes.indexOf(last(lineCommentNodes)) | ||
if (index === inputNode.nodes.length - 1) { | ||
@@ -286,3 +309,3 @@ // Put the line-consecutive comment(s) at the bottom-most of the block | ||
const belowNode = inputNode.nodes[index + 1] | ||
if (_.includes(sortedNonCommentNodes, belowNode)) { | ||
if (sortedNonCommentNodes.includes(belowNode)) { | ||
if (belowNode.commentsOnTop === undefined) { | ||
@@ -301,3 +324,3 @@ belowNode.commentsOnTop = [] | ||
} else if (options.wrapMode) { | ||
return _.some(originalBaseIndent) ? value === 'nested' : value === 'root' | ||
return originalBaseIndent && originalBaseIndent.length > 0 ? value === 'nested' : value === 'root' | ||
@@ -310,4 +333,4 @@ } else { | ||
// Insert CSS body and new-lines between them | ||
outputBuffer.append(_.chain(groupOfSortedNonCommentNodes) | ||
.map((nodes) => { | ||
outputBuffer.append(groupOfSortedNonCommentNodes | ||
.flatMap((nodes) => { | ||
const nodeType = getType(nodes[0]) | ||
@@ -325,3 +348,3 @@ | ||
return _.compact([ | ||
return compact([ | ||
newLineOrEmpty, | ||
@@ -332,4 +355,3 @@ nodes.map(node => travel(inputNode, node, childIndentLevel)).join(''), | ||
}) | ||
.flatten() | ||
.reject((text, rank, list) => text === options.newLineChar && ( | ||
.filter((text, rank, list) => text !== options.newLineChar || !( | ||
rank === 0 || | ||
@@ -340,7 +362,6 @@ rank > 1 && list[rank - 1] === options.newLineChar || | ||
.join('') | ||
.value() | ||
) | ||
// Insert the bottom comment(s) | ||
const bottomCommentNodes = tryGetSingleLineCommentNodesOnTheBottomOf(_.last(unsortedNonCommentNodes)) | ||
const bottomCommentNodes = tryGetSingleLineCommentNodesOnTheBottomOf(last(unsortedNonCommentNodes)) | ||
if (bottomCommentNodes) { | ||
@@ -376,3 +397,3 @@ outputBuffer.append(bottomCommentNodes.map(node => travel(inputNode.parent, node, childIndentLevel)).join('')) | ||
// margin: 8px 0; /* right-comment */ | ||
const commentsOnTheRight = _.takeRightWhile(inputNode.expr.nodes, node => node instanceof Stylus.nodes.Comment) | ||
const commentsOnTheRight = takeRightWhile(inputNode.expr.nodes, node => node instanceof Stylus.nodes.Comment) | ||
const nodesExcludingCommentsOnTheRight = inputNode.expr.nodes.slice(0, inputNode.expr.nodes.length - commentsOnTheRight.length) | ||
@@ -409,7 +430,4 @@ | ||
if (nodesExcludingCommentsOnTheRight.every(node => node instanceof Stylus.nodes.Expression)) { | ||
const numberOfLineTaken = _.chain(nodesExcludingCommentsOnTheRight) | ||
.map('lineno') | ||
.uniq() | ||
.value() | ||
.length | ||
const numberOfLineTaken = uniq(nodesExcludingCommentsOnTheRight.map(({ lineno }) => lineno) | ||
).length | ||
if (numberOfLineTaken > 1 && options.preserveNewLinesBetweenPropertyValues) { | ||
@@ -485,3 +503,3 @@ outputBuffer.append(':' + options.newLineChar) | ||
innerLines = innerLines.map(line => { | ||
const text = _.trimStart(line) | ||
const text = trimStart(line) | ||
const innerIndent = line.substring(0, line.length - text.length) | ||
@@ -492,3 +510,3 @@ return innerIndent.replace(indentPattern, options.tabStopChar) + text | ||
} | ||
if (_.last(innerLines).trim().length === 0) { | ||
if (last(innerLines).trim().length === 0) { | ||
innerLines = innerLines.slice(0, innerLines.length - 1) | ||
@@ -504,7 +522,7 @@ } | ||
} else { | ||
if (_.get(modifiedLines, (inputNode.lineno - 1) + '.' + (inputNode.column - 1)) === '\\') { | ||
if (get(modifiedLines, (inputNode.lineno - 1) + '.' + (inputNode.column - 1)) === '\\') { | ||
outputBuffer.append('\\') | ||
} | ||
if (_.isString(inputNode.val)) { | ||
if (isString(inputNode.val)) { | ||
outputBuffer.append(inputNode.val) | ||
@@ -517,3 +535,3 @@ } else { | ||
} else if (inputNode instanceof Stylus.nodes.String) { | ||
if (_.includes(inputNode.val, options.quoteChar)) { | ||
if (inputNode.val.includes(options.quoteChar)) { | ||
if (inputNode.val.startsWith('data:image/svg+xml;utf8,')) { // In case of SVG data-URL | ||
@@ -593,3 +611,3 @@ const counterQuoteChar = schema.quoteChar.enum.find(item => item !== options.quoteChar) | ||
} else { | ||
potentialCommentNodeInsideTheBlock = _.last(inputNode.params.nodes) | ||
potentialCommentNodeInsideTheBlock = last(inputNode.params.nodes) | ||
} | ||
@@ -644,10 +662,11 @@ | ||
const keyNodePairs = _.concat( | ||
// In case of ordinal-arguments | ||
const keyNodePairs = [ | ||
// In case of ordinal arguments | ||
inputNode.nodes.map(node => ['', node]), | ||
// In case of named-arguments | ||
_.toPairs(inputNode.map).map(pair => [pair[0] + ': ', pair[1]]) | ||
) | ||
// In case of named arguments | ||
Object.entries(inputNode.map) | ||
.map(pair => [pair[0] + ': ', pair[1]]) | ||
].flat() | ||
const lineCount = _.uniq(keyNodePairs.map(pair => pair[1].lineno)).length | ||
const lineCount = uniq(keyNodePairs.map(pair => pair[1].lineno)).length | ||
@@ -888,3 +907,3 @@ if (lineCount > 1) { | ||
} else if (inputNode instanceof Stylus.nodes.Object) { | ||
const keyValuePairs = _.toPairs(inputNode.vals) | ||
const keyValuePairs = Object.entries(inputNode.vals) | ||
if (keyValuePairs.length === 0) { // In case of an empty object | ||
@@ -1003,3 +1022,3 @@ outputBuffer.append('{}') | ||
const currentHasOnlyOneChild = _.size(inputNode.block.nodes) === 1 | ||
const currentHasOnlyOneChild = (inputNode.block.nodes || []).length === 1 | ||
const currentIsOnTheSameLineAsBody = inputNode.lineno === inputNode.block.nodes[0].lineno && inputNode.block.nodes[0].column < inputNode.column | ||
@@ -1009,3 +1028,3 @@ if (currentHasOnlyOneChild && currentIsOnTheSameLineAsBody) { // In case of postfix | ||
outputBuffer.append(' for ') | ||
outputBuffer.append(_.compact([inputNode.val, inputNode.key]).join(comma)) | ||
outputBuffer.append(compact([inputNode.val, inputNode.key]).join(comma)) | ||
outputBuffer.append(' in ') | ||
@@ -1023,3 +1042,3 @@ outputBuffer.append(travel(inputNode, inputNode.expr, indentLevel, true)) | ||
outputBuffer.append('for ') | ||
outputBuffer.append(_.compact([inputNode.val, inputNode.key]).join(comma)) | ||
outputBuffer.append(compact([inputNode.val, inputNode.key]).join(comma)) | ||
outputBuffer.append(' in ') | ||
@@ -1184,3 +1203,3 @@ outputBuffer.append(travel(inputNode, inputNode.expr, indentLevel, true)) | ||
} | ||
commentLines[zeroBasedLineIndex] = _.trimEnd(commentLines[zeroBasedLineIndex]) | ||
commentLines[zeroBasedLineIndex] = trimEnd(commentLines[zeroBasedLineIndex]) | ||
} | ||
@@ -1190,8 +1209,8 @@ } | ||
// Add a white-space before */ | ||
if (_.last(commentLines).trim() === '*/') { | ||
if (last(commentLines).trim() === '*/') { | ||
if (documenting) { | ||
commentLines[commentLines.length - 1] = ' ' + _.last(commentLines).trim() | ||
commentLines[commentLines.length - 1] = ' ' + last(commentLines).trim() | ||
} | ||
} else { | ||
commentLines[commentLines.length - 1] = _.trimEnd(_.last(commentLines).substring(0, _.last(commentLines).length - 2)) + spaceAfterComment + '*/' | ||
commentLines[commentLines.length - 1] = trimEnd(last(commentLines).substring(0, last(commentLines).length - 2)) + spaceAfterComment + '*/' | ||
} | ||
@@ -1203,7 +1222,7 @@ | ||
} else { | ||
const originalIndentLong = _.chain(commentLines) | ||
.slice(1) | ||
.map(line => line.match(/^(\s|\t)*/g)[0].length) | ||
.min() | ||
.value() || 0 | ||
const originalIndentLong = min( | ||
commentLines | ||
.slice(1) | ||
.map(line => line.match(/^(\s|\t)*/g)[0].length) | ||
) || 0 | ||
@@ -1216,3 +1235,2 @@ commentLines = commentLines.map((line, rank) => { | ||
} | ||
indent + line | ||
}) | ||
@@ -1267,5 +1285,5 @@ } | ||
if (checkIfMixin(inputNode)) { | ||
const params = _.get(inputNode, 'val.params.nodes', []) | ||
const params = get(inputNode, 'val.params.nodes', []) | ||
if (params.length > 0) { | ||
inputNode = _.first(params) | ||
inputNode = first(params) | ||
} else { | ||
@@ -1277,3 +1295,3 @@ inputNode = inputNode.val | ||
let zeroBasedLineIndex | ||
if (inputNode instanceof Stylus.nodes.Group && _.some(inputNode.nodes)) { | ||
if (inputNode instanceof Stylus.nodes.Group && Array.isArray(inputNode.nodes) && inputNode.nodes.length > 0) { | ||
zeroBasedLineIndex = inputNode.nodes[0].lineno - 1 | ||
@@ -1368,6 +1386,7 @@ } else if (checkIfTernary(inputNode) && inputNode.cond.left.val.lineno < inputNode.lineno) { | ||
let zeroBasedLineIndex = inputNode.column | ||
const leftmostStringThatHasDoubleSlashes = _.chain(findChildNodes(inputNode, node => node instanceof Stylus.nodes.String)) | ||
.filter(node => node.lineno === inputNode.lineno && node.val.includes('//')) | ||
.maxBy('column') | ||
.value() | ||
const leftmostStringThatHasDoubleSlashes = maxBy( | ||
findChildNodes(inputNode, node => node instanceof Stylus.nodes.String) | ||
.filter(node => node.lineno === inputNode.lineno && node.val.includes('//')), | ||
node => node.column | ||
) | ||
if (leftmostStringThatHasDoubleSlashes) { | ||
@@ -1439,6 +1458,6 @@ zeroBasedLineIndex = leftmostStringThatHasDoubleSlashes.column + leftmostStringThatHasDoubleSlashes.val.length + 1 | ||
const outputText = travel(null, rootNode, 0) | ||
let outputLines = outputText.split(new RegExp(_.escapeRegExp(options.newLineChar))) | ||
let outputLines = outputText.split(new RegExp(escapeRegExp(options.newLineChar))) | ||
// Trim a beginning new-line character | ||
if (_.first(outputLines).trim().length === 0) { | ||
if (first(outputLines).trim().length === 0) { | ||
outputLines.shift() | ||
@@ -1448,3 +1467,3 @@ } | ||
// Trim all trailing new-line characters | ||
while (outputLines.length > 0 && _.last(outputLines).trim().length === 0) { | ||
while (outputLines.length > 0 && last(outputLines).trim().length === 0) { | ||
outputLines.pop() | ||
@@ -1458,3 +1477,3 @@ } | ||
} | ||
if (options.insertBraces && _.last(outputLines).trim() === '}') { | ||
if (options.insertBraces && last(outputLines).trim() === '}') { | ||
outputLines.pop() | ||
@@ -1468,3 +1487,3 @@ } | ||
if (originalBaseIndent && originalTabStopChar) { | ||
const outputBaseIndent = _.repeat(options.tabStopChar, originalBaseIndent.length / originalTabStopChar.length) | ||
const outputBaseIndent = options.tabStopChar.repeat(originalBaseIndent.length / originalTabStopChar.length) | ||
outputLines = outputLines.map(line => line.trim().length > 0 ? (outputBaseIndent + line) : '') | ||
@@ -1553,5 +1572,5 @@ } else if (originalBaseIndent) { | ||
function getIndent(line) { | ||
return line.substring(0, line.length - _.trimStart(line).length) | ||
return line.substring(0, line.length - trimStart(line).length) | ||
} | ||
module.exports = format |
const fs = require('fs') | ||
const _ = require('lodash') | ||
const isEmpty = require('lodash/isEmpty') | ||
const isObject = require('lodash/isObject') | ||
const omitBy = require('lodash/omitBy') | ||
const uniq = require('lodash/uniq') | ||
const chunk = require('lodash/chunk') | ||
const sortBy = require('lodash/sortBy') | ||
const intersection = require('lodash/intersection') | ||
const escape = require('lodash/escape') | ||
const kebabCase = require('lodash/kebabCase') | ||
const camelCase = require('lodash/camelCase') | ||
const upperFirst = require('lodash/upperFirst') | ||
@@ -22,9 +32,9 @@ const schema = require('./schema') | ||
const output = worker() | ||
return _.first(chunks) + placeholder + output + placeholder + _.last(chunks) | ||
return chunks[0] + placeholder + output + placeholder + chunks[chunks.length - 1] | ||
} | ||
function createFormattingTogglersForDemo() { | ||
return _.chain(schema) | ||
.omitBy(item => item.hideInDemo === true) | ||
.map((item, name) => { | ||
return Object.entries(schema) | ||
.filter(([name, item]) => !item.hideInDemo) | ||
.map(([name, item]) => { | ||
if (item.type === 'boolean') { | ||
@@ -59,3 +69,3 @@ return ( | ||
`<select id="demo-${name}" value="${getType(item.default)}">` + | ||
_enum(item) + | ||
renderOptions(item.enum) + | ||
`</select>` + | ||
@@ -71,4 +81,4 @@ `</label>` | ||
item.oneOf.map(stub => stub.enum | ||
? _enum(stub) | ||
: `<option value="${getType(stub)}" ${_.isObject(stub) ? 'disabled' : ''}>${getType(stub)}</option>` | ||
? renderOptions(stub.enum) | ||
: `<option value="${getType(stub)}" ${isObject(stub) ? 'disabled' : ''}>${getType(stub)}</option>` | ||
) + | ||
@@ -81,11 +91,10 @@ `</select>` + | ||
.join('') | ||
.value() | ||
} | ||
function _enum(item) { | ||
return item.enum.map(stub => `<option value="${getType(stub)}">${getType(stub)}</option>`).join('') | ||
} | ||
function renderOptions(items) { | ||
return items.map(stub => `<option value="${getType(stub)}">${getType(stub)}</option>`).join('') | ||
} | ||
function createFormattingDescription() { | ||
const defaultOptionJSON = createCodeForHTML(JSON.stringify(_.omitBy(createFormattingOptions(), (item, name) => schema[name].deprecated), null, ' ')) | ||
const defaultOptionJSON = createCodeForHTML(JSON.stringify(omitBy(createFormattingOptions(), (item, name) => schema[name].deprecated), null, ' ')) | ||
@@ -96,3 +105,3 @@ const defaultOptionHTML = ( | ||
.replace(/<br>/g, '\n') | ||
.replace(/^ "(\w+)"/gm, (full, part) => full.replace(part, `<a href="#option-${_.kebabCase(part)}">stylusSupremacy.${createBreakableWords(part)}</a>`)) | ||
.replace(/^ "(\w+)"/gm, (full, part) => full.replace(part, `<a href="#option-${kebabCase(part)}">stylusSupremacy.${createBreakableWords(part)}</a>`)) | ||
.replace(/\n/g, '<br>') + | ||
@@ -102,5 +111,5 @@ '</code>' | ||
const formattingOptionDescription = _.chain(schema) | ||
.map((item, name) => [ | ||
`<section id="option-${_.kebabCase(name)}">`, | ||
const formattingOptionDescription = Object.entries(schema) | ||
.flatMap(([name, item]) => [ | ||
`<section id="option-${kebabCase(name)}">`, | ||
`<h2 class="${item.deprecated ? 'deprecated' : ''}">`, | ||
@@ -116,3 +125,3 @@ item.deprecated && '<b>DEPRECATED </b>', | ||
item.hideInVSCE ? '<p>This option is not available in the Visual Studio Code extension.</p>' : '', | ||
item.example && _.chunk(item.example.values, 2).map(values => | ||
item.example && chunk(item.example.values, 2).map(values => | ||
createResponsiveTable( | ||
@@ -125,6 +134,4 @@ values.map(value => JSON.stringify(value, null, '\t').replace(/(\[|\{)\n\t+/g, '[').replace(/^\t+/gm, ' ').replace(/\n/g, '')), | ||
]) | ||
.flatten() | ||
.compact() | ||
.filter(line => !!line) | ||
.join('') | ||
.value() | ||
@@ -135,10 +142,11 @@ return defaultOptionHTML + formattingOptionDescription | ||
function createStylintConversionTable() { | ||
const validFormattingOptionNames = _.keys(schema) | ||
const validFormattingOptionNames = Object.keys(schema) | ||
const stylintOptionMap = _.toPairs(createFormattingOptionsFromStylint.map) | ||
.reduce((temp, pair) => { | ||
const stylintOptionName = pair[0] | ||
const formattingOptionNames = _.chunk(pair[1], 2) | ||
.map(item => item[0]) | ||
.filter(item => validFormattingOptionNames.includes(item)) | ||
const stylintOptionMap = Object.entries(createFormattingOptionsFromStylint.map) | ||
.reduce((temp, [stylintOptionName, conversionRules]) => { | ||
const formattingOptionNames = intersection( | ||
chunk(conversionRules, 2) | ||
.map(([formattingOptionName]) => formattingOptionName), | ||
validFormattingOptionNames | ||
) | ||
@@ -149,15 +157,26 @@ temp[stylintOptionName] = formattingOptionNames | ||
return '<tbody>' + _.chain([stylintOptions, stylintOptionMap]).map(_.keys).flatten().uniq().sortBy().value().map(name => | ||
'<tr>' + | ||
'<td><mark class="alt">' + createBreakableWords(name) + '</mark></td>' + | ||
'<td>' + (_.some(stylintOptionMap[name]) | ||
? (stylintOptionMap[name].map(item => '<mark>' + createBreakableWords(item) + '</mark>').join(', ')) | ||
: 'Not applicable') + | ||
'</td>' + | ||
'</tr>' | ||
).join('') + '</tbody>' | ||
const stylintOptionNames = sortBy( | ||
uniq( | ||
[stylintOptions, stylintOptionMap] | ||
.flatMap((item) => Object.keys(item)) | ||
) | ||
) | ||
return '<tbody>' + | ||
stylintOptionNames.map(name => | ||
'<tr>' + | ||
'<td><mark class="alt">' + createBreakableWords(name) + '</mark></td>' + | ||
'<td>' + ( | ||
isEmpty(stylintOptionMap[name]) | ||
? 'Not applicable' | ||
: stylintOptionMap[name].map(item => '<mark>' + createBreakableWords(item) + '</mark>').join(', ') | ||
) + | ||
'</td>' + | ||
'</tr>' | ||
).join('') + | ||
'</tbody>' | ||
} | ||
function getType(item) { | ||
if (_.isObject(item)) { | ||
if (isObject(item)) { | ||
if (item.type) { | ||
@@ -169,3 +188,3 @@ return item.type + (item.items ? ('<' + getType(item.items) + '>') : '') | ||
} else { | ||
return _.escape(JSON.stringify(item)) | ||
return escape(JSON.stringify(item)) | ||
} | ||
@@ -183,7 +202,7 @@ } | ||
function createBreakableWords(text) { | ||
const pattern = _.camelCase(text) | ||
const pattern = camelCase(text) | ||
if (text === pattern) { | ||
return _.kebabCase(text) | ||
return kebabCase(text) | ||
.split('-') | ||
.map((word, rank) => rank === 0 ? word : _.upperFirst(word)) | ||
.map((word, rank) => rank === 0 ? word : upperFirst(word)) | ||
.join('<wbr>') | ||
@@ -190,0 +209,0 @@ |
const fs = require('fs') | ||
const _ = require('lodash') | ||
const findIndex = require('lodash/findIndex') | ||
const uniq = require('lodash/uniq') | ||
const schema = require('./schema') | ||
const createFormattingOptions = require('./createFormattingOptions') | ||
@@ -11,4 +11,4 @@ const filePath = 'edge/index.d.ts' | ||
const lines = content.split('\n') | ||
const begin = _.findIndex(lines, line => line === '\texport interface FormattingOptions {') | ||
const final = _.findIndex(lines, line => line === '\t}', begin + 1) | ||
const begin = findIndex(lines, line => line === '\texport interface FormattingOptions {') | ||
const final = findIndex(lines, line => line === '\t}', begin + 1) | ||
@@ -19,11 +19,10 @@ if (begin === -1 || final === -1) { | ||
const formattingOptionDefinition = _.chain(schema) | ||
.map((info, name) => '\t\t' + name + '?: ' + getType(info)) | ||
.value() | ||
const formattingOptionDefinition = Object.entries(schema) | ||
.map(([name, info]) => '\t\t' + name + '?: ' + getType(info)) | ||
content = _.concat( | ||
lines.slice(0, begin + 1), | ||
formattingOptionDefinition, | ||
lines.slice(final) | ||
).join('\n') | ||
content = [ | ||
...lines.slice(0, begin + 1), | ||
...formattingOptionDefinition, | ||
...lines.slice(final), | ||
].join('\n') | ||
@@ -38,17 +37,8 @@ fs.writeFileSync(filePath, content) | ||
return info.items.type + '[]' | ||
} else if (info.enum) { | ||
return _.chain(info.enum) | ||
.map(item => typeof item) | ||
.uniq() | ||
.value() | ||
.join(' | ') | ||
return uniq(info.enum.map(item => typeof item)).join(' | ') | ||
} else if (info.oneOf) { | ||
return _.chain(info.oneOf) | ||
.map(item => getType(item)) | ||
.flatten() | ||
.uniq() | ||
.value() | ||
.join(' | ') | ||
return uniq(info.oneOf.flatMap(item => getType(item))).join(' | ') | ||
@@ -55,0 +45,0 @@ } else { |
{ | ||
"name": "stylus-supremacy", | ||
"description": "Make your Stylus files look great again.", | ||
"version": "2.16.0", | ||
"version": "2.16.1", | ||
"author": { | ||
@@ -26,3 +26,3 @@ "name": "Anantachai Saothong", | ||
"engines": { | ||
"node": ">=12" | ||
"node": ">=14" | ||
}, | ||
@@ -53,3 +53,6 @@ "scripts": { | ||
"stylus": "^0.59.0" | ||
}, | ||
"volta": { | ||
"node": "14.20.1" | ||
} | ||
} |
97616
2355