ono-cli 0.0.1

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.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # 自定义脚手架
@@ -0,0 +1,29 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "fs";
2
+ import { decode, encode } from "ini";
3
+ import { configPath } from "../constants.js";
4
+ export default (value, option) => {
5
+ const { exists, config } = getAllConfig();
6
+ const action = Object.keys(option)[0];
7
+ const key = option[action];
8
+ if (action === 'get') {
9
+ console.log(config[key]);
10
+ }
11
+ else if (action === 'set') {
12
+ config[key] = value;
13
+ writeFileSync(configPath, encode(config));
14
+ }
15
+ else if (action === 'delete') {
16
+ delete config[key];
17
+ if (exists)
18
+ writeFileSync(configPath, encode(config));
19
+ }
20
+ };
21
+ export const getAllConfig = () => {
22
+ const config = { organization: '', access_token: '' };
23
+ const exists = existsSync(configPath);
24
+ if (exists) {
25
+ const userConfig = decode(readFileSync(configPath, 'utf-8'));
26
+ Object.assign(config, userConfig);
27
+ }
28
+ return { exists, config };
29
+ };
@@ -0,0 +1,203 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import chalk from "chalk";
11
+ import { existsSync } from "fs";
12
+ import inquirer from 'inquirer';
13
+ import path from "path";
14
+ import { cloneAndCheckoutTag } from "../utils/project.js";
15
+ export default (name, options) => __awaiter(void 0, void 0, void 0, function* () {
16
+ const projectConfig = {
17
+ name: '', // 项目名称
18
+ path: '', // 项目路径
19
+ isOverwrite: false, // 是否覆盖
20
+ };
21
+ if (!name) {
22
+ const { projectName } = yield inquirer.prompt([
23
+ {
24
+ name: 'projectName',
25
+ type: 'input', // list, input, confirm, checkbox, rawlist, expand
26
+ default: 'my-project',
27
+ message: '项目名称',
28
+ }
29
+ ]);
30
+ projectConfig.name = projectName ? projectName.trim() : 'my-project';
31
+ }
32
+ const cwd = process.cwd();
33
+ const targetDir = path.join(cwd, projectConfig.name);
34
+ if (existsSync(targetDir)) {
35
+ if (options.force) {
36
+ projectConfig.isOverwrite = true;
37
+ projectConfig.path = targetDir;
38
+ }
39
+ else {
40
+ const { action } = yield inquirer.prompt([
41
+ {
42
+ name: 'action',
43
+ type: 'list', // list, input, confirm, checkbox, rawlist, expand
44
+ message: `目录${projectConfig.name}已存在,是否覆盖?`,
45
+ choices: [{
46
+ name: '覆盖',
47
+ value: 'overwrite'
48
+ }, {
49
+ name: '取消',
50
+ value: 'cancel'
51
+ }]
52
+ }
53
+ ]);
54
+ switch (action) {
55
+ case 'overwrite':
56
+ projectConfig.isOverwrite = true;
57
+ projectConfig.path = targetDir;
58
+ break;
59
+ case 'cancel':
60
+ return console.log(`取消创建目录${projectConfig.name}`);
61
+ default:
62
+ break;
63
+ }
64
+ }
65
+ }
66
+ // const projects = await getOrganizationProject()
67
+ // const { projectName } = await inquirer.prompt([
68
+ // {
69
+ // name: 'projectName',
70
+ // type: 'list', // list, input, confirm, checkbox, rawlist, expand
71
+ // message: '选择模板',
72
+ // choices: projects
73
+ // }
74
+ // ])
75
+ // const tags = await getProjectVersion(projectName)
76
+ // const { tag } = await inquirer.prompt([
77
+ // {
78
+ // name: 'tag',
79
+ // type: 'list', // list, input, confirm, checkbox, rawlist, expand
80
+ // message: '请选择版本',
81
+ // choices: tags
82
+ // }
83
+ // ])
84
+ // console.log(tag);
85
+ const framework = yield inquirer.prompt([
86
+ {
87
+ name: 'framework',
88
+ type: 'list',
89
+ message: '选择框架',
90
+ choices: [
91
+ {
92
+ name: chalk.hex('#42b883')('Vue'),
93
+ value: 'vue'
94
+ },
95
+ {
96
+ name: chalk.hex('#087ea4')('React'),
97
+ value: 'react'
98
+ },
99
+ {
100
+ name: chalk.hex('#fecf05')('Vanilla'),
101
+ value: 'vanilla'
102
+ }
103
+ ]
104
+ }
105
+ ]);
106
+ const { language } = yield inquirer.prompt([
107
+ {
108
+ name: 'language',
109
+ type: 'confirm',
110
+ message: '是否使用TypeScript?',
111
+ }
112
+ ]);
113
+ const router = yield inquirer.prompt([
114
+ {
115
+ name: 'router',
116
+ type: 'list',
117
+ message: '选择路由',
118
+ choices: [
119
+ {
120
+ name: chalk.hex('#3451b2')('React Router'),
121
+ value: 'react-router'
122
+ },
123
+ {
124
+ name: chalk.hex('#39c05b')('TanStack Router'),
125
+ value: 'tanStack-router'
126
+ },
127
+ {
128
+ name: 'Vanilla',
129
+ value: ''
130
+ }
131
+ ]
132
+ }
133
+ ]);
134
+ const store = yield inquirer.prompt([
135
+ {
136
+ name: 'store',
137
+ type: 'list',
138
+ message: '选择状态管理仓库',
139
+ choices: [
140
+ {
141
+ name: chalk.hex('#764abc')('Redux'),
142
+ value: 'redux'
143
+ },
144
+ {
145
+ name: chalk.hex('#1c16df')('Zustand'),
146
+ value: 'zustand'
147
+ },
148
+ {
149
+ name: 'Vanilla',
150
+ value: ''
151
+ }
152
+ ]
153
+ }
154
+ ]);
155
+ const atomStyle = yield inquirer.prompt([
156
+ {
157
+ name: 'atomStyle',
158
+ type: 'list',
159
+ message: '选择原子化样式库',
160
+ choices: [
161
+ {
162
+ name: chalk.hex('#38bdf8')('Tailwind CSS'),
163
+ value: 'tailwindcss'
164
+ },
165
+ {
166
+ name: chalk.hex('#4d9375')('Uno CSS'),
167
+ value: 'unocss'
168
+ },
169
+ {
170
+ name: 'Vanilla',
171
+ value: ''
172
+ }
173
+ ]
174
+ }
175
+ ]);
176
+ const stylePrecompiler = yield inquirer.prompt([
177
+ {
178
+ name: 'stylePrecompiler',
179
+ type: 'list',
180
+ message: '选择预编译器',
181
+ choices: [
182
+ {
183
+ name: chalk.hex('#cc6699')('Sass'),
184
+ value: 'sass'
185
+ },
186
+ {
187
+ name: chalk.hex('#1d365d')('Less'),
188
+ value: 'less'
189
+ },
190
+ {
191
+ name: chalk.hex('#89ba1b')('Stylus'),
192
+ value: 'stylus'
193
+ },
194
+ {
195
+ name: 'Vanilla',
196
+ value: ''
197
+ }
198
+ ]
199
+ }
200
+ ]);
201
+ Object.assign(projectConfig, framework, { lanuage: language ? 'ts' : 'js' }, router, store, atomStyle, stylePrecompiler);
202
+ cloneAndCheckoutTag('master', projectConfig);
203
+ });
@@ -0,0 +1 @@
1
+ export * from './create.js';
@@ -0,0 +1,5 @@
1
+ export const defaultConfig = {
2
+ organization: 'fireflies_foam',
3
+ access_token: '0161dea0e646b4989aa911c4bc0c57d0',
4
+ };
5
+ export const configPath = `${process.env.HOME || process.env.USERPROFILE}/.onocrc`;
package/bin/index.js ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ import chalk from 'chalk';
12
+ import { program } from 'commander';
13
+ import pkg from './pkg.js';
14
+ const baseAction = (url, arg) => __awaiter(void 0, void 0, void 0, function* () { return (yield import(url)).default(...arg); });
15
+ const projectUrlList = {
16
+ 'vue': 'git@gitee.com:onoxm/test.git',
17
+ 'react': '456',
18
+ 'vue&ts': '789',
19
+ 'react&ts': '0'
20
+ };
21
+ // 首行提示
22
+ program.name('ono-cli').usage('<command> [option]');
23
+ // 版本号
24
+ /* program.option('-V, --version', '输出版本号'); */
25
+ program.version(`ono-cli@${pkg.version}`);
26
+ program
27
+ .command('create [project-name]')
28
+ .description('创建新项目')
29
+ .option('-f, --force', '强制创建')
30
+ // .option('-t, --template <template>', '指定模板')
31
+ .action((projectName, options) => baseAction('./commands/create.js', [projectName, options]));
32
+ program
33
+ .command('config [value]')
34
+ .description('inspect config')
35
+ .option('-g, --get <path>', 'get value')
36
+ .option('-s, --set <path> <value>', 'set value')
37
+ .option('-d, --delete <path>', 'delete value')
38
+ .action((value, options) => baseAction('./commands/config.js', [value, options]));
39
+ program.addHelpText('after', `Run ${chalk.blueBright('ono-cli <command> --help')} for detailed usage of given command.`);
40
+ program.parse(process.argv);
41
+ /* const options = program.opts();
42
+ console.log(options); */
package/bin/pkg.js ADDED
@@ -0,0 +1,7 @@
1
+ import { createRequire } from 'module';
2
+ import { dirname, join } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ const require = createRequire(import.meta.url);
6
+ const pkg = require(join(__dirname, '../package.json'));
7
+ export default pkg;
@@ -0,0 +1,17 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import ora from 'ora';
11
+ export const wrapLoading = (message, fn) => __awaiter(void 0, void 0, void 0, function* () {
12
+ const spinner = ora(message);
13
+ spinner.start();
14
+ const res = yield fn();
15
+ spinner.stop();
16
+ return res;
17
+ });
@@ -0,0 +1,71 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import axios from "axios";
11
+ import chalk from "chalk";
12
+ import { exec } from "child_process";
13
+ import { rmSync } from "fs";
14
+ import { rm } from "fs/promises";
15
+ import util from "util";
16
+ import { wrapLoading } from "./loading.js";
17
+ import { getAllConfig } from "../commands/config.js";
18
+ const execPromisified = util.promisify(exec);
19
+ const { organization, access_token } = getAllConfig().config;
20
+ export function getOrganizationProject() {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const res = yield axios.get(`https://gitee.com/api/v5/orgs/${organization}/repos`, {
23
+ headers: {
24
+ Authorization: `Bearer ${access_token}`
25
+ }
26
+ });
27
+ return res.data.map(item => item.name);
28
+ });
29
+ }
30
+ export function getProjectVersion(repo) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ const res = yield axios.get(`https://gitee.com/api/v5/repos/${organization}/${repo}/tags`, {
33
+ headers: {
34
+ Authorization: `Bearer ${access_token}`
35
+ }
36
+ });
37
+ return res.data.map(item => item.name);
38
+ });
39
+ }
40
+ export function cloneAndCheckoutTag(tag, projectConfig) {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ const oProjectConfig = Object.assign({}, projectConfig);
43
+ delete projectConfig.name;
44
+ delete projectConfig.path;
45
+ delete projectConfig.isOverwrite;
46
+ const projectConfigValues = Object.values(projectConfig).filter(item => item !== '');
47
+ const projects = yield getOrganizationProject();
48
+ const templateObj = projects.reduce((acc, item) => {
49
+ acc[item] = 0;
50
+ return acc;
51
+ }, {});
52
+ for (let i = 0; i < projects.length; i++) {
53
+ for (let j = 0; j < projectConfigValues.length; j++) {
54
+ if (projects[i].includes(projectConfigValues[j]))
55
+ templateObj[projects[i]]++;
56
+ }
57
+ }
58
+ const templateObjKeys = Object.keys(templateObj);
59
+ const matchedProject = templateObjKeys.find(template => templateObj[template] === projectConfigValues.length);
60
+ if (!matchedProject)
61
+ return console.log(chalk.red('🚀 没有找到匹配的项目模板!'));
62
+ if (oProjectConfig.isOverwrite)
63
+ wrapLoading('remove', () => __awaiter(this, void 0, void 0, function* () { return rmSync(oProjectConfig.path, { recursive: true }); }));
64
+ const cmd = `git clone --branch ${tag} --depth 1 https://gitee.com/${organization}/${matchedProject}.git ${oProjectConfig.name}`;
65
+ return wrapLoading(chalk.green(`🚀 创建项目 ${oProjectConfig.name}...`), () => __awaiter(this, void 0, void 0, function* () {
66
+ yield execPromisified(cmd);
67
+ console.log(chalk.green(`\n🚀 创建项目 ${oProjectConfig.name} 成功!`));
68
+ return rm(`${oProjectConfig.name}/.git`, { recursive: true });
69
+ }));
70
+ });
71
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "ono-cli",
3
+ "version": "0.0.1",
4
+ "description": "A CLI tool for ono template",
5
+ "main": "index.js",
6
+ "bin": "./bin/index.js",
7
+ "type": "module",
8
+ "scripts": {},
9
+ "files": ["bin", "lib"],
10
+ "keywords": ["cli", "ono", "template"],
11
+ "author": "ono",
12
+ "license": "ISC",
13
+ "dependencies": {
14
+ "axios": "^1.7.7",
15
+ "chalk": "^5.3.0",
16
+ "commander": "^12.0.0",
17
+ "figlet": "^1.7.0",
18
+ "fs-extra": "^11.2.0",
19
+ "git-clone": "^0.2.0",
20
+ "ini": "^5.0.0",
21
+ "inquirer": "^11.0.2",
22
+ "ora": "^8.0.1"
23
+ },
24
+ "devDependencies": {
25
+ "@types/ini": "^4.1.1",
26
+ "@types/node": "^22.7.2",
27
+ "nodemon": "^3.1.7",
28
+ "typescript": "^5.0.2"
29
+ }
30
+ }