@reliverse/build 2.2.7
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/dist/impl/assets.d.ts +28 -0
- package/dist/impl/assets.js +188 -0
- package/dist/impl/cache.d.ts +25 -0
- package/dist/impl/cache.js +209 -0
- package/dist/impl/constants.d.ts +44 -0
- package/dist/impl/constants.js +45 -0
- package/dist/impl/debug.d.ts +30 -0
- package/dist/impl/debug.js +150 -0
- package/dist/impl/dependency-tracker.d.ts +23 -0
- package/dist/impl/dependency-tracker.js +113 -0
- package/dist/impl/dev-server.d.ts +24 -0
- package/dist/impl/dev-server.js +360 -0
- package/dist/impl/dts-generator.d.ts +26 -0
- package/dist/impl/dts-generator.js +514 -0
- package/dist/impl/go-build.d.ts +10 -0
- package/dist/impl/go-build.js +350 -0
- package/dist/impl/html-processor.d.ts +21 -0
- package/dist/impl/html-processor.js +167 -0
- package/dist/impl/impl.d.ts +0 -0
- package/dist/impl/impl.js +0 -0
- package/dist/impl/plugins/asset-optimization.d.ts +2 -0
- package/dist/impl/plugins/asset-optimization.js +114 -0
- package/dist/impl/plugins/bundle-analyzer.d.ts +2 -0
- package/dist/impl/plugins/bundle-analyzer.js +156 -0
- package/dist/impl/plugins/css-modules.d.ts +2 -0
- package/dist/impl/plugins/css-modules.js +19 -0
- package/dist/impl/plugins/index.d.ts +21 -0
- package/dist/impl/plugins/index.js +65 -0
- package/dist/impl/plugins/performance.d.ts +2 -0
- package/dist/impl/plugins/performance.js +62 -0
- package/dist/impl/plugins/react-refresh.d.ts +2 -0
- package/dist/impl/plugins/react-refresh.js +33 -0
- package/dist/impl/plugins/svg-as-react.d.ts +2 -0
- package/dist/impl/plugins/svg-as-react.js +18 -0
- package/dist/impl/plugins/typescript-declarations.d.ts +2 -0
- package/dist/impl/plugins/typescript-declarations.js +48 -0
- package/dist/impl/plugins/worker.d.ts +2 -0
- package/dist/impl/plugins/worker.js +20 -0
- package/dist/impl/presets.d.ts +10 -0
- package/dist/impl/presets.js +196 -0
- package/dist/impl/providers/mkdist/loader.d.ts +4 -0
- package/dist/impl/providers/mkdist/loader.js +26 -0
- package/dist/impl/providers/mkdist/loaders/js.d.ts +2 -0
- package/dist/impl/providers/mkdist/loaders/js.js +50 -0
- package/dist/impl/providers/mkdist/loaders/loaders-mod.d.ts +9 -0
- package/dist/impl/providers/mkdist/loaders/loaders-mod.js +22 -0
- package/dist/impl/providers/mkdist/make.d.ts +11 -0
- package/dist/impl/providers/mkdist/make.js +230 -0
- package/dist/impl/providers/mkdist/utils/dts.d.ts +11 -0
- package/dist/impl/providers/mkdist/utils/dts.js +117 -0
- package/dist/impl/providers/mkdist/utils/fs.d.ts +1 -0
- package/dist/impl/providers/mkdist/utils/fs.js +15 -0
- package/dist/impl/providers/mkdist-dts.d.ts +24 -0
- package/dist/impl/providers/mkdist-dts.js +8 -0
- package/dist/impl/tsconfig-validator.d.ts +35 -0
- package/dist/impl/tsconfig-validator.js +184 -0
- package/dist/impl/type-guards.d.ts +20 -0
- package/dist/impl/type-guards.js +147 -0
- package/dist/impl/types.d.ts +322 -0
- package/dist/impl/types.js +0 -0
- package/dist/impl/utils/go-build-handler.d.ts +12 -0
- package/dist/impl/utils/go-build-handler.js +83 -0
- package/dist/impl/utils/log-extraction.d.ts +25 -0
- package/dist/impl/utils/log-extraction.js +24 -0
- package/dist/impl/utils/package-filtering.d.ts +5 -0
- package/dist/impl/utils/package-filtering.js +22 -0
- package/dist/impl/utils/rebuild-queue.d.ts +38 -0
- package/dist/impl/utils/rebuild-queue.js +110 -0
- package/dist/impl/validation.d.ts +9 -0
- package/dist/impl/validation.js +332 -0
- package/dist/impl/watch.d.ts +21 -0
- package/dist/impl/watch.js +144 -0
- package/dist/mod.d.ts +17 -0
- package/dist/mod.js +1390 -0
- package/package.json +42 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { resolveLoaders } from "./loaders/loaders-mod.js";
|
|
2
|
+
export function createLoader(loaderOptions = {}) {
|
|
3
|
+
const loaders = resolveLoaders(loaderOptions.loaders);
|
|
4
|
+
const loadFile = async (input) => {
|
|
5
|
+
const context = {
|
|
6
|
+
loadFile,
|
|
7
|
+
options: loaderOptions
|
|
8
|
+
};
|
|
9
|
+
for (const loader of loaders) {
|
|
10
|
+
const outputs = await loader(input, context);
|
|
11
|
+
if (outputs?.length) {
|
|
12
|
+
return outputs;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return [
|
|
16
|
+
{
|
|
17
|
+
path: input.path,
|
|
18
|
+
srcPath: input.srcPath,
|
|
19
|
+
raw: true
|
|
20
|
+
}
|
|
21
|
+
];
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
loadFile
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { transform } from "esbuild";
|
|
2
|
+
import jiti from "jiti";
|
|
3
|
+
const DECLARATION_RE = /\.d\.[cm]?ts$/;
|
|
4
|
+
const CM_LETTER_RE = /(?<=\.)(c|m)(?=[jt]s$)/;
|
|
5
|
+
const KNOWN_EXT_RE = /\.(c|m)?[jt]sx?$/;
|
|
6
|
+
const TS_EXTS = /* @__PURE__ */ new Set([".ts", ".mts", ".cts"]);
|
|
7
|
+
export const jsLoader = async (input, { options }) => {
|
|
8
|
+
if (!KNOWN_EXT_RE.test(input.path) || DECLARATION_RE.test(input.path)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const output = [];
|
|
12
|
+
let contents = await input.getContents();
|
|
13
|
+
if (options.declaration && !input.srcPath?.match(DECLARATION_RE)) {
|
|
14
|
+
const cm = input.srcPath?.match(CM_LETTER_RE)?.[0] || "";
|
|
15
|
+
const extension2 = `.d.${cm}ts`;
|
|
16
|
+
output.push({
|
|
17
|
+
contents,
|
|
18
|
+
srcPath: input.srcPath,
|
|
19
|
+
path: input.path,
|
|
20
|
+
extension: extension2,
|
|
21
|
+
declaration: true
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (TS_EXTS.has(input.extension)) {
|
|
25
|
+
contents = await transform(contents, {
|
|
26
|
+
...options.esbuild,
|
|
27
|
+
loader: "ts"
|
|
28
|
+
}).then((r) => r.code);
|
|
29
|
+
} else if (input.extension === ".jsx") {
|
|
30
|
+
contents = await transform(contents, {
|
|
31
|
+
loader: "jsx",
|
|
32
|
+
...options.esbuild
|
|
33
|
+
}).then((r) => r.code);
|
|
34
|
+
}
|
|
35
|
+
const isCjs = options.format === "cjs";
|
|
36
|
+
if (isCjs) {
|
|
37
|
+
contents = jiti("").transform({ source: contents, retainLines: false }).replace(/^exports.default = /gm, "module.exports = ").replace(/^var _default = exports.default = /gm, "module.exports = ").replace("module.exports = void 0;", "");
|
|
38
|
+
}
|
|
39
|
+
let extension = isCjs ? ".js" : ".mjs";
|
|
40
|
+
if (options.ext) {
|
|
41
|
+
extension = options.ext.startsWith(".") ? options.ext : `.${options.ext}`;
|
|
42
|
+
}
|
|
43
|
+
output.push({
|
|
44
|
+
contents,
|
|
45
|
+
path: input.path,
|
|
46
|
+
srcPath: input.srcPath,
|
|
47
|
+
extension
|
|
48
|
+
});
|
|
49
|
+
return output;
|
|
50
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Loader } from "../../../types.js";
|
|
2
|
+
declare const loaders: {
|
|
3
|
+
js: import("../../../types.js").MkdistLoader;
|
|
4
|
+
};
|
|
5
|
+
type LoaderName = keyof typeof loaders;
|
|
6
|
+
export declare const defaultLoaders: LoaderName[];
|
|
7
|
+
export declare function resolveLoader(loader: LoaderName | Loader): import("../../../types.js").MkdistLoader;
|
|
8
|
+
export declare function resolveLoaders(loadersParam?: (LoaderName | Loader)[]): import("../../../types.js").MkdistLoader[];
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsLoader } from "./js.js";
|
|
2
|
+
const loaders = {
|
|
3
|
+
js: jsLoader
|
|
4
|
+
};
|
|
5
|
+
export const defaultLoaders = ["js"];
|
|
6
|
+
export function resolveLoader(loader) {
|
|
7
|
+
if (typeof loader === "string") {
|
|
8
|
+
return loaders[loader];
|
|
9
|
+
}
|
|
10
|
+
return loader;
|
|
11
|
+
}
|
|
12
|
+
export function resolveLoaders(loadersParam = defaultLoaders) {
|
|
13
|
+
return loadersParam.map((loaderName) => {
|
|
14
|
+
const _loader = resolveLoader(loaderName);
|
|
15
|
+
if (!_loader) {
|
|
16
|
+
console.warn("Unknown loader:", loaderName);
|
|
17
|
+
}
|
|
18
|
+
return _loader;
|
|
19
|
+
}).filter(
|
|
20
|
+
(loader) => loader !== null && loader !== void 0
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import fsp from "node:fs/promises";
|
|
2
|
+
import { basename, dirname, extname, join, resolve } from "node:path";
|
|
3
|
+
import { logger } from "@reliverse/relinka";
|
|
4
|
+
import defu from "defu";
|
|
5
|
+
import { glob } from "tinyglobby";
|
|
6
|
+
import { createLoader } from "./loader.js";
|
|
7
|
+
import { getDeclarations, normalizeCompilerOptions } from "./utils/dts.js";
|
|
8
|
+
import { copyFileWithStream } from "./utils/fs.js";
|
|
9
|
+
export async function mkdist(options) {
|
|
10
|
+
const startTime = Date.now();
|
|
11
|
+
options.rootDir = resolve(process.cwd(), options.rootDir || ".");
|
|
12
|
+
options.srcDir = resolve(options.rootDir, options.srcDir || "src");
|
|
13
|
+
options.distDir = resolve(options.rootDir, options.distDir || "dist");
|
|
14
|
+
if (options.cleanDist !== false) {
|
|
15
|
+
if (options.verbose) {
|
|
16
|
+
logger.debug("Cleaning distribution directory...");
|
|
17
|
+
}
|
|
18
|
+
await fsp.unlink(options.distDir).catch(() => {
|
|
19
|
+
});
|
|
20
|
+
await fsp.rm(options.distDir, { recursive: true, force: true });
|
|
21
|
+
await fsp.mkdir(options.distDir, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
if (options.verbose) {
|
|
24
|
+
logger.debug("Scanning input files...");
|
|
25
|
+
}
|
|
26
|
+
const filePaths = await glob(options.pattern || "**", {
|
|
27
|
+
absolute: false,
|
|
28
|
+
ignore: ["**/node_modules", "**/coverage", "**/.git"],
|
|
29
|
+
cwd: options.srcDir,
|
|
30
|
+
dot: true,
|
|
31
|
+
...options.globOptions
|
|
32
|
+
});
|
|
33
|
+
const files = filePaths.map((path) => {
|
|
34
|
+
const sourcePath = resolve(options.srcDir, path);
|
|
35
|
+
return {
|
|
36
|
+
path,
|
|
37
|
+
srcPath: sourcePath,
|
|
38
|
+
extension: extname(path),
|
|
39
|
+
getContents: () => fsp.readFile(sourcePath, { encoding: "utf8" })
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
if (options.verbose) {
|
|
43
|
+
logger.debug(`Found ${files.length} files to process`);
|
|
44
|
+
}
|
|
45
|
+
options.typescript ||= {};
|
|
46
|
+
if (options.typescript.compilerOptions) {
|
|
47
|
+
if (options.verbose) {
|
|
48
|
+
logger.debug("Normalizing TypeScript compiler options...");
|
|
49
|
+
}
|
|
50
|
+
options.typescript.compilerOptions = await normalizeCompilerOptions(
|
|
51
|
+
options.typescript.compilerOptions
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
options.typescript.compilerOptions = defu(
|
|
55
|
+
{ noEmit: false },
|
|
56
|
+
options.typescript.compilerOptions,
|
|
57
|
+
{
|
|
58
|
+
allowJs: true,
|
|
59
|
+
declaration: true,
|
|
60
|
+
skipLibCheck: true,
|
|
61
|
+
strictNullChecks: true,
|
|
62
|
+
emitDeclarationOnly: true,
|
|
63
|
+
allowImportingTsExtensions: true,
|
|
64
|
+
allowNonTsExtensions: true
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
if (options.verbose) {
|
|
68
|
+
logger.debug("Creating file loaders...");
|
|
69
|
+
}
|
|
70
|
+
const { loadFile } = createLoader(options);
|
|
71
|
+
if (options.verbose) {
|
|
72
|
+
logger.debug("Processing files with loaders...");
|
|
73
|
+
}
|
|
74
|
+
const outputs = [];
|
|
75
|
+
let _processedCount = 0;
|
|
76
|
+
await Promise.all(
|
|
77
|
+
files.map(async (file) => {
|
|
78
|
+
const result = await loadFile(file);
|
|
79
|
+
if (result) {
|
|
80
|
+
outputs.push(...result);
|
|
81
|
+
}
|
|
82
|
+
_processedCount++;
|
|
83
|
+
})
|
|
84
|
+
);
|
|
85
|
+
if (options.verbose) {
|
|
86
|
+
logger.debug("Normalizing output extensions...");
|
|
87
|
+
}
|
|
88
|
+
const pathConflicts = [];
|
|
89
|
+
for (const output of outputs.filter((o) => o.extension)) {
|
|
90
|
+
const renamed = basename(output.path, extname(output.path)) + output.extension;
|
|
91
|
+
output.path = join(dirname(output.path), renamed);
|
|
92
|
+
const conflictingOutput = outputs.find(
|
|
93
|
+
(o) => o !== output && o.path === output.path
|
|
94
|
+
);
|
|
95
|
+
if (conflictingOutput) {
|
|
96
|
+
pathConflicts.push(output.path);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (pathConflicts.length > 0) {
|
|
100
|
+
const errorMessage = `Output path conflict detected for paths: ${pathConflicts.join(", ")}. Multiple files would write to the same output path.`;
|
|
101
|
+
logger.error(errorMessage);
|
|
102
|
+
throw new Error(errorMessage);
|
|
103
|
+
}
|
|
104
|
+
const dtsOutputs = outputs.filter((o) => o.declaration && !o.skip);
|
|
105
|
+
if (dtsOutputs.length > 0) {
|
|
106
|
+
if (options.verbose) {
|
|
107
|
+
logger.debug(
|
|
108
|
+
`Generating TypeScript declarations for ${dtsOutputs.length} files...`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
const vfs = /* @__PURE__ */ new Map();
|
|
112
|
+
for (const output of dtsOutputs) {
|
|
113
|
+
const originalContent = await fsp.readFile(output.srcPath, {
|
|
114
|
+
encoding: "utf8"
|
|
115
|
+
});
|
|
116
|
+
const normalizedPath = output.srcPath.replace(/\\/g, "/");
|
|
117
|
+
vfs.set(normalizedPath, originalContent);
|
|
118
|
+
}
|
|
119
|
+
const declarations = /* @__PURE__ */ Object.create(null);
|
|
120
|
+
const getDeclarationsResult = await getDeclarations(vfs, options);
|
|
121
|
+
Object.assign(declarations, getDeclarationsResult);
|
|
122
|
+
let _dtsProcessed = 0;
|
|
123
|
+
for (const output of dtsOutputs) {
|
|
124
|
+
const normalizedPath = output.srcPath.replace(/\\/g, "/");
|
|
125
|
+
const result = declarations[normalizedPath];
|
|
126
|
+
output.contents = result?.contents || "";
|
|
127
|
+
if (result?.errors) {
|
|
128
|
+
output.errors = result.errors;
|
|
129
|
+
}
|
|
130
|
+
_dtsProcessed++;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (options.verbose) {
|
|
134
|
+
logger.debug("Resolving relative imports...");
|
|
135
|
+
}
|
|
136
|
+
const outPaths = new Set(outputs.map((o) => o.path));
|
|
137
|
+
const resolveId = (from, id = "", resolveExtensions) => {
|
|
138
|
+
if (!id.startsWith(".")) {
|
|
139
|
+
return id;
|
|
140
|
+
}
|
|
141
|
+
for (const extension of resolveExtensions) {
|
|
142
|
+
if (outPaths.has(join(dirname(from), id + extension))) {
|
|
143
|
+
return id + extension;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return id;
|
|
147
|
+
};
|
|
148
|
+
const esmResolveExtensions = [
|
|
149
|
+
"",
|
|
150
|
+
"/index.mjs",
|
|
151
|
+
"/index.js",
|
|
152
|
+
".mjs",
|
|
153
|
+
".ts",
|
|
154
|
+
".js"
|
|
155
|
+
];
|
|
156
|
+
const esmOutputs = outputs.filter(
|
|
157
|
+
(o) => o.extension === ".mjs" || o.extension === ".js"
|
|
158
|
+
);
|
|
159
|
+
for (const output of esmOutputs) {
|
|
160
|
+
if (output.contents) {
|
|
161
|
+
output.contents = output.contents.replace(
|
|
162
|
+
/(import|export)(\s+(?:.+|{[\s\w,]+})\s+from\s+["'])(.*)(["'])/g,
|
|
163
|
+
(_, type, head, id, tail) => type + head + resolveId(output.path, id, esmResolveExtensions) + tail
|
|
164
|
+
).replace(
|
|
165
|
+
/import\((["'])(.*)(["'])\)/g,
|
|
166
|
+
(_, head, id, tail) => "import(" + head + resolveId(output.path, id, esmResolveExtensions) + tail + ")"
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const cjsResolveExtensions = ["", "/index.cjs", ".cjs"];
|
|
171
|
+
const cjsOutputs = outputs.filter((o) => o.extension === ".cjs");
|
|
172
|
+
for (const output of cjsOutputs) {
|
|
173
|
+
if (output.contents) {
|
|
174
|
+
output.contents = output.contents.replace(
|
|
175
|
+
/require\((["'])(.*)(["'])\)/g,
|
|
176
|
+
(_, head, id, tail) => "require(" + head + resolveId(output.path, id, cjsResolveExtensions) + tail + ")"
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const outputsToWrite = outputs.filter((o) => !o.skip);
|
|
181
|
+
if (options.verbose) {
|
|
182
|
+
logger.debug(`Writing ${outputsToWrite.length} output files...`);
|
|
183
|
+
}
|
|
184
|
+
const writtenFiles = [];
|
|
185
|
+
const errors = [];
|
|
186
|
+
let _writtenCount = 0;
|
|
187
|
+
await Promise.all(
|
|
188
|
+
outputsToWrite.map(async (output) => {
|
|
189
|
+
try {
|
|
190
|
+
const outFile = join(options.distDir, output.path);
|
|
191
|
+
await fsp.mkdir(dirname(outFile), { recursive: true });
|
|
192
|
+
await (output.raw ? copyFileWithStream(output.srcPath, outFile) : fsp.writeFile(outFile, output.contents || "", "utf8"));
|
|
193
|
+
writtenFiles.push(outFile);
|
|
194
|
+
if (output.errors) {
|
|
195
|
+
errors.push({ filename: outFile, errors: output.errors });
|
|
196
|
+
}
|
|
197
|
+
} catch (error) {
|
|
198
|
+
const errorMessage = `Failed to write file ${output.path}: ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
199
|
+
errors.push({
|
|
200
|
+
filename: output.path,
|
|
201
|
+
errors: [new TypeError(errorMessage)]
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
_writtenCount++;
|
|
205
|
+
})
|
|
206
|
+
);
|
|
207
|
+
const duration = Date.now() - startTime;
|
|
208
|
+
if (errors.length > 0) {
|
|
209
|
+
logger.warn(`Build completed with ${errors.length} errors`);
|
|
210
|
+
for (const error of errors.slice(0, 5)) {
|
|
211
|
+
logger.error(
|
|
212
|
+
`Error in ${error.filename}: ${error.errors[0]?.message || "Unknown error"}`
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
if (errors.length > 5) {
|
|
216
|
+
logger.error(`... and ${errors.length - 5} more errors`);
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
if (options.verbose) {
|
|
220
|
+
logger.debug("Build completed successfully!");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
result: {
|
|
225
|
+
errors,
|
|
226
|
+
writtenFiles
|
|
227
|
+
},
|
|
228
|
+
duration
|
|
229
|
+
};
|
|
230
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TSConfig } from "pkg-types";
|
|
2
|
+
import type { CompilerHost, EmitResult } from "typescript";
|
|
3
|
+
import type { MkdistOptions } from "../../../types.js";
|
|
4
|
+
export declare function normalizeCompilerOptions(_options: TSConfig["compilerOptions"]): Promise<any>;
|
|
5
|
+
export type DeclarationOutput = Record<string, {
|
|
6
|
+
contents: string;
|
|
7
|
+
errors?: Error[];
|
|
8
|
+
}>;
|
|
9
|
+
export declare function getDeclarations(vfs: Map<string, string>, opts?: Partial<MkdistOptions>): Promise<DeclarationOutput>;
|
|
10
|
+
export declare function extractDeclarations(vfs: Map<string, string>, inputFiles: string[], opts?: Partial<MkdistOptions>): DeclarationOutput;
|
|
11
|
+
export declare function augmentWithDiagnostics(result: EmitResult, output: DeclarationOutput, tsHost: CompilerHost, ts: typeof import("typescript")): void;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { statSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
findDynamicImports,
|
|
5
|
+
findExports,
|
|
6
|
+
findStaticImports,
|
|
7
|
+
findTypeExports
|
|
8
|
+
} from "mlly";
|
|
9
|
+
export async function normalizeCompilerOptions(_options) {
|
|
10
|
+
const ts = await import("typescript").then((r) => r.default || r);
|
|
11
|
+
return ts.convertCompilerOptionsFromJson(_options, process.cwd()).options;
|
|
12
|
+
}
|
|
13
|
+
export async function getDeclarations(vfs, opts) {
|
|
14
|
+
const ts = await import("typescript").then((r) => r.default || r);
|
|
15
|
+
const inputFiles = [...vfs.keys()];
|
|
16
|
+
const tsHost = ts.createCompilerHost(opts?.typescript?.compilerOptions || {});
|
|
17
|
+
tsHost.writeFile = (fileName, declaration) => {
|
|
18
|
+
vfs.set(fileName, declaration);
|
|
19
|
+
};
|
|
20
|
+
const _readFile = tsHost.readFile;
|
|
21
|
+
tsHost.readFile = (filename) => {
|
|
22
|
+
if (vfs.has(filename)) {
|
|
23
|
+
return vfs.get(filename);
|
|
24
|
+
}
|
|
25
|
+
return _readFile(filename);
|
|
26
|
+
};
|
|
27
|
+
const program = ts.createProgram(
|
|
28
|
+
inputFiles,
|
|
29
|
+
opts?.typescript?.compilerOptions || {},
|
|
30
|
+
tsHost
|
|
31
|
+
);
|
|
32
|
+
const result = program.emit();
|
|
33
|
+
const output = extractDeclarations(vfs, inputFiles, opts);
|
|
34
|
+
augmentWithDiagnostics(result, output, tsHost, ts);
|
|
35
|
+
return output;
|
|
36
|
+
}
|
|
37
|
+
const JS_EXT_RE = /\.(m|c)?(ts|js)$/;
|
|
38
|
+
const JSX_EXT_RE = /\.(m|c)?(ts|js)x?$/;
|
|
39
|
+
const RELATIVE_RE = /^\.{1,2}[/\\]/;
|
|
40
|
+
export function extractDeclarations(vfs, inputFiles, opts) {
|
|
41
|
+
const output = {};
|
|
42
|
+
for (const filename of inputFiles) {
|
|
43
|
+
const dtsFilename = filename.replace(JSX_EXT_RE, ".d.$1$2");
|
|
44
|
+
const dtsFilenameNormalized = dtsFilename.replace(/\\/g, "/");
|
|
45
|
+
let contents = vfs.get(dtsFilename) || vfs.get(dtsFilenameNormalized) || "";
|
|
46
|
+
if (opts?.addRelativeDeclarationExtensions) {
|
|
47
|
+
const ext = filename.match(JS_EXT_RE)?.[0].replace(/ts$/, "js") || ".js";
|
|
48
|
+
const imports = findStaticImports(contents);
|
|
49
|
+
const exports = findExports(contents);
|
|
50
|
+
const typeExports = findTypeExports(contents);
|
|
51
|
+
const dynamicImports = findDynamicImports(contents).map(
|
|
52
|
+
(dynamicImport) => {
|
|
53
|
+
let specifier;
|
|
54
|
+
try {
|
|
55
|
+
const value = JSON.parse(dynamicImport.expression);
|
|
56
|
+
if (typeof value === "string") {
|
|
57
|
+
specifier = value;
|
|
58
|
+
}
|
|
59
|
+
} catch {
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
code: dynamicImport.code,
|
|
63
|
+
specifier
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
for (const spec of [
|
|
68
|
+
...exports,
|
|
69
|
+
...typeExports,
|
|
70
|
+
...imports,
|
|
71
|
+
...dynamicImports
|
|
72
|
+
]) {
|
|
73
|
+
if (!spec.specifier || !RELATIVE_RE.test(spec.specifier)) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const srcPath = resolve(filename, "..", spec.specifier);
|
|
77
|
+
const srcDtsPath = srcPath + ext.replace(JS_EXT_RE, ".d.$1$2");
|
|
78
|
+
let specifier = spec.specifier;
|
|
79
|
+
try {
|
|
80
|
+
if (!vfs.get(srcDtsPath)) {
|
|
81
|
+
const stat = statSync(srcPath);
|
|
82
|
+
if (stat.isDirectory()) {
|
|
83
|
+
specifier += "/index";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
87
|
+
}
|
|
88
|
+
contents = contents.replace(
|
|
89
|
+
spec.code,
|
|
90
|
+
spec.code.replace(spec.specifier, specifier + ext)
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
output[filename] = { contents };
|
|
95
|
+
vfs.delete(filename);
|
|
96
|
+
}
|
|
97
|
+
return output;
|
|
98
|
+
}
|
|
99
|
+
export function augmentWithDiagnostics(result, output, tsHost, ts) {
|
|
100
|
+
if (result.diagnostics?.length) {
|
|
101
|
+
for (const diagnostic of result.diagnostics) {
|
|
102
|
+
const filename = diagnostic.file?.fileName;
|
|
103
|
+
if (filename && filename in output && output[filename]) {
|
|
104
|
+
const entry = output[filename];
|
|
105
|
+
if (entry) {
|
|
106
|
+
entry.errors = entry.errors || [];
|
|
107
|
+
entry.errors.push(
|
|
108
|
+
new TypeError(ts.formatDiagnostics([diagnostic], tsHost), {
|
|
109
|
+
cause: diagnostic
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
console.error(ts.formatDiagnostics(result.diagnostics, tsHost));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function copyFileWithStream(sourcePath: string, outPath: string): Promise<unknown>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createReadStream, createWriteStream } from "node:fs";
|
|
2
|
+
import { pipeline } from "node:stream";
|
|
3
|
+
export function copyFileWithStream(sourcePath, outPath) {
|
|
4
|
+
const sourceStream = createReadStream(sourcePath);
|
|
5
|
+
const outStream = createWriteStream(outPath);
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
pipeline(sourceStream, outStream, (error) => {
|
|
8
|
+
if (error) {
|
|
9
|
+
reject(error);
|
|
10
|
+
} else {
|
|
11
|
+
resolve(void 0);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DtsOptions } from "@reliverse/config/impl/build";
|
|
2
|
+
import type { TSConfig } from "pkg-types";
|
|
3
|
+
import type { PackageInfo } from "../types.js";
|
|
4
|
+
export interface MkdistDtsOptions {
|
|
5
|
+
addRelativeDeclarationExtensions?: boolean;
|
|
6
|
+
pattern?: string;
|
|
7
|
+
globOptions?: Record<string, unknown>;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface DeclarationOutput {
|
|
11
|
+
[filename: string]: {
|
|
12
|
+
contents: string;
|
|
13
|
+
errors?: Error[];
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generate TypeScript declarations using mkdist's VFS approach
|
|
18
|
+
* This function bridges the dts-generator.ts expectations with mkdist's internal implementation
|
|
19
|
+
*/
|
|
20
|
+
export declare function getDeclarations(vfs: Map<string, string>, _pkg: PackageInfo, _dtsOptions: DtsOptions, _outputDir: string, mkdistOptions?: MkdistDtsOptions): Promise<DeclarationOutput>;
|
|
21
|
+
/**
|
|
22
|
+
* Normalize TypeScript compiler options for declaration generation
|
|
23
|
+
*/
|
|
24
|
+
export declare function normalizeCompilerOptions(options: TSConfig["compilerOptions"]): Promise<import("typescript").CompilerOptions>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { getDeclarations as getMkdistDeclarations } from "./mkdist/utils/dts.js";
|
|
2
|
+
export async function getDeclarations(vfs, _pkg, _dtsOptions, _outputDir, mkdistOptions) {
|
|
3
|
+
return await getMkdistDeclarations(vfs, mkdistOptions);
|
|
4
|
+
}
|
|
5
|
+
export async function normalizeCompilerOptions(options) {
|
|
6
|
+
const ts = await import("typescript").then((r) => r.default || r);
|
|
7
|
+
return ts.convertCompilerOptionsFromJson(options, process.cwd()).options;
|
|
8
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { PackageInfo } from "./types.js";
|
|
2
|
+
export interface TSConfigValidationResult {
|
|
3
|
+
valid: boolean;
|
|
4
|
+
warnings: string[];
|
|
5
|
+
errors: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface TSConfigValidationOptions {
|
|
8
|
+
/** Whether to make validation errors fatal */
|
|
9
|
+
strict?: boolean;
|
|
10
|
+
/** Whether to check for declaration generation compatibility */
|
|
11
|
+
checkDeclarations?: boolean;
|
|
12
|
+
/** Whether to check for build output compatibility */
|
|
13
|
+
checkBuildOutput?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Validate tsconfig.json for common issues and best practices
|
|
17
|
+
*/
|
|
18
|
+
export declare function validateTSConfig(pkg: PackageInfo, options?: TSConfigValidationOptions): Promise<TSConfigValidationResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Validate tsconfig.json for all packages in a workspace
|
|
21
|
+
*/
|
|
22
|
+
export declare function validateAllTSConfigs(packages: PackageInfo[], options?: TSConfigValidationOptions): Promise<{
|
|
23
|
+
valid: boolean;
|
|
24
|
+
results: Array<{
|
|
25
|
+
package: string;
|
|
26
|
+
result: TSConfigValidationResult;
|
|
27
|
+
}>;
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Log validation results in a user-friendly format
|
|
31
|
+
*/
|
|
32
|
+
export declare function logValidationResults(results: Array<{
|
|
33
|
+
package: string;
|
|
34
|
+
result: TSConfigValidationResult;
|
|
35
|
+
}>, verbose?: boolean): void;
|