UNPKG

ts-add-js-extension

Version:

Add .js extension to each relative ESM import and export statement in JavaScript file

253 lines (252 loc) 7.71 kB
import fs from "fs"; import path from "path"; import pkg from "./package.js"; import { guard } from "./type.js"; const commandKeyWords = { help: { isMandatory: false, keyword: "help", }, version: { isMandatory: false, keyword: "version", }, dir: { isMandatory: true, keyword: "dir", }, include: { isMandatory: false, keyword: "include", }, showChanges: { type: "deprecated", isMandatory: false, keyword: "showchanges", reason: "The function showchanges is deprecated in favor of `showprogress`", }, assignment: { assign: "=", key: "--", }, }; class TokenParser { token; constructor(token) { this.token = token; } parseVersion = () => { const { keyword } = commandKeyWords.version; if (this.token.key !== keyword) { return { exists: false, }; } return { type: keyword, exists: true, value: pkg.version, }; }; parseHelp = () => { const { keyword } = commandKeyWords.help; if (this.token.key !== commandKeyWords.help.keyword) { return { exists: false, }; } return { type: keyword, exists: true, value: fs.readFileSync("public/help.md", { encoding: "utf-8" }), }; }; parseDir = () => { const { keyword } = commandKeyWords.dir; if (this.token.key !== commandKeyWords.dir.keyword) { return { exists: false, }; } return { type: keyword, exists: true, value: guard({ value: this.token.value.split(" ").at(0), error: new Error("There must be at least one element in values for dir"), }), }; }; parseInclude = () => { const { keyword } = commandKeyWords.include; if (this.token.key !== commandKeyWords.include.keyword) { return { exists: false, }; } return { type: keyword, exists: true, value: this.token.value.split(" "), }; }; parseShowChanges = () => { const { keyword } = commandKeyWords.showChanges; const { key, value } = this.token; if (key !== commandKeyWords.showChanges.keyword) { return { exists: false, }; } if (value === "true" || value === "false") { return { type: keyword, exists: true, value: JSON.parse(value), }; } throw new Error(`${key}=${value} is invalid, it can only receive boolean value`); }; processNonRecognisableToken = () => { return { type: "invalid", reason: `${this.token.key}=${this.token.value} token cannot be recognized`, token: this.token, }; }; } class ParseArgs { tokens; constructor(args) { this.tokens = this.tokenize(args); } static create = (arg) => { const tokens = arg.split(commandKeyWords.assignment.key); const result = ParseArgs.checkPackageName(tokens.at(0)); if (result.isInvalid) { throw result.error; } if (tokens.includes("add")) { console.log("The \"add\" in the command can be removed, as it is only used for backward compatibility"); } return new this(tokens .map((token) => { return token === "add" ? "" : token; }) .slice(1)); }; static checkPackageName = (name) => { const packageName = guard({ value: name, error: new Error("The pkg name is undefined"), }); return packageName.includes(pkg.name) ? { isInvalid: false, } : { isInvalid: true, error: new Error(`The pkg name "${packageName}" passed is invalid`), }; }; tokenize = (args) => { const { assign } = commandKeyWords.assignment; return args .flatMap((arg) => { if (arg.includes(assign)) { return [arg]; } const [nullableKey, ...value] = arg.split(" "); const key = guard({ value: nullableKey, error: new Error("Key cannot be undefined after being split"), }); return [`${key}${assign}${value.join(" ")}`]; }) .map((args) => { const [key, value] = args.split(assign); return { key: guard({ value: key, error: new Error("Key cannot be undefined after being flat mapped"), }), value: guard({ value, error: new Error("Value cannot be undefined after being flat mapped"), }).trim(), }; }); }; asVersion = () => { return this.tokens.reduce((result, token) => { if (result.exists) { return result; } return new TokenParser(token).parseVersion(); }, { exists: false, }); }; asHelp = () => { if (!this.tokens.length) { return { type: "help", exists: true, value: fs.readFileSync(path.join("public", "help.md"), { encoding: "utf-8", }), }; } return this.tokens.reduce((result, token) => { if (result.exists) { return result; } return new TokenParser(token).parseHelp(); }, { exists: false }); }; asOperation = () => { const processedToken = this.tokens.map((token) => { const parser = new TokenParser(token); const dir = parser.parseDir(); if (dir.exists) { return dir; } const include = parser.parseInclude(); if (include.exists) { return include; } const showChanges = parser.parseShowChanges(); if (showChanges.exists) { return showChanges; } return parser.processNonRecognisableToken(); }); processedToken .flatMap((node) => { return node.type !== "invalid" ? [] : [node]; }) .forEach((node) => { console.log(`The "${JSON.stringify(node.token, undefined, 4)}" in the command is invalid as ${node.reason}. So please remove it`); }); const nodes = processedToken.flatMap((node) => { return node.type === "invalid" ? [] : [node]; }); return { dir: guard({ value: nodes.find((node) => { return node.type === "dir"; })?.value, error: new Error("dir is a mandatory field, it should be present to know which dir it should operate on"), }), // optional include: nodes.find((node) => { return node.type === "include"; })?.value, showChanges: nodes.find((node) => { return node.type === "showchanges"; })?.value, }; }; } export default ParseArgs; //# sourceMappingURL=cli-command-parser.js.map