@ansstory/hias 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,40 +1,48 @@
1
- const chalk = require('chalk')
2
- const {
3
- beginAction,
4
- addVueComponentAction,
5
- addReactComponentAction,
6
- addReactTsComponentAction,
7
- addReduxStoreAction,
8
- addReduxTsStoreAction,
9
- } = require('./action')
10
-
11
- const beginCommander = function (program) {
12
- console.log()
13
- program.command('create <project> [other...]').alias('crt').description('create project. For example: hias create airbnb').action(beginAction)
14
- program
15
- .command('adv <vuecpnname> [...others]')
16
- .description(`add vue component into a folder, For example: ${chalk.green.bold(`hias addv Demo -d src/components or hias addv index -d src/views/demo`)}`)
17
- .action(addVueComponentAction)
18
- program
19
- .command('adr <reactcpnname> [...others]')
20
- .description(
21
- `add react jsx component into a folder, For example: ${chalk.green.bold(`hias addr Demo -d src/components or hias addr index -d src/views/demo`)}`
22
- )
23
- .action(addReactComponentAction)
24
- program
25
- .command('adrt <reactcpnname> [...others]')
26
- .description(
27
- `add react tsx component into a folder, For example: ${chalk.green.bold(`hias addrt Demo -d src/components or hias addrt index -d src/views/demo`)}`
28
- )
29
- .action(addReactTsComponentAction)
30
- program
31
- .command('adrd <reactcpnname> [...others]')
32
- .description(`add redux jsx store into a folder, For example: ${chalk.blue.bold(`hias adrd useDemoStore -d src/store/modules`)}`)
33
- .action(addReduxStoreAction)
34
- program
35
- .command('adrdt <reactcpnname> [...others]')
36
- .description(`add redux tsx store into a folder, For example: ${chalk.blue.bold(`hias adrdt useDemoStore -d src/store/modules`)}`)
37
- .action(addReduxTsStoreAction)
38
- }
39
-
40
- module.exports = beginCommander
1
+ // 命令行指令定义文件 - 配置 CLI 的所有可用命令
2
+
3
+ const chalk = require('chalk')
4
+ const i18n = require('../i18n')
5
+ const {
6
+ beginAction,
7
+ addVueComponentAction,
8
+ addReactComponentAction,
9
+ addReactTsComponentAction,
10
+ addReduxStoreAction,
11
+ addReduxTsStoreAction,
12
+ } = require('./action')
13
+ const { handleLanguageAction } = require('./lang')
14
+ const { handleClosePortAction } = require('./close-port')
15
+
16
+ // 注册所有命令行指令
17
+ const beginCommander = function (program) {
18
+ // 获取翻译函数
19
+ const t = i18n.getT()
20
+
21
+ console.log()
22
+
23
+ // 创建项目命令:下载框架模板
24
+ program.command('create <project> [other...]').alias('crt').description(t('commands.create')).action(beginAction)
25
+
26
+ // 添加 Vue 组件命令
27
+ program.command('adv <vuecpnname> [...others]').description(t('commands.adv')).action(addVueComponentAction)
28
+
29
+ // 添加 React JSX 组件命令
30
+ program.command('adr <reactcpnname> [...others]').description(t('commands.adr')).action(addReactComponentAction)
31
+
32
+ // 添加 React TSX 组件命令
33
+ program.command('adrt <reactcpnname> [...others]').description(t('commands.adrt')).action(addReactTsComponentAction)
34
+
35
+ // 添加 Redux JSX Store 命令
36
+ program.command('adrd <reactcpnname> [...others]').description(t('commands.adrd')).action(addReduxStoreAction)
37
+
38
+ // 添加 Redux TSX Store 命令
39
+ program.command('adrdt <reactcpnname> [...others]').description(t('commands.adrdt')).action(addReduxTsStoreAction)
40
+
41
+ // 语言切换命令
42
+ program.command('lang [language]').description(t('commands.lang')).option('-l --list', 'show current language').action(handleLanguageAction)
43
+
44
+ // 关闭端口命令
45
+ program.command('close-port <ports...>').description(t('commands.closePort')).action(handleClosePortAction)
46
+ }
47
+
48
+ module.exports = beginCommander
@@ -1,19 +1,32 @@
1
- const download = require('download-git-repo')
2
- const ora = require('ora')
3
- const chalk = require('chalk')
4
- const downloadFun = function (url, project) {
5
- const spinner = ora().start()
6
- spinner.text = 'in progress...'
7
- download('direct:' + url, project, { clone: true }, (err) => {
8
- if (!err) {
9
- spinner.succeed('succeed')
10
- console.log(chalk.blue.bold('you run:'))
11
- console.log(chalk.blue.bold('cd ' + project))
12
- console.log(chalk.blue.bold('code .'))
13
- } else {
14
- spinner.fail(`error: ${err}`)
15
- }
16
- })
17
- }
18
-
19
- module.exports = downloadFun
1
+ // 项目模板下载处理文件 - 从 Git 仓库下载框架模板
2
+
3
+ const download = require('download-git-repo')
4
+ const ora = require('ora')
5
+ const chalk = require('chalk')
6
+ const i18n = require('../i18n')
7
+
8
+ // 下载框架模板函数
9
+ const downloadFun = function (url, project) {
10
+ // 获取翻译函数
11
+ const t = i18n.getT()
12
+
13
+ // 创建加载动画
14
+ const spinner = ora().start()
15
+ spinner.text = t('messages.downloading')
16
+
17
+ // 使用 download-git-repo 库下载 Git 仓库
18
+ download('direct:' + url, project, { clone: true }, (err) => {
19
+ if (!err) {
20
+ // 下载成功,停止加载动画并显示成功提示
21
+ spinner.succeed(t('messages.downloadSuccess'))
22
+ console.log(chalk.blue.bold(t('messages.youRun')))
23
+ console.log(chalk.blue.bold('cd ' + project))
24
+ console.log(chalk.blue.bold('code .'))
25
+ } else {
26
+ // 下载失败,显示错误信息
27
+ spinner.fail(`${t('messages.downloadError')}: ${err}`)
28
+ }
29
+ })
30
+ }
31
+
32
+ module.exports = downloadFun
package/lib/core/help.js CHANGED
@@ -1,6 +1,17 @@
1
- const beginHelp = function (program) {
2
- const version = require('../../package.json').version
3
- program.version(version, '-v --version')
4
- program.option('-d --dest <dest>', 'a destination folder, For example: -d src/components')
5
- }
6
- module.exports = beginHelp
1
+ // 帮助信息配置 - 定义 CLI 版本号和全局选项
2
+
3
+ const i18n = require('../i18n')
4
+
5
+ const beginHelp = function (program) {
6
+ // 获取翻译函数
7
+ const t = i18n.getT()
8
+
9
+ // 从 package.json 中读取版本号
10
+ const version = require('../../package.json').version
11
+ // 设置版本号命令
12
+ program.version(version, '-v --version')
13
+ // 定义全局目标目录选项
14
+ program.option('-d --dest <dest>', t('options.dest'))
15
+ }
16
+
17
+ module.exports = beginHelp
@@ -0,0 +1,50 @@
1
+ // 语言切换命令处理 - 处理用户设置 CLI 语言的操作
2
+
3
+ const chalk = require('chalk')
4
+ const i18n = require('../i18n')
5
+
6
+ /**
7
+ * 处理语言切换命令
8
+ * @param {string} language - 语言代码
9
+ * @param {object} options - 命令选项
10
+ */
11
+ const handleLanguageAction = (language, options) => {
12
+ const t = i18n.getT()
13
+
14
+ // 查看当前语言
15
+ if (options.list || options.l) {
16
+ const currentLang = i18n.getCurrentLanguage()
17
+ const langName = t(`languages.${currentLang}`)
18
+ console.log(chalk.blue.bold(t('messages.langCurrent', { language: langName })))
19
+ return
20
+ }
21
+
22
+ // 如果没有提供语言参数
23
+ if (!language) {
24
+ console.log(chalk.yellow.bold('Usage: hias lang <language> | hias lang -l'))
25
+ console.log(chalk.gray(`Supported languages: ${i18n.getSupportedLanguages().join(', ')}`))
26
+ return
27
+ }
28
+
29
+ // 验证语言是否支持
30
+ if (!i18n.SUPPORTED_LANGUAGES.includes(language)) {
31
+ const supportedLangs = i18n
32
+ .getSupportedLanguages()
33
+ .map((lang) => `${lang} (${t(`languages.${lang}`)})`)
34
+ .join(', ')
35
+ console.log(chalk.red.bold(t('messages.invalidLanguage', { languages: supportedLangs })))
36
+ return
37
+ }
38
+
39
+ // 设置语言
40
+ if (i18n.changeLanguage(language)) {
41
+ const langName = t(`languages.${language}`)
42
+ console.log(chalk.green.bold(t('messages.langSet', { language: langName })))
43
+ } else {
44
+ console.log(chalk.red.bold('Failed to set language'))
45
+ }
46
+ }
47
+
48
+ module.exports = {
49
+ handleLanguageAction,
50
+ }
@@ -0,0 +1,77 @@
1
+ // i18n 初始化模块 - 设置国际化并提供翻译函数
2
+
3
+ const i18next = require('i18next')
4
+ const path = require('path')
5
+ const fs = require('fs')
6
+ const store = require('./store')
7
+
8
+ // 加载翻译资源
9
+ const en = require('./resources/en.json')
10
+ const zhCN = require('./resources/zh-CN.json')
11
+
12
+ // 获取当前语言
13
+ const currentLanguage = store.getLanguage()
14
+
15
+ /**
16
+ * 初始化 i18n
17
+ */
18
+ i18next.init({
19
+ lng: currentLanguage,
20
+ fallbackLng: 'en',
21
+ interpolation: {
22
+ escapeValue: false, // 不转义插值内容
23
+ },
24
+ resources: {
25
+ en: { translation: en },
26
+ 'zh-CN': { translation: zhCN },
27
+ },
28
+ })
29
+
30
+ /**
31
+ * 获取翻译函数
32
+ * @returns {function} t 翻译函数
33
+ */
34
+ function getT() {
35
+ return i18next.t.bind(i18next)
36
+ }
37
+
38
+ /**
39
+ * 更改语言
40
+ * @param {string} language - 语言代码
41
+ * @returns {boolean} 是否更改成功
42
+ */
43
+ function changeLanguage(language) {
44
+ if (!store.SUPPORTED_LANGUAGES.includes(language)) {
45
+ return false
46
+ }
47
+
48
+ if (store.setLanguage(language)) {
49
+ i18next.changeLanguage(language)
50
+ return true
51
+ }
52
+ return false
53
+ }
54
+
55
+ /**
56
+ * 获取当前语言代码
57
+ * @returns {string} 语言代码
58
+ */
59
+ function getCurrentLanguage() {
60
+ return i18next.language
61
+ }
62
+
63
+ /**
64
+ * 获取支持的语言列表
65
+ * @returns {array} 语言代码数组
66
+ */
67
+ function getSupportedLanguages() {
68
+ return store.SUPPORTED_LANGUAGES
69
+ }
70
+
71
+ module.exports = {
72
+ getT,
73
+ changeLanguage,
74
+ getCurrentLanguage,
75
+ getSupportedLanguages,
76
+ SUPPORTED_LANGUAGES: store.SUPPORTED_LANGUAGES,
77
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "commands": {
3
+ "create": "create project. For example: hias create airbnb",
4
+ "adv": "add vue component into a folder, For example: hias adv Demo -d src/components or hias adv index -d src/views/demo",
5
+ "adr": "add react jsx component into a folder, For example: hias adr Demo -d src/components or hias adr index -d src/views/demo",
6
+ "adrt": "add react tsx component into a folder, For example: hias adrt Demo -d src/components or hias adrt index -d src/views/demo",
7
+ "adrd": "add redux jsx store into a folder, For example: hias adrd useDemoStore -d src/store/modules",
8
+ "adrdt": "add redux tsx store into a folder, For example: hias adrdt useDemoStore -d src/store/modules",
9
+ "lang": "set CLI language. For example: hias lang zh-CN or hias lang en",
10
+ "closePort": "close processes occupying one or more ports. For example: hias close-port 8076 8077 or hias close-port 8076,8077"
11
+ },
12
+ "options": {
13
+ "dest": "a destination folder, For example: -d src/components"
14
+ },
15
+ "prompts": {
16
+ "selectTemplate": "Please select the template."
17
+ },
18
+ "messages": {
19
+ "downloading": "in progress...",
20
+ "downloadSuccess": "succeed",
21
+ "downloadError": "error",
22
+ "componentCreated": "Component creation was successful:",
23
+ "youRun": "you run:",
24
+ "langSet": "Language has been set to: {{language}}",
25
+ "langCurrent": "Current language: {{language}}",
26
+ "invalidLanguage": "Invalid language. Supported languages: {{languages}}",
27
+ "closePortSuccess": "Closed port {{port}}. Killed PID(s): {{pids}}",
28
+ "closePortNoProcess": "No process is occupying port {{port}}."
29
+ },
30
+ "languages": {
31
+ "en": "English",
32
+ "zh-CN": "简体中文"
33
+ }
34
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "commands": {
3
+ "create": "创建项目。示例: hias create airbnb",
4
+ "adv": "将 Vue 组件添加到文件夹,示例: hias adv Demo -d src/components 或 hias adv index -d src/views/demo",
5
+ "adr": "将 React JSX 组件添加到文件夹,示例: hias adr Demo -d src/components 或 hias adr index -d src/views/demo",
6
+ "adrt": "将 React TSX 组件添加到文件夹,示例: hias adrt Demo -d src/components 或 hias adrt index -d src/views/demo",
7
+ "adrd": "将 Redux JSX Store 添加到文件夹,示例: hias adrd useDemoStore -d src/store/modules",
8
+ "adrdt": "将 Redux TSX Store 添加到文件夹,示例: hias adrdt useDemoStore -d src/store/modules",
9
+ "lang": "设置 CLI 语言。示例: hias lang zh-CN 或 hias lang en",
10
+ "closePort": "关闭占用一个或多个端口的进程。示例: hias close-port 8076 8077 或 hias close-port 8076,8077"
11
+ },
12
+ "options": {
13
+ "dest": "目标文件夹,示例: -d src/components"
14
+ },
15
+ "prompts": {
16
+ "selectTemplate": "请选择模板。"
17
+ },
18
+ "messages": {
19
+ "downloading": "正在下载...",
20
+ "downloadSuccess": "成功",
21
+ "downloadError": "错误",
22
+ "componentCreated": "组件创建成功:",
23
+ "youRun": "请运行:",
24
+ "langSet": "语言已设置为: {{language}}",
25
+ "langCurrent": "当前语言: {{language}}",
26
+ "invalidLanguage": "无效的语言。支持的语言: {{languages}}",
27
+ "closePortSuccess": "已关闭端口 {{port}}。结束的 PID: {{pids}}",
28
+ "closePortNoProcess": "端口 {{port}} 当前没有被进程占用。"
29
+ },
30
+ "languages": {
31
+ "en": "English",
32
+ "zh-CN": "简体中文"
33
+ }
34
+ }
@@ -0,0 +1,85 @@
1
+ // i18n 配置存储模块 - 管理用户的语言偏好设置
2
+
3
+ const fs = require('fs')
4
+ const path = require('path')
5
+ const os = require('os')
6
+
7
+ // 配置文件路径:~/.hias-cli/config.json
8
+ const CONFIG_DIR = path.join(os.homedir(), '.hias-cli')
9
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json')
10
+
11
+ // 默认语言
12
+ const DEFAULT_LANGUAGE = 'en'
13
+
14
+ // 支持的语言列表
15
+ const SUPPORTED_LANGUAGES = ['en', 'zh-CN']
16
+
17
+ /**
18
+ * 确保配置目录存在
19
+ */
20
+ function ensureConfigDir() {
21
+ if (!fs.existsSync(CONFIG_DIR)) {
22
+ fs.mkdirSync(CONFIG_DIR, { recursive: true })
23
+ }
24
+ }
25
+
26
+ /**
27
+ * 获取当前设置的语言
28
+ * @returns {string} 语言代码 (如: 'en' 或 'zh-CN')
29
+ */
30
+ function getLanguage() {
31
+ try {
32
+ ensureConfigDir()
33
+ if (fs.existsSync(CONFIG_FILE)) {
34
+ const config = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'))
35
+ if (config.language && SUPPORTED_LANGUAGES.includes(config.language)) {
36
+ return config.language
37
+ }
38
+ }
39
+ } catch (err) {
40
+ console.error('Error reading config:', err)
41
+ }
42
+ return DEFAULT_LANGUAGE
43
+ }
44
+
45
+ /**
46
+ * 设置语言
47
+ * @param {string} language - 语言代码 (如: 'en' 或 'zh-CN')
48
+ * @returns {boolean} 是否设置成功
49
+ */
50
+ function setLanguage(language) {
51
+ try {
52
+ if (!SUPPORTED_LANGUAGES.includes(language)) {
53
+ return false
54
+ }
55
+
56
+ ensureConfigDir()
57
+ const config = {}
58
+
59
+ // 读取现有配置(如果存在)
60
+ if (fs.existsSync(CONFIG_FILE)) {
61
+ try {
62
+ Object.assign(config, JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8')))
63
+ } catch (err) {
64
+ // 忽略读取错误
65
+ }
66
+ }
67
+
68
+ // 更新语言设置
69
+ config.language = language
70
+
71
+ // 写入配置文件
72
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8')
73
+ return true
74
+ } catch (err) {
75
+ console.error('Error writing config:', err)
76
+ return false
77
+ }
78
+ }
79
+
80
+ module.exports = {
81
+ getLanguage,
82
+ setLanguage,
83
+ SUPPORTED_LANGUAGES,
84
+ DEFAULT_LANGUAGE,
85
+ }
package/lib/index.js CHANGED
@@ -1,7 +1,15 @@
1
1
  #! /usr/bin/env node
2
- const { program } = require('commander')
3
- const beginHelp = require('./core/help')
4
- const beginCommander = require('./core/commander')
5
- beginHelp(program)
6
- beginCommander(program)
7
- program.parse(process.argv)
2
+ // CLI 入口文件 - 项目模板生成工具的主程序
3
+ // 初始化国际化模块(必须在其他模块之前)
4
+ require('./i18n')
5
+
6
+ const { program } = require('commander')
7
+ const beginHelp = require('./core/help')
8
+ const beginCommander = require('./core/commander')
9
+
10
+ // 初始化帮助信息
11
+ beginHelp(program)
12
+ // 初始化命令行指令
13
+ beginCommander(program)
14
+ // 解析命令行参数
15
+ program.parse(process.argv)
@@ -1,11 +1,11 @@
1
- import React, { memo } from 'react'
2
-
3
- const <%= name %> = memo(() => {
4
- return (
5
- <div>
6
- <%= name %>
7
- </div>
8
- )
9
- })
10
-
11
- export default <%= name %>
1
+ import React, { memo } from 'react'
2
+
3
+ const <%= name %> = memo(() => {
4
+ return (
5
+ <div>
6
+ <%= name %>
7
+ </div>
8
+ )
9
+ })
10
+
11
+ export default <%= name %>
@@ -1,12 +1,12 @@
1
- import React, { memo } from "react"
2
- import type { FC, ReactNode } from "react"
3
-
4
- interface IProps {
5
- children?: ReactNode
6
- }
7
-
8
- const <%= name %>: FC<IProps> = memo(() => {
9
- return (<div> <%= name %> </div>)
10
- })
11
-
12
- export default <%= name %>
1
+ import React, { memo } from "react"
2
+ import type { FC, ReactNode } from "react"
3
+
4
+ interface IProps {
5
+ children?: ReactNode
6
+ }
7
+
8
+ const <%= name %>: FC<IProps> = memo(() => {
9
+ return (<div> <%= name %> </div>)
10
+ })
11
+
12
+ export default <%= name %>
@@ -1,13 +1,13 @@
1
- <script setup>
2
-
3
- </script>
4
-
5
- <template>
6
- <div class="<%= lowername %>">
7
- <%= name %>
8
- </div>
9
- </template>
10
-
11
- <style lang="scss" scoped>
12
- .<%=lowername %> {}
13
- </style>
1
+ <script setup>
2
+
3
+ </script>
4
+
5
+ <template>
6
+ <div class="<%= lowername %>">
7
+ <%= name %>
8
+ </div>
9
+ </template>
10
+
11
+ <style lang="scss" scoped>
12
+ .<%=lowername %> {}
13
+ </style>
@@ -1,16 +1,16 @@
1
- import { createSlice } from '@reduxjs/toolkit'
2
-
3
- const <%= name %>SliceModule = createSlice({
4
- name: '<%= name %>',
5
- initialState:{
6
- count: 100,
7
- },
8
- reducers: {
9
- changeCountAction(state, { payload }) {
10
- state.message = payload
11
- },
12
- },
13
- })
14
-
15
- export const { changeCountAction } = <%= name %>SliceModule.actions
16
- export default <%= name %>SliceModule.reducer
1
+ import { createSlice } from '@reduxjs/toolkit'
2
+
3
+ const <%= name %>SliceModule = createSlice({
4
+ name: '<%= name %>',
5
+ initialState:{
6
+ count: 100,
7
+ },
8
+ reducers: {
9
+ changeCountAction(state, { payload }) {
10
+ state.message = payload
11
+ },
12
+ },
13
+ })
14
+
15
+ export const { changeCountAction } = <%= name %>SliceModule.actions
16
+ export default <%= name %>SliceModule.reducer
@@ -1,22 +1,22 @@
1
- import { createSlice, PayloadAction } from '@reduxjs/toolkit'
2
-
3
- interface IState {
4
- count: number
5
- }
6
-
7
- const initialState: IState = {
8
- count: 100,
9
- }
10
-
11
- const <%= name %>SliceModule = createSlice({
12
- name: '<%= name %>',
13
- initialState,
14
- reducers: {
15
- changeCountAction(state, { payload }: PayloadAction<number>) {
16
- state.count = payload
17
- },
18
- },
19
- })
20
-
21
- export const { changeCountAction } = <%= name %>SliceModule.actions
22
- export default <%= name %>SliceModule.reducer
1
+ import { createSlice, PayloadAction } from '@reduxjs/toolkit'
2
+
3
+ interface IState {
4
+ count: number
5
+ }
6
+
7
+ const initialState: IState = {
8
+ count: 100,
9
+ }
10
+
11
+ const <%= name %>SliceModule = createSlice({
12
+ name: '<%= name %>',
13
+ initialState,
14
+ reducers: {
15
+ changeCountAction(state, { payload }: PayloadAction<number>) {
16
+ state.count = payload
17
+ },
18
+ },
19
+ })
20
+
21
+ export const { changeCountAction } = <%= name %>SliceModule.actions
22
+ export default <%= name %>SliceModule.reducer