@reliverse/rempts 1.7.15 โ†’ 1.7.17

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 CHANGED
@@ -25,7 +25,8 @@
25
25
  - ๐Ÿช„ minimal API surface, maximum expressiveness
26
26
  - ๐Ÿงช scriptable for testing, stable for production
27
27
  - ๐Ÿž๏ธ no more hacking together `inquirer`/`citty`/`commander`/`chalk`
28
- - ๐Ÿ†• automatic command creation (`bun dler rempts init --cmd my-cmd`)
28
+ - ๐Ÿ†• automatic command creation (`bun dler rempts --init cmd1 cmd2`)
29
+ - ๐Ÿฆโ€๐Ÿ”ฅ automatic creation of `src/app/cmds.ts` file (`bun dler rempts`)
29
30
 
30
31
  ## Installation
31
32
 
@@ -37,8 +38,8 @@ bun add @reliverse/rempts
37
38
 
38
39
  ```bash
39
40
  bun add -D @reliverse/dler
40
- bun dler rempts init --cmd my-cmd-1
41
- bun dler rempts init --cmds
41
+ bun dler rempts --init cmd1 cmd2 # creates `src/app/cmd1/cmd.ts` and `src/app/cmd2/cmd.ts` files
42
+ bun dler rempts # creates `src/app/cmds.ts` file
42
43
  ```
43
44
 
44
45
  ## Usage Examples
@@ -229,7 +230,7 @@ export default defineCommand({
229
230
  **Hint**:
230
231
 
231
232
  - Install `bun add -D @reliverse/dler`
232
- - Use `bun dler rempts init --cmd cmd1 cmd2` to init commands for rempts launcher's automatically
233
+ - Use `bun dler rempts --init cmd1 cmd2` to init commands for rempts launcher's automatically
233
234
 
234
235
  ### Advanced Launcher Usage
235
236
 
@@ -307,7 +308,7 @@ await runMain(defineCommand({}));
307
308
 
308
309
  ```bash
309
310
  bun add -D @reliverse/dler
310
- bun dler rempts init --cmd my-cmd-1 # or: dler rempts init my-cmd-1 my-cmd-2 --main src/mod.ts
311
+ bun dler rempts --init my-cmd-1 # or: dler rempts --init my-cmd-1 my-cmd-2 --main src/mod.ts
311
312
  # * `--main` is optional, default is `./src/mod.ts`
312
313
  # * you can specify multiple commands at once
313
314
  ```
@@ -662,111 +663,94 @@ export default defineCommand({
662
663
  });
663
664
  ```
664
665
 
665
- ```ts
666
- // example/launcher/app/minimal/cmd.ts
667
-
668
- import { relinka } from "@reliverse/relinka";
669
- import { defineArgs, defineCommand } from "@reliverse/rempts";
670
-
671
- export default defineCommand({
672
- meta: {
673
- name: "minimal",
674
- description: "hello world",
675
- },
676
- args: defineArgs({
677
- name: {
678
- type: "string",
679
- description: "your name",
680
- required: true,
681
- },
682
- }),
683
- run({ args }) {
684
- relinka("success", `๐Ÿ‘‹ Hello, ${args.name}!`);
685
- },
686
- });
687
- ```
688
-
689
- **Pro Tips & Best Practices**:
666
+ ### Loading Commands with `loadCommand`
690
667
 
691
- - Install `dler` globally and run `dler rempts init --cmds` to generate a `src/app/cmds.ts` (custom path is supported) file in your project.
692
- - You can use any name for the `cmds.ts` file and store it anywhere, but `src/app/cmds.ts` is a good convention you can follow.
693
- - Use the async function pattern for lazy loading if you have many commands or care about startup performance.
694
- - Use eager loading (const) for small CLIs or demos where simplicity is preferred.
668
+ The `loadCommand` utility helps you load command files from your filesystem. It automatically handles:
695
669
 
696
- **Lazy Loading (Recommended for Most CLIs)**:
670
+ - Relative paths (both `./build` and `build` work the same)
671
+ - Automatic detection of `cmd.{ts,js}` files
672
+ - Clear error messages when files are not found
697
673
 
698
674
  ```ts
699
- // example/launcher/app/cmds.ts
675
+ import { loadCommand } from "@reliverse/rempts";
700
676
 
701
- export async function cmdHooks() {
702
- return (await import("./hooks/cmd.js")).default;
703
- }
677
+ // These are equivalent:
678
+ const cmd1 = await loadCommand("./build"); // Looks for build/cmd.ts or build/cmd.js
679
+ const cmd2 = await loadCommand("build"); // Same as above
680
+ const cmd3 = await loadCommand("./build/cmd"); // Explicit path to cmd file
704
681
 
705
- export async function getCmdFoo() {
706
- return (await import("./foo/cmd.js")).default;
707
- }
708
-
709
- // ...more commands
682
+ // You can then use the loaded command with runCmd:
683
+ await runCmd(cmd1, ["--some-flag"]);
710
684
  ```
711
685
 
712
- Usage:
713
-
714
686
  ```ts
715
- // example/prompts/mod.ts
687
+ // src/app/cmds.ts
688
+ export const getBuildCmd = async (): Promise<Command> => loadCommand("./build");
716
689
 
717
- import { cmdHooks } from "@/launcher/app/cmds.js";
690
+ // src/cli.ts
718
691
  import { runCmd } from "@reliverse/rempts";
719
-
720
- await runCmd(await cmdHooks(), ["--flag"]);
721
- // OR:
722
- // const hooksCmd = await cmdHooks();
723
- // await runCmd(hooksCmd, ["--flag"]);
692
+ import { getBuildCmd } from "./app/cmds";
693
+ await runCmd(await getBuildCmd(), ["--prod"]);
724
694
  ```
725
695
 
726
- **Alternative: Eager Loading (All Commands Loaded at Startup)**:
727
-
728
- ```ts
729
- // example/launcher/app/cmds.ts
730
- export const hooksCmd = (await import("./hooks/cmd.js")).default;
731
- export const fooCmd = (await import("./foo/cmd.js")).default;
732
- // ...more commands
733
- ```
696
+ **Error Handling:**
697
+ If the command file is not found, you'll get a clear error message:
734
698
 
735
- Usage:
736
-
737
- ```ts
738
- import { hooksCmd } from "./cmds.js";
739
- import { runCmd } from "@reliverse/rempts";
740
-
741
- await runCmd(hooksCmd, ["--flag"]);
699
+ ```bash
700
+ No command file found in /path/to/build. Expected to find either:
701
+ - /path/to/build/cmd.ts
702
+ - /path/to/build/cmd.js
703
+ Please ensure one of these files exists and exports a default command.
742
704
  ```
743
705
 
744
- **Programmatic Command Execution with `runCmd`**:
706
+ **Best Practices:**
745
707
 
746
- The `runCmd` utility lets you run a command's `run()` handler with parsed arguments, outside of the full launcher context. This is useful for demos, tests, or custom flows:
708
+ - Use `loadCommand` when you need to load commands from the filesystem
709
+ - Use `runCmd` to execute the loaded command with arguments
710
+ - Keep your command files in a consistent location (e.g., `src/app/yourCmdName/cmd.ts`)
711
+ - Export commands from a central file like `src/app/cmds.ts` for better organization
747
712
 
748
713
  ```ts
749
- import { runCmd } from "@reliverse/rempts";
750
- import { hooksCmd } from "./cmds.js";
714
+ // example/launcher/app/cmds.ts
715
+ import { loadCommand } from "@reliverse/rempts";
751
716
 
752
- await runCmd(hooksCmd, ["--flag"]); // argv as array of strings
753
- ```
717
+ export async function getBuildCmd() {
718
+ return loadCommand("./build");
719
+ }
754
720
 
755
- Or with lazy loading:
721
+ export async function getDeployCmd() {
722
+ return loadCommand("./deploy");
723
+ }
756
724
 
757
- ```ts
758
- const hooksCmd = await cmdHooks();
759
- await runCmd(hooksCmd, ["--flag"]);
725
+ // Usage:
726
+ import { getBuildCmd } from "./cmds";
727
+ const buildCmd = await getBuildCmd();
728
+ await runCmd(buildCmd, ["--prod"]);
760
729
  ```
761
730
 
762
- **Note:** `runCmd` only runs the command's `run()` handler and does not handle subcommands, file-based commands, or global hooks. For full CLI behavior, use `runMain`.
763
-
764
- **Performance Note:**
731
+ ```ts
732
+ // example/launcher/app/minimal/cmd.ts
765
733
 
766
- - Eager loading (`const`) loads all commands at startup, which may impact performance for large CLIs.
767
- - Lazy loading (`async function`) loads each command only when needed, improving startup time and memory usage.
734
+ import { relinka } from "@reliverse/relinka";
735
+ import { defineArgs, defineCommand } from "@reliverse/rempts";
768
736
 
769
- Choose the pattern that best fits your CLI's size and usage!
737
+ export default defineCommand({
738
+ meta: {
739
+ name: "minimal",
740
+ description: "hello world",
741
+ },
742
+ args: defineArgs({
743
+ name: {
744
+ type: "string",
745
+ description: "your name",
746
+ required: true,
747
+ },
748
+ }),
749
+ run({ args }) {
750
+ relinka("success", `๐Ÿ‘‹ Hello, ${args.name}!`);
751
+ },
752
+ });
753
+ ```
770
754
 
771
755
  ## Argument Types: Usage Comparison
772
756
 
@@ -1,7 +1,8 @@
1
- import { resolve } from "@reliverse/pathkit";
1
+ import { resolve, dirname } from "@reliverse/pathkit";
2
2
  import fs from "@reliverse/relifso";
3
3
  import { relinka } from "@reliverse/relinka";
4
4
  import { createJiti } from "jiti";
5
+ import process from "node:process";
5
6
  const jiti = createJiti(import.meta.url, {
6
7
  debug: process.env.NODE_ENV === "development",
7
8
  fsCache: true,
@@ -9,8 +10,21 @@ const jiti = createJiti(import.meta.url, {
9
10
  });
10
11
  export async function loadCommand(cmdPath) {
11
12
  try {
13
+ const err = new Error();
14
+ const stack = err.stack?.split("\n");
15
+ let callerFile;
16
+ if (stack) {
17
+ for (const line of stack) {
18
+ const match = /\((.*):(\d+):(\d+)\)/.exec(line) || /at (.*):(\d+):(\d+)/.exec(line);
19
+ if (match?.[1] && !match[1].includes("run-command")) {
20
+ callerFile = match[1];
21
+ break;
22
+ }
23
+ }
24
+ }
25
+ const callerDir = callerFile ? dirname(callerFile) : process.cwd();
12
26
  const normalizedPath = cmdPath.replace(/^\.\//, "");
13
- const resolvedPath = normalizedPath.startsWith("../") ? resolve(process.cwd(), normalizedPath) : resolve(process.cwd(), normalizedPath);
27
+ const resolvedPath = resolve(callerDir, normalizedPath);
14
28
  if (!resolvedPath.endsWith("cmd.ts") && !resolvedPath.endsWith("cmd.js")) {
15
29
  const possiblePaths = [
16
30
  resolve(resolvedPath, "cmd.ts"),
package/package.json CHANGED
@@ -29,7 +29,7 @@
29
29
  "license": "MIT",
30
30
  "name": "@reliverse/rempts",
31
31
  "type": "module",
32
- "version": "1.7.15",
32
+ "version": "1.7.17",
33
33
  "author": "reliverse",
34
34
  "bugs": {
35
35
  "email": "blefnk@gmail.com",