@reliverse/dler 1.7.72 → 1.7.74

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.
Files changed (43) hide show
  1. package/README.md +2 -2
  2. package/bin/app/agg/cmd.d.ts +40 -0
  3. package/bin/app/agg/cmd.js +833 -27
  4. package/bin/app/build/postbuild.js +1 -0
  5. package/bin/app/cmds.d.ts +230 -4
  6. package/bin/app/cmds.js +36 -19
  7. package/bin/app/config/cmd.d.ts +18 -0
  8. package/bin/app/config/cmd.js +43 -0
  9. package/bin/app/config/impl/typebox.d.ts +8 -0
  10. package/bin/app/config/impl/typebox.js +82 -0
  11. package/bin/app/mkdist/cmd.js +1 -1
  12. package/bin/app/pub/cmd.js +1 -1
  13. package/bin/app/rempts/cmd.js +146 -8
  14. package/bin/cli.js +14 -20
  15. package/bin/libs/cfg/cfg-impl/{cfg-types.d.ts → cfg-dler.d.ts} +76 -0
  16. package/bin/libs/cfg/cfg-mod.d.ts +2 -2
  17. package/bin/libs/cfg/cfg-mod.js +1 -1
  18. package/bin/libs/get/get-impl/get-core.d.ts +3 -0
  19. package/bin/libs/get/get-impl/get-core.js +450 -0
  20. package/bin/libs/get/get-mod.d.ts +0 -6
  21. package/bin/libs/get/get-mod.js +38 -459
  22. package/bin/libs/sdk/sdk-impl/build/providers/bun/single-file.d.ts +2 -2
  23. package/bin/libs/sdk/sdk-impl/config/core.d.ts +8 -0
  24. package/bin/libs/sdk/sdk-impl/config/core.js +231 -0
  25. package/bin/libs/sdk/sdk-impl/config/info.js +1 -1
  26. package/bin/libs/sdk/sdk-impl/config/{init.js → prepare.js} +4 -35
  27. package/bin/libs/sdk/sdk-impl/magic/magic-spells.js +2 -1
  28. package/bin/libs/sdk/sdk-impl/utils/pm/pm-meta.d.ts +1 -1
  29. package/bin/libs/sdk/sdk-impl/utils/pm/pm-meta.js +2 -2
  30. package/bin/libs/sdk/sdk-impl/utils/resolve-cross-libs.d.ts +1 -3
  31. package/bin/libs/sdk/sdk-impl/utils/resolve-cross-libs.js +432 -9
  32. package/bin/libs/sdk/sdk-mod.d.ts +7 -4
  33. package/bin/libs/sdk/sdk-mod.js +18 -7
  34. package/bin/mod.js +4 -1
  35. package/package.json +5 -5
  36. package/bin/app/agg/impl.d.ts +0 -39
  37. package/bin/app/agg/impl.js +0 -341
  38. package/bin/app/agg/run.d.ts +0 -1
  39. package/bin/app/agg/run.js +0 -136
  40. package/bin/libs/cfg/cfg-impl/cfg-consts.d.ts +0 -77
  41. package/bin/libs/cfg/cfg-impl/cfg-types.js +0 -0
  42. /package/bin/libs/cfg/cfg-impl/{cfg-consts.js → cfg-dler.js} +0 -0
  43. /package/bin/libs/sdk/sdk-impl/config/{init.d.ts → prepare.d.ts} +0 -0
@@ -14,6 +14,7 @@ export async function dlerPostBuild(isDev, debugDontCopyNonBuildFiles) {
14
14
  relinka("info", "\u2014 \u2014 \u2014 dlerPostBuild \u2014 \u2014 \u2014");
15
15
  const config = await getConfigDler();
16
16
  await resolveAllCrossLibs(
17
+ "package",
17
18
  ALIAS_TO_REPLACE,
18
19
  ["npm", "jsr"],
19
20
  config.buildPreExtensions,
package/bin/app/cmds.d.ts CHANGED
@@ -1,19 +1,245 @@
1
1
  import type { Command } from "@reliverse/rempts";
2
+ interface CommandArgsMap {
3
+ agg: {
4
+ imports?: boolean;
5
+ input?: string;
6
+ named?: boolean;
7
+ out?: string;
8
+ recursive?: boolean;
9
+ strip?: string;
10
+ sort?: boolean;
11
+ header?: string;
12
+ verbose?: boolean;
13
+ includeInternal?: boolean;
14
+ internalMarker?: string;
15
+ override?: boolean;
16
+ extensions?: string;
17
+ separateTypesFile?: boolean;
18
+ typesOut?: string;
19
+ nonInteractive?: boolean;
20
+ };
21
+ build: {
22
+ dev?: boolean;
23
+ debugOnlyCopyNonBuildFiles?: boolean;
24
+ debugDontCopyNonBuildFiles?: boolean;
25
+ };
26
+ build_binary: {
27
+ input?: string;
28
+ targets?: string;
29
+ outdir?: string;
30
+ minify?: boolean;
31
+ sourcemap?: boolean;
32
+ bytecode?: boolean;
33
+ clean?: boolean;
34
+ parallel?: boolean;
35
+ external?: string[];
36
+ };
37
+ check: {
38
+ dev?: boolean;
39
+ directory?: string;
40
+ checks?: string;
41
+ strict?: boolean;
42
+ json?: boolean;
43
+ deps?: boolean;
44
+ all?: boolean;
45
+ ignore?: string;
46
+ builtins?: boolean;
47
+ peer?: boolean;
48
+ optional?: boolean;
49
+ fix?: boolean;
50
+ depth?: number;
51
+ };
52
+ conv: {};
53
+ create: {
54
+ template?: string;
55
+ mode?: "template" | "files";
56
+ fileType?: string;
57
+ destDir?: string;
58
+ multiple?: boolean;
59
+ parallel?: boolean;
60
+ concurrency?: string;
61
+ cwd?: string;
62
+ };
63
+ fs: {
64
+ mode: "copy" | "rm" | "rename";
65
+ target: string;
66
+ nonInteractive?: boolean;
67
+ source?: string;
68
+ destination?: string;
69
+ recursive?: boolean;
70
+ preserveStructure?: boolean;
71
+ increment?: boolean;
72
+ concurrency?: number;
73
+ gitignore?: boolean;
74
+ prepareMyCLI?: boolean;
75
+ revert?: boolean;
76
+ useDtsTxtForPrepareMyCLI?: boolean;
77
+ };
78
+ get: {};
79
+ init: {};
80
+ inject: {};
81
+ install: {
82
+ action?: string;
83
+ name?: string;
84
+ global?: boolean;
85
+ cwd?: string;
86
+ workspace?: boolean;
87
+ silent?: boolean;
88
+ recreateLockFile?: boolean;
89
+ linter?: boolean;
90
+ };
91
+ libs: {
92
+ init: string;
93
+ overwrite?: boolean;
94
+ };
95
+ magic: {
96
+ targets: string[];
97
+ lib?: string;
98
+ concurrency?: number;
99
+ batchSize?: number;
100
+ stopOnError?: boolean;
101
+ about?: boolean;
102
+ };
103
+ merge: {
104
+ s?: string[];
105
+ d?: string;
106
+ ignore?: string[];
107
+ format?: string;
108
+ stdout?: boolean;
109
+ noPath?: boolean;
110
+ pathAbove?: boolean;
111
+ };
112
+ migrate: {
113
+ interactive?: boolean;
114
+ codemod?: string;
115
+ project?: string;
116
+ mrTarget?: string;
117
+ dryRun?: boolean;
118
+ noBackup?: boolean;
119
+ consoleRelinkaInput?: string;
120
+ consoleRelinkaFrom?: string;
121
+ consoleRelinkaTo?: string;
122
+ };
123
+ mkdist: {
124
+ mkdistOnly?: boolean;
125
+ dev?: boolean;
126
+ dir?: string;
127
+ cwd?: string;
128
+ src?: string;
129
+ dist?: string;
130
+ clean?: boolean;
131
+ pattern?: string;
132
+ format?: string;
133
+ declaration?: boolean;
134
+ ext?: string;
135
+ jsx?: string;
136
+ jsxFactory?: string;
137
+ jsxFragment?: string;
138
+ loaders?: string;
139
+ minify?: boolean;
140
+ target?: string;
141
+ };
142
+ pack: {
143
+ input: string;
144
+ output?: string;
145
+ whitelabel?: string;
146
+ cdn?: string;
147
+ force?: boolean;
148
+ update?: boolean;
149
+ files?: string;
150
+ lastUpdate?: string;
151
+ unpack?: boolean;
152
+ };
153
+ pub: {
154
+ dev?: boolean;
155
+ };
156
+ remdn: {
157
+ mode?: "dirs-scan-only" | "dirs-scan-compare";
158
+ configPath?: string;
159
+ outputFilePath?: string;
160
+ initConfig?: string;
161
+ };
162
+ remove: {
163
+ action?: string;
164
+ name: string;
165
+ global?: boolean;
166
+ cwd?: string;
167
+ workspace?: boolean;
168
+ silent?: boolean;
169
+ linter?: boolean;
170
+ standalone?: boolean;
171
+ };
172
+ rempts: {
173
+ init?: string;
174
+ overwrite?: boolean;
175
+ customCmdsRoot?: string;
176
+ outFile?: string;
177
+ cmdDirs?: string[];
178
+ };
179
+ split: {
180
+ directory: string;
181
+ fileLineThreshold: number;
182
+ funcLineThreshold: number;
183
+ };
184
+ transform: {};
185
+ update: {
186
+ name?: string[];
187
+ ignore?: string[];
188
+ concurrency?: number;
189
+ linker?: "isolated" | "hoisted";
190
+ global?: boolean;
191
+ interactive?: boolean;
192
+ };
193
+ upgrade: {
194
+ interactive?: boolean;
195
+ };
196
+ x: {
197
+ action: string;
198
+ name?: string;
199
+ cwd?: string;
200
+ silent?: boolean;
201
+ target?: string;
202
+ timeout?: number;
203
+ throwOnError?: boolean;
204
+ args?: string;
205
+ global?: boolean;
206
+ yes?: boolean;
207
+ bun?: boolean;
208
+ npm?: boolean;
209
+ pnpm?: boolean;
210
+ yarn?: boolean;
211
+ };
212
+ }
213
+ export declare function loadTypedCommand<T extends keyof CommandArgsMap>(cmdName: T): Promise<Command>;
2
214
  export declare const getAggCmd: () => Promise<Command>;
3
215
  export declare const getBuildCmd: () => Promise<Command>;
216
+ export declare const getBuildBinaryCmd: () => Promise<Command>;
4
217
  export declare const getCheckCmd: () => Promise<Command>;
5
218
  export declare const getConvCmd: () => Promise<Command>;
6
- export declare const getCopyCmd: () => Promise<Command>;
219
+ export declare const getCreateCmd: () => Promise<Command>;
220
+ export declare const getFsCmd: () => Promise<Command>;
221
+ export declare const getGetCmd: () => Promise<Command>;
7
222
  export declare const getInitCmd: () => Promise<Command>;
8
223
  export declare const getInjectCmd: () => Promise<Command>;
224
+ export declare const getInstallCmd: () => Promise<Command>;
9
225
  export declare const getLibsCmd: () => Promise<Command>;
226
+ export declare const getMagicCmd: () => Promise<Command>;
10
227
  export declare const getMergeCmd: () => Promise<Command>;
11
228
  export declare const getMigrateCmd: () => Promise<Command>;
229
+ export declare const getMkdistCmd: () => Promise<Command>;
230
+ export declare const getPackCmd: () => Promise<Command>;
12
231
  export declare const getPubCmd: () => Promise<Command>;
232
+ export declare const getRemdnCmd: () => Promise<Command>;
233
+ export declare const getRemoveCmd: () => Promise<Command>;
13
234
  export declare const getRemptsCmd: () => Promise<Command>;
14
- export declare const getRenameCmd: () => Promise<Command>;
15
- export declare const getMagicCmd: () => Promise<Command>;
16
235
  export declare const getSplitCmd: () => Promise<Command>;
17
- export declare const getRmCmd: () => Promise<Command>;
236
+ export declare const getTransformCmd: () => Promise<Command>;
18
237
  export declare const getUpdateCmd: () => Promise<Command>;
19
238
  export declare const getUpgradeCmd: () => Promise<Command>;
239
+ export declare const getXCmd: () => Promise<Command>;
240
+ export declare function callCmd<T extends keyof CommandArgsMap>(cmdName: T, args?: CommandArgsMap[T]): Promise<void>;
241
+ export declare function getTypedCmd<T extends keyof CommandArgsMap>(cmdName: T): Promise<{
242
+ command: Command;
243
+ run: (args?: CommandArgsMap[T]) => Promise<void>;
244
+ }>;
245
+ export type { CommandArgsMap };
package/bin/app/cmds.js CHANGED
@@ -1,19 +1,36 @@
1
- import { loadCommand } from "@reliverse/rempts";
2
- export const getAggCmd = async () => loadCommand("agg");
3
- export const getBuildCmd = async () => loadCommand("build");
4
- export const getCheckCmd = async () => loadCommand("check");
5
- export const getConvCmd = async () => loadCommand("conv");
6
- export const getCopyCmd = async () => loadCommand("copy");
7
- export const getInitCmd = async () => loadCommand("init");
8
- export const getInjectCmd = async () => loadCommand("inject");
9
- export const getLibsCmd = async () => loadCommand("libs");
10
- export const getMergeCmd = async () => loadCommand("merge");
11
- export const getMigrateCmd = async () => loadCommand("migrate");
12
- export const getPubCmd = async () => loadCommand("pub");
13
- export const getRemptsCmd = async () => loadCommand("rempts");
14
- export const getRenameCmd = async () => loadCommand("rename");
15
- export const getMagicCmd = async () => loadCommand("magic");
16
- export const getSplitCmd = async () => loadCommand("split");
17
- export const getRmCmd = async () => loadCommand("rm");
18
- export const getUpdateCmd = async () => loadCommand("update");
19
- export const getUpgradeCmd = async () => loadCommand("upgrade");
1
+ import { loadCommand, callCmdImpl, getTypedCmdImpl } from "@reliverse/rempts";
2
+ export async function loadTypedCommand(cmdName) {
3
+ return await loadCommand(cmdName);
4
+ }
5
+ export const getAggCmd = async () => loadTypedCommand("agg");
6
+ export const getBuildCmd = async () => loadTypedCommand("build");
7
+ export const getBuildBinaryCmd = async () => loadTypedCommand("build_binary");
8
+ export const getCheckCmd = async () => loadTypedCommand("check");
9
+ export const getConvCmd = async () => loadTypedCommand("conv");
10
+ export const getCreateCmd = async () => loadTypedCommand("create");
11
+ export const getFsCmd = async () => loadTypedCommand("fs");
12
+ export const getGetCmd = async () => loadTypedCommand("get");
13
+ export const getInitCmd = async () => loadTypedCommand("init");
14
+ export const getInjectCmd = async () => loadTypedCommand("inject");
15
+ export const getInstallCmd = async () => loadTypedCommand("install");
16
+ export const getLibsCmd = async () => loadTypedCommand("libs");
17
+ export const getMagicCmd = async () => loadTypedCommand("magic");
18
+ export const getMergeCmd = async () => loadTypedCommand("merge");
19
+ export const getMigrateCmd = async () => loadTypedCommand("migrate");
20
+ export const getMkdistCmd = async () => loadTypedCommand("mkdist");
21
+ export const getPackCmd = async () => loadTypedCommand("pack");
22
+ export const getPubCmd = async () => loadTypedCommand("pub");
23
+ export const getRemdnCmd = async () => loadTypedCommand("remdn");
24
+ export const getRemoveCmd = async () => loadTypedCommand("remove");
25
+ export const getRemptsCmd = async () => loadTypedCommand("rempts");
26
+ export const getSplitCmd = async () => loadTypedCommand("split");
27
+ export const getTransformCmd = async () => loadTypedCommand("transform");
28
+ export const getUpdateCmd = async () => loadTypedCommand("update");
29
+ export const getUpgradeCmd = async () => loadTypedCommand("upgrade");
30
+ export const getXCmd = async () => loadTypedCommand("x");
31
+ export async function callCmd(cmdName, args) {
32
+ await callCmdImpl(cmdName, args);
33
+ }
34
+ export async function getTypedCmd(cmdName) {
35
+ return await getTypedCmdImpl(cmdName);
36
+ }
@@ -0,0 +1,18 @@
1
+ declare const _default: import("@reliverse/rempts").Command<{
2
+ mode: {
3
+ type: "string";
4
+ description: string;
5
+ default: string;
6
+ };
7
+ tool: {
8
+ type: "string";
9
+ description: string;
10
+ default: string;
11
+ };
12
+ update: {
13
+ type: "boolean";
14
+ description: string;
15
+ default: false;
16
+ };
17
+ }>;
18
+ export default _default;
@@ -0,0 +1,43 @@
1
+ import { relinka } from "@reliverse/relinka";
2
+ import { defineArgs, defineCommand } from "@reliverse/rempts";
3
+ import { ensureConfigMod } from "../../libs/sdk/sdk-impl/config/core.js";
4
+ export default defineCommand({
5
+ meta: {
6
+ name: "config",
7
+ description: "Manage project-level and device-global configurations"
8
+ },
9
+ args: defineArgs({
10
+ mode: {
11
+ type: "string",
12
+ description: "Config mode: copy-remote, copy-internal",
13
+ default: "copy-remote"
14
+ },
15
+ tool: {
16
+ type: "string",
17
+ description: "Tool name (e.g., dler, rse)",
18
+ default: "dler"
19
+ },
20
+ update: {
21
+ type: "boolean",
22
+ description: "Force update existing configuration",
23
+ default: false
24
+ }
25
+ }),
26
+ run: async ({ args }) => {
27
+ const { mode, tool, update } = args;
28
+ try {
29
+ await ensureConfigMod({
30
+ tool,
31
+ mode,
32
+ forceUpdate: update
33
+ });
34
+ relinka("success", `Configuration for ${tool} has been ${update ? "updated" : "created"}`);
35
+ } catch (error) {
36
+ relinka(
37
+ "error",
38
+ `Failed to manage config: ${error instanceof Error ? error.message : String(error)}`
39
+ );
40
+ process.exit(1);
41
+ }
42
+ }
43
+ });
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Generates a JSON schema file from the TypeBox schema
3
+ */
4
+ export declare function generateJsonSchema(typeboxSchema: any, outputPath: string): Promise<void>;
5
+ /**
6
+ * Generates the schema.json in the project root
7
+ */
8
+ export declare function generateSchemaFile(schema: any): Promise<void>;
@@ -0,0 +1,82 @@
1
+ import path from "@reliverse/pathkit";
2
+ import fs from "@reliverse/relifso";
3
+ function convertTypeBoxToJsonSchema(schema) {
4
+ if (!schema || typeof schema !== "object") return schema;
5
+ if (schema.type === "string" && schema.enum) {
6
+ return {
7
+ type: "string",
8
+ enum: schema.enum
9
+ };
10
+ }
11
+ if (schema.anyOf || schema.allOf || schema.oneOf) {
12
+ const variants = schema.anyOf || schema.allOf || schema.oneOf;
13
+ const allLiterals = variants.every((v) => v.const !== void 0);
14
+ if (allLiterals) {
15
+ return {
16
+ type: "string",
17
+ enum: variants.map((v) => v.const)
18
+ };
19
+ }
20
+ }
21
+ if (schema.type === "object") {
22
+ const result = {
23
+ type: "object",
24
+ properties: {}
25
+ };
26
+ if (schema.required) {
27
+ result.required = schema.required;
28
+ }
29
+ if (schema.properties) {
30
+ for (const [key, value] of Object.entries(schema.properties)) {
31
+ result.properties[key] = convertTypeBoxToJsonSchema(value);
32
+ }
33
+ }
34
+ if (schema.additionalProperties) {
35
+ result.additionalProperties = convertTypeBoxToJsonSchema(schema.additionalProperties);
36
+ }
37
+ if (schema.patternProperties) {
38
+ result.patternProperties = {};
39
+ for (const [pattern, value] of Object.entries(schema.patternProperties)) {
40
+ result.patternProperties[pattern] = convertTypeBoxToJsonSchema(value);
41
+ }
42
+ }
43
+ return result;
44
+ }
45
+ if (schema.type === "array") {
46
+ return {
47
+ type: "array",
48
+ items: convertTypeBoxToJsonSchema(schema.items)
49
+ };
50
+ }
51
+ if (schema.type) {
52
+ const result = { type: schema.type };
53
+ if (schema.minimum !== void 0) result.minimum = schema.minimum;
54
+ if (schema.maximum !== void 0) result.maximum = schema.maximum;
55
+ if (schema.minLength !== void 0) result.minLength = schema.minLength;
56
+ if (schema.maxLength !== void 0) result.maxLength = schema.maxLength;
57
+ if (schema.pattern !== void 0) result.pattern = schema.pattern;
58
+ if (schema.format !== void 0) result.format = schema.format;
59
+ if (schema.default !== void 0) result.default = schema.default;
60
+ return result;
61
+ }
62
+ return schema;
63
+ }
64
+ export async function generateJsonSchema(typeboxSchema, outputPath) {
65
+ const converted = convertTypeBoxToJsonSchema(typeboxSchema);
66
+ const schema = {
67
+ $schema: "http://json-schema.org/draft-07/schema#",
68
+ title: "rse configuration schema",
69
+ description: "https://docs.reliverse.org",
70
+ type: "object",
71
+ properties: converted.properties,
72
+ required: converted.required
73
+ };
74
+ await fs.writeFile(outputPath, JSON.stringify(schema, null, 2));
75
+ }
76
+ export async function generateSchemaFile(schema) {
77
+ const schemaPath = path.join(process.cwd(), "schema.json");
78
+ if (fs.existsSync(schemaPath)) {
79
+ await fs.remove(schemaPath);
80
+ }
81
+ await generateJsonSchema(schema, schemaPath);
82
+ }
@@ -2,7 +2,7 @@ import { resolve } from "@reliverse/pathkit";
2
2
  import { defineArgs, defineCommand } from "@reliverse/rempts";
3
3
  import { dlerBuild } from "../build/impl.js";
4
4
  import { mkdist } from "../../libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/make.js";
5
- import { ensureDlerConfig } from "../../libs/sdk/sdk-impl/config/init.js";
5
+ import { ensureDlerConfig } from "../../libs/sdk/sdk-impl/config/prepare.js";
6
6
  export default defineCommand({
7
7
  meta: {
8
8
  name: "mkdist",
@@ -1,7 +1,7 @@
1
1
  import { defineArgs, defineCommand } from "@reliverse/rempts";
2
2
  import { dlerPub } from "./impl.js";
3
- import { ensureDlerConfig } from "../../libs/sdk/sdk-impl/config/init.js";
4
3
  import { getConfigDler } from "../../libs/sdk/sdk-impl/config/load.js";
4
+ import { ensureDlerConfig } from "../../libs/sdk/sdk-impl/config/prepare.js";
5
5
  export default defineCommand({
6
6
  meta: {
7
7
  name: "pub",
@@ -115,7 +115,7 @@ export default defineCommand({
115
115
  relinka("warn", `\u274C File "${outPath2}" already exists. Use --overwrite to overwrite.`);
116
116
  return;
117
117
  }
118
- const exports2 = generateExports(cmdDirs2);
118
+ const exports2 = await generateExports(cmdDirs2);
119
119
  await fs.ensureDir(path.dirname(outPath2));
120
120
  await fs.writeFile(outPath2, exports2, "utf8");
121
121
  relinka("success", `\u2705 Generated command exports at: ${outPath2}`);
@@ -133,7 +133,7 @@ export default defineCommand({
133
133
  relinka("warn", "No command directories found with cmd.ts or cmd.js files.");
134
134
  return;
135
135
  }
136
- const exports = generateExports(cmdDirs);
136
+ const exports = await generateExports(cmdDirs);
137
137
  await fs.ensureDir(path.dirname(outPath));
138
138
  await fs.writeFile(outPath, exports, "utf8");
139
139
  relinka("success", `\u2705 Generated command exports at: ${outPath}`);
@@ -232,22 +232,160 @@ async function findCommandDirs(root) {
232
232
  await scan(root);
233
233
  return cmdDirs;
234
234
  }
235
- function generateExports(cmdDirs) {
235
+ async function generateCommandArgsMap(cmdDirs) {
236
+ let interfaceContent = "// Argument types for each command based on their defineArgs\ninterface CommandArgsMap {\n";
237
+ for (const dir of cmdDirs) {
238
+ const cmdPath = path.join("src/app", dir, "cmd.ts");
239
+ try {
240
+ if (await fs.pathExists(cmdPath)) {
241
+ const content = await fs.readFile(cmdPath, "utf-8");
242
+ const args = extractArgsFromContent(content);
243
+ const keyName = dir.replace(/[/\\]/g, "_");
244
+ interfaceContent += ` "${keyName}": {
245
+ `;
246
+ if (args.length > 0) {
247
+ for (const arg of args) {
248
+ let tsType;
249
+ switch (arg.type) {
250
+ case "boolean":
251
+ tsType = "boolean";
252
+ break;
253
+ case "number":
254
+ tsType = "number";
255
+ break;
256
+ case "array":
257
+ tsType = "string[]";
258
+ break;
259
+ case "string":
260
+ if (arg.allowed) {
261
+ tsType = arg.allowed.map((v) => `"${v}"`).join(" | ");
262
+ } else {
263
+ tsType = "string";
264
+ }
265
+ break;
266
+ default:
267
+ tsType = "string";
268
+ }
269
+ const optional = arg.required ? "" : "?";
270
+ interfaceContent += ` ${arg.name}${optional}: ${tsType};
271
+ `;
272
+ }
273
+ } else {
274
+ interfaceContent += ` // No arguments defined
275
+ `;
276
+ }
277
+ interfaceContent += " };\n";
278
+ } else {
279
+ const keyName = dir.replace(/[/\\]/g, "_");
280
+ interfaceContent += ` "${keyName}": Record<string, unknown>;
281
+ `;
282
+ }
283
+ } catch (error) {
284
+ const keyName = dir.replace(/[/\\]/g, "_");
285
+ interfaceContent += ` "${keyName}": Record<string, unknown>;
286
+ `;
287
+ }
288
+ }
289
+ interfaceContent += "}";
290
+ return interfaceContent;
291
+ }
292
+ function extractArgsFromContent(content) {
293
+ const args = [];
294
+ const defineArgsMatch = content.match(/defineArgs\(\s*\{([\s\S]*?)\}\s*\)/);
295
+ if (!defineArgsMatch?.[1]) return args;
296
+ const argsBlock = defineArgsMatch[1];
297
+ const argMatches = argsBlock.matchAll(/(\w+):\s*\{([^}]*)\}/g);
298
+ for (const match of argMatches) {
299
+ const argName = match[1];
300
+ const argProps = match[2];
301
+ if (!argName || !argProps) continue;
302
+ const typeMatch = argProps.match(/type:\s*["']([^"']+)["']/);
303
+ const type = typeMatch?.[1] || "string";
304
+ const requiredMatch = argProps.match(/required:\s*(true|false)/);
305
+ const required = requiredMatch?.[1] === "true";
306
+ const defaultMatch = argProps.match(/default:\s*([^,\n]+)/);
307
+ let defaultValue;
308
+ if (defaultMatch?.[1]) {
309
+ const defaultStr = defaultMatch[1].trim();
310
+ try {
311
+ defaultValue = JSON.parse(defaultStr);
312
+ } catch {
313
+ defaultValue = defaultStr.replace(/["']/g, "");
314
+ }
315
+ }
316
+ const allowedMatch = argProps.match(/allowed:\s*\[([^\]]+)\]/);
317
+ let allowed;
318
+ if (allowedMatch?.[1]) {
319
+ allowed = allowedMatch[1].split(",").map((s) => s.trim().replace(/["']/g, ""));
320
+ }
321
+ args.push({
322
+ name: argName,
323
+ type,
324
+ required,
325
+ default: defaultValue,
326
+ allowed
327
+ });
328
+ }
329
+ return args;
330
+ }
331
+ async function generateExports(cmdDirs) {
236
332
  const lines = [
237
- "// this file is auto-(re)generated by `dler rempts`",
333
+ "// autogenerated by `dler rempts`",
334
+ "// don't edit this file manually",
238
335
  "",
239
336
  'import type { Command } from "@reliverse/rempts";',
240
337
  "",
241
- 'import { loadCommand } from "@reliverse/rempts";',
338
+ 'import { loadCommand, callCmdImpl, getTypedCmdImpl } from "@reliverse/rempts";'
339
+ ];
340
+ lines.push("", "// ========== TYPED COMMAND SYSTEM ==========", "");
341
+ const commandArgsMap = await generateCommandArgsMap(cmdDirs);
342
+ lines.push(commandArgsMap);
343
+ lines.push(
344
+ "",
345
+ "// Typed loadCommand wrapper with intellisense",
346
+ "export async function loadTypedCommand<T extends keyof CommandArgsMap>(",
347
+ " cmdName: T",
348
+ "): Promise<Command> {",
349
+ " return await loadCommand(cmdName as string);",
350
+ "}",
351
+ ""
352
+ );
353
+ const traditionalExports = [
354
+ "",
355
+ "// ========== TRADITIONAL COMMAND EXPORTS (with typed intellisense) ==========",
242
356
  ""
243
357
  ];
244
358
  for (const dir of cmdDirs) {
245
359
  const funcName = "get" + dir.split(/[/\\]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1).replace(/[^a-zA-Z0-9]/g, "")).join("") + "Cmd";
246
- lines.push(
247
- `export const ${funcName} = async (): Promise<Command> => loadCommand("${dir}");`,
248
- ""
360
+ const keyName = dir.replace(/[/\\]/g, "_");
361
+ traditionalExports.push(
362
+ `export const ${funcName} = async (): Promise<Command> => loadTypedCommand("${keyName}");`
249
363
  );
250
364
  }
365
+ lines.push(...traditionalExports);
366
+ lines.push(
367
+ "",
368
+ "// Typed command functions with type safety",
369
+ "export async function callCmd<T extends keyof CommandArgsMap>(",
370
+ " cmdName: T,",
371
+ " args?: CommandArgsMap[T]",
372
+ "): Promise<void> {",
373
+ " await callCmdImpl<CommandArgsMap>(cmdName, args);",
374
+ "}",
375
+ "",
376
+ "export async function getTypedCmd<T extends keyof CommandArgsMap>(",
377
+ " cmdName: T",
378
+ "): Promise<{",
379
+ " command: Command;",
380
+ " run: (args?: CommandArgsMap[T]) => Promise<void>;",
381
+ "}> {",
382
+ " return await getTypedCmdImpl<CommandArgsMap>(cmdName);",
383
+ "}",
384
+ "",
385
+ "// Export type for external use",
386
+ "export type { CommandArgsMap };",
387
+ ""
388
+ );
251
389
  return lines.join("\n");
252
390
  }
253
391
  function generateCommandTemplate(cmdName) {