@reliverse/dler 1.7.75 → 1.7.77

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.
@@ -1,6 +1,6 @@
1
1
  import path from "@reliverse/pathkit";
2
2
  import { inputPrompt, defineArgs, defineCommand } from "@reliverse/rempts";
3
- import { useAggregator } from "../../libs/sdk/sdk-impl/utils/agg/agg.js";
3
+ import { useAggregator } from "../../libs/sdk/sdk-impl/utils/agg/agg-2.js";
4
4
  export default defineCommand({
5
5
  args: defineArgs({
6
6
  imports: {
package/bin/cli.js CHANGED
@@ -3,7 +3,7 @@ import { runMain, defineCommand, defineArgs, selectPrompt, showUsage } from "@re
3
3
  import { callCmd } from "./app/cmds.js";
4
4
  import { showEndPrompt, showStartPrompt } from "./libs/sdk/sdk-impl/config/info.js";
5
5
  import { prepareDlerEnvironment } from "./libs/sdk/sdk-impl/config/prepare.js";
6
- import { promptAggCommand } from "./libs/sdk/sdk-impl/utils/agg/agg.js";
6
+ import { promptAggCommand } from "./libs/sdk/sdk-impl/utils/agg/agg-1.js";
7
7
  const MENU_CMDS = ["agg", "build", "pub", "update"];
8
8
  let isDev = process.env.DLER_DEV_MODE === "true";
9
9
  const main = defineCommand({
@@ -1,5 +1,5 @@
1
1
  import { endPrompt, startPrompt } from "@reliverse/rempts";
2
- const version = "1.7.75";
2
+ const version = "1.7.77";
3
3
  export async function showStartPrompt(isDev) {
4
4
  await startPrompt({
5
5
  titleColor: "inverse",
@@ -173,7 +173,7 @@ function getFilterDepsPatterns(isDev) {
173
173
  }`;
174
174
  }
175
175
  function generateConfig(isDev, pkgDescription) {
176
- const importdefineConfigStatement = isDev ? `import { defineConfig } from "../../../cfg/cfg-impl/cfg-consts";` : `import { defineConfig } from "@reliverse/dler-cfg";`;
176
+ const importdefineConfigStatement = isDev ? `import { defineConfig } from "../../../cfg/cfg-impl/cfg-consts";` : `import { defineConfig } from "@reliverse/cfg";`;
177
177
  const verboseValue = getValue(isDev, true, DEFAULT_CONFIG_DLER.commonVerbose);
178
178
  const coreIsCLI = getCoreIsCLI(isDev);
179
179
  const registryValue = getValue(isDev, "npm-jsr", DEFAULT_CONFIG_DLER.commonPubRegistry);
@@ -0,0 +1 @@
1
+ export declare function promptAggCommand(): Promise<void>;
@@ -0,0 +1,194 @@
1
+ import path from "@reliverse/pathkit";
2
+ import { relinka } from "@reliverse/relinka";
3
+ import { selectPrompt, confirmPrompt, inputPrompt } from "@reliverse/rempts";
4
+ import { getConfigDler } from "../../config/load.js";
5
+ import { useAggregator } from "./agg-2.js";
6
+ import { findMainEntryFile } from "./agg-4.js";
7
+ import { isAggregationDisabled } from "./agg-5.js";
8
+ export async function promptAggCommand() {
9
+ const config = await getConfigDler();
10
+ let selectedLibName = null;
11
+ const mainEntryFile = await findMainEntryFile(config);
12
+ const isMainDisabled = mainEntryFile ? await isAggregationDisabled(mainEntryFile) : false;
13
+ if (config?.libsList && Object.keys(config.libsList).length > 0) {
14
+ const libEntries = await Promise.all(
15
+ Object.entries(config.libsList).map(async ([name, lib]) => {
16
+ const libMainFile = `${config.libsDirSrc}/${lib.libMainFile}`;
17
+ const isLibDisabled = await isAggregationDisabled(libMainFile);
18
+ return {
19
+ name,
20
+ lib,
21
+ isDisabled: isLibDisabled
22
+ };
23
+ })
24
+ );
25
+ const libs = libEntries.filter(({ isDisabled }) => !isDisabled).map(({ name, lib }) => ({
26
+ value: name,
27
+ label: name,
28
+ hint: `${config.libsDirSrc}/${lib.libDirName}/${lib.libDirName}-impl`
29
+ }));
30
+ if (mainEntryFile && !isMainDisabled) {
31
+ libs.unshift({
32
+ value: "main",
33
+ label: "Main package",
34
+ hint: mainEntryFile
35
+ });
36
+ }
37
+ libs.push({ value: "", label: "Skip selection", hint: "" });
38
+ selectedLibName = await selectPrompt({
39
+ title: "Select a package to aggregate or skip",
40
+ options: libs
41
+ });
42
+ } else if (mainEntryFile && !isMainDisabled) {
43
+ const shouldUseMain = await confirmPrompt({
44
+ title: `Use main package for aggregation? (Found: ${mainEntryFile})`,
45
+ defaultValue: true
46
+ });
47
+ if (shouldUseMain) {
48
+ selectedLibName = "main";
49
+ }
50
+ }
51
+ let imports = false;
52
+ let input = "";
53
+ let named = true;
54
+ let out = "";
55
+ let recursive = true;
56
+ let strip = "";
57
+ let separateTypesFile = false;
58
+ let typesOut = "";
59
+ if (selectedLibName && selectedLibName !== "") {
60
+ if (selectedLibName === "main" && mainEntryFile && !isMainDisabled) {
61
+ const entryDir = path.dirname(mainEntryFile);
62
+ input = entryDir;
63
+ out = mainEntryFile;
64
+ strip = entryDir;
65
+ } else if (selectedLibName === "main" && isMainDisabled) {
66
+ relinka.log("Main package aggregation is disabled due to <dler-disable-agg> comment.");
67
+ return;
68
+ } else {
69
+ const libConfig = config?.libsList?.[selectedLibName];
70
+ if (config && libConfig) {
71
+ input = `${config.libsDirSrc}/${libConfig.libDirName}/${libConfig.libDirName}-impl`;
72
+ out = `${config.libsDirSrc}/${libConfig.libMainFile}`;
73
+ strip = `${config.libsDirSrc}/${libConfig.libDirName}`;
74
+ }
75
+ }
76
+ }
77
+ if (!selectedLibName || !input) {
78
+ input = await inputPrompt({
79
+ title: "Enter the input directory",
80
+ defaultValue: input
81
+ });
82
+ if (input) {
83
+ if (mainEntryFile && isMainDisabled) {
84
+ const mainEntryDir = path.dirname(mainEntryFile);
85
+ if (path.resolve(input) === path.resolve(mainEntryDir) || path.resolve(input) === path.resolve(mainEntryFile)) {
86
+ relinka.log("Main package aggregation is disabled due to <dler-disable-agg> comment.");
87
+ return;
88
+ }
89
+ }
90
+ if (config?.libsList) {
91
+ for (const [libName, libConfig] of Object.entries(config.libsList)) {
92
+ const libImplPath = `${config.libsDirSrc}/${libConfig.libDirName}/${libConfig.libDirName}-impl`;
93
+ const libMainFile = `${config.libsDirSrc}/${libConfig.libMainFile}`;
94
+ if (path.resolve(input) === path.resolve(libImplPath) || path.resolve(input) === path.resolve(libMainFile)) {
95
+ const isLibDisabled = await isAggregationDisabled(libMainFile);
96
+ if (isLibDisabled) {
97
+ relinka.log(
98
+ `Library "${libName}" aggregation is disabled due to <dler-disable-agg> comment.`
99
+ );
100
+ return;
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+ const verbose = await confirmPrompt({
108
+ title: "Enable verbose logging and additional options?",
109
+ defaultValue: false
110
+ });
111
+ let sortLines = false;
112
+ let headerComment = "";
113
+ let includeInternal = false;
114
+ let internalMarker = "#";
115
+ let overrideFile = false;
116
+ let extensions = ".ts,.js,.mts,.cts,.mjs,.cjs";
117
+ if (verbose) {
118
+ sortLines = await confirmPrompt({
119
+ title: "Sort aggregated lines alphabetically?",
120
+ defaultValue: false
121
+ });
122
+ headerComment = await inputPrompt({
123
+ title: "Add a header comment to the aggregator output (optional):",
124
+ defaultValue: ""
125
+ });
126
+ includeInternal = await confirmPrompt({
127
+ title: "Include files marked as internal (starting with #)?",
128
+ defaultValue: false
129
+ });
130
+ internalMarker = await inputPrompt({
131
+ title: "Marker for internal files:",
132
+ defaultValue: "#"
133
+ });
134
+ overrideFile = await confirmPrompt({
135
+ title: "Override entire file instead of updating only the aggregator block?",
136
+ defaultValue: false
137
+ });
138
+ extensions = await inputPrompt({
139
+ title: "File extensions to process (comma-separated):",
140
+ defaultValue: ".ts,.js,.mts,.cts,.mjs,.cjs"
141
+ });
142
+ imports = await confirmPrompt({
143
+ title: "Do you want to generate imports instead of exports? (N generates exports)",
144
+ defaultValue: imports
145
+ });
146
+ named = await confirmPrompt({
147
+ title: imports ? "Do you want to generate named imports?" : "Do you want to generate named exports?",
148
+ defaultValue: named
149
+ });
150
+ recursive = await confirmPrompt({
151
+ title: "Do you want to recursively scan subdirectories?",
152
+ defaultValue: recursive
153
+ });
154
+ separateTypesFile = await confirmPrompt({
155
+ title: "Do you want to create a separate file for type exports?",
156
+ defaultValue: separateTypesFile
157
+ });
158
+ }
159
+ if (!selectedLibName || !out) {
160
+ out = await inputPrompt({
161
+ title: "Enter the output file",
162
+ defaultValue: out
163
+ });
164
+ }
165
+ if (!selectedLibName || !strip) {
166
+ strip = await inputPrompt({
167
+ title: "Enter the path to strip from the final imports/exports",
168
+ defaultValue: strip
169
+ });
170
+ }
171
+ if (separateTypesFile) {
172
+ typesOut = await inputPrompt({
173
+ title: "Enter the output file for types",
174
+ defaultValue: out.replace(/\.(ts|js)$/, ".types.$1")
175
+ });
176
+ }
177
+ await useAggregator({
178
+ inputDir: path.resolve(input),
179
+ isRecursive: recursive,
180
+ outFile: path.resolve(out),
181
+ stripPrefix: strip ? path.resolve(strip) : "",
182
+ useImport: imports,
183
+ useNamed: named,
184
+ sortLines,
185
+ headerComment,
186
+ verbose,
187
+ includeInternal,
188
+ internalMarker,
189
+ overrideFile,
190
+ fileExtensions: extensions.split(",").map((ext) => ext.trim()),
191
+ separateTypesFile,
192
+ typesOutFile: typesOut ? path.resolve(typesOut) : void 0
193
+ });
194
+ }
@@ -1,4 +1,3 @@
1
- export declare function promptAggCommand(): Promise<void>;
2
1
  /**
3
2
  * Aggregator supporting:
4
3
  * - --import or default export,
@@ -34,7 +33,3 @@ export declare function useAggregator({ inputDir, isRecursive, outFile, stripPre
34
33
  separateTypesFile?: boolean;
35
34
  typesOutFile?: string;
36
35
  }): Promise<void>;
37
- /**
38
- * Prints usage examples based on whether dev mode or not.
39
- */
40
- export declare function printUsage(isDev?: boolean): void;
@@ -0,0 +1,148 @@
1
+ import path from "@reliverse/pathkit";
2
+ import fs from "@reliverse/relifso";
3
+ import { relinka } from "@reliverse/relinka";
4
+ import { collectFiles, generateAggregatorLines } from "./agg-3.js";
5
+ const AGGREGATOR_START = "// AUTO-GENERATED AGGREGATOR START (via `dler agg`)";
6
+ const AGGREGATOR_END = "// AUTO-GENERATED AGGREGATOR END";
7
+ export async function useAggregator({
8
+ inputDir,
9
+ isRecursive,
10
+ outFile,
11
+ stripPrefix,
12
+ useImport,
13
+ useNamed,
14
+ ignoreDirs = ["node_modules", ".git"],
15
+ sortLines = false,
16
+ headerComment = "",
17
+ verbose = false,
18
+ includeInternal = false,
19
+ internalMarker = "#",
20
+ overrideFile = false,
21
+ fileExtensions = [".ts", ".js", ".mts", ".cts", ".mjs", ".cjs"],
22
+ separateTypesFile = false,
23
+ typesOutFile
24
+ }) {
25
+ try {
26
+ const st = await fs.stat(inputDir).catch(() => null);
27
+ if (!st?.isDirectory()) {
28
+ relinka("error", `Error: --input is not a valid directory: ${inputDir}`);
29
+ process.exit(1);
30
+ }
31
+ const outDir = path.dirname(outFile);
32
+ try {
33
+ await fs.ensureDir(outDir);
34
+ } catch (error) {
35
+ relinka("error", `Error: Cannot create output directory: ${outDir}
36
+ ${error}`);
37
+ process.exit(1);
38
+ }
39
+ if (separateTypesFile && typesOutFile) {
40
+ const typesOutDir = path.dirname(typesOutFile);
41
+ try {
42
+ await fs.ensureDir(typesOutDir);
43
+ } catch (error) {
44
+ relinka("error", `Error: Cannot create types output directory: ${typesOutDir}
45
+ ${error}`);
46
+ process.exit(1);
47
+ }
48
+ }
49
+ const outExt = path.extname(outFile).toLowerCase();
50
+ if (!fileExtensions.includes(outExt)) {
51
+ relinka(
52
+ "warn",
53
+ `Warning: Output file extension (${outExt}) doesn't match any of the input extensions: ${fileExtensions.join(", ")}`
54
+ );
55
+ }
56
+ if (stripPrefix) {
57
+ const stripSt = await fs.stat(stripPrefix).catch(() => null);
58
+ if (!stripSt?.isDirectory()) {
59
+ relinka("error", `Error: --strip is not a valid directory: ${stripPrefix}`);
60
+ process.exit(1);
61
+ }
62
+ }
63
+ if (verbose)
64
+ relinka(
65
+ "log",
66
+ `Scanning directory ${inputDir} for files with extensions: ${fileExtensions.join(", ")}`
67
+ );
68
+ const filePaths = await collectFiles(
69
+ inputDir,
70
+ fileExtensions,
71
+ isRecursive,
72
+ ignoreDirs,
73
+ verbose,
74
+ includeInternal,
75
+ internalMarker,
76
+ outFile
77
+ );
78
+ if (!filePaths.length) {
79
+ relinka(
80
+ "warn",
81
+ `No matching files found in ${inputDir} with extensions: ${fileExtensions.join(", ")}`
82
+ );
83
+ if (!overrideFile) {
84
+ relinka("warn", "No changes will be made to the output file.");
85
+ return;
86
+ }
87
+ }
88
+ const usedIdentifiers = /* @__PURE__ */ new Set();
89
+ const aggregatorLinesArrays = await Promise.all(
90
+ filePaths.map(
91
+ (fp) => generateAggregatorLines(
92
+ fp,
93
+ inputDir,
94
+ stripPrefix,
95
+ useImport,
96
+ useNamed,
97
+ usedIdentifiers
98
+ ).catch((error) => {
99
+ relinka("error", `Error processing file ${fp}: ${error}`);
100
+ return [];
101
+ })
102
+ )
103
+ );
104
+ const allLines = aggregatorLinesArrays.flat();
105
+ const typeLines = [];
106
+ const valueLines = [];
107
+ for (const line of allLines) {
108
+ if (line.includes("type {")) {
109
+ typeLines.push(line);
110
+ } else {
111
+ valueLines.push(line);
112
+ }
113
+ }
114
+ if (sortLines) {
115
+ typeLines.sort();
116
+ valueLines.sort();
117
+ if (verbose) relinka("log", "Sorted aggregator lines alphabetically.");
118
+ }
119
+ const buildAggregatorBlock = (lines) => `${headerComment ? `${headerComment}
120
+ ` : ""}${AGGREGATOR_START}
121
+ ${lines.join("\n")}
122
+ ${AGGREGATOR_END}
123
+ `;
124
+ if (separateTypesFile && typesOutFile) {
125
+ const typeBlock = buildAggregatorBlock(typeLines);
126
+ await fs.ensureFile(typesOutFile);
127
+ await fs.writeFile(typesOutFile, typeBlock, "utf8");
128
+ const valueBlock = buildAggregatorBlock([
129
+ ...valueLines,
130
+ `export * from "${path.relative(path.dirname(outFile), typesOutFile).replace(/\\/g, "/")}";`
131
+ ]);
132
+ await fs.ensureFile(outFile);
133
+ await fs.writeFile(outFile, valueBlock, "utf8");
134
+ relinka(
135
+ "success",
136
+ `Aggregator done: processed ${typeLines.length} type lines in: ${typesOutFile} and ${valueLines.length} value lines in: ${outFile}`
137
+ );
138
+ } else {
139
+ const aggregatorBlock = buildAggregatorBlock(allLines);
140
+ await fs.ensureFile(outFile);
141
+ await fs.writeFile(outFile, aggregatorBlock, "utf8");
142
+ relinka("success", `Aggregator done: processed ${allLines.length} lines in: ${outFile}`);
143
+ }
144
+ } catch (error) {
145
+ relinka("error", `Aggregator failed: ${error}`);
146
+ process.exit(1);
147
+ }
148
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Build a relative import/export path, removing `stripPrefix` if it is truly a prefix,
3
+ * converting .ts -> .js, and ensuring it starts with "./" or "../".
4
+ */
5
+ export declare function buildPathRelative(filePath: string, inputDir: string, stripPrefix: string): string;
6
+ /**
7
+ * Recursively collects files with given extensions, ignoring specified directories
8
+ * and files marked as internal.
9
+ */
10
+ export declare function collectFiles(dir: string, exts: string[], recursive: boolean, ignoreDirs: string[], verbose: boolean, includeInternal: boolean, internalMarker: string, outFile?: string): Promise<string[]>;
11
+ /**
12
+ * Creates aggregator lines for a single file.
13
+ *
14
+ * If `useNamed` is true, parses named exports and produces up to two lines:
15
+ * - import type { ... } / export type { ... }
16
+ * - import { ... } / export { ... }
17
+ *
18
+ * If `useNamed` is false, produces a single star import or export.
19
+ *
20
+ * @param usedIdentifiers A set to track and ensure unique identifiers for star imports.
21
+ */
22
+ export declare function generateAggregatorLines(filePath: string, inputDir: string, stripPrefix: string, useImport: boolean, useNamed: boolean, usedIdentifiers?: Set<string>): Promise<string[]>;
23
+ /**
24
+ * Parses a file to extract named exports, separating type exports from value exports.
25
+ * Deduplicates export names (to handle overloads).
26
+ */
27
+ export declare function getNamedExports(filePath: string): Promise<{
28
+ typeNames: string[];
29
+ valueNames: string[];
30
+ }>;
31
+ /**
32
+ * Generates a valid identifier for star imports based on the file name.
33
+ * For star imports, we generate an identifier from the filename, e.g.
34
+ * 'utils-cwd.ts' -> 'utils_cwd'
35
+ * so we do: import * as utils_cwd from "./utils-cwd";
36
+ */
37
+ export declare function guessStarImportIdentifier(filePath: string): string;
38
+ /**
39
+ * Prints usage examples based on whether dev mode or not.
40
+ */
41
+ export declare function printUsage(isDev?: boolean): void;
@@ -0,0 +1,197 @@
1
+ import path from "@reliverse/pathkit";
2
+ import fs from "@reliverse/relifso";
3
+ import { relinka } from "@reliverse/relinka";
4
+ export function buildPathRelative(filePath, inputDir, stripPrefix) {
5
+ let resolved = path.resolve(filePath);
6
+ const resolvedStrip = stripPrefix ? path.resolve(stripPrefix) : "";
7
+ if (resolvedStrip && resolved.startsWith(resolvedStrip)) {
8
+ resolved = resolved.slice(resolvedStrip.length);
9
+ } else {
10
+ resolved = path.relative(path.resolve(inputDir), resolved);
11
+ }
12
+ while (resolved.startsWith(path.sep)) {
13
+ resolved = resolved.slice(1);
14
+ }
15
+ resolved = resolved.replace(/\\/g, "/");
16
+ if (resolved.toLowerCase().endsWith(".ts")) {
17
+ resolved = `${resolved.slice(0, -3)}.js`;
18
+ }
19
+ if (!resolved.startsWith("./") && !resolved.startsWith("../")) {
20
+ resolved = `./${resolved}`;
21
+ }
22
+ resolved = resolved.replace(/\/+/g, "/");
23
+ return resolved;
24
+ }
25
+ export async function collectFiles(dir, exts, recursive, ignoreDirs, verbose, includeInternal, internalMarker, outFile) {
26
+ const found = [];
27
+ const entries = await fs.readdir(dir, { withFileTypes: true });
28
+ for (const entry of entries) {
29
+ const fullPath = path.join(dir, entry.name);
30
+ if (outFile && path.resolve(fullPath) === path.resolve(outFile)) {
31
+ if (verbose) {
32
+ relinka("log", `Skipping output file: ${fullPath}`);
33
+ }
34
+ continue;
35
+ }
36
+ if (entry.isDirectory()) {
37
+ if (ignoreDirs.includes(entry.name)) {
38
+ if (verbose) {
39
+ relinka("log", `Skipping ignored directory: ${fullPath}`);
40
+ }
41
+ continue;
42
+ }
43
+ if (recursive) {
44
+ const sub = await collectFiles(
45
+ fullPath,
46
+ exts,
47
+ recursive,
48
+ ignoreDirs,
49
+ verbose,
50
+ includeInternal,
51
+ internalMarker,
52
+ outFile
53
+ );
54
+ found.push(...sub);
55
+ }
56
+ } else if (entry.isFile()) {
57
+ if (!includeInternal && path.basename(fullPath).startsWith(internalMarker)) {
58
+ if (verbose) {
59
+ relinka("log", `Skipping internal file: ${fullPath}`);
60
+ }
61
+ continue;
62
+ }
63
+ if (exts.some((ext) => entry.name.toLowerCase().endsWith(ext))) {
64
+ if (verbose) {
65
+ relinka("log", `Found file: ${fullPath}`);
66
+ }
67
+ found.push(fullPath);
68
+ }
69
+ }
70
+ }
71
+ return found;
72
+ }
73
+ export async function generateAggregatorLines(filePath, inputDir, stripPrefix, useImport, useNamed, usedIdentifiers) {
74
+ const importPath = buildPathRelative(filePath, inputDir, stripPrefix);
75
+ if (!useNamed) {
76
+ if (useImport) {
77
+ let ident = guessStarImportIdentifier(filePath);
78
+ if (usedIdentifiers) {
79
+ let uniqueIdent = ident;
80
+ let counter = 1;
81
+ while (usedIdentifiers.has(uniqueIdent)) {
82
+ uniqueIdent = `${ident}_${counter}`;
83
+ counter++;
84
+ }
85
+ usedIdentifiers.add(uniqueIdent);
86
+ ident = uniqueIdent;
87
+ }
88
+ return [`import * as ${ident} from "${importPath}";`];
89
+ }
90
+ return [`export * from "${importPath}";`];
91
+ }
92
+ const { typeNames, valueNames } = await getNamedExports(filePath);
93
+ if (!typeNames.length && !valueNames.length) {
94
+ return [];
95
+ }
96
+ if (useImport) {
97
+ const lines2 = [];
98
+ if (typeNames.length > 0) {
99
+ lines2.push(`import type { ${typeNames.join(", ")} } from "${importPath}";`);
100
+ }
101
+ if (valueNames.length > 0) {
102
+ lines2.push(`import { ${valueNames.join(", ")} } from "${importPath}";`);
103
+ }
104
+ return lines2;
105
+ }
106
+ const lines = [];
107
+ if (typeNames.length > 0) {
108
+ lines.push(`export type { ${typeNames.join(", ")} } from "${importPath}";`);
109
+ }
110
+ if (valueNames.length > 0) {
111
+ lines.push(`export { ${valueNames.join(", ")} } from "${importPath}";`);
112
+ }
113
+ return lines;
114
+ }
115
+ export async function getNamedExports(filePath) {
116
+ try {
117
+ const code = await fs.readFile(filePath, "utf8");
118
+ const typeNamesSet = /* @__PURE__ */ new Set();
119
+ const valueNamesSet = /* @__PURE__ */ new Set();
120
+ const patterns = [
121
+ // Regular exports and default exports
122
+ /^export\s+(?:default\s+)?(?:async\s+)?(function|const|class|let|var|type|interface|enum)\s+([A-Za-z0-9_$]+)/gm,
123
+ // Named exports and re-exports
124
+ /^export\s*{([^}]+)}(?:\s+from\s+['"][^'"]+['"])?/gm,
125
+ // Export assignments
126
+ /^export\s*=\s*([A-Za-z0-9_$]+)/gm
127
+ ];
128
+ for (const pattern of patterns) {
129
+ let match;
130
+ while (true) {
131
+ match = pattern.exec(code);
132
+ if (!match) break;
133
+ const matchGroups = match;
134
+ if (pattern.source.includes("{([^}]+)}") && matchGroups[1]) {
135
+ const exports = (matchGroups[1] ?? "").split(",").map(
136
+ (e) => e?.trim()?.split(/\s+as\s+/)?.[0]?.trim() ?? ""
137
+ );
138
+ for (const exp of exports) {
139
+ const name = exp.replace(/^type\s+/, "");
140
+ if (exp.startsWith("type ")) {
141
+ typeNamesSet.add(name);
142
+ } else {
143
+ valueNamesSet.add(name);
144
+ }
145
+ }
146
+ } else if (pattern.source.includes("=\\s*([A-Za-z0-9_$]+)") && matchGroups[1]) {
147
+ valueNamesSet.add(matchGroups[1]);
148
+ } else {
149
+ const keyword = matchGroups[1];
150
+ const name = matchGroups[2];
151
+ if (keyword && name) {
152
+ if (keyword === "type" || keyword === "interface" || keyword === "enum") {
153
+ typeNamesSet.add(name);
154
+ } else {
155
+ valueNamesSet.add(name);
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }
161
+ return {
162
+ typeNames: Array.from(typeNamesSet),
163
+ valueNames: Array.from(valueNamesSet)
164
+ };
165
+ } catch (error) {
166
+ relinka("error", `Error reading file ${filePath}: ${error}`);
167
+ return { typeNames: [], valueNames: [] };
168
+ }
169
+ }
170
+ export function guessStarImportIdentifier(filePath) {
171
+ const base = path.basename(filePath, path.extname(filePath));
172
+ let identifier = base.replace(/[^a-zA-Z0-9_$]/g, "_");
173
+ if (/^\d/.test(identifier)) {
174
+ identifier = `_${identifier}`;
175
+ }
176
+ return identifier || "file";
177
+ }
178
+ export function printUsage(isDev) {
179
+ relinka("log", "====================");
180
+ relinka("log", "TOOLS USAGE EXAMPLES");
181
+ relinka("log", "====================");
182
+ relinka(
183
+ "log",
184
+ `${isDev ? "bun dev:agg" : "dler tools"} --tool agg --input <dir> --out <file> [options]`
185
+ );
186
+ if (isDev) {
187
+ relinka(
188
+ "log",
189
+ "bun dev:tools agg --input src/libs/sdk/sdk-impl --out src/libs/sdk/sdk-mod.ts --recursive --named --strip src/libs/sdk"
190
+ );
191
+ } else {
192
+ relinka(
193
+ "log",
194
+ "dler tools --tool agg --input src/libs --out aggregator.ts --recursive --named"
195
+ );
196
+ }
197
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Checks if a file exists at the given path
3
+ */
4
+ export declare function fileExists(filePath: string): Promise<boolean>;
5
+ /**
6
+ * Finds the main package based on dler configuration with fallbacks
7
+ */
8
+ export declare function findMainEntryFile(config: any): Promise<string | null>;
@@ -0,0 +1,26 @@
1
+ import path from "@reliverse/pathkit";
2
+ import fs from "@reliverse/relifso";
3
+ export async function fileExists(filePath) {
4
+ return await fs.pathExists(filePath);
5
+ }
6
+ export async function findMainEntryFile(config) {
7
+ const { coreEntryFile, coreEntrySrcDir } = config;
8
+ if (coreEntryFile && coreEntrySrcDir) {
9
+ const configuredPath = path.join(coreEntrySrcDir, coreEntryFile);
10
+ if (await fileExists(configuredPath)) {
11
+ return configuredPath;
12
+ }
13
+ }
14
+ const fallbackPatterns = [
15
+ path.join(coreEntrySrcDir || "src", "mod.ts"),
16
+ path.join(coreEntrySrcDir || "src", "index.ts"),
17
+ path.join(coreEntrySrcDir || "src", "mod.js"),
18
+ path.join(coreEntrySrcDir || "src", "index.js")
19
+ ];
20
+ for (const pattern of fallbackPatterns) {
21
+ if (await fileExists(pattern)) {
22
+ return pattern;
23
+ }
24
+ }
25
+ return null;
26
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Checks if the first line of a file contains the disable aggregation comment
3
+ */
4
+ export declare function isAggregationDisabled(filePath: any): Promise<boolean>;