UNPKG

sharec-utils

Version:
130 lines (109 loc) 3.07 kB
// @ts-check const { EOL } = require('os') const get = require('lodash.get') const detectIndent = require('detect-indent') const minimatch = require('minimatch') const { basename } = require('./path') const eolRe = new RegExp(`${EOL}$`) /** * @typedef {import('./index').FormattingRules} FormattingRules * @typedef {import('./index').MappedFormattingRules} MappedFormattingRules */ /** * Returns true if given string contains tab indent * @param {string} str * @returns {boolean} */ const hasTabsIndent = (str) => detectIndent(str).type === 'tab' /** * Returns true if given string containse space indent * @param {string} str * @returns {boolean} */ const hasSpacesIndent = (str) => detectIndent(str).type === 'space' /** * Returns true if given string contains empty line at the end * @param {string} str * @returns {boolean} */ const hasEOF = (str) => eolRe.test(str) /** * Cuts off EOL in the end of the file * @param {string} str * @returns {string} */ const cutEOF = (str) => str.replace(eolRe, '') /** * Replaces all indents in string by tabs * @param {string} [str = ''] * @returns {string} */ const indentWithTab = (str = '') => { const { type, indent } = detectIndent(str) if (type !== 'space') return str return str.replace(new RegExp(indent, 'gm'), '\t') } /** * Replaces all indents in string by spaces with given size * @param {string} [str = ''] * @param {number} [size = 2] * @returns {string} */ const indentWithSpace = (str = '', size = 2) => { const { indent } = detectIndent(str) const newIndent = Array(size).fill(' ').join('') return str.replace(new RegExp(indent, 'gm'), newIndent) } /** * Formats string (probably file's content) with given formatting options * @param {Object} params * @param {string} params.filename * @param {string} params.content * @param {FormattingRules} [params.rules] * @returns {string} */ const applyFormat = ({ filename, content, rules }) => { const indentType = get(rules, 'indentType', 'space') const indentSize = get(rules, 'indentSize', 2) const eof = get(rules, 'eof', true) const isYaml = filename && /\.ya?ml/.test(filename) let result = content switch (true) { case indentType === 'tab' && !isYaml: result = indentWithTab(result) break case indentType === 'space' || isYaml: result = indentWithSpace(result, indentSize) break case eof && !hasEOF(content): result += EOL break default: break } return result } /** * @param {MappedFormattingRules} formats * @param {string} filename * @returns {FormattingRules|null} */ const getFormatByFilename = (formats, filename) => { if (formats['*']) return formats['*'] const formatKey = Object.keys(formats).find((key) => { const fileBasename = basename(filename) return minimatch(fileBasename, key) }) if (!formatKey) return null return formats[formatKey] } module.exports = { hasSpacesIndent, hasTabsIndent, hasEOF, cutEOF, indentWithSpace, indentWithTab, applyFormat, getFormatByFilename, }