@reliverse/rempts 1.7.24 → 1.7.26

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.
@@ -307,8 +307,15 @@ export async function showUsage(command, parserOptions = {}) {
307
307
  }
308
308
  }
309
309
  export async function runMain(command, parserOptions = {}) {
310
- if (typeof command.onLauncherInit === "function")
311
- await command.onLauncherInit();
310
+ if (typeof command.onLauncherInit === "function") {
311
+ try {
312
+ await command.onLauncherInit();
313
+ } catch (err) {
314
+ relinka("error", "Error in onLauncherInit:", err);
315
+ if (parserOptions.autoExit !== false) process.exit(1);
316
+ throw err;
317
+ }
318
+ }
312
319
  try {
313
320
  if (!parserOptions.fileBasedCmds && !command.commands) {
314
321
  let callerDir = process.cwd();
@@ -327,26 +334,17 @@ export async function runMain(command, parserOptions = {}) {
327
334
  }
328
335
  if (callerFile) {
329
336
  callerDir = path.dirname(callerFile);
330
- const rel = path.relative(process.cwd(), callerFile);
331
- if (/app[/][^/]+[/]cmd\.(ts|js)$/.test(rel)) {
332
- relinka(
333
- "error",
334
- `runMain() should not be called from a file-based subcommand: ${rel}
337
+ if (parserOptions.fileBasedCmds?.enable) {
338
+ const rel = path.relative(process.cwd(), callerFile);
339
+ if (/app[/][^/]+[/]cmd\.(ts|js)$/.test(rel)) {
340
+ relinka(
341
+ "error",
342
+ `runMain() should not be called from a file-based subcommand: ${rel}
335
343
  This can cause recursion or unexpected behavior.
336
344
  Move your runMain() call to your main CLI entry file.`
337
- );
338
- process.exit(1);
339
- }
340
- const mainEntry = process.argv[1] ? path.resolve(process.argv[1]) : void 0;
341
- if (mainEntry && path.resolve(callerFile) !== mainEntry) {
342
- relinka(
343
- "error",
344
- `runMain() should only be called from your main CLI entry file.
345
- Detected: ${callerFile}
346
- Main entry: ${mainEntry}
347
- This can cause recursion or unexpected behavior.`
348
- );
349
- process.exit(1);
345
+ );
346
+ process.exit(1);
347
+ }
350
348
  }
351
349
  }
352
350
  } catch (_e) {
@@ -8,58 +8,71 @@ const jiti = createJiti(import.meta.url, {
8
8
  fsCache: true,
9
9
  sourceMaps: true
10
10
  });
11
+ const COMMAND_EXTENSIONS = [".ts", ".js"];
12
+ const COMMAND_FILENAMES = ["cmd.ts", "cmd.js"];
13
+ const getCallerDirectory = () => {
14
+ const stack = new Error().stack?.split("\n") ?? [];
15
+ for (const line of stack) {
16
+ const match = /\((.*):(\d+):(\d+)\)/.exec(line) || /at (.*):(\d+):(\d+)/.exec(line);
17
+ if (match?.[1] && !match[1].includes("run-command")) {
18
+ return dirname(match[1]);
19
+ }
20
+ }
21
+ return process.cwd();
22
+ };
23
+ const tryLoadCommand = async (path) => {
24
+ if (!await fs.pathExists(path)) return null;
25
+ try {
26
+ relinka("verbose", `Attempting to load command from: ${path}`);
27
+ const cmd = await jiti.import(path, { default: true });
28
+ relinka("verbose", `Successfully loaded command from: ${path}`);
29
+ return cmd;
30
+ } catch {
31
+ relinka("verbose", `Failed to load ${path} as a command file`);
32
+ return null;
33
+ }
34
+ };
35
+ const generateCandidatePaths = async (resolvedPath) => {
36
+ if (!await fs.pathExists(resolvedPath)) {
37
+ return COMMAND_EXTENSIONS.map((ext) => `${resolvedPath}${ext}`);
38
+ }
39
+ if (await fs.isDirectory(resolvedPath)) {
40
+ return COMMAND_FILENAMES.map((filename) => resolve(resolvedPath, filename));
41
+ }
42
+ return [resolvedPath];
43
+ };
44
+ const createCommandNotFoundError = (cmdPath, searchedPaths) => new Error(
45
+ `No command file found for "${cmdPath}". Expected to find either:
46
+ - A valid command file at the specified path
47
+ - A directory containing cmd.ts or cmd.js
48
+ - A file path that can be resolved with .ts or .js extension
49
+ Searched paths: ${searchedPaths.join(", ")}
50
+ Please ensure one of these exists and exports a default command.`
51
+ );
52
+ const createLoadError = (cmdPath, originalError) => new Error(
53
+ `Failed to load command from "${cmdPath}"
54
+ For developers: Ensure the command file:
55
+ - Exists and is accessible
56
+ - Exports a default command (e.g., export default defineCommand({...}))
57
+ - Is a valid TypeScript/JavaScript module
58
+ Original error: ${originalError instanceof Error ? originalError.message : String(originalError)}`
59
+ );
11
60
  export async function loadCommand(cmdPath) {
12
61
  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();
62
+ const callerDir = getCallerDirectory();
26
63
  const normalizedPath = cmdPath.replace(/^\.\//, "");
27
64
  const resolvedPath = resolve(callerDir, normalizedPath);
28
- if (!resolvedPath.endsWith("cmd.ts") && !resolvedPath.endsWith("cmd.js")) {
29
- const possiblePaths = [
30
- resolve(resolvedPath, "cmd.ts"),
31
- resolve(resolvedPath, "cmd.js")
32
- ];
33
- for (const path of possiblePaths) {
34
- if (await fs.pathExists(path)) {
35
- relinka("verbose", `Loading command from: ${path}`);
36
- const cmd2 = await jiti.import(path, { default: true });
37
- relinka("verbose", `Successfully loaded command from: ${path}`);
38
- return cmd2;
39
- }
40
- }
41
- throw new Error(
42
- `No command file found in ${resolvedPath}. Expected to find either:
43
- - ${possiblePaths[0]}
44
- - ${possiblePaths[1]}
45
- Please ensure one of these files exists and exports a default command.`
46
- );
65
+ const candidatePaths = await generateCandidatePaths(resolvedPath);
66
+ for (const path of candidatePaths) {
67
+ const command = await tryLoadCommand(path);
68
+ if (command) return command;
47
69
  }
48
- relinka("verbose", `Loading command from: ${resolvedPath}`);
49
- const cmd = await jiti.import(resolvedPath, { default: true });
50
- relinka("verbose", `Successfully loaded command from: ${resolvedPath}`);
51
- return cmd;
70
+ throw createCommandNotFoundError(cmdPath, candidatePaths);
52
71
  } catch (error) {
53
72
  if (error instanceof Error && error.message.includes("No command file found")) {
54
73
  throw error;
55
74
  }
56
75
  relinka("error", `Failed to load command from ${cmdPath}:`, error);
57
- throw new Error(
58
- `Failed to load command from ${cmdPath}:
59
- - Make sure the file exists and is accessible
60
- - Ensure the file exports a default command
61
- - Check that the file is a valid TypeScript/JavaScript module
62
- Original error: ${error instanceof Error ? error.message : String(error)}`
63
- );
76
+ throw createLoadError(cmdPath, error);
64
77
  }
65
78
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "dependencies": {
3
3
  "@figliolia/chalk-animation": "^1.0.4",
4
- "@reliverse/pathkit": "^1.2.1",
4
+ "@reliverse/pathkit": "^1.3.3",
5
5
  "@reliverse/reliarg": "^1.0.3",
6
6
  "@reliverse/relico": "^1.1.2",
7
7
  "@reliverse/relifso": "^1.4.5",
@@ -29,7 +29,7 @@
29
29
  "license": "MIT",
30
30
  "name": "@reliverse/rempts",
31
31
  "type": "module",
32
- "version": "1.7.24",
32
+ "version": "1.7.26",
33
33
  "author": "reliverse",
34
34
  "bugs": {
35
35
  "email": "blefnk@gmail.com",