mirror of
https://github.com/gosticks/svgr.git
synced 2025-10-16 11:55:43 +00:00
feat(cli): allow all CLI options in config (#615)
Also run Prettier on index.js file. Closes #570
This commit is contained in:
parent
10638d0dda
commit
aa9feb2b1c
@ -3,7 +3,7 @@ const path = require('path')
|
||||
function indexTemplate(files) {
|
||||
const exportEntries = files.map(file => {
|
||||
const basename = path.basename(file, path.extname(file))
|
||||
return `export { ${basename} } from './${basename}'`
|
||||
return `export { ${basename} } from './${basename}';`
|
||||
})
|
||||
return exportEntries.join('\n')
|
||||
}
|
||||
|
||||
@ -2,7 +2,8 @@
|
||||
|
||||
exports[`cli should add Svg prefix to index.js exports staring with number 1`] = `
|
||||
"export { default as Svg2File } from './2File'
|
||||
export { default as File } from './File'"
|
||||
export { default as File } from './File'
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`cli should not override config with cli defaults 1`] = `
|
||||
@ -19,7 +20,10 @@ export default SvgFile
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`cli should support --index-template in cli 1`] = `"export { File } from './File'"`;
|
||||
exports[`cli should support --index-template in cli 1`] = `
|
||||
"export { File } from './File'
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`cli should support --no-index 1`] = `
|
||||
Array [
|
||||
@ -92,7 +96,10 @@ Array [
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`cli should support custom index.js with directory output 1`] = `"export { default as File } from './File'"`;
|
||||
exports[`cli should support custom index.js with directory output 1`] = `
|
||||
"export { File } from './File'
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`cli should support different filename cases with directory output 1`] = `
|
||||
Array [
|
||||
|
||||
@ -3,13 +3,14 @@ import { promises as fs } from 'fs'
|
||||
import * as path from 'path'
|
||||
import { grey, white } from 'chalk'
|
||||
import { loadConfig, Config } from '@svgr/core'
|
||||
import { format, resolveConfig } from 'prettier'
|
||||
import {
|
||||
convertFile,
|
||||
transformFilename,
|
||||
politeWrite,
|
||||
formatExportName,
|
||||
} from './util'
|
||||
import type { SvgrCommand } from './index'
|
||||
import type { Options, SvgrCommand } from './index'
|
||||
|
||||
const exists = async (filepath: string) => {
|
||||
try {
|
||||
@ -50,20 +51,20 @@ const resolveExtension = (config: Config, ext?: string) =>
|
||||
ext || (config.typescript ? 'tsx' : 'js')
|
||||
|
||||
export const dirCommand: SvgrCommand = async (
|
||||
{
|
||||
opts,
|
||||
_,
|
||||
filenames,
|
||||
): Promise<void> => {
|
||||
const {
|
||||
ext: extOpt,
|
||||
filenameCase = 'pascal',
|
||||
ignoreExisting,
|
||||
silent,
|
||||
indexTemplate: indexTemplateOpt,
|
||||
configFile,
|
||||
outDir,
|
||||
},
|
||||
_,
|
||||
filenames,
|
||||
config,
|
||||
): Promise<void> => {
|
||||
const ext = resolveExtension(config, extOpt)
|
||||
} = opts
|
||||
|
||||
const ext = resolveExtension(opts, extOpt)
|
||||
|
||||
const write = async (src: string, dest: string) => {
|
||||
if (!isCompilable(src)) {
|
||||
@ -71,7 +72,7 @@ export const dirCommand: SvgrCommand = async (
|
||||
}
|
||||
|
||||
dest = rename(dest, ext, filenameCase)
|
||||
const code = await convertFile(src, config)
|
||||
const code = await convertFile(src, opts)
|
||||
const cwdRelative = path.relative(process.cwd(), dest)
|
||||
const logOutput = `${src} -> ${cwdRelative}\n`
|
||||
|
||||
@ -86,10 +87,25 @@ export const dirCommand: SvgrCommand = async (
|
||||
return { transformed: true, dest }
|
||||
}
|
||||
|
||||
const generateIndex = async (dest: string, files: string[]) => {
|
||||
const indexFile = path.join(dest, `index.${ext}`)
|
||||
const indexTemplate = indexTemplateOpt || defaultIndexTemplate
|
||||
await fs.writeFile(indexFile, indexTemplate(files))
|
||||
const generateIndex = async (
|
||||
dest: string,
|
||||
files: string[],
|
||||
opts: Options,
|
||||
) => {
|
||||
const filepath = path.join(dest, `index.${ext}`)
|
||||
const indexTemplate = opts.indexTemplate || defaultIndexTemplate
|
||||
const fileContent = indexTemplate(files)
|
||||
const prettyContent = await (async () => {
|
||||
if (!opts.prettier) return fileContent
|
||||
const prettierRcConfig = opts.runtimeConfig
|
||||
? await resolveConfig(filepath, { editorconfig: true })
|
||||
: {}
|
||||
return format(fileContent, {
|
||||
...prettierRcConfig,
|
||||
...opts.prettierConfig,
|
||||
})
|
||||
})()
|
||||
await fs.writeFile(filepath, prettyContent)
|
||||
}
|
||||
|
||||
async function handle(filename: string, root: string) {
|
||||
@ -114,11 +130,11 @@ export const dirCommand: SvgrCommand = async (
|
||||
path.relative(root, dirname),
|
||||
)
|
||||
const resolvedConfig = loadConfig.sync(
|
||||
{ configFile, ...config },
|
||||
{ configFile, ...opts },
|
||||
{ filePath: dest },
|
||||
)
|
||||
) as Options
|
||||
if (resolvedConfig.index) {
|
||||
await generateIndex(dest, destFiles)
|
||||
await generateIndex(dest, destFiles, opts)
|
||||
}
|
||||
}
|
||||
return { transformed: false, dest: null }
|
||||
|
||||
@ -21,11 +21,10 @@ export const fileCommand: SvgrCommand = async (
|
||||
opts,
|
||||
program,
|
||||
filenames,
|
||||
config,
|
||||
): Promise<void> => {
|
||||
if (opts.stdin || (filenames.length === 0 && !process.stdin.isTTY)) {
|
||||
const input = await readStdin()
|
||||
const output = convert(input, config, { filePath: opts.stdinFilepath })
|
||||
const output = convert(input, opts, { filePath: opts.stdinFilepath })
|
||||
process.stdout.write(`${output}\n`)
|
||||
return
|
||||
}
|
||||
@ -46,6 +45,6 @@ export const fileCommand: SvgrCommand = async (
|
||||
exitError('Directory are not supported without `--out-dir` option instead.')
|
||||
}
|
||||
|
||||
const output = await convertFile(filename, config)
|
||||
const output = await convertFile(filename, opts)
|
||||
process.stdout.write(`${output}\n`)
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ describe('cli', () => {
|
||||
it('should work with a simple file', async () => {
|
||||
const result = await cli('__fixtures__/simple/file.svg')
|
||||
expect(result).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should not work with a directory without --out-dir option', async () => {
|
||||
expect.assertions(1)
|
||||
@ -29,7 +29,7 @@ describe('cli', () => {
|
||||
'Directory are not supported without `--out-dir` option instead',
|
||||
)
|
||||
}
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should not work with several files without destination', async () => {
|
||||
expect.assertions(1)
|
||||
@ -40,19 +40,19 @@ describe('cli', () => {
|
||||
'Please specify only one filename or use `--out-dir` option',
|
||||
)
|
||||
}
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should work with stdin', async () => {
|
||||
const result = await cli('< __fixtures__/simple/file.svg')
|
||||
expect(result).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should support stdin filepath', async () => {
|
||||
const result = await cli(
|
||||
'--stdin-filepath __fixtures__/simple/file.svg < __fixtures__/simple/file.svg',
|
||||
)
|
||||
expect(result).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should transform a whole directory and output relative destination paths', async () => {
|
||||
const result = await cli('--out-dir __fixtures_build__/whole __fixtures__')
|
||||
@ -62,7 +62,7 @@ describe('cli', () => {
|
||||
.map((x) => x.toLowerCase())
|
||||
.join('\n')
|
||||
expect(sorted).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should transform a whole directory with --typescript', async () => {
|
||||
const result = await cli(
|
||||
@ -74,7 +74,7 @@ describe('cli', () => {
|
||||
.map((x) => x.toLowerCase())
|
||||
.join('\n')
|
||||
expect(sorted).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should suppress output when transforming a directory with a --silent option', async () => {
|
||||
const result = await cli(
|
||||
@ -82,35 +82,35 @@ describe('cli', () => {
|
||||
)
|
||||
const sorted = result.split(/\n/).sort().join('\n')
|
||||
expect(sorted).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should support --prettier-config as json', async () => {
|
||||
const result = await cli(
|
||||
`--prettier-config '{"tabWidth": 5}' __fixtures__/simple/file.svg`,
|
||||
)
|
||||
expect(result).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should support --prettier-config as file', async () => {
|
||||
const result = await cli(
|
||||
`--prettier-config __fixtures__/withPrettierRc/.prettierrc __fixtures__/simple/file.svg`,
|
||||
)
|
||||
expect(result).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should support --svgo-config as json', async () => {
|
||||
const result = await cli(
|
||||
`--svgo-config '{"plugins":[{"name":"preset-default","params":{"overrides":{"removeTitle":false}}}]}' __fixtures__/simple/file.svg`,
|
||||
)
|
||||
expect(result).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should support --svgo-config as file', async () => {
|
||||
const result = await cli(
|
||||
`--svgo-config __fixtures__/withSvgoConfig/svgo.config.js __fixtures__/simple/file.svg`,
|
||||
)
|
||||
expect(result).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it.each([
|
||||
['--no-dimensions'],
|
||||
@ -164,7 +164,7 @@ describe('cli', () => {
|
||||
await del(outDir)
|
||||
await cli(`--ext=ts ${inDir} --out-dir=${outDir}`)
|
||||
expect(await fs.readdir(outDir)).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should support "--ignore-existing"', async () => {
|
||||
const inDir = '__fixtures__/simple'
|
||||
@ -172,14 +172,14 @@ describe('cli', () => {
|
||||
await cli(`${inDir} --out-dir=${outDir} --ignore-existing`)
|
||||
const content = await fs.readFile(path.join(outDir, 'File.js'), 'utf-8')
|
||||
expect(content).toBe('// nothing')
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should not override config with cli defaults', async () => {
|
||||
const result = await cli(
|
||||
'__fixtures__/simple/file.svg --config-file=__fixtures__/overrides.config.js',
|
||||
)
|
||||
expect(result).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should add Svg prefix to index.js exports staring with number', async () => {
|
||||
const inDir = '__fixtures__/numeric'
|
||||
@ -188,7 +188,7 @@ describe('cli', () => {
|
||||
await cli(`${inDir} --out-dir=${outDir}`)
|
||||
const content = await fs.readFile(path.join(outDir, 'index.js'), 'utf-8')
|
||||
expect(content).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should support custom index.js with directory output', async () => {
|
||||
const inDir = '__fixtures__/simple'
|
||||
@ -199,7 +199,7 @@ describe('cli', () => {
|
||||
)
|
||||
const content = await fs.readFile(path.join(outDir, 'index.js'), 'utf-8')
|
||||
expect(content).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should support --index-template in cli', async () => {
|
||||
const inDir = '__fixtures__/simple'
|
||||
@ -210,7 +210,7 @@ describe('cli', () => {
|
||||
)
|
||||
const content = await fs.readFile(path.join(outDir, 'index.js'), 'utf-8')
|
||||
expect(content).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
it('should support --no-index', async () => {
|
||||
const inDir = '__fixtures__/simple'
|
||||
@ -218,5 +218,5 @@ describe('cli', () => {
|
||||
await del(outDir)
|
||||
await cli(`--no-index ${inDir} --out-dir=${outDir}`)
|
||||
expect(await fs.readdir(outDir)).toMatchSnapshot()
|
||||
}, 10000)
|
||||
})
|
||||
})
|
||||
|
||||
@ -68,7 +68,7 @@ const parseTemplate = (name: string) => (arg: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
interface ProgramOpts extends Config {
|
||||
export interface Options extends Config {
|
||||
configFile?: string
|
||||
runtimeConfig?: boolean
|
||||
outDir?: string
|
||||
@ -82,12 +82,7 @@ interface ProgramOpts extends Config {
|
||||
}
|
||||
|
||||
export interface SvgrCommand {
|
||||
(
|
||||
opts: ProgramOpts,
|
||||
program: Command,
|
||||
filenames: string[],
|
||||
config: Config,
|
||||
): Promise<void>
|
||||
(opts: Options, program: Command, filenames: string[]): Promise<void>
|
||||
}
|
||||
|
||||
program
|
||||
@ -193,28 +188,13 @@ async function run() {
|
||||
process.exit(2)
|
||||
}
|
||||
|
||||
const opts = noUndefinedKeys(program.opts<ProgramOpts>())
|
||||
|
||||
const config = await loadConfig(opts, { filePath: process.cwd() })
|
||||
|
||||
if (opts.dimensions === true) {
|
||||
delete config.dimensions
|
||||
}
|
||||
|
||||
if (opts.svgo === true) {
|
||||
delete config.svgo
|
||||
}
|
||||
|
||||
if (opts.prettier === true) {
|
||||
delete config.prettier
|
||||
}
|
||||
|
||||
if (opts.index === false) {
|
||||
delete config.index
|
||||
}
|
||||
const programOpts = noUndefinedKeys(program.opts<Options>())
|
||||
const opts = (await loadConfig(programOpts, {
|
||||
filePath: process.cwd(),
|
||||
})) as Options
|
||||
|
||||
const command = opts.outDir ? dirCommand : fileCommand
|
||||
await command(opts, program, filenames, config)
|
||||
await command(opts, program, filenames)
|
||||
}
|
||||
|
||||
run().catch((error) => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user