@reliverse/dler 1.5.1 → 1.5.3

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.
@@ -65,5 +65,15 @@ declare const _default: import("@reliverse/rempts").Command<{
65
65
  type: "string";
66
66
  default: string;
67
67
  };
68
+ separateTypesFile: {
69
+ description: string;
70
+ type: "boolean";
71
+ default: false;
72
+ };
73
+ typesOut: {
74
+ description: string;
75
+ type: "string";
76
+ required: false;
77
+ };
68
78
  }>;
69
79
  export default _default;
@@ -68,6 +68,16 @@ export default defineCommand({
68
68
  description: "Comma-separated list of file extensions to process (default: .ts,.js,.mts,.cts,.mjs,.cjs)",
69
69
  type: "string",
70
70
  default: ".ts,.js,.mts,.cts,.mjs,.cjs"
71
+ },
72
+ separateTypesFile: {
73
+ description: "Create a separate file for type exports",
74
+ type: "boolean",
75
+ default: false
76
+ },
77
+ typesOut: {
78
+ description: "Output file path for types (used when separateTypesFile is true)",
79
+ type: "string",
80
+ required: false
71
81
  }
72
82
  }),
73
83
  async run({ args }) {
@@ -84,7 +94,9 @@ export default defineCommand({
84
94
  includeInternal: !!args.includeInternal,
85
95
  internalMarker: args.internalMarker,
86
96
  overrideFile: !!args.override,
87
- fileExtensions: args.extensions.split(",").map((ext) => ext.trim())
97
+ fileExtensions: args.extensions.split(",").map((ext) => ext.trim()),
98
+ separateTypesFile: !!args.separateTypesFile,
99
+ typesOutFile: args.typesOut ? path.resolve(args.typesOut) : void 0
88
100
  });
89
101
  }
90
102
  });
@@ -15,7 +15,7 @@
15
15
  * - By default, updates only the auto-generated block in the aggregator file,
16
16
  * leaving any other content intact. Pass `overrideFile: true` to rewrite the entire file.
17
17
  */
18
- export declare function useAggregator({ inputDir, isRecursive, outFile, stripPrefix, useImport, useNamed, ignoreDirs, sortLines, headerComment, verbose, includeInternal, internalMarker, overrideFile, fileExtensions, }: {
18
+ export declare function useAggregator({ inputDir, isRecursive, outFile, stripPrefix, useImport, useNamed, ignoreDirs, sortLines, headerComment, verbose, includeInternal, internalMarker, overrideFile, fileExtensions, separateTypesFile, typesOutFile, }: {
19
19
  inputDir: string;
20
20
  isRecursive: boolean;
21
21
  outFile: string;
@@ -30,6 +30,8 @@ export declare function useAggregator({ inputDir, isRecursive, outFile, stripPre
30
30
  internalMarker?: string;
31
31
  overrideFile?: boolean;
32
32
  fileExtensions?: string[];
33
+ separateTypesFile?: boolean;
34
+ typesOutFile?: string;
33
35
  }): Promise<void>;
34
36
  /**
35
37
  * Prints usage examples based on whether dev mode or not.
@@ -1,7 +1,6 @@
1
1
  import path from "@reliverse/pathkit";
2
2
  import fs from "@reliverse/relifso";
3
3
  import { relinka } from "@reliverse/relinka";
4
- import MagicString from "magic-string";
5
4
  const AGGREGATOR_START = "// AUTO-GENERATED AGGREGATOR START";
6
5
  const AGGREGATOR_END = "// AUTO-GENERATED AGGREGATOR END";
7
6
  export async function useAggregator({
@@ -18,7 +17,9 @@ export async function useAggregator({
18
17
  includeInternal = false,
19
18
  internalMarker = "#",
20
19
  overrideFile = false,
21
- fileExtensions = [".ts", ".js", ".mts", ".cts", ".mjs", ".cjs"]
20
+ fileExtensions = [".ts", ".js", ".mts", ".cts", ".mjs", ".cjs"],
21
+ separateTypesFile = false,
22
+ typesOutFile
22
23
  }) {
23
24
  try {
24
25
  const st = await fs.stat(inputDir).catch(() => null);
@@ -37,6 +38,19 @@ ${error}`
37
38
  );
38
39
  process.exit(1);
39
40
  }
41
+ if (separateTypesFile && typesOutFile) {
42
+ const typesOutDir = path.dirname(typesOutFile);
43
+ try {
44
+ await fs.ensureDir(typesOutDir);
45
+ } catch (error) {
46
+ relinka(
47
+ "error",
48
+ `Error: Cannot create types output directory: ${typesOutDir}
49
+ ${error}`
50
+ );
51
+ process.exit(1);
52
+ }
53
+ }
40
54
  const outExt = path.extname(outFile).toLowerCase();
41
55
  if (!fileExtensions.includes(outExt)) {
42
56
  relinka(
@@ -98,62 +112,48 @@ ${error}`
98
112
  )
99
113
  );
100
114
  const allLines = aggregatorLinesArrays.flat();
115
+ const typeLines = [];
116
+ const valueLines = [];
117
+ for (const line of allLines) {
118
+ if (line.includes("type {")) {
119
+ typeLines.push(line);
120
+ } else {
121
+ valueLines.push(line);
122
+ }
123
+ }
101
124
  if (sortLines) {
102
- allLines.sort();
125
+ typeLines.sort();
126
+ valueLines.sort();
103
127
  if (verbose) relinka("log", "Sorted aggregator lines alphabetically.");
104
128
  }
105
- const aggregatorContent = allLines.join("\n");
106
- const aggregatorBlock = `${headerComment ? `${headerComment}
129
+ const buildAggregatorBlock = (lines) => `${headerComment ? `${headerComment}
107
130
  ` : ""}${AGGREGATOR_START}
108
- ${aggregatorContent}
131
+ ${lines.join("\n")}
109
132
  ${AGGREGATOR_END}
110
133
  `;
111
- let finalText;
112
- if (overrideFile) {
113
- finalText = aggregatorBlock;
114
- if (verbose) {
115
- relinka("log", "Override mode: rewriting entire file.");
116
- }
134
+ if (separateTypesFile && typesOutFile) {
135
+ const typeBlock = buildAggregatorBlock(typeLines);
136
+ await fs.ensureFile(typesOutFile);
137
+ await fs.writeFile(typesOutFile, typeBlock, "utf8");
138
+ const valueBlock = buildAggregatorBlock([
139
+ ...valueLines,
140
+ `export * from "${path.relative(path.dirname(outFile), typesOutFile).replace(/\\/g, "/")}";`
141
+ ]);
142
+ await fs.ensureFile(outFile);
143
+ await fs.writeFile(outFile, valueBlock, "utf8");
144
+ relinka(
145
+ "success",
146
+ `Aggregator done: processed ${typeLines.length} type lines in: ${typesOutFile} and ${valueLines.length} value lines in: ${outFile}`
147
+ );
117
148
  } else {
118
- let existingContent = "";
119
- try {
120
- existingContent = await fs.readFile(outFile, "utf8");
121
- } catch {
122
- if (verbose)
123
- relinka("log", "Aggregator file does not exist. Creating new one.");
124
- }
125
- if (existingContent?.includes(AGGREGATOR_START) && existingContent.includes(AGGREGATOR_END)) {
126
- if (verbose) {
127
- relinka(
128
- "log",
129
- "Existing aggregator block found. Updating auto-generated section."
130
- );
131
- }
132
- const s = new MagicString(existingContent);
133
- const startIdx = existingContent.indexOf(AGGREGATOR_START);
134
- const endIdx = existingContent.indexOf(AGGREGATOR_END) + AGGREGATOR_END.length;
135
- s.update(startIdx, endIdx, aggregatorBlock.trim());
136
- finalText = s.toString();
137
- } else {
138
- if (existingContent) {
139
- if (verbose)
140
- relinka(
141
- "log",
142
- "No aggregator block found. Appending auto-generated section."
143
- );
144
- finalText = `${existingContent.trim()}
145
- ${aggregatorBlock}`;
146
- } else {
147
- finalText = aggregatorBlock;
148
- }
149
- }
149
+ const aggregatorBlock = buildAggregatorBlock(allLines);
150
+ await fs.ensureFile(outFile);
151
+ await fs.writeFile(outFile, aggregatorBlock, "utf8");
152
+ relinka(
153
+ "success",
154
+ `Aggregator done: processed ${allLines.length} lines in: ${outFile}`
155
+ );
150
156
  }
151
- await fs.ensureFile(outFile);
152
- await fs.writeFile(outFile, finalText, "utf8");
153
- relinka(
154
- "success",
155
- `Aggregator done: processed ${allLines.length} lines in: ${outFile}`
156
- );
157
157
  } catch (error) {
158
158
  relinka("error", `Aggregator failed: ${error}`);
159
159
  process.exit(1);
@@ -33,6 +33,8 @@ export async function promptAggCommand() {
33
33
  let out = "";
34
34
  let recursive = true;
35
35
  let strip = "";
36
+ let separateTypesFile = false;
37
+ let typesOut = "";
36
38
  if (selectedLibName && selectedLibName !== "") {
37
39
  const libConfig = config?.libsList?.[selectedLibName];
38
40
  if (config && libConfig) {
@@ -72,12 +74,24 @@ export async function promptAggCommand() {
72
74
  defaultValue: strip
73
75
  });
74
76
  }
77
+ separateTypesFile = await confirmPrompt({
78
+ title: "Do you want to create a separate file for type exports?",
79
+ defaultValue: separateTypesFile
80
+ });
81
+ if (separateTypesFile) {
82
+ typesOut = await inputPrompt({
83
+ title: "Enter the output file for types",
84
+ defaultValue: out.replace(/\.(ts|js)$/, ".types.$1")
85
+ });
86
+ }
75
87
  await runCmd(await cmdAgg(), [
76
88
  `--imports=${imports}`,
77
89
  `--input=${input}`,
78
90
  `--named=${named}`,
79
91
  `--out=${out}`,
80
92
  `--recursive=${recursive}`,
81
- `--strip=${strip}`
93
+ `--strip=${strip}`,
94
+ `--separateTypesFile=${separateTypesFile}`,
95
+ ...separateTypesFile ? [`--typesOut=${typesOut}`] : []
82
96
  ]);
83
97
  }
package/bin/app/cmds.d.ts CHANGED
@@ -134,6 +134,16 @@ export declare function cmdAgg(): Promise<import("@reliverse/rempts").Command<{
134
134
  type: "string";
135
135
  default: string;
136
136
  };
137
+ separateTypesFile: {
138
+ description: string;
139
+ type: "boolean";
140
+ default: false;
141
+ };
142
+ typesOut: {
143
+ description: string;
144
+ type: "string";
145
+ required: false;
146
+ };
137
147
  }>>;
138
148
  export declare function cmdBuild(): Promise<import("@reliverse/rempts").Command<{
139
149
  dev: {
@@ -172,4 +182,16 @@ export declare function cmdRelifsoRename(): Promise<import("@reliverse/rempts").
172
182
  description: string;
173
183
  required: false;
174
184
  };
185
+ recursive: {
186
+ type: "boolean";
187
+ description: string;
188
+ required: false;
189
+ default: true;
190
+ };
191
+ useDtsTxtForPrepareMyCLI: {
192
+ type: "boolean";
193
+ description: string;
194
+ required: false;
195
+ default: false;
196
+ };
175
197
  }>>;
@@ -29,11 +29,11 @@ export default defineCommand({
29
29
  },
30
30
  {
31
31
  value: "rename-prepare",
32
- label: "Rename files (prepare CLI)"
32
+ label: "My project is a bootstrapper CLI (apply rename optimizations)"
33
33
  },
34
34
  {
35
35
  value: "rename-prepare-revert",
36
- label: "Rename files (prepare CLI)"
36
+ label: "Revert rename CLI files optimizations"
37
37
  }
38
38
  ]
39
39
  });
@@ -23,5 +23,17 @@ declare const _default: import("@reliverse/rempts").Command<{
23
23
  description: string;
24
24
  required: false;
25
25
  };
26
+ recursive: {
27
+ type: "boolean";
28
+ description: string;
29
+ required: false;
30
+ default: true;
31
+ };
32
+ useDtsTxtForPrepareMyCLI: {
33
+ type: "boolean";
34
+ description: string;
35
+ required: false;
36
+ default: false;
37
+ };
26
38
  }>;
27
39
  export default _default;
@@ -1,8 +1,8 @@
1
1
  import { relinka } from "@reliverse/relinka";
2
2
  import { defineCommand } from "@reliverse/rempts";
3
- import { existsSync, readdirSync } from "node:fs";
3
+ import { existsSync } from "node:fs";
4
4
  import { readFileSync } from "node:fs";
5
- import { rename, access } from "node:fs/promises";
5
+ import { rename, access, readdir } from "node:fs/promises";
6
6
  import { join, dirname, basename, extname } from "node:path";
7
7
  async function fileExists(path) {
8
8
  try {
@@ -21,7 +21,26 @@ async function safeRename(source, destination) {
21
21
  function isCommonJSFile(content) {
22
22
  return content.includes("module.exports") || content.includes("require(");
23
23
  }
24
- async function prepareCLIFiles(revert = false) {
24
+ async function getAllFilesAsync(dir, baseDir = dir, recursive = true) {
25
+ let fileList = [];
26
+ const entries = await readdir(dir, {
27
+ encoding: "utf-8",
28
+ withFileTypes: true
29
+ });
30
+ for (const entry of entries) {
31
+ const fullPath = join(dir, entry.name);
32
+ if (entry.isDirectory()) {
33
+ if (recursive) {
34
+ const subFiles = await getAllFilesAsync(fullPath, baseDir, recursive);
35
+ fileList = fileList.concat(subFiles);
36
+ }
37
+ } else if (entry.isFile()) {
38
+ fileList.push(fullPath.slice(baseDir.length + 1));
39
+ }
40
+ }
41
+ return fileList;
42
+ }
43
+ async function prepareCLIFiles(revert = false, recursive = true, useDtsTxtForPrepareMyCLI = false) {
25
44
  const configPath = ".config/dler.ts";
26
45
  let srcDir = "src";
27
46
  if (existsSync(configPath)) {
@@ -34,17 +53,17 @@ async function prepareCLIFiles(revert = false) {
34
53
  if (!existsSync(srcDir)) {
35
54
  throw new Error(`Source directory not found: ${srcDir}`);
36
55
  }
37
- const files = readdirSync(srcDir, { recursive: true, encoding: "utf-8" });
56
+ const files = await getAllFilesAsync(srcDir, srcDir, recursive);
38
57
  for (const file of files) {
39
58
  const fullPath = join(srcDir, file);
40
- if (!existsSync(fullPath)) continue;
59
+ if (!await fileExists(fullPath)) continue;
41
60
  const ext = extname(file);
42
61
  const baseName = basename(file, ext);
43
62
  const dir = dirname(fullPath);
44
63
  if (revert) {
45
64
  if (file.endsWith(".json.json")) {
46
65
  await safeRename(fullPath, join(dir, baseName));
47
- } else if (file.endsWith(".d.ts.txt")) {
66
+ } else if (file.endsWith(".d.ts.txt") && useDtsTxtForPrepareMyCLI) {
48
67
  await safeRename(fullPath, join(dir, `${baseName}.d.ts`));
49
68
  } else if (file.endsWith(".cjs")) {
50
69
  await safeRename(fullPath, join(dir, `${baseName}.js`));
@@ -54,8 +73,9 @@ async function prepareCLIFiles(revert = false) {
54
73
  await safeRename(fullPath, join(dir, "tsconfig.json.json"));
55
74
  } else if (file === "package.json" && !file.endsWith(".json.json")) {
56
75
  await safeRename(fullPath, join(dir, "package.json.json"));
57
- } else if (file.endsWith(".d.ts") && !file.endsWith(".d.ts.txt")) {
58
- await safeRename(fullPath, join(dir, `${baseName}.d.ts.txt`));
76
+ } else if (file.endsWith(".d.ts") && !file.endsWith(".d.ts.txt") && useDtsTxtForPrepareMyCLI) {
77
+ const baseWithoutD = baseName.slice(0, -2);
78
+ await safeRename(fullPath, join(dir, `${baseWithoutD}.d.ts.txt`));
59
79
  } else if (file.endsWith(".js") && !file.endsWith(".cjs")) {
60
80
  const content = readFileSync(fullPath, "utf-8");
61
81
  if (isCommonJSFile(content)) {
@@ -95,13 +115,36 @@ export default defineCommand({
95
115
  type: "string",
96
116
  description: "Destination name for the rename operation",
97
117
  required: false
118
+ },
119
+ recursive: {
120
+ type: "boolean",
121
+ description: "Recursively process all files in subdirectories (default: true)",
122
+ required: false,
123
+ default: true
124
+ },
125
+ useDtsTxtForPrepareMyCLI: {
126
+ type: "boolean",
127
+ description: "Use .d.ts.txt extension for .d.ts files in prepareMyCLI mode (default: false)",
128
+ required: false,
129
+ default: false
98
130
  }
99
131
  },
100
132
  async run({ args }) {
101
- const { prepareMyCLI, revert, source, destination } = args;
133
+ const {
134
+ prepareMyCLI,
135
+ revert,
136
+ source,
137
+ destination,
138
+ recursive = true,
139
+ useDtsTxtForPrepareMyCLI = false
140
+ } = args;
102
141
  if (prepareMyCLI === true) {
103
142
  try {
104
- await prepareCLIFiles(revert === true);
143
+ await prepareCLIFiles(
144
+ revert === true,
145
+ recursive,
146
+ useDtsTxtForPrepareMyCLI
147
+ );
105
148
  relinka("log", "Successfully prepared CLI files");
106
149
  } catch (error) {
107
150
  const errorMessage = error instanceof Error ? error.message : String(error);
package/bin/init/info.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { endPrompt, startPrompt } from "@reliverse/rempts";
2
+ const version = "1.5.3";
2
3
  export async function showStartPrompt(isDev) {
3
4
  await startPrompt({
4
5
  titleColor: "inverse",
@@ -6,7 +7,7 @@ export async function showStartPrompt(isDev) {
6
7
  // packageName: getPkgName(),
7
8
  // packageVersion: getPkgVersion(),
8
9
  packageName: "dler",
9
- packageVersion: "1.3.5",
10
+ packageVersion: version,
10
11
  isDev
11
12
  });
12
13
  }
package/package.json CHANGED
@@ -41,7 +41,7 @@
41
41
  "license": "MIT",
42
42
  "name": "@reliverse/dler",
43
43
  "type": "module",
44
- "version": "1.5.1",
44
+ "version": "1.5.3",
45
45
  "keywords": [
46
46
  "reliverse",
47
47
  "cli",