@reliverse/rempts 2.2.9 → 2.3.1
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 +213 -1431
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +51 -0
- package/dist/create-project.d.ts +14 -0
- package/dist/create-project.js +84 -0
- package/dist/create.d.ts +11 -0
- package/dist/create.js +62 -0
- package/dist/mod.d.ts +4 -6
- package/dist/mod.js +7 -6
- package/dist/template-engine.d.ts +27 -0
- package/dist/template-engine.js +145 -0
- package/dist/types.d.ts +45 -0
- package/package.json +41 -39
- package/src/cli.ts +64 -0
- package/templates/advanced/README.md +118 -0
- package/templates/advanced/dler.config.ts +41 -0
- package/templates/advanced/package.json +42 -0
- package/templates/advanced/src/commands/config.ts +157 -0
- package/templates/advanced/src/commands/init.ts +149 -0
- package/templates/advanced/src/commands/serve.ts +172 -0
- package/templates/advanced/src/commands/validate.ts +130 -0
- package/templates/advanced/src/mod.ts +44 -0
- package/templates/advanced/src/utils/config.ts +83 -0
- package/templates/advanced/src/utils/constants.ts +12 -0
- package/templates/advanced/src/utils/glob.ts +49 -0
- package/templates/advanced/src/utils/validator.ts +128 -0
- package/templates/advanced/template.json +40 -0
- package/templates/advanced/tsconfig.json +23 -0
- package/templates/basic/README.md +41 -0
- package/templates/basic/dler.config.ts +40 -0
- package/templates/basic/package.json +31 -0
- package/templates/basic/src/commands/hello.ts +26 -0
- package/templates/basic/src/mod.ts +13 -0
- package/templates/basic/template.json +27 -0
- package/templates/basic/tsconfig.json +19 -0
- package/templates/monorepo/README.md +74 -0
- package/templates/monorepo/dler.config.ts +45 -0
- package/templates/monorepo/package.json +30 -0
- package/templates/monorepo/packages/cli/package.json +40 -0
- package/templates/monorepo/packages/cli/src/mod.ts +22 -0
- package/templates/monorepo/packages/cli/tsconfig.json +13 -0
- package/templates/monorepo/packages/core/package.json +33 -0
- package/templates/monorepo/packages/core/scripts/build.ts +18 -0
- package/templates/monorepo/packages/core/src/commands/analyze.ts +87 -0
- package/templates/monorepo/packages/core/src/commands/process.ts +57 -0
- package/templates/monorepo/packages/core/src/mod.ts +3 -0
- package/templates/monorepo/packages/core/src/types.ts +21 -0
- package/templates/monorepo/packages/core/tsconfig.json +14 -0
- package/templates/monorepo/packages/utils/package.json +27 -0
- package/templates/monorepo/packages/utils/scripts/build.ts +17 -0
- package/templates/monorepo/packages/utils/src/format.ts +29 -0
- package/templates/monorepo/packages/utils/src/json.ts +11 -0
- package/templates/monorepo/packages/utils/src/logger.ts +19 -0
- package/templates/monorepo/packages/utils/src/mod.ts +3 -0
- package/templates/monorepo/packages/utils/tsconfig.json +13 -0
- package/templates/monorepo/template.json +27 -0
- package/templates/monorepo/tsconfig.json +14 -0
- package/templates/monorepo/turbo.json +28 -0
- package/LICENSE +0 -21
- package/cleanup.mjs +0 -33
- package/dist/cancel.d.ts +0 -31
- package/dist/cancel.js +0 -28
- package/dist/ffi.d.ts +0 -1
- package/dist/ffi.js +0 -165
- package/dist/group.d.ts +0 -16
- package/dist/group.js +0 -22
- package/dist/launcher/command.d.ts +0 -8
- package/dist/launcher/command.js +0 -10
- package/dist/launcher/discovery.d.ts +0 -3
- package/dist/launcher/discovery.js +0 -207
- package/dist/launcher/errors.d.ts +0 -15
- package/dist/launcher/errors.js +0 -31
- package/dist/launcher/help.d.ts +0 -3
- package/dist/launcher/help.js +0 -145
- package/dist/launcher/mod.d.ts +0 -12
- package/dist/launcher/mod.js +0 -222
- package/dist/launcher/parser.d.ts +0 -14
- package/dist/launcher/parser.js +0 -255
- package/dist/launcher/registry.d.ts +0 -10
- package/dist/launcher/registry.js +0 -42
- package/dist/launcher/types.d.ts +0 -78
- package/dist/launcher/validator.d.ts +0 -3
- package/dist/launcher/validator.js +0 -39
- package/dist/prompt.d.ts +0 -13
- package/dist/prompt.js +0 -53
- package/dist/selection.d.ts +0 -92
- package/dist/selection.js +0 -191
- package/dist/spinner.d.ts +0 -26
- package/dist/spinner.js +0 -141
- package/dist/utils.d.ts +0 -3
- package/dist/utils.js +0 -11
- /package/dist/{launcher/types.js → types.js} +0 -0
package/dist/launcher/help.js
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import pMap from "@reliverse/mapkit";
|
|
2
|
-
import { re } from "@reliverse/relico";
|
|
3
|
-
const HELP_TEMPLATES = {
|
|
4
|
-
commandHeader: (name, description) => `
|
|
5
|
-
${re.bold.cyan(name)} - ${re.gray(description)}`,
|
|
6
|
-
version: (version) => `${re.yellow("Version:")} ${re.white(version)}`,
|
|
7
|
-
usage: (name) => `
|
|
8
|
-
${re.bold("Usage:")}
|
|
9
|
-
${re.green(name)} ${re.gray("[options]")}`,
|
|
10
|
-
usageWithSubCommands: (name) => `
|
|
11
|
-
${re.bold("Usage:")}
|
|
12
|
-
${re.green(name)} ${re.gray("[subcommand] [options]")}`,
|
|
13
|
-
usageWithPositionals: (name, positionalStr) => `
|
|
14
|
-
${re.bold("Usage:")}
|
|
15
|
-
${re.green(name)} ${positionalStr} ${re.gray("[options]")}`,
|
|
16
|
-
optionsHeader: `
|
|
17
|
-
${re.bold("Options:")}`,
|
|
18
|
-
argumentsHeader: `
|
|
19
|
-
${re.bold("Arguments:")}`,
|
|
20
|
-
requiredNote: `
|
|
21
|
-
${re.red("*")} = ${re.gray("required")}`,
|
|
22
|
-
examplesHeader: `
|
|
23
|
-
${re.bold("Examples:")}`,
|
|
24
|
-
globalHeader: `
|
|
25
|
-
${re.bold("Available commands:")}
|
|
26
|
-
`,
|
|
27
|
-
helpFooter: `
|
|
28
|
-
${re.gray('Use "command --help" for command-specific help')}
|
|
29
|
-
`
|
|
30
|
-
};
|
|
31
|
-
const getPositionalName = (name) => {
|
|
32
|
-
return name.toUpperCase();
|
|
33
|
-
};
|
|
34
|
-
const formatArgName = (name, def) => {
|
|
35
|
-
const aliases = def.aliases ? re.gray(` (-${def.aliases.join(", -")})`) : "";
|
|
36
|
-
const required = def.required ? re.red("*") : "";
|
|
37
|
-
return `${re.cyan(`--${name}`)}${aliases}${required}`;
|
|
38
|
-
};
|
|
39
|
-
const formatArgType = (def) => {
|
|
40
|
-
if (def.type === "boolean") return "";
|
|
41
|
-
return re.dim(`<${def.type}>`);
|
|
42
|
-
};
|
|
43
|
-
const getArgHelp = (name, def) => {
|
|
44
|
-
const argName = formatArgName(name, def);
|
|
45
|
-
const argType = formatArgType(def);
|
|
46
|
-
const desc = def.description ?? "";
|
|
47
|
-
const defaultVal = "default" in def && def.default !== void 0 ? re.gray(` (default: ${def.default})`) : "";
|
|
48
|
-
const allowedVal = "allowed" in def && def.allowed && def.allowed.length > 0 ? re.gray(
|
|
49
|
-
` (allowed: ${def.allowed.map((v) => typeof v === "string" ? `"${v}"` : String(v)).join(", ")})`
|
|
50
|
-
) : "";
|
|
51
|
-
return ` ${argName} ${argType}
|
|
52
|
-
${desc}${defaultVal}${allowedVal}`;
|
|
53
|
-
};
|
|
54
|
-
const getPositionalArgHelp = (name, def) => {
|
|
55
|
-
const required = def.required ? re.red("*") : "";
|
|
56
|
-
const argName = `${re.cyan(getPositionalName(name))}${required}`;
|
|
57
|
-
const argType = def.type ? re.dim(`<${def.type}>`) : "";
|
|
58
|
-
const desc = def.description ?? "";
|
|
59
|
-
const defaultVal = "default" in def && def.default !== void 0 ? re.gray(` (default: ${def.default})`) : "";
|
|
60
|
-
const allowedVal = "allowed" in def && def.allowed && def.allowed.length > 0 ? re.gray(
|
|
61
|
-
` (allowed: ${def.allowed.map((v) => typeof v === "string" ? `"${v}"` : String(v)).join(", ")})`
|
|
62
|
-
) : "";
|
|
63
|
-
return ` ${argName} ${argType}
|
|
64
|
-
${desc}${defaultVal}${allowedVal}`;
|
|
65
|
-
};
|
|
66
|
-
export const generateCommandHelp = async (definition) => {
|
|
67
|
-
const { meta, args } = definition;
|
|
68
|
-
const lines = [
|
|
69
|
-
HELP_TEMPLATES.commandHeader(
|
|
70
|
-
meta.name,
|
|
71
|
-
meta.description || "No description available"
|
|
72
|
-
)
|
|
73
|
-
];
|
|
74
|
-
if (meta.version) {
|
|
75
|
-
lines.push(HELP_TEMPLATES.version(meta.version));
|
|
76
|
-
}
|
|
77
|
-
const positionalArgs = [];
|
|
78
|
-
const flagArgs = [];
|
|
79
|
-
for (const [name, def] of Object.entries(args)) {
|
|
80
|
-
if (def.positional === true) {
|
|
81
|
-
positionalArgs.push([name, def]);
|
|
82
|
-
} else {
|
|
83
|
-
flagArgs.push([name, def]);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
let positionalStr = "";
|
|
87
|
-
if (positionalArgs.length > 0) {
|
|
88
|
-
const positionalParts = positionalArgs.map(
|
|
89
|
-
([name, def]) => `${def.required ? "" : "["}${getPositionalName(name)}${def.required ? "" : "]"}`
|
|
90
|
-
);
|
|
91
|
-
positionalStr = positionalParts.join(" ");
|
|
92
|
-
}
|
|
93
|
-
if (positionalArgs.length > 0) {
|
|
94
|
-
lines.push(HELP_TEMPLATES.usageWithPositionals(meta.name, positionalStr));
|
|
95
|
-
} else {
|
|
96
|
-
lines.push(HELP_TEMPLATES.usage(meta.name));
|
|
97
|
-
}
|
|
98
|
-
if (positionalArgs.length > 0) {
|
|
99
|
-
lines.push(HELP_TEMPLATES.argumentsHeader);
|
|
100
|
-
for (const [name, def] of positionalArgs) {
|
|
101
|
-
lines.push(getPositionalArgHelp(name, def));
|
|
102
|
-
}
|
|
103
|
-
lines.push(HELP_TEMPLATES.requiredNote);
|
|
104
|
-
}
|
|
105
|
-
if (flagArgs.length > 0) {
|
|
106
|
-
lines.push(HELP_TEMPLATES.optionsHeader);
|
|
107
|
-
for (const [name, def] of flagArgs) {
|
|
108
|
-
lines.push(getArgHelp(name, def));
|
|
109
|
-
}
|
|
110
|
-
if (positionalArgs.length === 0) {
|
|
111
|
-
lines.push(HELP_TEMPLATES.requiredNote);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (meta.examples && meta.examples.length > 0) {
|
|
115
|
-
lines.push(HELP_TEMPLATES.examplesHeader);
|
|
116
|
-
for (const example of meta.examples) {
|
|
117
|
-
lines.push(` ${re.cyan(example)}`);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return lines.join("\n");
|
|
121
|
-
};
|
|
122
|
-
const formatCommandHelp = (name, metadata) => {
|
|
123
|
-
const aliases = metadata.aliases ? re.gray(` (${metadata.aliases.join(", ")})`) : "";
|
|
124
|
-
const description = metadata.description || "No description available";
|
|
125
|
-
return ` ${re.cyan(name)}${aliases}
|
|
126
|
-
${re.gray(description)}`;
|
|
127
|
-
};
|
|
128
|
-
export const generateGlobalHelp = async (registry) => {
|
|
129
|
-
const lines = [HELP_TEMPLATES.globalHeader];
|
|
130
|
-
const metadataResults = await pMap(
|
|
131
|
-
Array.from(registry.metadata.entries()),
|
|
132
|
-
async ([name, metadataLoader]) => {
|
|
133
|
-
const metadata = await metadataLoader();
|
|
134
|
-
return [name, metadata];
|
|
135
|
-
},
|
|
136
|
-
{ concurrency: 5 }
|
|
137
|
-
// Limit concurrency for metadata loading
|
|
138
|
-
);
|
|
139
|
-
metadataResults.sort(([a], [b]) => a.localeCompare(b));
|
|
140
|
-
for (const [name, metadata] of metadataResults) {
|
|
141
|
-
lines.push(formatCommandHelp(name, metadata));
|
|
142
|
-
}
|
|
143
|
-
lines.push(HELP_TEMPLATES.helpFooter);
|
|
144
|
-
return lines.join("\n");
|
|
145
|
-
};
|
package/dist/launcher/mod.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { LauncherError } from "./errors.js";
|
|
2
|
-
export { defineArgs, defineCommand } from "./command.js";
|
|
3
|
-
export { ArgumentValidationError, CommandLoadError, CommandNotFoundError, LauncherError, } from "./errors.js";
|
|
4
|
-
export type { CmdArgDefinition, CmdArgsSchema, CmdDefinition, CmdHandler, CmdLoader, CmdMeta, CmdRegistry, DiscoveryResult, ParsedArgs, } from "./types.js";
|
|
5
|
-
export type PackageManager = "bun" | "npm" | "yarn" | "pnpm";
|
|
6
|
-
export interface LauncherOptions {
|
|
7
|
-
cmdsDir?: string;
|
|
8
|
-
onError?: (error: LauncherError) => void;
|
|
9
|
-
verbose?: boolean;
|
|
10
|
-
supportedPkgManagers?: PackageManager[];
|
|
11
|
-
}
|
|
12
|
-
export declare const runLauncher: (importMetaUrl: string, options?: LauncherOptions) => Promise<void>;
|
package/dist/launcher/mod.js
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { writeErrorLines } from "@reliverse/helpers";
|
|
5
|
-
import { re } from "@reliverse/relico";
|
|
6
|
-
import { logger } from "@reliverse/relinka";
|
|
7
|
-
import { discoverCommands } from "./discovery.js";
|
|
8
|
-
import {
|
|
9
|
-
CommandLoadError,
|
|
10
|
-
CommandNotFoundError,
|
|
11
|
-
LauncherError
|
|
12
|
-
} from "./errors.js";
|
|
13
|
-
import { generateCommandHelp, generateGlobalHelp } from "./help.js";
|
|
14
|
-
import { kebabCase, parseArgs } from "./parser.js";
|
|
15
|
-
import {
|
|
16
|
-
clearRegistry,
|
|
17
|
-
getRegistry,
|
|
18
|
-
resolveCommand,
|
|
19
|
-
setRegistry
|
|
20
|
-
} from "./registry.js";
|
|
21
|
-
export { defineArgs, defineCommand } from "./command.js";
|
|
22
|
-
export {
|
|
23
|
-
ArgumentValidationError,
|
|
24
|
-
CommandLoadError,
|
|
25
|
-
CommandNotFoundError,
|
|
26
|
-
LauncherError
|
|
27
|
-
} from "./errors.js";
|
|
28
|
-
const getCallerDirectory = (importMetaUrl) => {
|
|
29
|
-
return dirname(fileURLToPath(importMetaUrl));
|
|
30
|
-
};
|
|
31
|
-
const detectPackageManager = (cwd) => {
|
|
32
|
-
if (typeof process.versions.bun !== "undefined") {
|
|
33
|
-
return "bun";
|
|
34
|
-
}
|
|
35
|
-
if (existsSync(join(cwd, "pnpm-lock.yaml"))) {
|
|
36
|
-
return "pnpm";
|
|
37
|
-
}
|
|
38
|
-
if (existsSync(join(cwd, "yarn.lock"))) {
|
|
39
|
-
return "yarn";
|
|
40
|
-
}
|
|
41
|
-
if (existsSync(join(cwd, "package-lock.json"))) {
|
|
42
|
-
return "npm";
|
|
43
|
-
}
|
|
44
|
-
try {
|
|
45
|
-
const packageJsonPath = join(cwd, "package.json");
|
|
46
|
-
if (existsSync(packageJsonPath)) {
|
|
47
|
-
const content = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
48
|
-
if (content.packageManager) {
|
|
49
|
-
const pkgManager = content.packageManager.split("@")[0];
|
|
50
|
-
if (pkgManager === "bun" || pkgManager === "npm" || pkgManager === "yarn" || pkgManager === "pnpm") {
|
|
51
|
-
return pkgManager;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
} catch {
|
|
56
|
-
}
|
|
57
|
-
const userAgent = process.env.npm_config_user_agent || "";
|
|
58
|
-
if (userAgent.includes("pnpm")) {
|
|
59
|
-
return "pnpm";
|
|
60
|
-
}
|
|
61
|
-
if (userAgent.includes("yarn")) {
|
|
62
|
-
return "yarn";
|
|
63
|
-
}
|
|
64
|
-
if (userAgent.includes("npm")) {
|
|
65
|
-
return "npm";
|
|
66
|
-
}
|
|
67
|
-
return "npm";
|
|
68
|
-
};
|
|
69
|
-
export const runLauncher = async (importMetaUrl, options = {}) => {
|
|
70
|
-
const {
|
|
71
|
-
cmdsDir = "./cmds",
|
|
72
|
-
onError,
|
|
73
|
-
verbose = false,
|
|
74
|
-
supportedPkgManagers
|
|
75
|
-
} = options;
|
|
76
|
-
if (supportedPkgManagers && supportedPkgManagers.length > 0) {
|
|
77
|
-
const callerDir = getCallerDirectory(importMetaUrl);
|
|
78
|
-
const detectedPkgManager = detectPackageManager(callerDir);
|
|
79
|
-
if (!supportedPkgManagers.includes(detectedPkgManager)) {
|
|
80
|
-
const errorMessage = `\u274C Unsupported package manager: ${detectedPkgManager}. Supported: ${supportedPkgManagers.join(", ")}`;
|
|
81
|
-
if (onError) {
|
|
82
|
-
onError(new LauncherError(errorMessage, "UNSUPPORTED_PKG_MANAGER"));
|
|
83
|
-
} else {
|
|
84
|
-
writeErrorLines([`
|
|
85
|
-
${re.red.bold(errorMessage)}
|
|
86
|
-
`]);
|
|
87
|
-
}
|
|
88
|
-
process.exit(1);
|
|
89
|
-
}
|
|
90
|
-
if (verbose) {
|
|
91
|
-
console.debug(`\u2713 Package manager: ${detectedPkgManager}`);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
try {
|
|
95
|
-
clearRegistry();
|
|
96
|
-
let registry = getRegistry();
|
|
97
|
-
if (!registry) {
|
|
98
|
-
const callerDir = getCallerDirectory(importMetaUrl);
|
|
99
|
-
if (verbose) {
|
|
100
|
-
console.debug(`\u{1F4CD} Caller directory: ${callerDir}`);
|
|
101
|
-
}
|
|
102
|
-
registry = await discoverCommands(cmdsDir, callerDir, verbose);
|
|
103
|
-
setRegistry(registry);
|
|
104
|
-
}
|
|
105
|
-
const argv = process.argv.slice(2);
|
|
106
|
-
if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") {
|
|
107
|
-
logger.log(await generateGlobalHelp(registry));
|
|
108
|
-
process.exit(0);
|
|
109
|
-
}
|
|
110
|
-
let isSubCommand = false;
|
|
111
|
-
let parentName;
|
|
112
|
-
let subCommandName;
|
|
113
|
-
let parentNode;
|
|
114
|
-
let subCommandNode;
|
|
115
|
-
if (argv.length > 1 && !argv[1]?.startsWith("-")) {
|
|
116
|
-
const potentialParentName = resolveCommand(registry, argv[0]);
|
|
117
|
-
const potentialParentNode = registry.hierarchy.get(potentialParentName);
|
|
118
|
-
if (potentialParentNode && potentialParentNode.children.size > 0) {
|
|
119
|
-
const potentialSubCommandName = resolveCommand(registry, argv[1]);
|
|
120
|
-
const potentialSubCommandNode = registry.hierarchy.get(
|
|
121
|
-
potentialSubCommandName
|
|
122
|
-
);
|
|
123
|
-
if (potentialSubCommandNode && potentialSubCommandNode.parent === potentialParentName) {
|
|
124
|
-
isSubCommand = true;
|
|
125
|
-
parentName = potentialParentName;
|
|
126
|
-
subCommandName = potentialSubCommandName;
|
|
127
|
-
parentNode = potentialParentNode;
|
|
128
|
-
subCommandNode = potentialSubCommandNode;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
if (isSubCommand && parentName && subCommandName && parentNode && subCommandNode) {
|
|
133
|
-
const parentDefinition = await parentNode.loader();
|
|
134
|
-
const subCommandDefinition = await subCommandNode.loader();
|
|
135
|
-
if (argv.includes("--help") || argv.includes("-h")) {
|
|
136
|
-
logger.log(await generateCommandHelp(subCommandDefinition));
|
|
137
|
-
process.exit(0);
|
|
138
|
-
}
|
|
139
|
-
const subCommandIndex = argv.findIndex(
|
|
140
|
-
(arg, index) => index > 0 && !arg.startsWith("-")
|
|
141
|
-
);
|
|
142
|
-
const parentArgs = [];
|
|
143
|
-
const subCommandArgsFiltered = [];
|
|
144
|
-
for (let i = 1; i < argv.length; i++) {
|
|
145
|
-
const arg = argv[i];
|
|
146
|
-
if (i === subCommandIndex) {
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
const isParentArg = Object.keys(parentDefinition.args).some((key) => {
|
|
150
|
-
const def = parentDefinition.args[key];
|
|
151
|
-
if (!def) return false;
|
|
152
|
-
const kebabKey = kebabCase(key);
|
|
153
|
-
return arg === `--${key}` || arg === `-${key}` || arg === `--${kebabKey}` || arg === `--no-${key}` || arg === `--no-${kebabKey}` || def.aliases?.some((alias) => {
|
|
154
|
-
const kebabAlias = kebabCase(alias);
|
|
155
|
-
return arg === `-${alias}` || arg === `--${alias}` || arg === `--${kebabAlias}` || arg === `--no-${alias}` || arg === `--no-${kebabAlias}`;
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
if (isParentArg) {
|
|
159
|
-
parentArgs.push(arg);
|
|
160
|
-
if (i + 1 < argv.length && !argv[i + 1]?.startsWith("-")) {
|
|
161
|
-
parentArgs.push(argv[i + 1]);
|
|
162
|
-
i++;
|
|
163
|
-
}
|
|
164
|
-
} else {
|
|
165
|
-
subCommandArgsFiltered.push(arg);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
let parentParsedArgs = {};
|
|
169
|
-
if (parentArgs.length > 0) {
|
|
170
|
-
const { parsedArgs } = parseArgs(
|
|
171
|
-
[parentName, ...parentArgs],
|
|
172
|
-
parentDefinition.args
|
|
173
|
-
);
|
|
174
|
-
parentParsedArgs = parsedArgs;
|
|
175
|
-
}
|
|
176
|
-
const { parsedArgs: subCommandParsedArgs } = parseArgs(
|
|
177
|
-
[subCommandName, ...subCommandArgsFiltered],
|
|
178
|
-
subCommandDefinition.args
|
|
179
|
-
);
|
|
180
|
-
await subCommandDefinition.handler({
|
|
181
|
-
args: subCommandParsedArgs,
|
|
182
|
-
parentArgs: parentParsedArgs
|
|
183
|
-
});
|
|
184
|
-
} else {
|
|
185
|
-
const cmdNameOrAlias = argv[0];
|
|
186
|
-
const cmdName = resolveCommand(registry, cmdNameOrAlias);
|
|
187
|
-
const loader = registry.registry.get(cmdName);
|
|
188
|
-
if (!loader) {
|
|
189
|
-
throw new CommandNotFoundError(
|
|
190
|
-
cmdNameOrAlias,
|
|
191
|
-
Array.from(registry.registry.keys())
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
const definition = await loader();
|
|
195
|
-
if (argv.includes("--help") || argv.includes("-h")) {
|
|
196
|
-
logger.log(await generateCommandHelp(definition));
|
|
197
|
-
process.exit(0);
|
|
198
|
-
}
|
|
199
|
-
const { parsedArgs } = parseArgs(argv, definition.args);
|
|
200
|
-
await definition.handler({ args: parsedArgs });
|
|
201
|
-
}
|
|
202
|
-
} catch (error) {
|
|
203
|
-
if (error instanceof LauncherError) {
|
|
204
|
-
if (onError) {
|
|
205
|
-
onError(error);
|
|
206
|
-
} else {
|
|
207
|
-
const errorLines = [
|
|
208
|
-
`
|
|
209
|
-
${re.red.bold("\u274C Error:")} ${re.red(error.message)}`
|
|
210
|
-
];
|
|
211
|
-
if (error instanceof CommandLoadError && error.cause) {
|
|
212
|
-
errorLines.push(`${re.yellow("Cause:")} ${error.cause}`);
|
|
213
|
-
}
|
|
214
|
-
errorLines.push("");
|
|
215
|
-
writeErrorLines(errorLines);
|
|
216
|
-
}
|
|
217
|
-
process.exit(1);
|
|
218
|
-
} else {
|
|
219
|
-
throw error;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { CmdArgsSchema } from "./types.js";
|
|
2
|
-
interface ParseResult {
|
|
3
|
-
cmdName: string;
|
|
4
|
-
parsedArgs: Record<string, unknown>;
|
|
5
|
-
}
|
|
6
|
-
interface ChainParseResult {
|
|
7
|
-
cmdChain: string[];
|
|
8
|
-
parsedArgs: Record<string, unknown>[];
|
|
9
|
-
remainingArgs: string[];
|
|
10
|
-
}
|
|
11
|
-
export declare const kebabCase: (str: string) => string;
|
|
12
|
-
export declare const parseArgs: (argv: string[], schema: CmdArgsSchema) => ParseResult;
|
|
13
|
-
export declare const parseCommandChain: (argv: string[], schemas: CmdArgsSchema[]) => ChainParseResult;
|
|
14
|
-
export {};
|
package/dist/launcher/parser.js
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
import { ArgumentValidationError } from "./errors.js";
|
|
2
|
-
import { validateArgValue } from "./validator.js";
|
|
3
|
-
const camelCase = (str) => str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
4
|
-
export const kebabCase = (str) => {
|
|
5
|
-
if (!str) return str;
|
|
6
|
-
let result = str.replace(
|
|
7
|
-
/([a-z])([0-9])([A-Z])/g,
|
|
8
|
-
(_, g1, g2, g3) => `${g1}-${g2}${g3}`
|
|
9
|
-
);
|
|
10
|
-
result = result.replace(
|
|
11
|
-
/([a-z0-9])([A-Z])/g,
|
|
12
|
-
(match, g1, g2, offset, string) => {
|
|
13
|
-
if (offset > 0 && string[offset - 1] === "-") {
|
|
14
|
-
return match;
|
|
15
|
-
}
|
|
16
|
-
return `${g1}-${g2}`;
|
|
17
|
-
}
|
|
18
|
-
);
|
|
19
|
-
result = result.replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2");
|
|
20
|
-
return result.toLowerCase();
|
|
21
|
-
};
|
|
22
|
-
const createSchemaMetadata = (schema) => {
|
|
23
|
-
const aliasMap = /* @__PURE__ */ new Map();
|
|
24
|
-
const camelCaseCache = /* @__PURE__ */ new Map();
|
|
25
|
-
const kebabCaseMap = /* @__PURE__ */ new Map();
|
|
26
|
-
const defaults = {};
|
|
27
|
-
const requiredKeys = /* @__PURE__ */ new Set();
|
|
28
|
-
const availableKeys = [];
|
|
29
|
-
for (const [key, def] of Object.entries(schema)) {
|
|
30
|
-
availableKeys.push(key);
|
|
31
|
-
const camelKey = camelCase(key);
|
|
32
|
-
if (camelKey !== key) {
|
|
33
|
-
camelCaseCache.set(key, camelKey);
|
|
34
|
-
}
|
|
35
|
-
const kebabKey = kebabCase(key);
|
|
36
|
-
if (kebabKey !== key) {
|
|
37
|
-
kebabCaseMap.set(kebabKey, key);
|
|
38
|
-
}
|
|
39
|
-
if (def.aliases) {
|
|
40
|
-
for (const alias of def.aliases) {
|
|
41
|
-
aliasMap.set(alias, key);
|
|
42
|
-
const camelAlias = camelCase(alias);
|
|
43
|
-
if (camelAlias !== alias) {
|
|
44
|
-
camelCaseCache.set(alias, camelAlias);
|
|
45
|
-
}
|
|
46
|
-
const kebabAlias = kebabCase(alias);
|
|
47
|
-
if (kebabAlias !== alias) {
|
|
48
|
-
kebabCaseMap.set(kebabAlias, key);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
if ("default" in def && def.default !== void 0) {
|
|
53
|
-
if ("allowed" in def && def.allowed) {
|
|
54
|
-
if (!def.allowed.includes(def.default)) {
|
|
55
|
-
const allowedValues = def.allowed.map((v) => typeof v === "string" ? `"${v}"` : String(v)).join(", ");
|
|
56
|
-
throw new ArgumentValidationError(
|
|
57
|
-
key,
|
|
58
|
-
`Default value must be one of: ${allowedValues}. Got: ${typeof def.default === "string" ? `"${def.default}"` : def.default}`
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
defaults[key] = def.default;
|
|
63
|
-
}
|
|
64
|
-
if (def.required) {
|
|
65
|
-
requiredKeys.add(key);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
aliasMap,
|
|
70
|
-
camelCaseCache,
|
|
71
|
-
kebabCaseMap,
|
|
72
|
-
defaults,
|
|
73
|
-
requiredKeys,
|
|
74
|
-
availableKeys
|
|
75
|
-
};
|
|
76
|
-
};
|
|
77
|
-
const getSchemaMetadata = (schema) => {
|
|
78
|
-
return createSchemaMetadata(schema);
|
|
79
|
-
};
|
|
80
|
-
export const parseArgs = (argv, schema) => {
|
|
81
|
-
const [cmdName, ...rawArgs] = argv;
|
|
82
|
-
if (!cmdName) {
|
|
83
|
-
throw new ArgumentValidationError("command", "No command provided");
|
|
84
|
-
}
|
|
85
|
-
const positionalKeys = Object.entries(schema).filter(([, def]) => def.positional === true).map(([key]) => key);
|
|
86
|
-
return parseArgsWithPositionalSupport(
|
|
87
|
-
cmdName,
|
|
88
|
-
rawArgs,
|
|
89
|
-
schema,
|
|
90
|
-
positionalKeys
|
|
91
|
-
);
|
|
92
|
-
};
|
|
93
|
-
const parseArgsWithPositionalSupport = (cmdName, rawArgs, schema, positionalKeys) => {
|
|
94
|
-
const {
|
|
95
|
-
aliasMap,
|
|
96
|
-
camelCaseCache,
|
|
97
|
-
kebabCaseMap,
|
|
98
|
-
defaults,
|
|
99
|
-
requiredKeys,
|
|
100
|
-
availableKeys
|
|
101
|
-
} = getSchemaMetadata(schema);
|
|
102
|
-
const parsedArgs = { ...defaults };
|
|
103
|
-
let positionalIndex = 0;
|
|
104
|
-
for (let i = 0; i < rawArgs.length; i++) {
|
|
105
|
-
const arg = rawArgs[i];
|
|
106
|
-
if (!arg || !arg.startsWith("-")) {
|
|
107
|
-
if (!arg) continue;
|
|
108
|
-
if (positionalIndex < positionalKeys.length) {
|
|
109
|
-
const positionalKey = positionalKeys[positionalIndex];
|
|
110
|
-
const definition2 = schema[positionalKey];
|
|
111
|
-
let value2 = arg;
|
|
112
|
-
if (definition2.type === "number") {
|
|
113
|
-
value2 = Number(arg);
|
|
114
|
-
if (Number.isNaN(value2)) {
|
|
115
|
-
throw new ArgumentValidationError(
|
|
116
|
-
positionalKey,
|
|
117
|
-
`Expected number for positional argument "${positionalKey}", got "${arg}"`
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
validateArgValue(positionalKey, value2, definition2);
|
|
122
|
-
parsedArgs[positionalKey] = value2;
|
|
123
|
-
positionalIndex++;
|
|
124
|
-
} else {
|
|
125
|
-
throw new ArgumentValidationError(
|
|
126
|
-
`positional_${positionalIndex}`,
|
|
127
|
-
`Too many positional arguments. Expected ${positionalKeys.length}, got at least ${positionalIndex + 1}`
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
const isLongForm = arg.startsWith("--");
|
|
133
|
-
let flagName = arg.slice(isLongForm ? 2 : 1);
|
|
134
|
-
let isNegated = false;
|
|
135
|
-
if (isLongForm && flagName.startsWith("no-")) {
|
|
136
|
-
flagName = flagName.slice(3);
|
|
137
|
-
isNegated = true;
|
|
138
|
-
}
|
|
139
|
-
const actualKey = aliasMap.get(flagName) ?? kebabCaseMap.get(flagName) ?? camelCaseCache.get(flagName) ?? camelCase(flagName);
|
|
140
|
-
const definition = schema[actualKey];
|
|
141
|
-
if (!definition) {
|
|
142
|
-
throw new ArgumentValidationError(
|
|
143
|
-
flagName,
|
|
144
|
-
`Unknown argument. Available: ${availableKeys.join(", ")}`
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
if (definition.type === "boolean") {
|
|
148
|
-
if (isNegated) {
|
|
149
|
-
const nextArg3 = rawArgs[i + 1];
|
|
150
|
-
if (nextArg3 !== void 0 && !nextArg3.startsWith("-")) {
|
|
151
|
-
const lowerNext = nextArg3.toLowerCase();
|
|
152
|
-
if (lowerNext === "true" || lowerNext === "false" || lowerNext === "1" || lowerNext === "0" || lowerNext === "yes" || lowerNext === "no" || lowerNext === "on" || lowerNext === "off") {
|
|
153
|
-
throw new ArgumentValidationError(
|
|
154
|
-
flagName,
|
|
155
|
-
`--no-* flags cannot accept values. Use --${flagName} ${nextArg3} instead of --no-${flagName} ${nextArg3}`
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
const falseValue = false;
|
|
160
|
-
validateArgValue(actualKey, falseValue, definition);
|
|
161
|
-
parsedArgs[actualKey] = falseValue;
|
|
162
|
-
continue;
|
|
163
|
-
}
|
|
164
|
-
const nextArg2 = rawArgs[i + 1];
|
|
165
|
-
if (nextArg2 !== void 0 && !nextArg2.startsWith("-")) {
|
|
166
|
-
const lowerNext = nextArg2.toLowerCase();
|
|
167
|
-
if (lowerNext === "true" || lowerNext === "1" || lowerNext === "yes" || lowerNext === "on") {
|
|
168
|
-
const trueValue2 = true;
|
|
169
|
-
validateArgValue(actualKey, trueValue2, definition);
|
|
170
|
-
parsedArgs[actualKey] = trueValue2;
|
|
171
|
-
i++;
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
if (lowerNext === "false" || lowerNext === "0" || lowerNext === "no" || lowerNext === "off") {
|
|
175
|
-
const falseValue = false;
|
|
176
|
-
validateArgValue(actualKey, falseValue, definition);
|
|
177
|
-
parsedArgs[actualKey] = falseValue;
|
|
178
|
-
i++;
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
const trueValue = true;
|
|
183
|
-
validateArgValue(actualKey, trueValue, definition);
|
|
184
|
-
parsedArgs[actualKey] = trueValue;
|
|
185
|
-
continue;
|
|
186
|
-
}
|
|
187
|
-
const nextArg = rawArgs[++i];
|
|
188
|
-
if (nextArg === void 0 || nextArg.startsWith("-")) {
|
|
189
|
-
throw new ArgumentValidationError(
|
|
190
|
-
flagName,
|
|
191
|
-
`Expected value for argument "${flagName}"`
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
let value = nextArg;
|
|
195
|
-
if (definition.type === "number") {
|
|
196
|
-
value = Number(nextArg);
|
|
197
|
-
if (Number.isNaN(value)) {
|
|
198
|
-
throw new ArgumentValidationError(
|
|
199
|
-
flagName,
|
|
200
|
-
`Expected number, got "${nextArg}"`
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
validateArgValue(actualKey, value, definition);
|
|
205
|
-
parsedArgs[actualKey] = value;
|
|
206
|
-
}
|
|
207
|
-
for (const requiredKey of requiredKeys) {
|
|
208
|
-
if (!(requiredKey in parsedArgs)) {
|
|
209
|
-
throw new ArgumentValidationError(
|
|
210
|
-
requiredKey,
|
|
211
|
-
`Required argument "${requiredKey}" is missing`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return { cmdName, parsedArgs };
|
|
216
|
-
};
|
|
217
|
-
export const parseCommandChain = (argv, schemas) => {
|
|
218
|
-
const cmdChain = [];
|
|
219
|
-
const parsedArgs = [];
|
|
220
|
-
let remainingArgs = [...argv];
|
|
221
|
-
for (let i = 0; i < schemas.length; i++) {
|
|
222
|
-
const schema = schemas[i];
|
|
223
|
-
if (!schema) break;
|
|
224
|
-
let cmdName = "";
|
|
225
|
-
let argsStartIndex = 0;
|
|
226
|
-
for (let j = 0; j < remainingArgs.length; j++) {
|
|
227
|
-
const arg = remainingArgs[j];
|
|
228
|
-
if (arg && !arg.startsWith("-")) {
|
|
229
|
-
cmdName = arg;
|
|
230
|
-
argsStartIndex = j + 1;
|
|
231
|
-
break;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
if (!cmdName) {
|
|
235
|
-
throw new ArgumentValidationError("command", "No command provided");
|
|
236
|
-
}
|
|
237
|
-
cmdChain.push(cmdName);
|
|
238
|
-
const commandArgs = [];
|
|
239
|
-
for (let j = argsStartIndex; j < remainingArgs.length; j++) {
|
|
240
|
-
const arg = remainingArgs[j];
|
|
241
|
-
if (!arg) continue;
|
|
242
|
-
if (!arg.startsWith("-")) {
|
|
243
|
-
remainingArgs = remainingArgs.slice(j);
|
|
244
|
-
break;
|
|
245
|
-
}
|
|
246
|
-
commandArgs.push(arg);
|
|
247
|
-
}
|
|
248
|
-
const { parsedArgs: cmdParsedArgs } = parseArgs(
|
|
249
|
-
[cmdName, ...commandArgs],
|
|
250
|
-
schema
|
|
251
|
-
);
|
|
252
|
-
parsedArgs.push(cmdParsedArgs);
|
|
253
|
-
}
|
|
254
|
-
return { cmdChain, parsedArgs, remainingArgs };
|
|
255
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { CmdNode, DiscoveryResult } from "./types.js";
|
|
2
|
-
export declare const getRegistry: () => DiscoveryResult | null;
|
|
3
|
-
export declare const setRegistry: (registry: DiscoveryResult) => void;
|
|
4
|
-
export declare const clearRegistry: () => void;
|
|
5
|
-
export declare const resolveCommand: (registry: DiscoveryResult, cmdNameOrAlias: string) => string;
|
|
6
|
-
export declare const resolveCommandChain: (registry: DiscoveryResult, cmdChain: string[]) => {
|
|
7
|
-
parent?: CmdNode;
|
|
8
|
-
child?: CmdNode;
|
|
9
|
-
fullPath: string[];
|
|
10
|
-
};
|