Skip to content

Commit 51ffc91

Browse files
committed
feat: init project
0 parents  commit 51ffc91

File tree

11 files changed

+619
-0
lines changed

11 files changed

+619
-0
lines changed

.beginrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"tasks": [["🎉Example", "echo \"Hello world!\"", "An example task that prints hello world"]]
3+
}

.cache.javascript

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
let name
2+
[name] = [123]
3+
console.log(name)

.gitignore

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
lerna-debug.log*
8+
.pnpm-debug.log*
9+
10+
# Diagnostic reports (https://nodejs.org/api/report.html)
11+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12+
13+
# Runtime data
14+
pids
15+
*.pid
16+
*.seed
17+
*.pid.lock
18+
19+
# Directory for instrumented libs generated by jscoverage/JSCover
20+
lib-cov
21+
22+
# Coverage directory used by tools like istanbul
23+
coverage
24+
*.lcov
25+
26+
# nyc test coverage
27+
.nyc_output
28+
29+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
30+
.grunt
31+
32+
# Bower dependency directory (https://bower.io/)
33+
bower_components
34+
35+
# node-waf configuration
36+
.lock-wscript
37+
38+
# Compiled binary addons (https://nodejs.org/api/addons.html)
39+
build/Release
40+
41+
# Dependency directories
42+
node_modules/
43+
jspm_packages/
44+
45+
# Snowpack dependency directory (https://snowpack.dev/)
46+
web_modules/
47+
48+
# TypeScript cache
49+
*.tsbuildinfo
50+
51+
# Optional npm cache directory
52+
.npm
53+
54+
# Optional eslint cache
55+
.eslintcache
56+
57+
# Optional stylelint cache
58+
.stylelintcache
59+
60+
# Microbundle cache
61+
.rpt2_cache/
62+
.rts2_cache_cjs/
63+
.rts2_cache_es/
64+
.rts2_cache_umd/
65+
66+
# Optional REPL history
67+
.node_repl_history
68+
69+
# Output of 'npm pack'
70+
*.tgz
71+
72+
# Yarn Integrity file
73+
.yarn-integrity
74+
75+
# dotenv environment variable files
76+
.env
77+
.env.development.local
78+
.env.test.local
79+
.env.production.local
80+
.env.local
81+
82+
# parcel-bundler cache (https://parceljs.org/)
83+
.cache
84+
.parcel-cache
85+
86+
# Next.js build output
87+
.next
88+
out
89+
90+
# Nuxt.js build / generate output
91+
.nuxt
92+
dist
93+
94+
# Gatsby files
95+
.cache/
96+
# Comment in the public line in if your project uses Gatsby and not Next.js
97+
# https://nextjs.org/blog/next-9-1#public-directory-support
98+
# public
99+
100+
# vuepress build output
101+
.vuepress/dist
102+
103+
# vuepress v2.x temp and cache directory
104+
.temp
105+
.cache
106+
107+
# Docusaurus cache and generated files
108+
.docusaurus
109+
110+
# Serverless directories
111+
.serverless/
112+
113+
# FuseBox cache
114+
.fusebox/
115+
116+
# DynamoDB Local files
117+
.dynamodb/
118+
119+
# TernJS port file
120+
.tern-port
121+
122+
# Stores VSCode versions used for testing VSCode extensions
123+
.vscode-test
124+
125+
# yarn v2
126+
.yarn/cache
127+
.yarn/unplugged
128+
.yarn/build-state.yml
129+
.yarn/install-state.gz
130+
.pnp.*
131+
132+
# General
133+
.DS_Store
134+
.AppleDouble
135+
.LSOverride
136+
137+
# Icon must end with two \r
138+
Icon
139+
140+
# Thumbnails
141+
._*
142+
143+
# Files that might appear in the root of a volume
144+
.DocumentRevisions-V100
145+
.fseventsd
146+
.Spotlight-V100
147+
.TemporaryItems
148+
.Trashes
149+
.VolumeIcon.icns
150+
.com.apple.timemachine.donotpresent
151+
152+
# Directories potentially created on remote AFP share
153+
.AppleDB
154+
.AppleDesktop
155+
Network Trash Folder
156+
Temporary Items
157+
.apdisk

bin/begin-script.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env node
2+
3+
import chalk from 'chalk';
4+
import yargs from 'yargs';
5+
import {hideBin} from 'yargs/helpers';
6+
import {defaultCommand} from '../lib/commands/defaultCommand.js';
7+
import {getPkg} from '../lib/getPkg.js';
8+
9+
const pkg = getPkg();
10+
11+
const argv = yargs(hideBin(process.argv))
12+
.usage(chalk.magenta('\n' + pkg.description))
13+
.command('$0', 'Begin to run', {}, defaultCommand)
14+
.example('npx $0', 'Begin to run')
15+
.option('config', {alias: 'c', desc: 'Specified config filepath.\nDefaults to ".beginrc"', type: 'string'})
16+
.alias('help', 'h')
17+
.alias('version', 'v').argv;

lib/commands/defaultCommand.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import prompts from 'prompts';
2+
import {getConfig} from '../getConfig.js';
3+
import child_process from 'node:child_process';
4+
import {parseConfigTasks} from '../parseConfigTasks.js';
5+
import chalk from 'chalk';
6+
7+
export async function defaultCommand(argv) {
8+
const {config: specifiedConfigPath} = argv;
9+
10+
/** @type {import('../types.js').BeginConfig} */
11+
const config = getConfig(specifiedConfigPath);
12+
13+
/** @type {{task: import('../types.js').TaskObjectForm}} */
14+
const {task} = await prompts({
15+
type: 'autocomplete',
16+
name: 'task',
17+
message: 'Select a task to run',
18+
suggest: (input, choices) =>
19+
Promise.resolve(
20+
choices.filter(choice =>
21+
choice.title.toLowerCase().includes(input.toLowerCase())
22+
)
23+
),
24+
clearFirst: true,
25+
choices: parseConfigTasks(config).map(({name, script, description}) => ({
26+
title: name ?? script,
27+
value: {name, script, description},
28+
description
29+
}))
30+
});
31+
32+
if (task) {
33+
console.log();
34+
console.log(
35+
`${chalk.bgMagenta.bold(' Task ➤_ ')} ${chalk.magenta.bold(task.description)}
36+
`
37+
);
38+
console.log(chalk.grey(task.script));
39+
child_process.spawnSync(
40+
task.script.split(' ')[0],
41+
task.script.split(' ').slice(1),
42+
{stdio: 'inherit', shell: true}
43+
);
44+
console.log();
45+
}
46+
}

lib/getConfig.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import chalk from 'chalk';
2+
import {cosmiconfig, cosmiconfigSync} from 'cosmiconfig';
3+
4+
/**Get begin config file */
5+
export function getConfig(specifiedConfigPath) {
6+
const explorerSync = cosmiconfigSync('begin');
7+
8+
/** @type {import('cosmiconfig/dist/types').CosmiconfigResult} */
9+
let result;
10+
11+
// specified config path or search
12+
if (specifiedConfigPath) {
13+
result = explorerSync.load(specifiedConfigPath);
14+
} else {
15+
result = explorerSync.search();
16+
}
17+
18+
const isNotFound = !result || result.isEmpty;
19+
20+
// not found when specified
21+
if (specifiedConfigPath && isNotFound) {
22+
console.log(
23+
chalk.red(`\nConfig file not found in ${specifiedConfigPath}\n`)
24+
);
25+
return
26+
}
27+
28+
// not found when search
29+
if (!specifiedConfigPath && isNotFound) {
30+
console.log(
31+
chalk.red('\nPlease add "begin.config.json" in the root directory\n')
32+
);
33+
return;
34+
}
35+
36+
return result.config;
37+
}

lib/getPkg.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {createRequire} from 'node:module';
2+
3+
// Get internal source package.json
4+
export function getPkg() {
5+
const require = createRequire(import.meta.url);
6+
const pkg = require('../package.json');
7+
return pkg;
8+
}

lib/parseConfigTasks.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import chalk from 'chalk';
2+
3+
/**
4+
* @param {import('./types').BeginConfig} config
5+
* @returns {import('./types').TaskObjectForm[]}
6+
*/
7+
export function parseConfigTasks(config) {
8+
return config.tasks.map(task => {
9+
let name, script, description;
10+
11+
if (task.length < 2) {
12+
throw console.log(chalk.red('Config validation error: task type wrong'));
13+
}
14+
if (task.length === 2) {
15+
[script, description] = task;
16+
}
17+
if (task.length > 2) {
18+
[name, script, description] = task;
19+
}
20+
21+
return {
22+
name,
23+
script,
24+
description
25+
};
26+
});
27+
}

lib/types.d.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
type TaskArrayForm1 = [script: string, description: string];
2+
type TaskArrayForm2 = [name: string, script: string, description: string];
3+
type TaskObjectForm = {
4+
name?: string;
5+
script: string;
6+
description: string;
7+
};
8+
type Task = TaskArrayForm1 | TaskArrayForm2 | TaskObjectForm;
9+
10+
export interface BeginConfig {
11+
tasks: Task[];
12+
}

package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "begin-script",
3+
"version": "0.0.0",
4+
"type": "module",
5+
"bin": {
6+
"begin-script": "bin/begin-script.js"
7+
},
8+
"engines": {
9+
"node": "^14.13.1 || >=16.0.0"
10+
},
11+
"files": [
12+
"bin",
13+
"lib"
14+
],
15+
"license": "MIT",
16+
"description": "➤_ A User-friendly CLI to run any npm scripts with one command from \"begin\"",
17+
"dependencies": {
18+
"chalk": "^5.0.1",
19+
"cosmiconfig": "^7.0.1",
20+
"prompts": "^2.4.2",
21+
"yargs": "^17.5.1"
22+
}
23+
}

0 commit comments

Comments
 (0)