@mbsi/mkcmd 0.2.1 → 0.2.3
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/CHANGELOG.md +33 -1
- package/README.md +88 -66
- package/dist/index.js +336 -12
- package/package.json +23 -22
package/CHANGELOG.md
CHANGED
|
@@ -7,30 +7,61 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.3] - 2025-12-30
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
I forgot to push some files from 0.2.2 to github and then forgot to make sure they existed before publishing to npm.
|
|
15
|
+
Oh well.
|
|
16
|
+
|
|
17
|
+
## [0.2.2] - 2025-12-30
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- `src/core/helpers/stringifier.ts` to codegen before building
|
|
22
|
+
- `prebuild` script to dynamically update the code located in data/core at build time.
|
|
23
|
+
- `src/data/core.ts` is generated / regenerated at before building for use in dist
|
|
24
|
+
- `README.md` - Rewrote to make sense for display on NPM store as NPX package
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- `src/functions/scaffold-core.ts` doesn't try to pull data that doesn't exist anymore :^)
|
|
29
|
+
- `src/core/cli.ts` doesn't try to read the version from the user's computer anymore (hopefully)
|
|
30
|
+
|
|
31
|
+
### Moved
|
|
32
|
+
|
|
33
|
+
- Original `README.md` moved to `src/README.md` - it's for devs, anyways.
|
|
34
|
+
|
|
10
35
|
## [0.2.1] - 2025-12-30
|
|
36
|
+
|
|
11
37
|
### Added
|
|
38
|
+
|
|
12
39
|
- `CHANGELOG.md` for tracking changes
|
|
13
40
|
|
|
14
41
|
### Changed
|
|
42
|
+
|
|
15
43
|
- Simplified `file-utils.ts` by removing path caching (was causing issues with non-existent directories)
|
|
16
44
|
|
|
17
45
|
### Fixed
|
|
46
|
+
|
|
18
47
|
- Directory creation bug: `realpath()` now replaced with `resolve()` to handle new target directories
|
|
19
48
|
- Path resolution in bundled code for version command
|
|
20
49
|
|
|
21
50
|
### Removed
|
|
51
|
+
|
|
22
52
|
- Path caching in `file-utils.ts` (unnecessary optimization causing failures)
|
|
23
53
|
- Removed unused imports in `src/functions/orchestrate-scaffold.ts` to lint warnings
|
|
24
54
|
|
|
25
55
|
## [0.2.0] - 2025-12-30
|
|
26
56
|
|
|
27
57
|
### Added
|
|
58
|
+
|
|
28
59
|
- Build system with `bun build --target=bun`
|
|
29
60
|
- Build scripts: `build`, `build:exe`, `prepack`
|
|
30
61
|
- npm package preparation (removed `private: true`)
|
|
31
62
|
|
|
32
|
-
|
|
33
63
|
### Changed
|
|
64
|
+
|
|
34
65
|
- Moved `typescript` from peerDependencies to devDependencies
|
|
35
66
|
- Updated package.json entry points to `./dist/index.js`
|
|
36
67
|
- Fixed `--version` command to use `process.cwd()` for package.json resolution
|
|
@@ -38,6 +69,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
38
69
|
## [0.1.0] - 2025-12-30
|
|
39
70
|
|
|
40
71
|
### Added
|
|
72
|
+
|
|
41
73
|
- Initial CLI scaffolding tool
|
|
42
74
|
- Interactive project setup with `@clack/prompts`
|
|
43
75
|
- Full CLI scaffold generation (package.json, tsconfig.json, README.md, core files)
|
package/README.md
CHANGED
|
@@ -1,111 +1,133 @@
|
|
|
1
1
|
# mkcmd
|
|
2
2
|
|
|
3
|
-
A
|
|
4
|
-
|
|
5
|
-
**Version:** 0.2.0 | See [CHANGELOG.md](./CHANGELOG.md) for version history.
|
|
3
|
+
A CLI tool for scaffolding new CLI projects with sensible defaults. Create command-line tools with TypeScript, Bun runtime, and a solid core structure out of the box.
|
|
6
4
|
|
|
7
5
|
## Features
|
|
8
6
|
|
|
9
|
-
- **Interactive
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
7
|
+
- **Interactive Setup** - Prompts for project name, location, and description
|
|
8
|
+
- **Complete CLI Framework** - Generates a working CLI with command registration, logging, and helpers
|
|
9
|
+
- **TypeScript + Bun** - Pre-configured with TypeScript and Bun runtime support
|
|
10
|
+
- **Core Utilities** - Includes `FileBuilder` for dynamic code generation and file utilities
|
|
11
|
+
- **Extensible** - Easy to add your own commands
|
|
12
|
+
|
|
13
|
+
> [!WARNING]
|
|
14
|
+
> While you can *run* the program in without Bun, the source code itself **depends on Bun** for development and building.
|
|
15
|
+
|
|
16
|
+
## Run remotely
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx @mbsi/mkcmd init
|
|
20
|
+
# or
|
|
21
|
+
bun @mbsi/mkcmd init
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install -g @mbsi/mkcmd
|
|
28
|
+
# or
|
|
29
|
+
bun install -g @mbsi/mkcmd
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
mkcmd init
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The `init` command will prompt you for:
|
|
39
|
+
- Project name
|
|
40
|
+
- Target directory (defaults to `./<project-name>`)
|
|
41
|
+
- Project description
|
|
14
42
|
|
|
15
43
|
## What Gets Scaffolding
|
|
16
44
|
|
|
17
|
-
|
|
45
|
+
After running `mkcmd init`, you'll have a complete CLI project:
|
|
18
46
|
|
|
19
47
|
```
|
|
20
|
-
|
|
48
|
+
my-cli/
|
|
21
49
|
├── src/
|
|
22
50
|
│ ├── core/
|
|
23
|
-
│ │ ├── cli.ts
|
|
24
|
-
│ │ ├── log.ts
|
|
25
|
-
│ │
|
|
26
|
-
│ │
|
|
51
|
+
│ │ ├── cli.ts # CLI framework with command registration
|
|
52
|
+
│ │ ├── log.ts # Logging helpers (single/multi info/warn/err, title)
|
|
53
|
+
│ │ └── helpers/
|
|
54
|
+
│ │ ├── file-builder.ts # Indentation-aware file builder
|
|
55
|
+
│ │ └── file-utils.ts # Path and file writing utilities
|
|
27
56
|
│ ├── commands/
|
|
28
|
-
│ │ └── index.ts
|
|
29
|
-
│ └── config.ts
|
|
57
|
+
│ │ └── index.ts # Command registration hook
|
|
58
|
+
│ └── config.ts # Project configuration
|
|
30
59
|
├── package.json
|
|
31
60
|
├── tsconfig.json
|
|
32
61
|
└── README.md
|
|
33
62
|
```
|
|
34
63
|
|
|
35
|
-
##
|
|
64
|
+
## Usage
|
|
36
65
|
|
|
37
|
-
###
|
|
66
|
+
### Running Your New CLI
|
|
38
67
|
|
|
39
68
|
```bash
|
|
69
|
+
cd my-cli
|
|
40
70
|
bun install
|
|
71
|
+
bun run src/index.ts --help
|
|
41
72
|
```
|
|
42
73
|
|
|
43
|
-
###
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
npm install -g mkcmd
|
|
47
|
-
# or
|
|
48
|
-
bun install -g mkcmd
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Usage
|
|
52
|
-
|
|
53
|
-
### Development
|
|
74
|
+
### Adding Commands
|
|
54
75
|
|
|
55
|
-
|
|
56
|
-
# Show help
|
|
57
|
-
bun run src/index.ts --help
|
|
76
|
+
Commands are registered in `src/commands/index.ts`. Here's the pattern:
|
|
58
77
|
|
|
59
|
-
|
|
60
|
-
|
|
78
|
+
```typescript
|
|
79
|
+
import { registerCommand } from "../core/cli";
|
|
61
80
|
|
|
62
|
-
|
|
63
|
-
|
|
81
|
+
registerCommand({
|
|
82
|
+
name: "greet",
|
|
83
|
+
description: "Say hello",
|
|
84
|
+
instructions: "Pass a name to greet",
|
|
85
|
+
run: async (args: string[]) => {
|
|
86
|
+
const name = args[0] || "world";
|
|
87
|
+
console.log(`Hello, ${name}!`);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
64
90
|
```
|
|
65
91
|
|
|
66
|
-
|
|
92
|
+
Then run:
|
|
67
93
|
|
|
68
94
|
```bash
|
|
69
|
-
|
|
70
|
-
bun run
|
|
71
|
-
bun dist/index.js --help
|
|
72
|
-
|
|
73
|
-
# Build standalone executable
|
|
74
|
-
bun run build:exe
|
|
75
|
-
./dist/mkcmd --help
|
|
95
|
+
bun run src/index.ts greet
|
|
96
|
+
bun run src/index.ts greet Alice
|
|
76
97
|
```
|
|
77
98
|
|
|
78
|
-
###
|
|
99
|
+
### Using the File Builder
|
|
79
100
|
|
|
80
|
-
|
|
81
|
-
mkcmd --help
|
|
82
|
-
mkcmd init
|
|
83
|
-
```
|
|
101
|
+
The included `FileBuilder` helps generate code files dynamically:
|
|
84
102
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
103
|
+
```typescript
|
|
104
|
+
import { FileBuilder } from "./core/helpers/file-builder";
|
|
105
|
+
|
|
106
|
+
const fb = new FileBuilder();
|
|
107
|
+
fb.addLine("export function hello() {");
|
|
108
|
+
fb.addLine(' console.log("Hello!");', 1);
|
|
109
|
+
fb.addLine("}");
|
|
110
|
+
const code = fb.build();
|
|
111
|
+
```
|
|
89
112
|
|
|
90
|
-
##
|
|
113
|
+
## CLI Flags
|
|
91
114
|
|
|
92
|
-
|
|
115
|
+
After installation, `mkcmd` supports:
|
|
93
116
|
|
|
94
117
|
```bash
|
|
95
|
-
#
|
|
96
|
-
|
|
118
|
+
mkcmd --help # Show help
|
|
119
|
+
mkcmd --version # Show version
|
|
120
|
+
```
|
|
97
121
|
|
|
98
|
-
|
|
99
|
-
bun run build:exe
|
|
122
|
+
## Requirements
|
|
100
123
|
|
|
101
|
-
|
|
102
|
-
npm
|
|
103
|
-
```
|
|
124
|
+
- Bun runtime (for running the generated project)
|
|
125
|
+
- Node.js 16+ (for installation via npm)
|
|
104
126
|
|
|
105
|
-
|
|
127
|
+
## License
|
|
106
128
|
|
|
107
|
-
|
|
129
|
+
See LICENSE file for details.
|
|
108
130
|
|
|
109
|
-
|
|
131
|
+
---
|
|
110
132
|
|
|
111
|
-
See
|
|
133
|
+
**Version:** See `npm info @mbsi/mkcmd version`, `npx @mbsi/mkcmd --version`, or run `mkcmd --version` after installation.
|
package/dist/index.js
CHANGED
|
@@ -1631,7 +1631,8 @@ async function runCLI(argv = Bun.argv.slice(2)) {
|
|
|
1631
1631
|
return;
|
|
1632
1632
|
}
|
|
1633
1633
|
if (["-v", "--version"].includes(name)) {
|
|
1634
|
-
const
|
|
1634
|
+
const pkgPath = join2(import.meta.dir, "..", "package.json");
|
|
1635
|
+
const pkgText = await Bun.file(pkgPath).text();
|
|
1635
1636
|
const pkg = JSON.parse(pkgText);
|
|
1636
1637
|
log_default.multi.info([
|
|
1637
1638
|
{
|
|
@@ -2250,18 +2251,341 @@ async function scaffoldProject(prompts) {
|
|
|
2250
2251
|
}
|
|
2251
2252
|
|
|
2252
2253
|
// src/functions/scaffold-core.ts
|
|
2253
|
-
import { join as join4 } from "path";
|
|
2254
|
-
import {
|
|
2255
|
-
import {
|
|
2256
|
-
|
|
2257
|
-
|
|
2254
|
+
import { join as join4, dirname as dirname2 } from "path";
|
|
2255
|
+
import { existsSync } from "fs";
|
|
2256
|
+
import { mkdir as mkdir2, writeFile } from "fs/promises";
|
|
2257
|
+
import { cwd } from "process";
|
|
2258
|
+
|
|
2259
|
+
// src/data/core.ts
|
|
2260
|
+
var src_core_cli_init = () => {
|
|
2261
|
+
const fb = new FileBuilder;
|
|
2262
|
+
fb.addLine('import log from "./log";');
|
|
2263
|
+
fb.addLine('import { join } from "node:path";');
|
|
2264
|
+
fb.addLine('import { config } from "../config";');
|
|
2265
|
+
fb.addLine("");
|
|
2266
|
+
fb.addLine("export type Command = {");
|
|
2267
|
+
fb.addLine(" name: string;");
|
|
2268
|
+
fb.addLine(" description: string;");
|
|
2269
|
+
fb.addLine(" instructions: string;");
|
|
2270
|
+
fb.addLine(" run: (args: string[]) => Promise<void> | void;");
|
|
2271
|
+
fb.addLine("};");
|
|
2272
|
+
fb.addLine("");
|
|
2273
|
+
fb.addLine("const commands = new Map<string, Command>();");
|
|
2274
|
+
fb.addLine("");
|
|
2275
|
+
fb.addLine("export function registerCommand(cmd: Command) {");
|
|
2276
|
+
fb.addLine(" commands.set(cmd.name, cmd);");
|
|
2277
|
+
fb.addLine("}");
|
|
2278
|
+
fb.addLine("");
|
|
2279
|
+
fb.addLine("export async function runCLI(argv = Bun.argv.slice(2)) {");
|
|
2280
|
+
fb.addLine(" const [name, ...args] = argv;");
|
|
2281
|
+
fb.addLine(" // -- TS Defense --");
|
|
2282
|
+
fb.addLine(" if (!name) {");
|
|
2283
|
+
fb.addLine(' log.single.err("ARGS", "No Argument Supplied");');
|
|
2284
|
+
fb.addLine(" return;");
|
|
2285
|
+
fb.addLine(" }");
|
|
2286
|
+
fb.addLine(' if (["-h", "--help"].includes(name)) {');
|
|
2287
|
+
fb.addLine(" const multiLog: any[] = [];");
|
|
2288
|
+
fb.addLine(" multiLog.push({");
|
|
2289
|
+
fb.addLine(' t: "About",');
|
|
2290
|
+
fb.addLine(" m: config.about_text,");
|
|
2291
|
+
fb.addLine(" });");
|
|
2292
|
+
fb.addLine(" multiLog.push({");
|
|
2293
|
+
fb.addLine(' t: "Commands",');
|
|
2294
|
+
fb.addLine(' m: "Available Commands",');
|
|
2295
|
+
fb.addLine(" });");
|
|
2296
|
+
fb.addLine(" for (const cmd of commands.values()) {");
|
|
2297
|
+
fb.addLine(" multiLog.push({");
|
|
2298
|
+
fb.addLine(" t: cmd.name,");
|
|
2299
|
+
fb.addLine(" m: `${cmd.description}\\n |-> [Instructions]: ${cmd.instructions}\\n`,");
|
|
2300
|
+
fb.addLine(" });");
|
|
2301
|
+
fb.addLine(" }");
|
|
2302
|
+
fb.addLine(" multiLog.push({");
|
|
2303
|
+
fb.addLine(' t: "More Info",');
|
|
2304
|
+
fb.addLine(" m: config.more_info_text,");
|
|
2305
|
+
fb.addLine(" });");
|
|
2306
|
+
fb.addLine(" log.multi.info(multiLog);");
|
|
2307
|
+
fb.addLine(" return;");
|
|
2308
|
+
fb.addLine(" }");
|
|
2309
|
+
fb.addLine("");
|
|
2310
|
+
fb.addLine(' if (["-v", "--version"].includes(name)) {');
|
|
2311
|
+
fb.addLine(' const pkgPath = join(import.meta.dir, "..", "package.json");');
|
|
2312
|
+
fb.addLine(" const pkgText = await Bun.file(pkgPath).text();");
|
|
2313
|
+
fb.addLine(" const pkg = JSON.parse(pkgText);");
|
|
2314
|
+
fb.addLine(" log.multi.info([");
|
|
2315
|
+
fb.addLine(" {");
|
|
2316
|
+
fb.addLine(' t: "Package Name",');
|
|
2317
|
+
fb.addLine(" m: pkg.name,");
|
|
2318
|
+
fb.addLine(" },");
|
|
2319
|
+
fb.addLine(" {");
|
|
2320
|
+
fb.addLine(' t: "Package Version",');
|
|
2321
|
+
fb.addLine(" m: pkg.version,");
|
|
2322
|
+
fb.addLine(" },");
|
|
2323
|
+
fb.addLine(" ]);");
|
|
2324
|
+
fb.addLine(" return;");
|
|
2325
|
+
fb.addLine(" }");
|
|
2326
|
+
fb.addLine("");
|
|
2327
|
+
fb.addLine(" const command = commands.get(name);");
|
|
2328
|
+
fb.addLine(" if (!command) {");
|
|
2329
|
+
fb.addLine(' log.single.err("Command", "No Command Supplied");');
|
|
2330
|
+
fb.addLine(" process.exit(1);");
|
|
2331
|
+
fb.addLine(" }");
|
|
2332
|
+
fb.addLine("");
|
|
2333
|
+
fb.addLine(" try {");
|
|
2334
|
+
fb.addLine(" await command.run(args);");
|
|
2335
|
+
fb.addLine(" } catch (err) {");
|
|
2336
|
+
fb.addLine(" const multilog: any[] = [];");
|
|
2337
|
+
fb.addLine(" multilog.push({");
|
|
2338
|
+
fb.addLine(' t: "Panic",');
|
|
2339
|
+
fb.addLine(" m: `Failed to run ${name}`,");
|
|
2340
|
+
fb.addLine(" });");
|
|
2341
|
+
fb.addLine(" if (err instanceof Error) {");
|
|
2342
|
+
fb.addLine(" multilog.push({");
|
|
2343
|
+
fb.addLine(' t: "Error",');
|
|
2344
|
+
fb.addLine(" m: err.message,");
|
|
2345
|
+
fb.addLine(" });");
|
|
2346
|
+
fb.addLine(" } else {");
|
|
2347
|
+
fb.addLine(" multilog.push({");
|
|
2348
|
+
fb.addLine(' t: "Unknown Error",');
|
|
2349
|
+
fb.addLine(" m: JSON.stringify(err),");
|
|
2350
|
+
fb.addLine(" });");
|
|
2351
|
+
fb.addLine(" }");
|
|
2352
|
+
fb.addLine(" log.multi.err(multilog);");
|
|
2353
|
+
fb.addLine(" process.exit(1);");
|
|
2354
|
+
fb.addLine(" }");
|
|
2355
|
+
fb.addLine("}");
|
|
2356
|
+
fb.addLine("");
|
|
2357
|
+
return fb.build();
|
|
2358
|
+
};
|
|
2359
|
+
var src_core_cli = {
|
|
2360
|
+
location: "src/core/cli.ts",
|
|
2361
|
+
content: src_core_cli_init
|
|
2362
|
+
};
|
|
2363
|
+
var src_core_log_init = () => {
|
|
2364
|
+
const fb = new FileBuilder;
|
|
2365
|
+
fb.addLine('import figlet from "figlet";');
|
|
2366
|
+
fb.addLine("");
|
|
2367
|
+
fb.addLine("const infoLogSingle = (title: string, message: string) => {");
|
|
2368
|
+
fb.addLine(' console.log("");');
|
|
2369
|
+
fb.addLine(' console.info(" [INFO]");');
|
|
2370
|
+
fb.addLine(" console.info(` [${title}]: ${message}`);");
|
|
2371
|
+
fb.addLine(' console.log("");');
|
|
2372
|
+
fb.addLine("};");
|
|
2373
|
+
fb.addLine("");
|
|
2374
|
+
fb.addLine("type MultiLogArgs = {");
|
|
2375
|
+
fb.addLine(" t: string;");
|
|
2376
|
+
fb.addLine(" m: string;");
|
|
2377
|
+
fb.addLine("}[];");
|
|
2378
|
+
fb.addLine("");
|
|
2379
|
+
fb.addLine("const infoLogMulti = (args: MultiLogArgs) => {");
|
|
2380
|
+
fb.addLine(' console.log("");');
|
|
2381
|
+
fb.addLine(' console.info(" [INFO]");');
|
|
2382
|
+
fb.addLine(" for (const arg of args) {");
|
|
2383
|
+
fb.addLine(" console.info(` [${arg.t}]: ${arg.m}`);");
|
|
2384
|
+
fb.addLine(" }");
|
|
2385
|
+
fb.addLine(' console.log("");');
|
|
2386
|
+
fb.addLine("};");
|
|
2387
|
+
fb.addLine("");
|
|
2388
|
+
fb.addLine("const warnLogSingle = (title: string, message: string) => {");
|
|
2389
|
+
fb.addLine(' console.log("");');
|
|
2390
|
+
fb.addLine(' console.warn(" [WARNING]");');
|
|
2391
|
+
fb.addLine(" console.warn(` [${title}]: ${message}`);");
|
|
2392
|
+
fb.addLine(' console.log("");');
|
|
2393
|
+
fb.addLine("};");
|
|
2394
|
+
fb.addLine("");
|
|
2395
|
+
fb.addLine("const warnLogMulti = (args: MultiLogArgs) => {");
|
|
2396
|
+
fb.addLine(' console.log("");');
|
|
2397
|
+
fb.addLine(' console.warn(" [WARNING]");');
|
|
2398
|
+
fb.addLine(" for (const arg of args) {");
|
|
2399
|
+
fb.addLine(" console.warn(` [${arg.t}]: ${arg.m}`);");
|
|
2400
|
+
fb.addLine(" }");
|
|
2401
|
+
fb.addLine(' console.log("");');
|
|
2402
|
+
fb.addLine("};");
|
|
2403
|
+
fb.addLine("");
|
|
2404
|
+
fb.addLine("const errLogSingle = (title: string, message: string) => {");
|
|
2405
|
+
fb.addLine(' console.log("");');
|
|
2406
|
+
fb.addLine(' console.error(" [ERROR]");');
|
|
2407
|
+
fb.addLine(" console.error(` [${title}]: ${message}`);");
|
|
2408
|
+
fb.addLine(' console.log("");');
|
|
2409
|
+
fb.addLine("};");
|
|
2410
|
+
fb.addLine("");
|
|
2411
|
+
fb.addLine("const errLogMulti = (args: MultiLogArgs) => {");
|
|
2412
|
+
fb.addLine(' console.log("");');
|
|
2413
|
+
fb.addLine(' console.error(" [ERROR]");');
|
|
2414
|
+
fb.addLine(" for (const arg of args) {");
|
|
2415
|
+
fb.addLine(" console.error(` [${arg.t}]: ${arg.m}`);");
|
|
2416
|
+
fb.addLine(" }");
|
|
2417
|
+
fb.addLine(' console.log("");');
|
|
2418
|
+
fb.addLine("};");
|
|
2419
|
+
fb.addLine("");
|
|
2420
|
+
fb.addLine("const title = (title: string, subtitle?: string) => {");
|
|
2421
|
+
fb.addLine(" console.clear();");
|
|
2422
|
+
fb.addLine(" console.log();");
|
|
2423
|
+
fb.addLine(" console.log(");
|
|
2424
|
+
fb.addLine(" figlet.textSync(title, {");
|
|
2425
|
+
fb.addLine(' font: "ANSI Regular",');
|
|
2426
|
+
fb.addLine(" }),");
|
|
2427
|
+
fb.addLine(" );");
|
|
2428
|
+
fb.addLine(" console.log(` [${subtitle}]`);");
|
|
2429
|
+
fb.addLine(" console.log();");
|
|
2430
|
+
fb.addLine("};");
|
|
2431
|
+
fb.addLine("");
|
|
2432
|
+
fb.addLine("const log = {");
|
|
2433
|
+
fb.addLine(" single: {");
|
|
2434
|
+
fb.addLine(" info: infoLogSingle,");
|
|
2435
|
+
fb.addLine(" warn: warnLogSingle,");
|
|
2436
|
+
fb.addLine(" err: errLogSingle,");
|
|
2437
|
+
fb.addLine(" },");
|
|
2438
|
+
fb.addLine(" multi: {");
|
|
2439
|
+
fb.addLine(" info: infoLogMulti,");
|
|
2440
|
+
fb.addLine(" warn: warnLogMulti,");
|
|
2441
|
+
fb.addLine(" err: errLogMulti,");
|
|
2442
|
+
fb.addLine(" },");
|
|
2443
|
+
fb.addLine(" title,");
|
|
2444
|
+
fb.addLine("};");
|
|
2445
|
+
fb.addLine("");
|
|
2446
|
+
fb.addLine("export default log;");
|
|
2447
|
+
fb.addLine("");
|
|
2448
|
+
return fb.build();
|
|
2449
|
+
};
|
|
2450
|
+
var src_core_log = {
|
|
2451
|
+
location: "src/core/log.ts",
|
|
2452
|
+
content: src_core_log_init
|
|
2453
|
+
};
|
|
2454
|
+
var src_core_helpers_file_builder_init = () => {
|
|
2455
|
+
const fb = new FileBuilder;
|
|
2456
|
+
fb.addLine("export function line(content: string, depth: number): string {");
|
|
2457
|
+
fb.addLine(' return `\\n${"\\t".repeat(depth)}${content}`;');
|
|
2458
|
+
fb.addLine("}");
|
|
2459
|
+
fb.addLine("");
|
|
2460
|
+
fb.addLine("export class FileBuilder {");
|
|
2461
|
+
fb.addLine(" private lines: string[] = [];");
|
|
2462
|
+
fb.addLine("");
|
|
2463
|
+
fb.addLine(" addLine(content: string, depth: number = 0): void {");
|
|
2464
|
+
fb.addLine(' this.lines.push(`${"\\t".repeat(depth)}${content}`);');
|
|
2465
|
+
fb.addLine(" }");
|
|
2466
|
+
fb.addLine("");
|
|
2467
|
+
fb.addLine(" addEmptyLine(): void {");
|
|
2468
|
+
fb.addLine(' this.lines.push("");');
|
|
2469
|
+
fb.addLine(" }");
|
|
2470
|
+
fb.addLine("");
|
|
2471
|
+
fb.addLine(" build(): string {");
|
|
2472
|
+
fb.addLine(' return this.lines.join("\\n");');
|
|
2473
|
+
fb.addLine(" }");
|
|
2474
|
+
fb.addLine("}");
|
|
2475
|
+
fb.addLine("");
|
|
2476
|
+
return fb.build();
|
|
2477
|
+
};
|
|
2478
|
+
var src_core_helpers_file_builder = {
|
|
2479
|
+
location: "src/core/helpers/file-builder.ts",
|
|
2480
|
+
content: src_core_helpers_file_builder_init
|
|
2481
|
+
};
|
|
2482
|
+
var src_core_helpers_stringifier_init = () => {
|
|
2483
|
+
const fb = new FileBuilder;
|
|
2484
|
+
fb.addLine('import { join } from "node:path";');
|
|
2485
|
+
fb.addLine('import { readdir, writeFile } from "node:fs/promises";');
|
|
2486
|
+
fb.addLine('import { FileBuilder } from "./file-builder";');
|
|
2487
|
+
fb.addLine('import { statSync } from "node:fs";');
|
|
2488
|
+
fb.addLine("");
|
|
2489
|
+
fb.addLine("const outExport: string[] = [];");
|
|
2490
|
+
fb.addLine("");
|
|
2491
|
+
fb.addLine("async function generateTemplate(path: string) {");
|
|
2492
|
+
fb.addLine(' if (path.endsWith(".ts")) {');
|
|
2493
|
+
fb.addLine(" const content = await Bun.file(path).text();");
|
|
2494
|
+
fb.addLine(" const fb = new FileBuilder();");
|
|
2495
|
+
fb.addLine(" const snaked_title = path");
|
|
2496
|
+
fb.addLine(' .split("/")');
|
|
2497
|
+
fb.addLine(' .join("_")');
|
|
2498
|
+
fb.addLine(' .split("-")');
|
|
2499
|
+
fb.addLine(' .join("_")');
|
|
2500
|
+
fb.addLine(' .split(".")[0];');
|
|
2501
|
+
fb.addLine(' fb.addLine(`const ${snaked_title + "_init"} = () => {`);');
|
|
2502
|
+
fb.addLine(" fb.addLine(`const fb = new FileBuilder();`, 1);");
|
|
2503
|
+
fb.addLine(' const lines = content.split("\\n");');
|
|
2504
|
+
fb.addLine(" for (const line of lines) {");
|
|
2505
|
+
fb.addLine(` const cleanLine = line.replaceAll("\\\\", "\\\\\\\\").replaceAll('"', '\\\\"');`);
|
|
2506
|
+
fb.addLine(' fb.addLine(`fb.addLine("${cleanLine}")`, 1);');
|
|
2507
|
+
fb.addLine(" }");
|
|
2508
|
+
fb.addLine(' fb.addLine("return fb.build();", 1);');
|
|
2509
|
+
fb.addLine(' fb.addLine("};");');
|
|
2510
|
+
fb.addLine(" fb.addEmptyLine();");
|
|
2511
|
+
fb.addLine(" fb.addLine(`export const ${snaked_title} = {`);");
|
|
2512
|
+
fb.addLine(' fb.addLine(`location: "${path}",`, 1);');
|
|
2513
|
+
fb.addLine(' fb.addLine(`content: ${snaked_title + "_init"}`, 1);');
|
|
2514
|
+
fb.addLine(" fb.addLine(`};`);");
|
|
2515
|
+
fb.addLine(" const out = fb.build();");
|
|
2516
|
+
fb.addLine(" outExport.push(`${snaked_title}`);");
|
|
2517
|
+
fb.addLine(" return out;");
|
|
2518
|
+
fb.addLine(" }");
|
|
2519
|
+
fb.addLine(' return "";');
|
|
2520
|
+
fb.addLine("}");
|
|
2521
|
+
fb.addLine("");
|
|
2522
|
+
fb.addLine("async function parseFolder(path: string, fb: FileBuilder) {");
|
|
2523
|
+
fb.addLine(" const items = await readdir(path);");
|
|
2524
|
+
fb.addLine(" for (const item of items) {");
|
|
2525
|
+
fb.addLine(" const relPath = join(path, item);");
|
|
2526
|
+
fb.addLine(" const itemStat = statSync(relPath);");
|
|
2527
|
+
fb.addLine(" if (itemStat.isDirectory()) {");
|
|
2528
|
+
fb.addLine(" await parseFolder(relPath, fb);");
|
|
2529
|
+
fb.addLine(" }");
|
|
2530
|
+
fb.addLine(' if (item.endsWith(".ts")) {');
|
|
2531
|
+
fb.addLine(" fb.addLine(await generateTemplate(relPath));");
|
|
2532
|
+
fb.addLine(" fb.addEmptyLine();");
|
|
2533
|
+
fb.addLine(" }");
|
|
2534
|
+
fb.addLine(" }");
|
|
2535
|
+
fb.addLine("}");
|
|
2536
|
+
fb.addLine("");
|
|
2537
|
+
fb.addLine("async function generateTemplates() {");
|
|
2538
|
+
fb.addLine(' const sourceCoreDir = join(".", "src", "core");');
|
|
2539
|
+
fb.addLine(" const fb = new FileBuilder();");
|
|
2540
|
+
fb.addLine(' fb.addLine(`import { FileBuilder } from "../core/helpers/file-builder";`);');
|
|
2541
|
+
fb.addLine(" fb.addEmptyLine();");
|
|
2542
|
+
fb.addLine(" await parseFolder(sourceCoreDir, fb);");
|
|
2543
|
+
fb.addLine(' fb.addLine(`const core = [${outExport.join(", ")}]`);');
|
|
2544
|
+
fb.addLine(" fb.addLine(`export { core }`);");
|
|
2545
|
+
fb.addLine(" const out = fb.build();");
|
|
2546
|
+
fb.addLine(' await writeFile(join(".", "src", "data", "core.ts"), out, "utf8");');
|
|
2547
|
+
fb.addLine("}");
|
|
2548
|
+
fb.addLine("");
|
|
2549
|
+
fb.addLine("generateTemplates();");
|
|
2550
|
+
fb.addLine("");
|
|
2551
|
+
return fb.build();
|
|
2552
|
+
};
|
|
2553
|
+
var src_core_helpers_stringifier = {
|
|
2554
|
+
location: "src/core/helpers/stringifier.ts",
|
|
2555
|
+
content: src_core_helpers_stringifier_init
|
|
2556
|
+
};
|
|
2557
|
+
var src_core_helpers_file_utils_init = () => {
|
|
2558
|
+
const fb = new FileBuilder;
|
|
2559
|
+
fb.addLine('import { mkdir } from "node:fs/promises";');
|
|
2560
|
+
fb.addLine('import { resolve, join } from "node:path";');
|
|
2561
|
+
fb.addLine("");
|
|
2562
|
+
fb.addLine("export async function writeFileTuple([targetDir, relativePath, content]: [string, string, string]): Promise<void> {");
|
|
2563
|
+
fb.addLine(" const fullPath = resolve(targetDir, relativePath);");
|
|
2564
|
+
fb.addLine(' await mkdir(join(fullPath, ".."), { recursive: true });');
|
|
2565
|
+
fb.addLine(" await Bun.write(fullPath, content);");
|
|
2566
|
+
fb.addLine("}");
|
|
2567
|
+
fb.addLine("");
|
|
2568
|
+
return fb.build();
|
|
2569
|
+
};
|
|
2570
|
+
var src_core_helpers_file_utils = {
|
|
2571
|
+
location: "src/core/helpers/file-utils.ts",
|
|
2572
|
+
content: src_core_helpers_file_utils_init
|
|
2573
|
+
};
|
|
2574
|
+
var core = [src_core_cli, src_core_log, src_core_helpers_file_builder, src_core_helpers_stringifier, src_core_helpers_file_utils];
|
|
2575
|
+
|
|
2576
|
+
// src/functions/scaffold-core.ts
|
|
2577
|
+
var currentDir = join4(cwd());
|
|
2258
2578
|
async function scaffoldCore(targetDir) {
|
|
2259
|
-
const
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
}
|
|
2579
|
+
const combinedPath = join4(currentDir, targetDir);
|
|
2580
|
+
console.dir(combinedPath);
|
|
2581
|
+
for (const file of core) {
|
|
2582
|
+
const relativePath = file.location.replace(/^\.\//, "");
|
|
2583
|
+
const parentDir = join4(combinedPath, dirname2(relativePath));
|
|
2584
|
+
console.dir({ parentDir });
|
|
2585
|
+
if (!existsSync(parentDir)) {
|
|
2586
|
+
mkdir2(parentDir, { recursive: true });
|
|
2587
|
+
}
|
|
2588
|
+
writeFile(join4(combinedPath, relativePath), file.content(), "utf8");
|
|
2265
2589
|
}
|
|
2266
2590
|
}
|
|
2267
2591
|
|
package/package.json
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
2
|
+
"name": "@mbsi/mkcmd",
|
|
3
|
+
"version": "0.2.3",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"module": "./dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mkcmd": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"prebuild": "bun run src/core/helpers/stringifier.ts",
|
|
12
|
+
"build": "bun build --target=bun --outfile=dist/index.js src/index.ts",
|
|
13
|
+
"build:exe": "bun build --compile --outfile=dist/mkcmd src/index.ts",
|
|
14
|
+
"prepack": "bun run build"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/bun": "latest",
|
|
18
|
+
"typescript": "^5"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@clack/prompts": "^0.11.0",
|
|
22
|
+
"@types/figlet": "^1.7.0",
|
|
23
|
+
"figlet": "^1.9.4"
|
|
24
|
+
}
|
|
24
25
|
}
|