@reliverse/rempts 1.7.14 → 1.7.16

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
@@ -662,111 +662,94 @@ export default defineCommand({
662
662
  });
663
663
  ```
664
664
 
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**:
665
+ ### Loading Commands with `loadCommand`
690
666
 
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.
667
+ The `loadCommand` utility helps you load command files from your filesystem. It automatically handles:
695
668
 
696
- **Lazy Loading (Recommended for Most CLIs)**:
669
+ - Relative paths (both `./build` and `build` work the same)
670
+ - Automatic detection of `cmd.{ts,js}` files
671
+ - Clear error messages when files are not found
697
672
 
698
673
  ```ts
699
- // example/launcher/app/cmds.ts
674
+ import { loadCommand } from "@reliverse/rempts";
700
675
 
701
- export async function cmdHooks() {
702
- return (await import("./hooks/cmd.js")).default;
703
- }
676
+ // These are equivalent:
677
+ const cmd1 = await loadCommand("./build"); // Looks for build/cmd.ts or build/cmd.js
678
+ const cmd2 = await loadCommand("build"); // Same as above
679
+ const cmd3 = await loadCommand("./build/cmd"); // Explicit path to cmd file
704
680
 
705
- export async function getCmdFoo() {
706
- return (await import("./foo/cmd.js")).default;
707
- }
708
-
709
- // ...more commands
681
+ // You can then use the loaded command with runCmd:
682
+ await runCmd(cmd1, ["--some-flag"]);
710
683
  ```
711
684
 
712
- Usage:
713
-
714
685
  ```ts
715
- // example/prompts/mod.ts
686
+ // src/app/cmds.ts
687
+ export const getBuildCmd = async (): Promise<Command> => loadCommand("./build");
716
688
 
717
- import { cmdHooks } from "@/launcher/app/cmds.js";
689
+ // src/cli.ts
718
690
  import { runCmd } from "@reliverse/rempts";
719
-
720
- await runCmd(await cmdHooks(), ["--flag"]);
721
- // OR:
722
- // const hooksCmd = await cmdHooks();
723
- // await runCmd(hooksCmd, ["--flag"]);
691
+ import { getBuildCmd } from "./app/cmds";
692
+ await runCmd(await getBuildCmd(), ["--prod"]);
724
693
  ```
725
694
 
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
- ```
695
+ **Error Handling:**
696
+ If the command file is not found, you'll get a clear error message:
734
697
 
735
- Usage:
736
-
737
- ```ts
738
- import { hooksCmd } from "./cmds.js";
739
- import { runCmd } from "@reliverse/rempts";
740
-
741
- await runCmd(hooksCmd, ["--flag"]);
698
+ ```bash
699
+ No command file found in /path/to/build. Expected to find either:
700
+ - /path/to/build/cmd.ts
701
+ - /path/to/build/cmd.js
702
+ Please ensure one of these files exists and exports a default command.
742
703
  ```
743
704
 
744
- **Programmatic Command Execution with `runCmd`**:
705
+ **Best Practices:**
745
706
 
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:
707
+ - Use `loadCommand` when you need to load commands from the filesystem
708
+ - Use `runCmd` to execute the loaded command with arguments
709
+ - Keep your command files in a consistent location (e.g., `src/app/yourCmdName/cmd.ts`)
710
+ - Export commands from a central file like `src/app/cmds.ts` for better organization
747
711
 
748
712
  ```ts
749
- import { runCmd } from "@reliverse/rempts";
750
- import { hooksCmd } from "./cmds.js";
713
+ // example/launcher/app/cmds.ts
714
+ import { loadCommand } from "@reliverse/rempts";
751
715
 
752
- await runCmd(hooksCmd, ["--flag"]); // argv as array of strings
753
- ```
716
+ export async function getBuildCmd() {
717
+ return loadCommand("./build");
718
+ }
754
719
 
755
- Or with lazy loading:
720
+ export async function getDeployCmd() {
721
+ return loadCommand("./deploy");
722
+ }
756
723
 
757
- ```ts
758
- const hooksCmd = await cmdHooks();
759
- await runCmd(hooksCmd, ["--flag"]);
724
+ // Usage:
725
+ import { getBuildCmd } from "./cmds";
726
+ const buildCmd = await getBuildCmd();
727
+ await runCmd(buildCmd, ["--prod"]);
760
728
  ```
761
729
 
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:**
730
+ ```ts
731
+ // example/launcher/app/minimal/cmd.ts
765
732
 
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.
733
+ import { relinka } from "@reliverse/relinka";
734
+ import { defineArgs, defineCommand } from "@reliverse/rempts";
768
735
 
769
- Choose the pattern that best fits your CLI's size and usage!
736
+ export default defineCommand({
737
+ meta: {
738
+ name: "minimal",
739
+ description: "hello world",
740
+ },
741
+ args: defineArgs({
742
+ name: {
743
+ type: "string",
744
+ description: "your name",
745
+ required: true,
746
+ },
747
+ }),
748
+ run({ args }) {
749
+ relinka("success", `👋 Hello, ${args.name}!`);
750
+ },
751
+ });
752
+ ```
770
753
 
771
754
  ## Argument Types: Usage Comparison
772
755
 
@@ -1,8 +1,8 @@
1
1
  import path from "@reliverse/pathkit";
2
2
  import { re } from "@reliverse/relico";
3
+ import fs from "@reliverse/relifso";
3
4
  import { relinka } from "@reliverse/relinka";
4
5
  import { loadConfig } from "c12";
5
- import fs from "fs-extra";
6
6
  import termkit from "terminal-kit";
7
7
  const { terminal: term } = termkit;
8
8
  let state = {
@@ -1,8 +1,8 @@
1
1
  import path from "@reliverse/pathkit";
2
2
  import { reliArgParser } from "@reliverse/reliarg";
3
3
  import { re } from "@reliverse/relico";
4
+ import fs from "@reliverse/relifso";
4
5
  import { relinka, relinkaConfig, relinkaShutdown } from "@reliverse/relinka";
5
- import fs from "fs-extra";
6
6
  import process from "node:process";
7
7
  import { readPackageJSON } from "pkg-types";
8
8
  function buildExampleArgs(args) {
@@ -1,7 +1,8 @@
1
- import { resolve } from "@reliverse/pathkit";
1
+ import { resolve, dirname } from "@reliverse/pathkit";
2
+ import fs from "@reliverse/relifso";
2
3
  import { relinka } from "@reliverse/relinka";
3
- import fs from "fs-extra";
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,7 +10,21 @@ const jiti = createJiti(import.meta.url, {
9
10
  });
10
11
  export async function loadCommand(cmdPath) {
11
12
  try {
12
- const resolvedPath = cmdPath.startsWith("./") || cmdPath.startsWith("../") ? resolve(process.cwd(), cmdPath) : cmdPath;
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();
26
+ const normalizedPath = cmdPath.replace(/^\.\//, "");
27
+ const resolvedPath = resolve(callerDir, normalizedPath);
13
28
  if (!resolvedPath.endsWith("cmd.ts") && !resolvedPath.endsWith("cmd.js")) {
14
29
  const possiblePaths = [
15
30
  resolve(resolvedPath, "cmd.ts"),
package/package.json CHANGED
@@ -4,6 +4,7 @@
4
4
  "@reliverse/pathkit": "^1.2.1",
5
5
  "@reliverse/reliarg": "^1.0.3",
6
6
  "@reliverse/relico": "^1.1.2",
7
+ "@reliverse/relifso": "^1.3.1",
7
8
  "@reliverse/relinka": "^1.4.7",
8
9
  "@reliverse/runtime": "^1.0.3",
9
10
  "ansi-escapes": "^7.0.0",
@@ -11,7 +12,6 @@
11
12
  "cli-spinners": "^3.2.0",
12
13
  "detect-package-manager": "^3.0.2",
13
14
  "figlet": "^1.8.1",
14
- "fs-extra": "^11.3.0",
15
15
  "gradient-string": "^3.0.0",
16
16
  "jiti": "^2.4.2",
17
17
  "log-update": "^6.1.0",
@@ -29,7 +29,7 @@
29
29
  "license": "MIT",
30
30
  "name": "@reliverse/rempts",
31
31
  "type": "module",
32
- "version": "1.7.14",
32
+ "version": "1.7.16",
33
33
  "author": "reliverse",
34
34
  "bugs": {
35
35
  "email": "blefnk@gmail.com",