@mbsi/mkcmd 0.2.2 → 0.2.4

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 CHANGED
@@ -7,40 +7,84 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2026-1-1
11
+
12
+ ### Added
13
+
14
+ - `WatchConfig` interface in `src/config.ts` for defining watch targets
15
+ - Support for both `"dir"` and `"file"` types in watch configurations
16
+ - `scaffold-rest.ts` function for handling arbitrary watch targets
17
+ - `src/data/index.ts` for centralized data exports
18
+
19
+ ### Changed
20
+
21
+ - `stringifier.ts` now reads from `config.watchConfigs` instead of hardcoded paths
22
+ - `stringifier.ts` supports watching individual files and multiple directories
23
+ - `parseFolder` renamed and refactored to support both directory and file processing
24
+ - `stringifier.ts` currently only supports typescript and md files - other file types may need special file handling.
25
+ - `README.md` to match current export structure.
26
+
27
+ ### Fixed
28
+ The following are marked under 0.2.4 in git, but are released in 0.3.0+
29
+ - `src/functions/scaffold-core.ts` - using `cwd` to handle folder creation, matching the relative pathing intimated by the clack prompt masking.
30
+ - `src/functions/scaffold-project.ts` - same as above
31
+ - `src/README.md` - finished styling directory markup
32
+
33
+ ## [0.2.3] - 2025-12-30
34
+
35
+ ### Fixed
36
+
37
+ I forgot to push some files from 0.2.2 to github and then forgot to make sure they existed before publishing to npm.
38
+ Oh well.
10
39
 
11
40
  ## [0.2.2] - 2025-12-30
12
41
 
13
42
  ### Added
43
+
14
44
  - `src/core/helpers/stringifier.ts` to codegen before building
15
45
  - `prebuild` script to dynamically update the code located in data/core at build time.
16
46
  - `src/data/core.ts` is generated / regenerated at before building for use in dist
47
+ - `README.md` - Rewrote to make sense for display on NPM store as NPX package
17
48
 
18
49
  ### Fixed
50
+
19
51
  - `src/functions/scaffold-core.ts` doesn't try to pull data that doesn't exist anymore :^)
52
+ - `src/core/cli.ts` doesn't try to read the version from the user's computer anymore (hopefully)
53
+
54
+ ### Moved
55
+
56
+ - Original `README.md` moved to `src/README.md` - it's for devs, anyways.
20
57
 
21
58
  ## [0.2.1] - 2025-12-30
59
+
22
60
  ### Added
61
+
23
62
  - `CHANGELOG.md` for tracking changes
24
63
 
25
64
  ### Changed
65
+
26
66
  - Simplified `file-utils.ts` by removing path caching (was causing issues with non-existent directories)
27
67
 
28
68
  ### Fixed
69
+
29
70
  - Directory creation bug: `realpath()` now replaced with `resolve()` to handle new target directories
30
71
  - Path resolution in bundled code for version command
31
72
 
32
73
  ### Removed
74
+
33
75
  - Path caching in `file-utils.ts` (unnecessary optimization causing failures)
34
76
  - Removed unused imports in `src/functions/orchestrate-scaffold.ts` to lint warnings
35
77
 
36
78
  ## [0.2.0] - 2025-12-30
37
79
 
38
80
  ### Added
81
+
39
82
  - Build system with `bun build --target=bun`
40
83
  - Build scripts: `build`, `build:exe`, `prepack`
41
84
  - npm package preparation (removed `private: true`)
42
85
 
43
86
  ### Changed
87
+
44
88
  - Moved `typescript` from peerDependencies to devDependencies
45
89
  - Updated package.json entry points to `./dist/index.js`
46
90
  - Fixed `--version` command to use `process.cwd()` for package.json resolution
@@ -48,6 +92,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
48
92
  ## [0.1.0] - 2025-12-30
49
93
 
50
94
  ### Added
95
+
51
96
  - Initial CLI scaffolding tool
52
97
  - Interactive project setup with `@clack/prompts`
53
98
  - Full CLI scaffold generation (package.json, tsconfig.json, README.md, core files)
package/README.md CHANGED
@@ -1,111 +1,134 @@
1
1
  # mkcmd
2
2
 
3
- A remote node executable for scaffolding other remote node executables with sensible defaults.
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 Project Setup** - Prompts for project name, target directory, and description using `@clack/prompts`
10
- - **Full CLI Scaffold** - Generates a complete CLI project structure with configuration files
11
- - **Core Utilities Included** - Ships with `file-builder.ts` and `file-utils.ts` for dynamic code generation
12
- - **TypeScript & Bun** - Pre-configured TypeScript settings and Bun runtime support
13
- - **Dynamic Core Copying** - Automatically copies all core CLI files to your new project
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
- When you run `mkcmd init`, it creates:
45
+ After running `mkcmd init`, you'll have a complete CLI project:
18
46
 
19
47
  ```
20
- project-name/
48
+ my-cli/
21
49
  ├── src/
22
50
  │ ├── core/
23
- │ │ ├── cli.ts # CLI framework with command registration
24
- │ │ ├── log.ts # Logging helpers (single/multi info/warn/err, title)
25
- │ │ ├── file-builder.ts # Indentation-aware file builder
26
- │ │ └── file-utils.ts # Path caching and file writing utilities
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
56
+ │ │ └── stringifier.ts # Dynamic template code generation
27
57
  │ ├── commands/
28
- │ │ └── index.ts # Command registration hook
29
- │ └── config.ts # Project configuration
58
+ │ │ └── index.ts # Command registration hook
59
+ │ └── config.ts # Project configuration
30
60
  ├── package.json
31
61
  ├── tsconfig.json
32
62
  └── README.md
33
63
  ```
34
64
 
35
- ## Installation
65
+ ## Usage
36
66
 
37
- ### For Development
67
+ ### Running Your New CLI
38
68
 
39
69
  ```bash
70
+ cd my-cli
40
71
  bun install
72
+ bun run src/index.ts --help
41
73
  ```
42
74
 
43
- ### From npm (after publishing)
44
-
45
- ```bash
46
- npm install -g mkcmd
47
- # or
48
- bun install -g mkcmd
49
- ```
50
-
51
- ## Usage
52
-
53
- ### Development
75
+ ### Adding Commands
54
76
 
55
- ```bash
56
- # Show help
57
- bun run src/index.ts --help
77
+ Commands are registered in `src/commands/index.ts`. Here's the pattern:
58
78
 
59
- # Show version
60
- bun run src/index.ts --version
79
+ ```typescript
80
+ import { registerCommand } from "../core/cli";
61
81
 
62
- # Initialize a new CLI project
63
- bun run src/index.ts init
82
+ registerCommand({
83
+ name: "greet",
84
+ description: "Say hello",
85
+ instructions: "Pass a name to greet",
86
+ run: async (args: string[]) => {
87
+ const name = args[0] || "world";
88
+ console.log(`Hello, ${name}!`);
89
+ }
90
+ });
64
91
  ```
65
92
 
66
- ### Using Built Distribution
93
+ Then run:
67
94
 
68
95
  ```bash
69
- # Build for Bun runtime
70
- bun run build
71
- bun dist/index.js --help
72
-
73
- # Build standalone executable
74
- bun run build:exe
75
- ./dist/mkcmd --help
96
+ bun run src/index.ts greet
97
+ bun run src/index.ts greet Alice
76
98
  ```
77
99
 
78
- ### After Installation (from npm)
100
+ ### Using the File Builder
79
101
 
80
- ```bash
81
- mkcmd --help
82
- mkcmd init
83
- ```
102
+ The included `FileBuilder` helps generate code files dynamically:
84
103
 
85
- The `init` command will prompt you for:
86
- - Project name
87
- - Target directory (defaults to `./<project-name>`)
88
- - Project description
104
+ ```typescript
105
+ import { FileBuilder } from "./core/helpers/file-builder";
106
+
107
+ const fb = new FileBuilder();
108
+ fb.addLine("export function hello() {");
109
+ fb.addLine(' console.log("Hello!");', 1);
110
+ fb.addLine("}");
111
+ const code = fb.build();
112
+ ```
89
113
 
90
- ## Building for npm
114
+ ## CLI Flags
91
115
 
92
- To build and prepare for publishing:
116
+ After installation, `mkcmd` supports:
93
117
 
94
118
  ```bash
95
- # Build the bundled JS file (requires Bun runtime)
96
- bun run build
119
+ mkcmd --help # Show help
120
+ mkcmd --version # Show version
121
+ ```
97
122
 
98
- # Build standalone executable (works without Bun)
99
- bun run build:exe
123
+ ## Requirements
100
124
 
101
- # Publish to npm
102
- npm publish
103
- ```
125
+ - Bun runtime (for running the generated project)
126
+ - Node.js 16+ (for installation via npm)
104
127
 
105
- **Note**: The default build (`bun run build`) produces a bundled JS file that requires Bun to run. The standalone executable (`bun run build:exe`) works independently but is platform-specific.
128
+ ## License
106
129
 
107
- ## Development
130
+ See LICENSE file for details.
108
131
 
109
- This project was created using `bun init` in bun v1.2.13. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
132
+ ---
110
133
 
111
- See [AGENTS.md](./AGENTS.md) for development guidelines, [CHANGELOG.md](./CHANGELOG.md) for version history.
134
+ **Version:** See `npm info @mbsi/mkcmd version`, `npx @mbsi/mkcmd --version`, or run `mkcmd --version` after installation.
package/dist/index.js CHANGED
@@ -1586,12 +1586,21 @@ var log = {
1586
1586
  var log_default = log;
1587
1587
 
1588
1588
  // src/core/cli.ts
1589
- import { join as join2 } from "path";
1589
+ import { join as join3 } from "path";
1590
1590
 
1591
1591
  // src/config.ts
1592
+ import { join as join2 } from "path";
1592
1593
  var config = {
1593
1594
  about_text: "mkcmd is a remote node executable for scaffolding other remote node executables with sensible defaults.",
1594
- more_info_text: "See https://github.com/mackenziebowes/mkcmd for more details."
1595
+ more_info_text: "See https://github.com/mackenziebowes/mkcmd for more details.",
1596
+ watchConfigs: [
1597
+ {
1598
+ name: "core",
1599
+ type: "dir",
1600
+ sourcePath: join2(".", "src", "core"),
1601
+ outputPath: join2(".", "src", "data", "core.ts")
1602
+ }
1603
+ ]
1595
1604
  };
1596
1605
 
1597
1606
  // src/core/cli.ts
@@ -1631,7 +1640,8 @@ async function runCLI(argv = Bun.argv.slice(2)) {
1631
1640
  return;
1632
1641
  }
1633
1642
  if (["-v", "--version"].includes(name)) {
1634
- const pkgText = await Bun.file(join2(process.cwd(), "package.json")).text();
1643
+ const pkgPath = join3(import.meta.dir, "..", "package.json");
1644
+ const pkgText = await Bun.file(pkgPath).text();
1635
1645
  const pkg = JSON.parse(pkgText);
1636
1646
  log_default.multi.info([
1637
1647
  {
@@ -2124,10 +2134,10 @@ async function promptProjectDetails() {
2124
2134
 
2125
2135
  // src/core/helpers/file-utils.ts
2126
2136
  import { mkdir } from "fs/promises";
2127
- import { resolve, join as join3 } from "path";
2137
+ import { resolve, join as join4 } from "path";
2128
2138
  async function writeFileTuple([targetDir, relativePath, content]) {
2129
2139
  const fullPath = resolve(targetDir, relativePath);
2130
- await mkdir(join3(fullPath, ".."), { recursive: true });
2140
+ await mkdir(join4(fullPath, ".."), { recursive: true });
2131
2141
  await Bun.write(fullPath, content);
2132
2142
  }
2133
2143
 
@@ -2156,11 +2166,33 @@ var commands_init = () => {
2156
2166
  };
2157
2167
  var config_init = (about) => {
2158
2168
  const file = new FileBuilder;
2159
- file.addLine(`export const config = {`, 0);
2169
+ file.addLine(`import { join } from "node:path";`);
2170
+ file.addEmptyLine();
2171
+ file.addLine(`export interface WatchConfig {`);
2172
+ file.addLine(`name: string;`, 1);
2173
+ file.addLine(`type: "dir" | "file";`, 1);
2174
+ file.addLine(`sourcePath: string;`, 1);
2175
+ file.addLine(`outputPath: string;`, 1);
2176
+ file.addLine(`}`);
2177
+ file.addEmptyLine();
2178
+ file.addLine(`type Config = {`);
2179
+ file.addLine(`about_text: string;`, 1);
2180
+ file.addLine(`more_info_text: string;`, 1);
2181
+ file.addLine(`watchConfigs: WatchConfig[];`, 1);
2182
+ file.addLine(`}`);
2183
+ file.addLine(`export const config: Config = {`, 0);
2160
2184
  file.addLine(`about_text:`, 2);
2161
2185
  file.addLine(`"${about}",`, 1);
2162
2186
  file.addLine(`more_info_text:`, 2);
2163
2187
  file.addLine(`"See https://github.com/mackenziebowes/mkcmd for more details.",`, 1);
2188
+ file.addLine(`watchConfigs: [`, 1);
2189
+ file.addLine(`{`, 2);
2190
+ file.addLine(`name: "core",`, 3);
2191
+ file.addLine(`type: "dir",`, 3);
2192
+ file.addLine(`sourcePath: join(".", "src", "core"),`, 3);
2193
+ file.addLine(`outputPath: join(".", "src", "data", "core.ts"),`, 3);
2194
+ file.addLine(`},`, 2);
2195
+ file.addLine(`],`, 1);
2164
2196
  file.addLine(`};`, 0);
2165
2197
  return file.build();
2166
2198
  };
@@ -2250,10 +2282,10 @@ async function scaffoldProject(prompts) {
2250
2282
  }
2251
2283
 
2252
2284
  // src/functions/scaffold-core.ts
2253
- import { join as join4, dirname as dirname2 } from "path";
2285
+ import { join as join5, dirname as dirname2 } from "path";
2286
+ import { cwd } from "process";
2254
2287
  import { existsSync } from "fs";
2255
2288
  import { mkdir as mkdir2, writeFile } from "fs/promises";
2256
- import { cwd } from "process";
2257
2289
 
2258
2290
  // src/data/core.ts
2259
2291
  var src_core_cli_init = () => {
@@ -2307,7 +2339,8 @@ var src_core_cli_init = () => {
2307
2339
  fb.addLine(" }");
2308
2340
  fb.addLine("");
2309
2341
  fb.addLine(' if (["-v", "--version"].includes(name)) {');
2310
- fb.addLine(' const pkgText = await Bun.file(join(process.cwd(), "package.json")).text();');
2342
+ fb.addLine(' const pkgPath = join(import.meta.dir, "..", "package.json");');
2343
+ fb.addLine(" const pkgText = await Bun.file(pkgPath).text();");
2311
2344
  fb.addLine(" const pkg = JSON.parse(pkgText);");
2312
2345
  fb.addLine(" log.multi.info([");
2313
2346
  fb.addLine(" {");
@@ -2483,10 +2516,10 @@ var src_core_helpers_stringifier_init = () => {
2483
2516
  fb.addLine('import { readdir, writeFile } from "node:fs/promises";');
2484
2517
  fb.addLine('import { FileBuilder } from "./file-builder";');
2485
2518
  fb.addLine('import { statSync } from "node:fs";');
2519
+ fb.addLine('import { cwd } from "node:process";');
2520
+ fb.addLine('import { config } from "../../config";');
2486
2521
  fb.addLine("");
2487
- fb.addLine("const outExport: string[] = [];");
2488
- fb.addLine("");
2489
- fb.addLine("async function generateTemplate(path: string) {");
2522
+ fb.addLine("async function generateTemplateFromTs(path: string) {");
2490
2523
  fb.addLine(' if (path.endsWith(".ts")) {');
2491
2524
  fb.addLine(" const content = await Bun.file(path).text();");
2492
2525
  fb.addLine(" const fb = new FileBuilder();");
@@ -2496,6 +2529,8 @@ var src_core_helpers_stringifier_init = () => {
2496
2529
  fb.addLine(' .split("-")');
2497
2530
  fb.addLine(' .join("_")');
2498
2531
  fb.addLine(' .split(".")[0];');
2532
+ fb.addLine(" if (!snaked_title)");
2533
+ fb.addLine(" throw new Error(`Failed to generate identifier for path: ${path}`);");
2499
2534
  fb.addLine(' fb.addLine(`const ${snaked_title + "_init"} = () => {`);');
2500
2535
  fb.addLine(" fb.addLine(`const fb = new FileBuilder();`, 1);");
2501
2536
  fb.addLine(' const lines = content.split("\\n");');
@@ -2506,42 +2541,135 @@ var src_core_helpers_stringifier_init = () => {
2506
2541
  fb.addLine(' fb.addLine("return fb.build();", 1);');
2507
2542
  fb.addLine(' fb.addLine("};");');
2508
2543
  fb.addLine(" fb.addEmptyLine();");
2509
- fb.addLine(" fb.addLine(`export const ${snaked_title} = {`);");
2544
+ fb.addLine(" fb.addLine(`const ${snaked_title} = {`);");
2510
2545
  fb.addLine(' fb.addLine(`location: "${path}",`, 1);');
2511
2546
  fb.addLine(' fb.addLine(`content: ${snaked_title + "_init"}`, 1);');
2512
2547
  fb.addLine(" fb.addLine(`};`);");
2513
2548
  fb.addLine(" const out = fb.build();");
2514
- fb.addLine(" outExport.push(`${snaked_title}`);");
2515
- fb.addLine(" return out;");
2549
+ fb.addLine(" return { name: snaked_title, content: out };");
2516
2550
  fb.addLine(" }");
2517
- fb.addLine(' return "";');
2551
+ fb.addLine(" return null;");
2552
+ fb.addLine("}");
2553
+ fb.addLine("");
2554
+ fb.addLine("async function generateTemplateFromMd(path: string) {");
2555
+ fb.addLine(' if (path.endsWith(".md")) {');
2556
+ fb.addLine(" const content = await Bun.file(path).text();");
2557
+ fb.addLine(" const fb = new FileBuilder();");
2558
+ fb.addLine(" const snaked_title = path");
2559
+ fb.addLine(' .split("/")');
2560
+ fb.addLine(' .join("_")');
2561
+ fb.addLine(' .split("-")');
2562
+ fb.addLine(' .join("_")');
2563
+ fb.addLine(' .split(".")[0];');
2564
+ fb.addLine(" if (!snaked_title)");
2565
+ fb.addLine(" throw new Error(`Failed to generate identifier for path: ${path}`);");
2566
+ fb.addLine(' fb.addLine(`const ${snaked_title + "_init"} = () => {`);');
2567
+ fb.addLine(" fb.addLine(`const fb = new FileBuilder();`, 1);");
2568
+ fb.addLine(' const lines = content.split("\\n");');
2569
+ fb.addLine(" for (const line of lines) {");
2570
+ fb.addLine(` const cleanLine = line.replaceAll("\\\\", "\\\\\\\\").replaceAll('"', '\\\\"');`);
2571
+ fb.addLine(' fb.addLine(`fb.addLine("${cleanLine}")`, 1);');
2572
+ fb.addLine(" }");
2573
+ fb.addLine(' fb.addLine("return fb.build();", 1);');
2574
+ fb.addLine(' fb.addLine("};");');
2575
+ fb.addLine(" fb.addEmptyLine();");
2576
+ fb.addLine(" fb.addLine(`const ${snaked_title} = {`);");
2577
+ fb.addLine(' fb.addLine(`location: "${path}",`, 1);');
2578
+ fb.addLine(' fb.addLine(`content: ${snaked_title + "_init"}`, 1);');
2579
+ fb.addLine(" fb.addLine(`};`);");
2580
+ fb.addLine(" const out = fb.build();");
2581
+ fb.addLine(" return { name: snaked_title, content: out };");
2582
+ fb.addLine(" }");
2583
+ fb.addLine(" return null;");
2584
+ fb.addLine("}");
2585
+ fb.addLine("");
2586
+ fb.addLine("async function generateTemplate(path: string) {");
2587
+ fb.addLine(' if (path.endsWith(".ts")) {');
2588
+ fb.addLine(" return generateTemplateFromTs(path);");
2589
+ fb.addLine(" }");
2590
+ fb.addLine(' if (path.endsWith(".md")) {');
2591
+ fb.addLine(" return generateTemplateFromMd(path);");
2592
+ fb.addLine(" }");
2593
+ fb.addLine(" return null;");
2518
2594
  fb.addLine("}");
2519
2595
  fb.addLine("");
2520
2596
  fb.addLine("async function parseFolder(path: string, fb: FileBuilder) {");
2597
+ fb.addLine(" const outExport: string[] = [];");
2521
2598
  fb.addLine(" const items = await readdir(path);");
2522
2599
  fb.addLine(" for (const item of items) {");
2523
2600
  fb.addLine(" const relPath = join(path, item);");
2524
2601
  fb.addLine(" const itemStat = statSync(relPath);");
2525
2602
  fb.addLine(" if (itemStat.isDirectory()) {");
2526
- fb.addLine(" await parseFolder(relPath, fb);");
2603
+ fb.addLine(" const nestedExports = await parseFolder(relPath, fb);");
2604
+ fb.addLine(" outExport.push(...nestedExports);");
2527
2605
  fb.addLine(" }");
2528
2606
  fb.addLine(' if (item.endsWith(".ts")) {');
2529
- fb.addLine(" fb.addLine(await generateTemplate(relPath));");
2530
- fb.addLine(" fb.addEmptyLine();");
2607
+ fb.addLine(" const template = await generateTemplate(relPath);");
2608
+ fb.addLine(" if (template) {");
2609
+ fb.addLine(" fb.addLine(template.content);");
2610
+ fb.addLine(" fb.addEmptyLine();");
2611
+ fb.addLine(" outExport.push(template.name);");
2612
+ fb.addLine(" }");
2531
2613
  fb.addLine(" }");
2532
2614
  fb.addLine(" }");
2615
+ fb.addLine(" return outExport;");
2533
2616
  fb.addLine("}");
2534
2617
  fb.addLine("");
2535
- fb.addLine("async function generateTemplates() {");
2536
- fb.addLine(' const sourceCoreDir = join(".", "src", "core");');
2618
+ fb.addLine("async function exportDataTemplates() {");
2537
2619
  fb.addLine(" const fb = new FileBuilder();");
2538
- fb.addLine(' fb.addLine(`import { FileBuilder } from "../core/helpers/file-builder";`);');
2620
+ fb.addLine(" const exportList: string[] = [];");
2621
+ fb.addLine(' const dataFiles = await readdir(join(cwd(), "src", "data"));');
2622
+ fb.addLine(" for (const file of dataFiles) {");
2623
+ fb.addLine(' if (file == "init.ts" || file == "core.ts" || file == "index.ts") {');
2624
+ fb.addLine(" continue;");
2625
+ fb.addLine(" }");
2626
+ fb.addLine(' const content = await Bun.file(join(cwd(), "src", "data", file)).text();');
2627
+ fb.addLine(' const lines = content.split("\\n");');
2628
+ fb.addLine(" const exportStatement = lines.pop();");
2629
+ fb.addLine(" if (!exportStatement) throw new Error(`Parsed file ${file} is empty`);");
2630
+ fb.addLine(' const functionName = exportStatement.split(" ")[2];');
2631
+ fb.addLine(" if (!functionName)");
2632
+ fb.addLine(" throw new Error(");
2633
+ fb.addLine(" `Parse file ${file} is malformed - missing export statement`,");
2634
+ fb.addLine(" );");
2635
+ fb.addLine(" exportList.push(functionName);");
2636
+ fb.addLine(' fb.addLine(`import { ${functionName} } from "./${file}";`);');
2637
+ fb.addLine(" }");
2539
2638
  fb.addLine(" fb.addEmptyLine();");
2540
- fb.addLine(" await parseFolder(sourceCoreDir, fb);");
2541
- fb.addLine(' fb.addLine(`const core = [${outExport.join(", ")}]`);');
2542
- fb.addLine(" fb.addLine(`export { core }`);");
2639
+ fb.addLine(' fb.addLine("type DataExport = {");');
2640
+ fb.addLine(' fb.addLine("location: string", 1);');
2641
+ fb.addLine(' fb.addLine("content: () => string", 1);');
2642
+ fb.addLine(' fb.addLine("};");');
2643
+ fb.addLine(" fb.addEmptyLine();");
2644
+ fb.addLine(' fb.addLine(`const data: DataExport[] = [${exportList.join(", ")}];`);');
2645
+ fb.addLine(' fb.addLine("export { data }");');
2543
2646
  fb.addLine(" const out = fb.build();");
2544
- fb.addLine(' await writeFile(join(".", "src", "data", "core.ts"), out, "utf8");');
2647
+ fb.addLine(' await writeFile(join(cwd(), "src", "data", "index.ts"), out, "utf8");');
2648
+ fb.addLine("}");
2649
+ fb.addLine("");
2650
+ fb.addLine("async function generateTemplates() {");
2651
+ fb.addLine(" for (const watchConfig of config.watchConfigs) {");
2652
+ fb.addLine(" const fb = new FileBuilder();");
2653
+ fb.addLine(' fb.addLine(`import { FileBuilder } from "../core/helpers/file-builder";`);');
2654
+ fb.addLine(" fb.addEmptyLine();");
2655
+ fb.addLine(' if (watchConfig.type == "dir") {');
2656
+ fb.addLine(" const exports = await parseFolder(watchConfig.sourcePath, fb);");
2657
+ fb.addLine(' fb.addLine(`const ${watchConfig.name} = [${exports.join(", ")}]`);');
2658
+ fb.addLine(" fb.addLine(`export { ${watchConfig.name} }`);");
2659
+ fb.addLine(" const out = fb.build();");
2660
+ fb.addLine(' await writeFile(watchConfig.outputPath, out, "utf8");');
2661
+ fb.addLine(" } else {");
2662
+ fb.addLine(" const template = await generateTemplate(watchConfig.sourcePath);");
2663
+ fb.addLine(" if (template) {");
2664
+ fb.addLine(" fb.addLine(template.content);");
2665
+ fb.addLine(" fb.addEmptyLine();");
2666
+ fb.addLine(" fb.addLine(`export { ${template.name} }`);");
2667
+ fb.addLine(" const out = fb.build();");
2668
+ fb.addLine(' await writeFile(watchConfig.outputPath, out, "utf8");');
2669
+ fb.addLine(" }");
2670
+ fb.addLine(" }");
2671
+ fb.addLine(" }");
2672
+ fb.addLine(" exportDataTemplates();");
2545
2673
  fb.addLine("}");
2546
2674
  fb.addLine("");
2547
2675
  fb.addLine("generateTemplates();");
@@ -2572,18 +2700,43 @@ var src_core_helpers_file_utils = {
2572
2700
  var core = [src_core_cli, src_core_log, src_core_helpers_file_builder, src_core_helpers_stringifier, src_core_helpers_file_utils];
2573
2701
 
2574
2702
  // src/functions/scaffold-core.ts
2575
- var currentDir = join4(cwd());
2576
2703
  async function scaffoldCore(targetDir) {
2577
- const combinedPath = join4(currentDir, targetDir);
2578
- console.dir(combinedPath);
2704
+ const combinedPath = join5(cwd(), targetDir);
2705
+ if (!existsSync(combinedPath)) {
2706
+ await mkdir2(combinedPath, { recursive: true });
2707
+ }
2579
2708
  for (const file of core) {
2580
2709
  const relativePath = file.location.replace(/^\.\//, "");
2581
- const parentDir = join4(combinedPath, dirname2(relativePath));
2582
- console.dir({ parentDir });
2710
+ const parentDir = join5(combinedPath, dirname2(relativePath));
2583
2711
  if (!existsSync(parentDir)) {
2584
- mkdir2(parentDir, { recursive: true });
2712
+ await mkdir2(parentDir, { recursive: true });
2713
+ }
2714
+ await writeFile(join5(combinedPath, relativePath), file.content(), "utf8");
2715
+ }
2716
+ }
2717
+
2718
+ // src/functions/scaffold-rest.ts
2719
+ import { join as join6, dirname as dirname3 } from "path";
2720
+ import { cwd as cwd2 } from "process";
2721
+ import { existsSync as existsSync2 } from "fs";
2722
+ import { mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
2723
+
2724
+ // src/data/index.ts
2725
+ var data = [];
2726
+
2727
+ // src/functions/scaffold-rest.ts
2728
+ async function scaffoldRest(targetDir) {
2729
+ const combinedPath = join6(cwd2(), targetDir);
2730
+ if (!existsSync2(combinedPath)) {
2731
+ await mkdir3(combinedPath, { recursive: true });
2732
+ }
2733
+ for (const file of data) {
2734
+ const relativePath = file.location.replace(/^\.\//, "");
2735
+ const parentDir = join6(combinedPath, dirname3(relativePath));
2736
+ if (!existsSync2(parentDir)) {
2737
+ await mkdir3(parentDir, { recursive: true });
2585
2738
  }
2586
- writeFile(join4(combinedPath, relativePath), file.content(), "utf8");
2739
+ await writeFile2(join6(combinedPath, relativePath), file.content(), "utf8");
2587
2740
  }
2588
2741
  }
2589
2742
 
@@ -2594,6 +2747,8 @@ async function orchestrateScaffold() {
2594
2747
  log_default.single.info("Project", "Project files created");
2595
2748
  await scaffoldCore(prompts.targetDir);
2596
2749
  log_default.single.info("Core", "Core files copied");
2750
+ await scaffoldRest(prompts.targetDir);
2751
+ log_default.single.info("Rest", "All files copied");
2597
2752
  log_default.multi.info([
2598
2753
  { t: "Success", m: "Project scaffolded successfully!" },
2599
2754
  { t: "Location", m: prompts.targetDir },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mbsi/mkcmd",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",