-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(CLI): renew command line arguments (#3)
* chore: add change-case for support case style * docs: add inputs arguments in README.md * feat(CLI): add flags and options * `-v, --version`: Print version information. * `-C, --case`: Sets case for export name declarations * refactor(CLI): remove unused and fix typo for function declarations * feat(CLI): add missing style case * feat(CLI): support multiple input directories or files
- Loading branch information
Showing
5 changed files
with
256 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,73 +1,142 @@ | ||
#!/usr/bin/env node | ||
const { | ||
name: packageName, | ||
version: packageVersion, | ||
} = require("./package.json"); | ||
const Fs = require("fs"); | ||
const Path = require("path"); | ||
const BabelGenerator = require("@babel/generator").default; | ||
const argv = require("minimist")(process.argv.slice(2)); | ||
const { createChakraIcon } = require("./lib/chakra"); | ||
const { stdout: output, stdin: input, exit } = process; | ||
const { | ||
stdout: output, | ||
stdin: input, | ||
exit, | ||
stderr: error, | ||
} = require("process"); | ||
const { | ||
pascalCase: PascalCase, | ||
camelCase, | ||
snakeCase: snake_case, | ||
constantCase: CONSTANT_CASE, | ||
} = require("change-case"); | ||
const encoding = "utf-8"; | ||
|
||
if (input.isTTY) { | ||
main(argv); | ||
} else { | ||
input.setEncoding(encoding); | ||
input.on("data", function (data) { | ||
if (data) { | ||
const name = argv.name || argv.n || "Unamed"; | ||
const exportNameCase = argv.C || argv.case; | ||
const source = createCode(name, { | ||
file: data, | ||
displayName: name, | ||
source: data, | ||
displayName: stringToCase(name, exportNameCase), | ||
}); | ||
output.write(source); | ||
} | ||
}); | ||
} | ||
|
||
function createCode(name, ...svgs) { | ||
const icon = createChakraIcon(name, ...svgs); | ||
function createCode(...sources) { | ||
const icon = createChakraIcon(...sources); | ||
return BabelGenerator(icon).code; | ||
} | ||
|
||
function stringToCase(str, _case) { | ||
return { | ||
[true]: PascalCase(str), | ||
[_case === "pascal"]: PascalCase(str), | ||
[_case === "camel"]: camelCase(str), | ||
[_case === "constant"]: CONSTANT_CASE(str), | ||
[_case === "snake"]: snake_case(str), | ||
}[true]; | ||
} | ||
|
||
function stringToInput({ displayName, exportNameCase, encoding }) { | ||
return function (acc, str) { | ||
if (Fs.existsSync(str)) { | ||
if (Fs.lstatSync(str).isDirectory()) { | ||
const pathResolved = Path.resolve(str); | ||
acc.push( | ||
...Fs.readdirSync(pathResolved) | ||
.filter((f) => f.split(".")[1] === "svg") | ||
.map((f) => Path.join(pathResolved, f)) | ||
.map((source) => ({ | ||
displayName: stringToCase( | ||
Path.basename(source).split(".")[0], | ||
exportNameCase | ||
), | ||
source: Fs.readFileSync(source, encoding), | ||
})) | ||
); | ||
} else { | ||
acc.push({ | ||
displayName: stringToCase(displayName, exportNameCase), | ||
source: Fs.readFileSync(str, encoding), | ||
}); | ||
} | ||
} | ||
return acc; | ||
}; | ||
} | ||
// :: [Object] -> () *Effect* | ||
function main(args) { | ||
const fileOrDirs = args.i || args.input; | ||
const inputs = (args.i && [args.i]) || (args.input && [args.input]) || args._; | ||
const version = args.V || args.version; | ||
const outFile = args.o || args.output; | ||
const name = args.name || args.n || "Unamed"; | ||
const exportNameCase = args.C || args.case; | ||
|
||
// check is {file} exist | ||
Fs.exists(fileOrDirs, (isExist) => { | ||
if (!isExist) { | ||
console.error("Cannot handle input") && exit(1); | ||
} | ||
// all the input will put in an array {_files} | ||
let _files = []; | ||
// handle when {-i} || {--input} is file.svg or dirs/ | ||
if (Fs.lstatSync(fileOrDirs).isDirectory()) { | ||
const pathResolved = Path.resolve(fileOrDirs); | ||
_files = _files.concat( | ||
Fs.readdirSync(pathResolved) | ||
.filter((f) => f.split(".")[1] === "svg") | ||
.map((f) => Path.join(pathResolved, f)) | ||
); | ||
} else { | ||
_files = _files.concat([fileOrDirs]); | ||
} | ||
if (inputs.length > 0) { | ||
// make code | ||
const source = createCode( | ||
name, | ||
..._files.map((_file) => ({ | ||
file: Fs.readFileSync(_file, encoding), | ||
displayName: (() => { | ||
const [_name] = Path.basename(_file).split(".") || [name]; | ||
return _name; | ||
})(), | ||
})) | ||
...inputs.reduce( | ||
stringToInput({ displayName: name, exportNameCase, encoding }), | ||
[] | ||
) | ||
); | ||
// write output in output | ||
outFile | ||
return outFile | ||
? Fs.writeFile(Path.resolve(outFile), source, (err) => { | ||
if (err) { | ||
console.log(err) && exit(1); | ||
error.write(err, () => exit(1)); | ||
} | ||
}) | ||
: output.write(source); | ||
}); | ||
: output.write(`${source}`); | ||
} else if (version) { | ||
return output.write(packageVersion); | ||
} | ||
|
||
output.write(` | ||
USAGE: ${packageName} [FLAGS] [OPTIONS] [INPUT] | ||
By default, output is written to stdout. | ||
Stdin is read if is piped to create-chakra-icons. | ||
FLAGS: | ||
-h, --help Prints help information | ||
-V, --version Prints version information | ||
OPTIONS: | ||
-i, --input <PATH> This option for read the input from PATH from FILE or DIRECTORIES. | ||
[e.g.: -i some/path , -i file.svg] | ||
-o, --output <PATH> Writes the output. [default: stdout] | ||
-n, --name <STRING> Sets value for \`displayName\` properties | ||
(*ONLY for pipelines command). [default: Unamed] [e.g. -n "MyIcon"] | ||
-C, --case <snake|camel|constant|pascal> | ||
Sets for case [snake|camel|constant|pascal] in export named declaration | ||
output. [default: pascal] | ||
-S, --suffix <STRING> Sets for suffix in export named declaration. | ||
[e.g.: -S "Icon"] | ||
--ts, --typescript Sets output as TypeScript code. (UNAVAILABLE, SOON). | ||
[INPUT]: This option for read the input from PATH of FILE or DIRECTORIES. | ||
[e.g.: create-chakra-icons ./MyICON.svg ~/assets] | ||
${packageName} (version: ${packageVersion}) | ||
`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.