|
| 1 | +import inquirer from 'inquirer' |
| 2 | +import ejs from 'ejs' |
| 3 | +import path from 'path' |
| 4 | +import { fileURLToPath } from 'url' |
| 5 | +import * as fs from 'fs/promises' |
| 6 | + |
| 7 | +// 获取当前所在路径 |
| 8 | +const dirname = path.dirname(fileURLToPath(import.meta.url)) |
| 9 | + |
| 10 | +/** EJS 模板参数 */ |
| 11 | +const templateParams = { |
| 12 | + /** 题目编号 */ |
| 13 | + titleNumber: 0, |
| 14 | + /** 题目中文标题 */ |
| 15 | + titleChinese: '', |
| 16 | + /** 题目英文标题 */ |
| 17 | + titleEnglish: '', |
| 18 | + /** LeetCode 入口函数名 */ |
| 19 | + leetCodeFunctionName: '', |
| 20 | + /** LeetCode 题目链接 */ |
| 21 | + problemLink: '', |
| 22 | + /** 题目难度(简单 中等 困难) */ |
| 23 | + difficulty: '', |
| 24 | + /** JS 模块名称,格式:[题目编号]_[英文小驼峰题目名称] */ |
| 25 | + moduleName: '' |
| 26 | +} |
| 27 | + |
| 28 | +/** |
| 29 | + * 将英文句子转换为小驼峰字符串 |
| 30 | + * @param {string} sentence - 英文句子 |
| 31 | + */ |
| 32 | +function getLowerCamelCaseBySentence (sentence: string): string { |
| 33 | + let result: string = '' |
| 34 | + const words = sentence.split(' ').map(word => word.toLowerCase()) |
| 35 | + result += words.shift() ?? '' |
| 36 | + words.forEach(word => { result += word.charAt(0).toUpperCase() + word.slice(1) }) |
| 37 | + return result |
| 38 | +} |
| 39 | + |
| 40 | +/** |
| 41 | + * 通过用户输入设置模板参数 |
| 42 | + */ |
| 43 | +async function setTemplateParams (): Promise<void> { |
| 44 | + // 通过控制台用户输入或选择参数 |
| 45 | + const answers = await inquirer.prompt( |
| 46 | + [ |
| 47 | + { name: 'titleNumber', type: 'number', message: 'Title number:' }, |
| 48 | + { name: 'titleChinese', type: 'string', message: 'Chinese title:' }, |
| 49 | + { name: 'titleEnglish', type: 'string', message: 'English title:' }, |
| 50 | + { name: 'leetCodeFunctionName', type: 'string', message: 'LeetCode function name:', default: 'main' }, |
| 51 | + { name: 'problemLink', type: 'string', message: 'LeetCode link:' }, |
| 52 | + { name: 'difficulty', type: 'list', message: 'Difficulty:', choices: ['Easy', 'Medium', 'Hard'], default: 'Medium' } |
| 53 | + ] |
| 54 | + ) |
| 55 | + |
| 56 | + // 设置难度 |
| 57 | + answers.difficulty = { |
| 58 | + Easy: '简单', |
| 59 | + Medium: '中等', |
| 60 | + Hard: '困难' |
| 61 | + }[answers.difficulty as string] |
| 62 | + |
| 63 | + // 设置模块名称 |
| 64 | + templateParams.moduleName = `${answers.titleNumber as string}_${getLowerCamelCaseBySentence(answers.titleEnglish)}` |
| 65 | + |
| 66 | + // 合并模板参数 |
| 67 | + Object.assign(templateParams, answers) |
| 68 | +} |
| 69 | + |
| 70 | +/** |
| 71 | + * 创建文件 |
| 72 | + * @description 创建源码、单元测试、测试用例文件 |
| 73 | + */ |
| 74 | +function createFiles (): void { |
| 75 | + // 创建源码文件 |
| 76 | + const srcFilePath = path.join(dirname, `../src/${templateParams.moduleName}.ts`) |
| 77 | + ejs.renderFile(path.join(dirname, './templates/src.ts.ejs'), templateParams).then(result => { |
| 78 | + void fs.writeFile(srcFilePath, result) |
| 79 | + }) |
| 80 | + |
| 81 | + // 创建单元测试文件 |
| 82 | + const unitTestFilePath = path.join(dirname, `../tests/${templateParams.moduleName}.test.ts`) |
| 83 | + ejs.renderFile(path.join(dirname, './templates/unitTest.ts.ejs'), templateParams).then(result => { |
| 84 | + void fs.writeFile(unitTestFilePath, result) |
| 85 | + }) |
| 86 | + |
| 87 | + // 创建测试用例文件 |
| 88 | + const testCaseFilePath = path.join(dirname, `../tests/testCases/${templateParams.moduleName}.ts`) |
| 89 | + ejs.renderFile(path.join(dirname, './templates/testCase.ts.ejs'), templateParams).then(result => { |
| 90 | + void fs.writeFile(testCaseFilePath, result) |
| 91 | + }) |
| 92 | +} |
| 93 | + |
| 94 | +// 程序入口 |
| 95 | +void (async function (): Promise<void> { |
| 96 | + // 设置模板参数 |
| 97 | + await setTemplateParams() |
| 98 | + |
| 99 | + // 创建文件 |
| 100 | + createFiles() |
| 101 | +})() |
0 commit comments