@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.
Files changed (75) hide show
  1. package/dist/impl/assets.d.ts +28 -0
  2. package/dist/impl/assets.js +188 -0
  3. package/dist/impl/cache.d.ts +25 -0
  4. package/dist/impl/cache.js +209 -0
  5. package/dist/impl/constants.d.ts +44 -0
  6. package/dist/impl/constants.js +45 -0
  7. package/dist/impl/debug.d.ts +30 -0
  8. package/dist/impl/debug.js +150 -0
  9. package/dist/impl/dependency-tracker.d.ts +23 -0
  10. package/dist/impl/dependency-tracker.js +113 -0
  11. package/dist/impl/dev-server.d.ts +24 -0
  12. package/dist/impl/dev-server.js +360 -0
  13. package/dist/impl/dts-generator.d.ts +26 -0
  14. package/dist/impl/dts-generator.js +514 -0
  15. package/dist/impl/go-build.d.ts +10 -0
  16. package/dist/impl/go-build.js +350 -0
  17. package/dist/impl/html-processor.d.ts +21 -0
  18. package/dist/impl/html-processor.js +167 -0
  19. package/dist/impl/impl.d.ts +0 -0
  20. package/dist/impl/impl.js +0 -0
  21. package/dist/impl/plugins/asset-optimization.d.ts +2 -0
  22. package/dist/impl/plugins/asset-optimization.js +114 -0
  23. package/dist/impl/plugins/bundle-analyzer.d.ts +2 -0
  24. package/dist/impl/plugins/bundle-analyzer.js +156 -0
  25. package/dist/impl/plugins/css-modules.d.ts +2 -0
  26. package/dist/impl/plugins/css-modules.js +19 -0
  27. package/dist/impl/plugins/index.d.ts +21 -0
  28. package/dist/impl/plugins/index.js +65 -0
  29. package/dist/impl/plugins/performance.d.ts +2 -0
  30. package/dist/impl/plugins/performance.js +62 -0
  31. package/dist/impl/plugins/react-refresh.d.ts +2 -0
  32. package/dist/impl/plugins/react-refresh.js +33 -0
  33. package/dist/impl/plugins/svg-as-react.d.ts +2 -0
  34. package/dist/impl/plugins/svg-as-react.js +18 -0
  35. package/dist/impl/plugins/typescript-declarations.d.ts +2 -0
  36. package/dist/impl/plugins/typescript-declarations.js +48 -0
  37. package/dist/impl/plugins/worker.d.ts +2 -0
  38. package/dist/impl/plugins/worker.js +20 -0
  39. package/dist/impl/presets.d.ts +10 -0
  40. package/dist/impl/presets.js +196 -0
  41. package/dist/impl/providers/mkdist/loader.d.ts +4 -0
  42. package/dist/impl/providers/mkdist/loader.js +26 -0
  43. package/dist/impl/providers/mkdist/loaders/js.d.ts +2 -0
  44. package/dist/impl/providers/mkdist/loaders/js.js +50 -0
  45. package/dist/impl/providers/mkdist/loaders/loaders-mod.d.ts +9 -0
  46. package/dist/impl/providers/mkdist/loaders/loaders-mod.js +22 -0
  47. package/dist/impl/providers/mkdist/make.d.ts +11 -0
  48. package/dist/impl/providers/mkdist/make.js +230 -0
  49. package/dist/impl/providers/mkdist/utils/dts.d.ts +11 -0
  50. package/dist/impl/providers/mkdist/utils/dts.js +117 -0
  51. package/dist/impl/providers/mkdist/utils/fs.d.ts +1 -0
  52. package/dist/impl/providers/mkdist/utils/fs.js +15 -0
  53. package/dist/impl/providers/mkdist-dts.d.ts +24 -0
  54. package/dist/impl/providers/mkdist-dts.js +8 -0
  55. package/dist/impl/tsconfig-validator.d.ts +35 -0
  56. package/dist/impl/tsconfig-validator.js +184 -0
  57. package/dist/impl/type-guards.d.ts +20 -0
  58. package/dist/impl/type-guards.js +147 -0
  59. package/dist/impl/types.d.ts +322 -0
  60. package/dist/impl/types.js +0 -0
  61. package/dist/impl/utils/go-build-handler.d.ts +12 -0
  62. package/dist/impl/utils/go-build-handler.js +83 -0
  63. package/dist/impl/utils/log-extraction.d.ts +25 -0
  64. package/dist/impl/utils/log-extraction.js +24 -0
  65. package/dist/impl/utils/package-filtering.d.ts +5 -0
  66. package/dist/impl/utils/package-filtering.js +22 -0
  67. package/dist/impl/utils/rebuild-queue.d.ts +38 -0
  68. package/dist/impl/utils/rebuild-queue.js +110 -0
  69. package/dist/impl/validation.d.ts +9 -0
  70. package/dist/impl/validation.js +332 -0
  71. package/dist/impl/watch.d.ts +21 -0
  72. package/dist/impl/watch.js +144 -0
  73. package/dist/mod.d.ts +17 -0
  74. package/dist/mod.js +1390 -0
  75. package/package.json +42 -0
package/dist/mod.js ADDED
@@ -0,0 +1,1390 @@
1
+ import { existsSync, mkdirSync, statSync } from "node:fs";
2
+ import { readdir } from "node:fs/promises";
3
+ import { join, resolve } from "node:path";
4
+ import {
5
+ getPackageBuildConfig,
6
+ mergeBuildOptions
7
+ } from "@reliverse/config/impl/build";
8
+ import {
9
+ findMonorepoRoot,
10
+ loadDlerConfig
11
+ } from "@reliverse/config/impl/discovery";
12
+ import { writeErrorLines } from "@reliverse/helpers";
13
+ import pMap from "@reliverse/mapkit";
14
+ import {
15
+ createIgnoreFilter,
16
+ createIncludeFilter,
17
+ normalizePatterns
18
+ } from "@reliverse/matcha";
19
+ import { relinka } from "@reliverse/relinka";
20
+ import {
21
+ getWorkspacePatterns,
22
+ preparePackageJsonForPublishing,
23
+ readPackageJSON,
24
+ readTSConfig
25
+ } from "@reliverse/typerso";
26
+ import { processAssetsForPackage, processCSSForPackage } from "./impl/assets.js";
27
+ import { BuildCache } from "./impl/cache.js";
28
+ import {
29
+ ALWAYS_IGNORED_PACKAGES,
30
+ FRONTEND_FRAMEWORKS,
31
+ FRONTEND_HTML_PATTERNS,
32
+ GO_PROJECT_DIRS,
33
+ JS_ENTRY_PATTERNS,
34
+ LIBRARY_ENTRY_PATTERNS
35
+ } from "./impl/constants.js";
36
+ import { createDebugLogger } from "./impl/debug.js";
37
+ import { startDevServer } from "./impl/dev-server.js";
38
+ import { processHTMLForPackage } from "./impl/html-processor.js";
39
+ import {
40
+ AssetOptimizationPlugin,
41
+ applyPlugins,
42
+ BundleAnalyzerPlugin,
43
+ CSSModulesPlugin,
44
+ loadPlugins,
45
+ PerformancePlugin,
46
+ pluginRegistry,
47
+ ReactRefreshPlugin,
48
+ SVGAsReactPlugin,
49
+ TypeScriptDeclarationsPlugin,
50
+ WorkerPlugin
51
+ } from "./impl/plugins/index.js";
52
+ import { validateTSConfig } from "./impl/tsconfig-validator.js";
53
+ import { validateBuildConfig } from "./impl/type-guards.js";
54
+ import {
55
+ handleGoBuild,
56
+ handleGoOnlyBuild
57
+ } from "./impl/utils/go-build-handler.js";
58
+ import {
59
+ extractErrors,
60
+ extractWarnings,
61
+ formatLogMessages
62
+ } from "./impl/utils/log-extraction.js";
63
+ import { filterPrivatePackages } from "./impl/utils/package-filtering.js";
64
+ import { startWatchMode } from "./impl/watch.js";
65
+ export {
66
+ addBinFieldToPackageJson,
67
+ extractPackageName,
68
+ parseBinArgument,
69
+ preparePackageJsonForPublishing,
70
+ transformExportsForBuild
71
+ } from "@reliverse/typerso";
72
+ export { generateDeclarations } from "./impl/dts-generator.js";
73
+ export { buildGo } from "./impl/go-build.js";
74
+ export { applyPresets } from "./impl/presets.js";
75
+ export {
76
+ logValidationResults,
77
+ validateAllTSConfigs,
78
+ validateTSConfig
79
+ } from "./impl/tsconfig-validator.js";
80
+ export { validateAndExit } from "./impl/validation.js";
81
+ import { DEFAULT_CONCURRENCY } from "./impl/constants.js";
82
+ let pluginsInitialized = false;
83
+ const initializePlugins = () => {
84
+ if (pluginsInitialized) return;
85
+ pluginRegistry.register(ReactRefreshPlugin);
86
+ pluginRegistry.register(TypeScriptDeclarationsPlugin);
87
+ pluginRegistry.register(AssetOptimizationPlugin);
88
+ pluginRegistry.register(BundleAnalyzerPlugin);
89
+ pluginRegistry.register(CSSModulesPlugin);
90
+ pluginRegistry.register(SVGAsReactPlugin);
91
+ pluginRegistry.register(WorkerPlugin);
92
+ pluginRegistry.register(PerformancePlugin);
93
+ pluginsInitialized = true;
94
+ };
95
+ const formatBytes = (bytes) => {
96
+ if (bytes === 0) return "0 B";
97
+ const k = 1024;
98
+ const sizes = ["B", "KB", "MB", "GB"];
99
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
100
+ return `${parseFloat((bytes / k ** i).toFixed(1))} ${sizes[i]}`;
101
+ };
102
+ const getWorkspacePackages = async (cwd) => {
103
+ const monorepoRoot = await findMonorepoRoot(cwd);
104
+ if (!monorepoRoot) {
105
+ const currentDir = cwd || process.cwd();
106
+ const pkgInfo = await resolvePackageInfo(currentDir, null);
107
+ if (pkgInfo) {
108
+ return [pkgInfo];
109
+ }
110
+ throw new Error(
111
+ "\u274C No monorepo or valid package found. Ensure package.json has 'workspaces' field or contains a valid 'name' field."
112
+ );
113
+ }
114
+ const rootPkg = await readPackageJSON(monorepoRoot);
115
+ if (!rootPkg) {
116
+ throw new Error("\u274C Could not read root package.json");
117
+ }
118
+ const patterns = getWorkspacePatterns(rootPkg);
119
+ if (!patterns.length) {
120
+ throw new Error("\u274C No workspace patterns found in package.json");
121
+ }
122
+ const dlerConfig = await loadDlerConfig(monorepoRoot);
123
+ const packages = [];
124
+ const seenPaths = /* @__PURE__ */ new Set();
125
+ const patternPromises = patterns.map(async (pattern) => {
126
+ let matches = [];
127
+ if (pattern.includes("*")) {
128
+ const glob = new Bun.Glob(pattern);
129
+ matches = Array.from(
130
+ glob.scanSync({ cwd: monorepoRoot, onlyFiles: false })
131
+ );
132
+ } else {
133
+ matches = [pattern];
134
+ }
135
+ const packagePromises = matches.map(async (match) => {
136
+ const packagePath = resolve(monorepoRoot, match);
137
+ if (seenPaths.has(packagePath)) return null;
138
+ seenPaths.add(packagePath);
139
+ return await resolvePackageInfo(packagePath, dlerConfig);
140
+ });
141
+ return await Promise.all(packagePromises);
142
+ });
143
+ const patternResults = await Promise.all(patternPromises);
144
+ for (const patternResult of patternResults) {
145
+ for (const pkgInfo of patternResult) {
146
+ if (pkgInfo) {
147
+ packages.push(pkgInfo);
148
+ }
149
+ }
150
+ }
151
+ const filteredPackages = packages.filter((pkg) => {
152
+ const normalizedPkgPath = resolve(pkg.path);
153
+ const normalizedRootPath = resolve(monorepoRoot);
154
+ return normalizedPkgPath !== normalizedRootPath;
155
+ });
156
+ return filteredPackages;
157
+ };
158
+ const packageJsonCache = /* @__PURE__ */ new Map();
159
+ const entryPointCache = /* @__PURE__ */ new Map();
160
+ const isBuildArtifact = (path) => {
161
+ return path.includes("/dist/") || path.includes("/build/") || path.includes("\\dist\\") || path.includes("\\build\\");
162
+ };
163
+ const detectEntryPoints = async (packagePath) => {
164
+ const cached = entryPointCache.get(packagePath);
165
+ if (cached !== void 0) {
166
+ return cached;
167
+ }
168
+ let pkg = packageJsonCache.get(packagePath);
169
+ if (!pkg) {
170
+ pkg = await readPackageJSON(packagePath);
171
+ if (pkg) {
172
+ packageJsonCache.set(packagePath, pkg);
173
+ }
174
+ }
175
+ if (!pkg) {
176
+ entryPointCache.set(packagePath, []);
177
+ return [];
178
+ }
179
+ const entryPoints = [];
180
+ if (pkg.build?.entrypoints) {
181
+ const entrypoints = Array.isArray(pkg.build.entrypoints) ? pkg.build.entrypoints : [pkg.build.entrypoints];
182
+ const result = entrypoints.map((ep) => resolve(packagePath, ep));
183
+ entryPointCache.set(packagePath, result);
184
+ return result;
185
+ }
186
+ if (pkg.exports) {
187
+ const extractFromExports = (exports, basePath = "") => {
188
+ if (typeof exports === "string") {
189
+ const fullPath = resolve(packagePath, basePath, exports);
190
+ if (existsSync(fullPath) && !isBuildArtifact(fullPath)) {
191
+ entryPoints.push(fullPath);
192
+ }
193
+ } else if (typeof exports === "object" && exports !== null) {
194
+ for (const [key, value] of Object.entries(exports)) {
195
+ if (key === "." || key.startsWith("./")) {
196
+ extractFromExports(value, basePath);
197
+ } else if (key === "import" || key === "require" || key === "types" || key === "default") {
198
+ if (key !== "types") {
199
+ extractFromExports(value, basePath);
200
+ }
201
+ } else if (typeof value === "object" && value !== null) {
202
+ extractFromExports(value, basePath);
203
+ } else if (typeof value === "string") {
204
+ const fullPath = resolve(packagePath, basePath, value);
205
+ if (existsSync(fullPath) && !isBuildArtifact(fullPath)) {
206
+ entryPoints.push(fullPath);
207
+ }
208
+ }
209
+ }
210
+ }
211
+ };
212
+ extractFromExports(pkg.exports);
213
+ }
214
+ const binEntries = await detectBinEntryPoints(packagePath, pkg);
215
+ if (binEntries.length > 0) {
216
+ entryPoints.push(...binEntries);
217
+ }
218
+ if (entryPoints.length > 0) {
219
+ const result = [...new Set(entryPoints)];
220
+ entryPointCache.set(packagePath, result);
221
+ return result;
222
+ }
223
+ for (const pattern of FRONTEND_HTML_PATTERNS) {
224
+ const fullPath = resolve(packagePath, pattern);
225
+ if (existsSync(fullPath)) {
226
+ const jsEntryPoints = await detectJSEntryPoints(packagePath);
227
+ const result = [fullPath, ...jsEntryPoints];
228
+ entryPointCache.set(packagePath, result);
229
+ return result;
230
+ }
231
+ }
232
+ for (const pattern of LIBRARY_ENTRY_PATTERNS) {
233
+ const fullPath = resolve(packagePath, pattern);
234
+ if (existsSync(fullPath)) {
235
+ entryPointCache.set(packagePath, [fullPath]);
236
+ return [fullPath];
237
+ }
238
+ }
239
+ entryPointCache.set(packagePath, []);
240
+ return [];
241
+ };
242
+ const detectJSEntryPoints = async (packagePath) => {
243
+ const entryPoints = [];
244
+ for (const pattern of JS_ENTRY_PATTERNS) {
245
+ const fullPath = resolve(packagePath, pattern);
246
+ if (existsSync(fullPath)) {
247
+ entryPoints.push(fullPath);
248
+ }
249
+ }
250
+ return entryPoints;
251
+ };
252
+ const detectBinEntryPoints = async (packagePath, pkg) => {
253
+ if (!pkg.bin) return [];
254
+ const binEntries = [];
255
+ const binField = pkg.bin;
256
+ const binPaths = typeof binField === "string" ? [binField] : Object.values(binField);
257
+ for (const binPath of binPaths) {
258
+ const sourcePath = binPath.replace(/^\.\/dist\//, "src/").replace(/^dist\//, "src/").replace(/\.js$/, ".ts");
259
+ const potentialPaths = [
260
+ sourcePath,
261
+ // Direct conversion
262
+ sourcePath.replace(/^src\//, ""),
263
+ // Remove src/ prefix
264
+ `src/${sourcePath}`
265
+ // Add src/ prefix
266
+ ];
267
+ for (const potential of new Set(potentialPaths)) {
268
+ const fullPath = resolve(packagePath, potential);
269
+ if (existsSync(fullPath)) {
270
+ binEntries.push(fullPath);
271
+ break;
272
+ }
273
+ }
274
+ }
275
+ return binEntries;
276
+ };
277
+ const detectFrontendApp = async (packagePath, pkg) => {
278
+ for (const pattern of FRONTEND_HTML_PATTERNS) {
279
+ const fullPath = resolve(packagePath, pattern);
280
+ if (existsSync(fullPath)) {
281
+ return true;
282
+ }
283
+ }
284
+ const allDeps = {
285
+ ...pkg.dependencies,
286
+ ...pkg.devDependencies,
287
+ ...pkg.peerDependencies
288
+ };
289
+ for (const framework of FRONTEND_FRAMEWORKS) {
290
+ if (allDeps[framework]) {
291
+ return true;
292
+ }
293
+ }
294
+ const publicDir = resolve(packagePath, "public");
295
+ if (existsSync(publicDir) && statSync(publicDir).isDirectory()) {
296
+ return true;
297
+ }
298
+ return false;
299
+ };
300
+ const detectGoProject = async (packagePath) => {
301
+ const mainGoPath = resolve(packagePath, "main.go");
302
+ if (existsSync(mainGoPath)) {
303
+ return true;
304
+ }
305
+ const goModPath = resolve(packagePath, "go.mod");
306
+ if (!existsSync(goModPath)) {
307
+ return false;
308
+ }
309
+ try {
310
+ const entries = await readdir(packagePath, { withFileTypes: true });
311
+ for (const entry of entries) {
312
+ if (entry.isFile() && entry.name.endsWith(".go")) {
313
+ return true;
314
+ }
315
+ if (entry.isDirectory()) {
316
+ if (GO_PROJECT_DIRS.includes(
317
+ entry.name
318
+ )) {
319
+ const subPath = resolve(packagePath, entry.name);
320
+ try {
321
+ const subEntries = await readdir(subPath, { recursive: true });
322
+ if (subEntries.some((name) => name.endsWith(".go"))) {
323
+ return true;
324
+ }
325
+ } catch {
326
+ }
327
+ }
328
+ }
329
+ }
330
+ } catch {
331
+ return true;
332
+ }
333
+ return false;
334
+ };
335
+ const resolveOutputDir = async (packagePath) => {
336
+ try {
337
+ const tsconfig = await readTSConfig(packagePath);
338
+ if (tsconfig?.compilerOptions?.outDir) {
339
+ return resolve(packagePath, tsconfig.compilerOptions.outDir);
340
+ }
341
+ } catch {
342
+ }
343
+ return resolve(packagePath, "dist");
344
+ };
345
+ const resolvePackageInfo = async (packagePath, dlerConfig) => {
346
+ const pkgJsonPath = join(packagePath, "package.json");
347
+ if (!existsSync(pkgJsonPath)) {
348
+ return null;
349
+ }
350
+ try {
351
+ let pkg = packageJsonCache.get(packagePath);
352
+ if (!pkg) {
353
+ pkg = await readPackageJSON(packagePath);
354
+ if (pkg) {
355
+ packageJsonCache.set(packagePath, pkg);
356
+ }
357
+ }
358
+ if (!pkg?.name) {
359
+ return null;
360
+ }
361
+ const hasTsConfig = existsSync(join(packagePath, "tsconfig.json"));
362
+ const entryPoints = await detectEntryPoints(packagePath);
363
+ const outputDir = await resolveOutputDir(packagePath);
364
+ const isFrontendApp = await detectFrontendApp(packagePath, pkg);
365
+ const hasHtmlEntry = entryPoints.some((ep) => ep.endsWith(".html"));
366
+ const hasPublicDir = existsSync(join(packagePath, "public")) && statSync(join(packagePath, "public")).isDirectory();
367
+ const hasGoFiles = await detectGoProject(packagePath);
368
+ const buildConfig = await getPackageBuildConfig(pkg.name, dlerConfig);
369
+ const isCLI = !!(pkg.bin && (typeof pkg.bin === "string" || typeof pkg.bin === "object" && Object.keys(pkg.bin).length > 0));
370
+ return {
371
+ name: pkg.name,
372
+ path: packagePath,
373
+ hasTsConfig,
374
+ entryPoints,
375
+ outputDir,
376
+ buildConfig,
377
+ isFrontendApp,
378
+ hasHtmlEntry,
379
+ hasPublicDir,
380
+ private: pkg.private === true,
381
+ isCLI,
382
+ hasGoFiles
383
+ };
384
+ } catch {
385
+ return null;
386
+ }
387
+ };
388
+ const filterPackages = (packages, ignore, allowPrivateBuild, filter) => {
389
+ if (filter) {
390
+ const includeFilter = createIncludeFilter(filter);
391
+ const filteredPackages2 = includeFilter(packages);
392
+ return filterPrivatePackages(filteredPackages2, allowPrivateBuild);
393
+ }
394
+ const combinedIgnore = ignore ? Array.isArray(ignore) ? [...ALWAYS_IGNORED_PACKAGES, ...ignore] : [...ALWAYS_IGNORED_PACKAGES, ignore] : ALWAYS_IGNORED_PACKAGES;
395
+ const ignoreFilter = createIgnoreFilter(combinedIgnore);
396
+ const filteredPackages = ignoreFilter(packages);
397
+ return filterPrivatePackages(filteredPackages, allowPrivateBuild);
398
+ };
399
+ const compileToExecutable = async (pkg, _outputs, options) => {
400
+ const entryPoint = pkg.entryPoints[0];
401
+ if (!entryPoint) {
402
+ await relinka.warn(`\u26A0\uFE0F ${pkg.name}: No entry point found for compilation`);
403
+ return;
404
+ }
405
+ const executableName = entryPoint.split("/").pop()?.split("\\").pop()?.replace(/\.(ts|js|mjs|cjs)$/, "") || "app";
406
+ const executablePath = join(
407
+ pkg.outputDir,
408
+ executableName + (process.platform === "win32" ? ".exe" : "")
409
+ );
410
+ if (!existsSync(pkg.outputDir)) {
411
+ mkdirSync(pkg.outputDir, { recursive: true });
412
+ }
413
+ await relinka.info(
414
+ `\u{1F528} Compiling ${pkg.name} to executable: ${executablePath}`
415
+ );
416
+ try {
417
+ const buildConfig = {
418
+ entrypoints: [entryPoint],
419
+ outfile: executablePath,
420
+ compile: true,
421
+ target: options.target || "bun",
422
+ format: options.format || "cjs"
423
+ };
424
+ if (process.platform === "win32") {
425
+ if (options.windowsHideConsole)
426
+ buildConfig.windowsHideConsole = options.windowsHideConsole;
427
+ if (options.windowsIcon) buildConfig.windowsIcon = options.windowsIcon;
428
+ if (options.windowsTitle) buildConfig.windowsTitle = options.windowsTitle;
429
+ if (options.windowsPublisher)
430
+ buildConfig.windowsPublisher = options.windowsPublisher;
431
+ if (options.windowsVersion)
432
+ buildConfig.windowsVersion = options.windowsVersion;
433
+ if (options.windowsDescription)
434
+ buildConfig.windowsDescription = options.windowsDescription;
435
+ if (options.windowsCopyright)
436
+ buildConfig.windowsCopyright = options.windowsCopyright;
437
+ }
438
+ const { $ } = await import("bun");
439
+ try {
440
+ const cmd = $`bun build ${entryPoint} --outfile ${executablePath} --compile --target ${buildConfig.target || "bun"}`;
441
+ await cmd.cwd(pkg.path).quiet();
442
+ } catch (error) {
443
+ await relinka.error(`\u274C Bun CLI compilation failed: ${error}`);
444
+ throw error;
445
+ }
446
+ if (!existsSync(executablePath)) {
447
+ throw new Error(`Executable was not created at ${executablePath}`);
448
+ }
449
+ const stats = statSync(executablePath);
450
+ await relinka.success(
451
+ `\u2705 ${pkg.name}: Executable created (${formatBytes(stats.size)})`
452
+ );
453
+ } catch (error) {
454
+ await relinka.error(`\u274C ${pkg.name}: Compilation failed - ${error}`);
455
+ throw error;
456
+ }
457
+ };
458
+ const buildWithMkdist = async (pkg, options, _bunBuildConfig) => {
459
+ const startTime = Date.now();
460
+ try {
461
+ const { mkdist } = await import("./impl/providers/mkdist/make.js");
462
+ const mkdistOptions = {
463
+ srcDir: "src",
464
+ distDir: pkg.outputDir,
465
+ rootDir: pkg.path,
466
+ format: options.format === "cjs" ? "cjs" : "esm",
467
+ ext: options.format === "cjs" ? ".cjs" : ".js",
468
+ cleanDist: false,
469
+ addRelativeDeclarationExtensions: true,
470
+ declaration: true,
471
+ verbose: options.verbose,
472
+ typescript: {
473
+ compilerOptions: {
474
+ // Don't override emitDeclarationOnly here - let mkdist handle it
475
+ // mkdist will set it to true to generate declarations
476
+ allowJs: true,
477
+ skipLibCheck: true
478
+ }
479
+ }
480
+ };
481
+ const { result, duration } = await mkdist(mkdistOptions);
482
+ let bundleSize = 0;
483
+ const outputFiles = [];
484
+ for (const filePath of result.writtenFiles) {
485
+ try {
486
+ const stats = statSync(filePath);
487
+ bundleSize += stats.size;
488
+ outputFiles.push(filePath);
489
+ } catch {
490
+ }
491
+ }
492
+ const buildSuccess = result.errors.length === 0;
493
+ if (buildSuccess) {
494
+ try {
495
+ const prepResult = await preparePackageJsonForPublishing(pkg.path, {
496
+ kind: options.kind,
497
+ binDefinitions: options.bin,
498
+ access: "public",
499
+ addPublishConfig: true,
500
+ transformExports: options.replaceExports === true
501
+ });
502
+ if (!prepResult.success && options.verbose) {
503
+ await relinka.warn(
504
+ `\u26A0\uFE0F ${pkg.name}: Failed to prepare package.json for publishing: ${prepResult.error}`
505
+ );
506
+ } else if (options.verbose) {
507
+ await relinka.info(
508
+ `\u{1F4E6} ${pkg.name}: Package.json prepared for publishing`
509
+ );
510
+ }
511
+ } catch (error) {
512
+ await relinka.warn(
513
+ `\u26A0\uFE0F ${pkg.name}: Error preparing package.json for publishing: ${error instanceof Error ? error.message : String(error)}`
514
+ );
515
+ }
516
+ await handleGoBuild(pkg, options, options.verbose ?? false);
517
+ }
518
+ return {
519
+ package: pkg,
520
+ success: buildSuccess,
521
+ skipped: false,
522
+ output: `Built ${result.writtenFiles.length} files`,
523
+ errors: result.errors.map((e) => e.filename),
524
+ warnings: [],
525
+ buildTime: duration,
526
+ bundleSize
527
+ };
528
+ } catch (error) {
529
+ const buildTime = Date.now() - startTime;
530
+ const errorMessage = error instanceof Error ? error.message : String(error);
531
+ await relinka.error(
532
+ `\u274C ${pkg.name}: mkdist build failed - ${errorMessage}`
533
+ );
534
+ return {
535
+ package: pkg,
536
+ success: false,
537
+ skipped: false,
538
+ output: errorMessage,
539
+ errors: [errorMessage],
540
+ warnings: [],
541
+ buildTime,
542
+ bundleSize: 0
543
+ };
544
+ }
545
+ };
546
+ export const buildPackage = async (pkg, options = {}, cache) => {
547
+ const mergedOptions = mergeBuildOptions(options, pkg.buildConfig);
548
+ if (mergedOptions.goOnly) {
549
+ const startTime2 = Date.now();
550
+ if (!pkg.hasGoFiles) {
551
+ return {
552
+ package: pkg,
553
+ success: true,
554
+ skipped: true,
555
+ output: "Skipped (no Go files)",
556
+ errors: [],
557
+ warnings: [],
558
+ buildTime: Date.now() - startTime2,
559
+ bundleSize: 0
560
+ };
561
+ }
562
+ const goResult = await handleGoOnlyBuild(pkg, mergedOptions);
563
+ return {
564
+ package: pkg,
565
+ success: goResult.success,
566
+ skipped: false,
567
+ output: goResult.success ? "Go binaries built successfully" : `Go build failed: ${goResult.errors.join(", ")}`,
568
+ errors: goResult.errors,
569
+ warnings: [],
570
+ buildTime: Date.now() - startTime2,
571
+ bundleSize: 0
572
+ };
573
+ }
574
+ const debugLogger = createDebugLogger(mergedOptions);
575
+ debugLogger.start();
576
+ const {
577
+ verbose = false,
578
+ bundler,
579
+ target = "node",
580
+ format = "esm",
581
+ minify = false,
582
+ sourcemap = "none",
583
+ splitting = true,
584
+ external,
585
+ bytecode = false,
586
+ drop,
587
+ packages = "bundle",
588
+ publicPath,
589
+ root,
590
+ define,
591
+ naming,
592
+ env = "disable",
593
+ banner,
594
+ footer,
595
+ conditions,
596
+ loader,
597
+ ignoreDCEAnnotations = false,
598
+ emitDCEAnnotations = true,
599
+ throw: throwOnError = false,
600
+ jsx,
601
+ keepNames = false,
602
+ // Frontend-specific options
603
+ assets,
604
+ cssChunking,
605
+ // Enhanced features
606
+ macros = false,
607
+ sideEffects,
608
+ bundleAnalyzer = false,
609
+ typeCheck = false,
610
+ generateTypes = true,
611
+ // bundleSizeLimit, // Used in performance monitoring
612
+ performanceBudget,
613
+ imageOptimization = false,
614
+ fontOptimization = false,
615
+ cssOptimization = false,
616
+ svgAsReact = false,
617
+ cssModules = false,
618
+ workerSupport = false,
619
+ plugins = [],
620
+ performanceMonitoring = false,
621
+ bundleAnalysis = false,
622
+ // TSConfig validation
623
+ validateTsconfig = true,
624
+ strictTsconfig = false
625
+ } = mergedOptions;
626
+ const isFrontendApp = pkg.isFrontendApp || pkg.hasHtmlEntry;
627
+ const shouldUseCssChunking = cssChunking !== false && (cssChunking === true || isFrontendApp);
628
+ const effectiveBundler = bundler || (pkg.buildConfig?.kind === "browser-app" || pkg.buildConfig?.kind === "native-app" ? "bun" : "mkdist");
629
+ const frontendTarget = isFrontendApp && !mergedOptions.compile ? "browser" : target;
630
+ const frontendFormat = isFrontendApp && !mergedOptions.compile ? "esm" : format;
631
+ const frontendSplitting = isFrontendApp && !mergedOptions.compile ? true : splitting;
632
+ initializePlugins();
633
+ const activePlugins = [];
634
+ if (mergedOptions.reactFastRefresh || isFrontendApp && !mergedOptions.production) {
635
+ activePlugins.push(ReactRefreshPlugin);
636
+ }
637
+ if (generateTypes || typeCheck || typeof pkg.buildConfig?.dts === "object" && pkg.buildConfig.dts?.enable) {
638
+ activePlugins.push(TypeScriptDeclarationsPlugin);
639
+ }
640
+ if (imageOptimization || fontOptimization || cssOptimization) {
641
+ activePlugins.push(AssetOptimizationPlugin);
642
+ }
643
+ if (bundleAnalyzer || bundleAnalysis) {
644
+ activePlugins.push(BundleAnalyzerPlugin);
645
+ }
646
+ if (cssModules) {
647
+ activePlugins.push(CSSModulesPlugin);
648
+ }
649
+ if (svgAsReact) {
650
+ activePlugins.push(SVGAsReactPlugin);
651
+ }
652
+ if (workerSupport) {
653
+ activePlugins.push(WorkerPlugin);
654
+ }
655
+ if (performanceMonitoring || performanceBudget) {
656
+ activePlugins.push(PerformancePlugin);
657
+ }
658
+ if (plugins.length > 0) {
659
+ const customPlugins = loadPlugins(plugins);
660
+ activePlugins.push(...customPlugins);
661
+ }
662
+ const validTarget = frontendTarget;
663
+ const validFormat = frontendFormat === "cjs" || frontendFormat === "iife" ? frontendFormat : "esm";
664
+ let validSourcemap = sourcemap;
665
+ if (typeof sourcemap === "boolean") {
666
+ validSourcemap = sourcemap ? "inline" : "none";
667
+ } else if (sourcemap === "linked" || sourcemap === "inline" || sourcemap === "external") {
668
+ validSourcemap = sourcemap;
669
+ } else {
670
+ validSourcemap = "none";
671
+ }
672
+ if (pkg.entryPoints.length === 0) {
673
+ if (verbose) {
674
+ await relinka.info(`\u23ED\uFE0F Skipping ${pkg.name} (no entry points found)`);
675
+ }
676
+ return {
677
+ package: pkg,
678
+ success: true,
679
+ skipped: true,
680
+ output: "",
681
+ errors: [],
682
+ warnings: [],
683
+ buildTime: 0
684
+ };
685
+ }
686
+ if (validateTsconfig) {
687
+ try {
688
+ const validationResult = await validateTSConfig(pkg, {
689
+ strict: strictTsconfig,
690
+ checkDeclarations: generateTypes || typeCheck,
691
+ checkBuildOutput: true
692
+ });
693
+ if (!validationResult.valid) {
694
+ if (strictTsconfig) {
695
+ return {
696
+ package: pkg,
697
+ success: false,
698
+ skipped: false,
699
+ output: `TSConfig validation failed: ${validationResult.errors.join(", ")}`,
700
+ errors: validationResult.errors,
701
+ warnings: validationResult.warnings,
702
+ buildTime: 0
703
+ };
704
+ } else {
705
+ for (const warning of validationResult.warnings) {
706
+ await relinka.warn(`\u26A0\uFE0F ${pkg.name}: ${warning}`);
707
+ }
708
+ for (const error of validationResult.errors) {
709
+ await relinka.warn(`\u26A0\uFE0F ${pkg.name}: ${error}`);
710
+ }
711
+ }
712
+ } else if (validationResult.warnings.length > 0 && verbose) {
713
+ for (const warning of validationResult.warnings) {
714
+ await relinka.warn(`\u26A0\uFE0F ${pkg.name}: ${warning}`);
715
+ }
716
+ }
717
+ } catch (error) {
718
+ if (strictTsconfig) {
719
+ return {
720
+ package: pkg,
721
+ success: false,
722
+ skipped: false,
723
+ output: `TSConfig validation error: ${error instanceof Error ? error.message : String(error)}`,
724
+ errors: [error instanceof Error ? error.message : String(error)],
725
+ warnings: [],
726
+ buildTime: 0
727
+ };
728
+ } else {
729
+ await relinka.warn(
730
+ `\u26A0\uFE0F ${pkg.name}: TSConfig validation failed: ${error instanceof Error ? error.message : String(error)}`
731
+ );
732
+ }
733
+ }
734
+ }
735
+ if (cache) {
736
+ const cacheEntry = await cache.get(pkg, mergedOptions);
737
+ if (cacheEntry) {
738
+ if (verbose) {
739
+ await relinka.info(
740
+ `\u26A1 ${pkg.name}: Using cache (${cacheEntry.buildTime}ms, ${formatBytes(cacheEntry.bundleSize)})`
741
+ );
742
+ }
743
+ return {
744
+ package: pkg,
745
+ success: true,
746
+ skipped: false,
747
+ output: "",
748
+ errors: [],
749
+ warnings: [],
750
+ buildTime: cacheEntry.buildTime,
751
+ bundleSize: cacheEntry.bundleSize,
752
+ cacheHit: true
753
+ };
754
+ }
755
+ }
756
+ if (verbose) {
757
+ await relinka.info(`\u{1F528} Building ${pkg.name}...`);
758
+ }
759
+ debugLogger.logConfigResolution(pkg, pkg.buildConfig ? "dler" : "default");
760
+ debugLogger.logBuildOptions(mergedOptions, pkg);
761
+ debugLogger.logEntryPoints(pkg);
762
+ const startTime = Date.now();
763
+ try {
764
+ const validation = validateBuildConfig(mergedOptions);
765
+ if (!validation.valid) {
766
+ await relinka.warn(
767
+ `\u26A0\uFE0F ${pkg.name}: Invalid build options - ${validation.errors.join(", ")}`
768
+ );
769
+ }
770
+ const buildConfig = {
771
+ entrypoints: pkg.entryPoints,
772
+ outdir: pkg.outputDir,
773
+ target: validTarget,
774
+ format: validFormat,
775
+ sourcemap: validSourcemap,
776
+ splitting: frontendSplitting,
777
+ verbose
778
+ };
779
+ if (pkg.name === "@reliverse/native-app-example") {
780
+ await relinka.info(
781
+ `\u{1F50D} Debug: target=${validTarget}, format=${validFormat}, bytecode=${bytecode}`
782
+ );
783
+ }
784
+ applyPlugins(activePlugins, buildConfig);
785
+ if (jsx) {
786
+ buildConfig.jsx = jsx;
787
+ }
788
+ if (keepNames) {
789
+ buildConfig.keepNames = keepNames;
790
+ }
791
+ if (isFrontendApp) {
792
+ buildConfig.loader = {
793
+ ...loader,
794
+ ".png": "file",
795
+ ".jpg": "file",
796
+ ".jpeg": "file",
797
+ ".gif": "file",
798
+ ".svg": "file",
799
+ ".webp": "file",
800
+ ".ico": "file",
801
+ ".woff": "file",
802
+ ".woff2": "file",
803
+ ".ttf": "file",
804
+ ".eot": "file",
805
+ ".css": "css",
806
+ ...loader
807
+ };
808
+ }
809
+ if (typeof minify === "boolean") {
810
+ buildConfig.minify = minify;
811
+ } else if (typeof minify === "object" && minify !== null) {
812
+ const validMinify = {};
813
+ if (minify.whitespace !== void 0)
814
+ validMinify.whitespace = minify.whitespace;
815
+ if (minify.syntax !== void 0) validMinify.syntax = minify.syntax;
816
+ if (minify.identifiers !== void 0)
817
+ validMinify.identifiers = minify.identifiers;
818
+ buildConfig.minify = validMinify;
819
+ }
820
+ if (external) {
821
+ const externalArray = Array.isArray(external) ? external : [external];
822
+ if (!externalArray.includes("node-fetch-native")) {
823
+ externalArray.push("node-fetch-native");
824
+ }
825
+ buildConfig.external = externalArray;
826
+ } else {
827
+ buildConfig.external = ["node-fetch-native"];
828
+ }
829
+ if (bytecode) {
830
+ buildConfig.bytecode = bytecode;
831
+ }
832
+ if (drop) {
833
+ buildConfig.drop = Array.isArray(drop) ? drop : [drop];
834
+ }
835
+ if (packages) {
836
+ buildConfig.packages = packages;
837
+ }
838
+ if (publicPath) {
839
+ buildConfig.publicPath = publicPath;
840
+ }
841
+ if (root) {
842
+ buildConfig.root = root;
843
+ }
844
+ if (define) {
845
+ buildConfig.define = define;
846
+ }
847
+ if (naming) {
848
+ buildConfig.naming = naming;
849
+ }
850
+ if (env) {
851
+ buildConfig.env = env;
852
+ }
853
+ if (banner) {
854
+ buildConfig.banner = banner;
855
+ }
856
+ if (footer) {
857
+ buildConfig.footer = footer;
858
+ }
859
+ if (conditions) {
860
+ buildConfig.conditions = Array.isArray(conditions) ? conditions : [conditions];
861
+ }
862
+ if (loader) {
863
+ buildConfig.loader = loader;
864
+ }
865
+ if (ignoreDCEAnnotations !== void 0) {
866
+ buildConfig.ignoreDCEAnnotations = ignoreDCEAnnotations;
867
+ }
868
+ if (emitDCEAnnotations !== void 0) {
869
+ buildConfig.emitDCEAnnotations = emitDCEAnnotations;
870
+ }
871
+ if (throwOnError !== void 0) {
872
+ buildConfig.throw = throwOnError;
873
+ }
874
+ if (mergedOptions.noBundle) {
875
+ buildConfig.noBundle = true;
876
+ }
877
+ if (mergedOptions.reactFastRefresh) {
878
+ buildConfig.reactFastRefresh = true;
879
+ }
880
+ if (mergedOptions.noClearScreen) {
881
+ buildConfig.noClearScreen = true;
882
+ }
883
+ if (mergedOptions.windowsHideConsole) {
884
+ buildConfig.windowsHideConsole = true;
885
+ }
886
+ if (mergedOptions.windowsIcon) {
887
+ buildConfig.windowsIcon = mergedOptions.windowsIcon;
888
+ }
889
+ if (mergedOptions.windowsTitle) {
890
+ buildConfig.windowsTitle = mergedOptions.windowsTitle;
891
+ }
892
+ if (mergedOptions.windowsPublisher) {
893
+ buildConfig.windowsPublisher = mergedOptions.windowsPublisher;
894
+ }
895
+ if (mergedOptions.windowsVersion) {
896
+ buildConfig.windowsVersion = mergedOptions.windowsVersion;
897
+ }
898
+ if (mergedOptions.windowsDescription) {
899
+ buildConfig.windowsDescription = mergedOptions.windowsDescription;
900
+ }
901
+ if (mergedOptions.windowsCopyright) {
902
+ buildConfig.windowsCopyright = mergedOptions.windowsCopyright;
903
+ }
904
+ if (mergedOptions.app) {
905
+ buildConfig.app = true;
906
+ }
907
+ if (mergedOptions.serverComponents) {
908
+ buildConfig.serverComponents = true;
909
+ }
910
+ if (mergedOptions.debugDumpServerFiles) {
911
+ buildConfig.debugDumpServerFiles = true;
912
+ }
913
+ if (mergedOptions.debugNoMinify) {
914
+ buildConfig.debugNoMinify = true;
915
+ }
916
+ if (macros) {
917
+ buildConfig.macros = true;
918
+ }
919
+ if (sideEffects !== void 0) {
920
+ buildConfig.sideEffects = sideEffects;
921
+ }
922
+ if (pkg.name === "@reliverse/native-app-example") {
923
+ await relinka.info(
924
+ `\u{1F50D} Final build config: ${JSON.stringify(buildConfig, null, 2)}`
925
+ );
926
+ }
927
+ if (effectiveBundler === "mkdist") {
928
+ return await buildWithMkdist(pkg, mergedOptions, buildConfig);
929
+ }
930
+ const result = await Bun.build(buildConfig);
931
+ const buildTime = Date.now() - startTime;
932
+ let bundleSize = 0;
933
+ const outputFiles = [];
934
+ if (result.outputs) {
935
+ for (const output of result.outputs) {
936
+ if (output.path) {
937
+ try {
938
+ const stats = statSync(output.path);
939
+ bundleSize += stats.size;
940
+ outputFiles.push(output.path);
941
+ } catch {
942
+ }
943
+ }
944
+ }
945
+ }
946
+ if (!result.success) {
947
+ const errors = extractErrors(result.logs);
948
+ const warnings = extractWarnings(result.logs);
949
+ if (verbose) {
950
+ await relinka.error(`\u274C ${pkg.name}: Build failed (${buildTime}ms)`);
951
+ for (const error of errors) {
952
+ await relinka.error(` ${error}`);
953
+ }
954
+ if (warnings.length > 0) {
955
+ await relinka.warn(` Warnings:`);
956
+ for (const warning of warnings) {
957
+ await relinka.warn(` ${warning}`);
958
+ }
959
+ }
960
+ }
961
+ return {
962
+ package: pkg,
963
+ success: false,
964
+ skipped: false,
965
+ output: formatLogMessages(result.logs),
966
+ errors,
967
+ warnings,
968
+ buildTime,
969
+ bundleSize
970
+ };
971
+ }
972
+ if (result.success) {
973
+ await handleGoBuild(pkg, mergedOptions, verbose);
974
+ } else if (verbose && pkg.hasGoFiles) {
975
+ await relinka.info(
976
+ `\u23ED\uFE0F ${pkg.name}: Skipping Go build (TypeScript build failed)`
977
+ );
978
+ }
979
+ if (isFrontendApp) {
980
+ try {
981
+ await processAssetsForPackage(pkg, pkg.outputDir, assets);
982
+ await processCSSForPackage(pkg, pkg.outputDir, shouldUseCssChunking);
983
+ await processHTMLForPackage(pkg, pkg.outputDir, {
984
+ minify: typeof minify === "boolean" ? minify : minify?.whitespace ?? false,
985
+ injectAssets: true,
986
+ publicPath: publicPath || "/"
987
+ });
988
+ } catch (error) {
989
+ await relinka.warn(
990
+ `\u26A0\uFE0F ${pkg.name}: Asset processing failed - ${error}`
991
+ );
992
+ }
993
+ }
994
+ for (const plugin of activePlugins) {
995
+ if (plugin.onBuildEnd) {
996
+ try {
997
+ await plugin.onBuildEnd(
998
+ {
999
+ package: pkg,
1000
+ success: true,
1001
+ skipped: false,
1002
+ output: formatLogMessages(result.logs),
1003
+ errors: [],
1004
+ warnings: extractWarnings(result.logs),
1005
+ buildTime,
1006
+ bundleSize
1007
+ },
1008
+ mergedOptions
1009
+ );
1010
+ } catch (error) {
1011
+ await relinka.warn(
1012
+ `\u26A0\uFE0F ${pkg.name}: Plugin ${plugin.name} onBuildEnd failed - ${error}`
1013
+ );
1014
+ }
1015
+ }
1016
+ }
1017
+ if (cache) {
1018
+ await cache.set(pkg, mergedOptions, {
1019
+ buildTime,
1020
+ bundleSize,
1021
+ outputFiles
1022
+ });
1023
+ }
1024
+ if (mergedOptions.compile && result.success && result.outputs) {
1025
+ await compileToExecutable(pkg, result.outputs, mergedOptions);
1026
+ }
1027
+ if (result.success) {
1028
+ try {
1029
+ const prepResult = await preparePackageJsonForPublishing(pkg.path, {
1030
+ kind: mergedOptions.kind,
1031
+ binDefinitions: mergedOptions.bin,
1032
+ access: "public",
1033
+ addPublishConfig: true,
1034
+ transformExports: mergedOptions.replaceExports === true
1035
+ });
1036
+ if (!prepResult.success) {
1037
+ await relinka.warn(
1038
+ `\u26A0\uFE0F ${pkg.name}: Failed to prepare package.json for publishing: ${prepResult.error}`
1039
+ );
1040
+ } else if (verbose) {
1041
+ await relinka.info(
1042
+ `\u{1F4E6} ${pkg.name}: Package.json prepared for publishing`
1043
+ );
1044
+ }
1045
+ } catch (error) {
1046
+ await relinka.warn(
1047
+ `\u26A0\uFE0F ${pkg.name}: Error preparing package.json for publishing: ${error instanceof Error ? error.message : String(error)}`
1048
+ );
1049
+ }
1050
+ }
1051
+ if (verbose) {
1052
+ await relinka.success(
1053
+ `\u2705 ${pkg.name}: Built successfully (${buildTime}ms, ${formatBytes(bundleSize)})`
1054
+ );
1055
+ }
1056
+ return {
1057
+ package: pkg,
1058
+ success: true,
1059
+ skipped: false,
1060
+ output: formatLogMessages(result.logs),
1061
+ errors: [],
1062
+ warnings: extractWarnings(result.logs),
1063
+ buildTime,
1064
+ bundleSize
1065
+ };
1066
+ } catch (error) {
1067
+ const buildTime = Date.now() - startTime;
1068
+ const errorMessage = error instanceof Error ? error.message : String(error);
1069
+ await relinka.error(`\u274C ${pkg.name}: Build failed - ${errorMessage}`);
1070
+ return {
1071
+ package: pkg,
1072
+ success: false,
1073
+ skipped: false,
1074
+ output: errorMessage,
1075
+ errors: [errorMessage],
1076
+ warnings: [],
1077
+ buildTime,
1078
+ bundleSize: 0
1079
+ };
1080
+ }
1081
+ };
1082
+ const collectAllResults = async (packages, options = {}, cache) => {
1083
+ const {
1084
+ concurrency = DEFAULT_CONCURRENCY,
1085
+ stopOnError = false,
1086
+ verbose = false,
1087
+ watch = false
1088
+ } = options;
1089
+ if (watch) {
1090
+ await startWatchMode(packages, options);
1091
+ return new Promise(() => {
1092
+ });
1093
+ }
1094
+ if (!verbose) {
1095
+ await relinka.info(`Building ${packages.length} packages...`);
1096
+ }
1097
+ try {
1098
+ const buildResults = await pMap(
1099
+ packages,
1100
+ async (pkg, index) => {
1101
+ if (!verbose) {
1102
+ await relinka.info(
1103
+ `Building ${pkg.name} (${index + 1}/${packages.length})...`
1104
+ );
1105
+ }
1106
+ return buildPackage(pkg, options, cache);
1107
+ },
1108
+ {
1109
+ concurrency,
1110
+ stopOnError
1111
+ }
1112
+ );
1113
+ const failedPackages = buildResults.filter(
1114
+ (r) => !r.success && !r.skipped
1115
+ ).length;
1116
+ const successfulPackages = buildResults.filter((r) => r.success).length;
1117
+ const skippedPackages = buildResults.filter((r) => r.skipped).length;
1118
+ const totalBuildTime = buildResults.reduce(
1119
+ (sum, r) => sum + r.buildTime,
1120
+ 0
1121
+ );
1122
+ const totalBundleSize = buildResults.reduce(
1123
+ (sum, r) => sum + (r.bundleSize || 0),
1124
+ 0
1125
+ );
1126
+ const cacheHits = buildResults.filter((r) => r.cacheHit).length;
1127
+ return {
1128
+ totalPackages: packages.length,
1129
+ failedPackages,
1130
+ successfulPackages,
1131
+ skippedPackages,
1132
+ hasErrors: failedPackages > 0,
1133
+ results: buildResults,
1134
+ totalBuildTime,
1135
+ totalBundleSize,
1136
+ cacheHits
1137
+ };
1138
+ } catch (error) {
1139
+ if (error instanceof AggregateError) {
1140
+ const buildResults = error.errors.map((err, index) => {
1141
+ const pkg = packages[index];
1142
+ if (!pkg) {
1143
+ throw new Error(`Package at index ${index} not found`);
1144
+ }
1145
+ if (verbose) {
1146
+ void relinka.error(
1147
+ `\u274C ${pkg.name}: Aggregate error - ${err instanceof Error ? err.message : String(err)}`
1148
+ );
1149
+ }
1150
+ return {
1151
+ package: pkg,
1152
+ success: false,
1153
+ skipped: false,
1154
+ output: err instanceof Error ? err.message : String(err),
1155
+ errors: [err instanceof Error ? err.message : String(err)],
1156
+ warnings: [],
1157
+ buildTime: 0
1158
+ };
1159
+ });
1160
+ const failedPackages = buildResults.filter(
1161
+ (r) => !r.success && !r.skipped
1162
+ ).length;
1163
+ const successfulPackages = buildResults.filter((r) => r.success).length;
1164
+ const skippedPackages = buildResults.filter((r) => r.skipped).length;
1165
+ const totalBuildTime = buildResults.reduce(
1166
+ (sum, r) => sum + r.buildTime,
1167
+ 0
1168
+ );
1169
+ const totalBundleSize = buildResults.reduce(
1170
+ (sum, r) => sum + (r.bundleSize || 0),
1171
+ 0
1172
+ );
1173
+ const cacheHits = buildResults.filter((r) => r.cacheHit).length;
1174
+ return {
1175
+ totalPackages: packages.length,
1176
+ failedPackages,
1177
+ successfulPackages,
1178
+ skippedPackages,
1179
+ hasErrors: failedPackages > 0,
1180
+ results: buildResults,
1181
+ totalBuildTime,
1182
+ totalBundleSize,
1183
+ cacheHits
1184
+ };
1185
+ }
1186
+ throw error;
1187
+ }
1188
+ };
1189
+ const formatOutput = async (summary, verbose) => {
1190
+ const {
1191
+ totalPackages,
1192
+ failedPackages,
1193
+ successfulPackages,
1194
+ skippedPackages,
1195
+ totalBuildTime,
1196
+ totalBundleSize,
1197
+ cacheHits
1198
+ } = summary;
1199
+ await relinka.log("\u2501".repeat(60));
1200
+ await relinka.log(`\u{1F4E6} Build Summary:`);
1201
+ await relinka.log(` Total packages: ${totalPackages}`);
1202
+ await relinka.log(` \u2705 Built: ${successfulPackages}`);
1203
+ await relinka.log(` \u274C Failed: ${failedPackages}`);
1204
+ await relinka.log(` \u23ED\uFE0F Skipped: ${skippedPackages}`);
1205
+ if (cacheHits > 0) {
1206
+ await relinka.log(` \u26A1 Cache hits: ${cacheHits}`);
1207
+ }
1208
+ await relinka.log(` \u23F1\uFE0F Total time: ${totalBuildTime}ms`);
1209
+ await relinka.log(` \u{1F4E6} Total size: ${formatBytes(totalBundleSize)}`);
1210
+ await relinka.log("\u2501".repeat(60));
1211
+ const failed = summary.results.filter((r) => !r.success && !r.skipped);
1212
+ if (failed.length > 0) {
1213
+ await relinka.error("\n\u274C Failed Packages:\n");
1214
+ for (const result of failed) {
1215
+ await relinka.error(`\u{1F4E6} ${result.package.name} (${result.buildTime}ms)`);
1216
+ await relinka.error(
1217
+ ` Entry points: ${result.package.entryPoints.join(", ")}`
1218
+ );
1219
+ await relinka.error(` Output dir: ${result.package.outputDir}`);
1220
+ if (result.errors.length > 0) {
1221
+ await relinka.error(" \u2500".repeat(30));
1222
+ const errorLines = result.errors.map((error) => ` ${error}`);
1223
+ writeErrorLines(errorLines);
1224
+ await relinka.error("");
1225
+ }
1226
+ }
1227
+ }
1228
+ if (verbose) {
1229
+ const successful = summary.results.filter((r) => r.success && !r.skipped);
1230
+ if (successful.length > 0) {
1231
+ await relinka.success("\n\u2705 Successful Packages:\n");
1232
+ for (const result of successful) {
1233
+ const sizeInfo = result.bundleSize ? `, ${formatBytes(result.bundleSize)}` : "";
1234
+ const cacheInfo = result.cacheHit ? " (cached)" : "";
1235
+ await relinka.success(
1236
+ ` \u2022 ${result.package.name} (${result.buildTime}ms${sizeInfo})${cacheInfo}`
1237
+ );
1238
+ if (result.warnings.length > 0) {
1239
+ await relinka.log(` Warnings: ${result.warnings.length}`);
1240
+ }
1241
+ }
1242
+ }
1243
+ const skipped = summary.results.filter((r) => r.skipped);
1244
+ if (skipped.length > 0) {
1245
+ await relinka.info("\n\u23ED\uFE0F Skipped Packages (no entry points):\n");
1246
+ for (const result of skipped) {
1247
+ await relinka.info(` \u2022 ${result.package.name}`);
1248
+ }
1249
+ }
1250
+ await relinka.log("");
1251
+ }
1252
+ };
1253
+ export const runBuildOnAllPackages = async (ignore, cwd, options = {}) => {
1254
+ const {
1255
+ verbose = false,
1256
+ watch = false,
1257
+ cache: enableCache = true,
1258
+ noCache = false,
1259
+ devServer = false,
1260
+ port = 3e3,
1261
+ open = false,
1262
+ allowPrivateBuild,
1263
+ filter
1264
+ } = options;
1265
+ const cache = enableCache && !noCache ? new BuildCache() : void 0;
1266
+ if (verbose) {
1267
+ await relinka.info("\u{1F50D} Discovering workspace packages...");
1268
+ }
1269
+ const result = await (async () => {
1270
+ const allPackages = await getWorkspacePackages(cwd);
1271
+ if (verbose) {
1272
+ await relinka.info(` Found ${allPackages.length} packages`);
1273
+ const dlerConfig = await loadDlerConfig(cwd);
1274
+ if (dlerConfig?.build) {
1275
+ await relinka.info(" \u{1F4CB} Using dler.ts configuration");
1276
+ if (dlerConfig.build.global) {
1277
+ await relinka.info(" Global config: \u2705");
1278
+ }
1279
+ if (dlerConfig.build.packages) {
1280
+ await relinka.info(
1281
+ ` Package configs: ${Object.keys(dlerConfig.build.packages).length}`
1282
+ );
1283
+ }
1284
+ if (dlerConfig.build.patterns) {
1285
+ await relinka.info(
1286
+ ` Pattern configs: ${dlerConfig.build.patterns.length}`
1287
+ );
1288
+ }
1289
+ } else {
1290
+ await relinka.info(
1291
+ " \u2699\uFE0F No dler.ts found, using default configuration"
1292
+ );
1293
+ }
1294
+ await relinka.info(" Packages found:");
1295
+ for (const pkg of allPackages) {
1296
+ const entryStatus = pkg.entryPoints.length > 0 ? "\u2705" : "\u23ED\uFE0F";
1297
+ const configSource = pkg.buildConfig ? "\u{1F4CB}" : "\u2699\uFE0F";
1298
+ const frontendStatus = pkg.isFrontendApp ? "\u{1F310}" : "\u{1F4E6}";
1299
+ const htmlStatus = pkg.hasHtmlEntry ? "\u{1F4C4}" : "";
1300
+ const cliStatus = pkg.isCLI ? "\u26A1" : "";
1301
+ await relinka.info(
1302
+ ` ${entryStatus} ${configSource} ${frontendStatus}${htmlStatus}${cliStatus} ${pkg.name} (${pkg.entryPoints.length} entry points)`
1303
+ );
1304
+ if (pkg.entryPoints.length > 0) {
1305
+ await relinka.info(
1306
+ ` Entry points: ${pkg.entryPoints.join(", ")}`
1307
+ );
1308
+ await relinka.info(` Output dir: ${pkg.outputDir}`);
1309
+ if (pkg.isFrontendApp) {
1310
+ await relinka.info(` Type: Frontend app`);
1311
+ if (pkg.hasHtmlEntry) await relinka.info(` HTML entry: \u2705`);
1312
+ if (pkg.hasPublicDir) await relinka.info(` Public dir: \u2705`);
1313
+ } else if (pkg.isCLI) {
1314
+ await relinka.info(
1315
+ ` Type: CLI${pkg.entryPoints.length > 1 ? " (with library exports)" : ""}`
1316
+ );
1317
+ } else {
1318
+ await relinka.info(` Type: Library`);
1319
+ }
1320
+ if (pkg.buildConfig) {
1321
+ await relinka.info(
1322
+ ` Build config: ${JSON.stringify(pkg.buildConfig, null, 2).split("\n").map((line) => ` ${line}`).join("\n")}`
1323
+ );
1324
+ }
1325
+ }
1326
+ }
1327
+ await relinka.info("");
1328
+ }
1329
+ const packages = filterPackages(
1330
+ allPackages,
1331
+ ignore,
1332
+ allowPrivateBuild,
1333
+ filter
1334
+ );
1335
+ const filteredCount = allPackages.length - packages.length;
1336
+ if (filter) {
1337
+ const patterns = normalizePatterns(filter);
1338
+ await relinka.info(
1339
+ ` Filtering to ${packages.length} packages matching: ${patterns.join(", ")}`
1340
+ );
1341
+ } else if (filteredCount > 0) {
1342
+ const combinedIgnore = ignore ? Array.isArray(ignore) ? [...ALWAYS_IGNORED_PACKAGES, ...ignore] : [...ALWAYS_IGNORED_PACKAGES, ignore] : ALWAYS_IGNORED_PACKAGES;
1343
+ const patterns = normalizePatterns(combinedIgnore);
1344
+ await relinka.info(
1345
+ ` Ignoring ${filteredCount} packages matching: ${patterns.join(", ")}`
1346
+ );
1347
+ }
1348
+ const { concurrency = DEFAULT_CONCURRENCY, stopOnError = false } = options;
1349
+ await relinka.info(
1350
+ ` Building ${packages.length} packages (concurrency: ${concurrency}, stopOnError: ${stopOnError})...
1351
+ `
1352
+ );
1353
+ if (watch || devServer) {
1354
+ if (devServer) {
1355
+ const frontendPackages = packages.filter(
1356
+ (pkg) => pkg.isFrontendApp || pkg.hasHtmlEntry
1357
+ );
1358
+ if (frontendPackages.length === 0) {
1359
+ await relinka.warn("\u26A0\uFE0F No frontend packages found for dev server");
1360
+ await relinka.info(
1361
+ " Dev server works best with packages that have HTML entry points"
1362
+ );
1363
+ }
1364
+ await relinka.info(
1365
+ `\u{1F680} Starting dev server for ${frontendPackages.length} frontend packages...`
1366
+ );
1367
+ try {
1368
+ await startDevServer(frontendPackages, options, {
1369
+ port,
1370
+ open,
1371
+ hmr: true
1372
+ });
1373
+ return new Promise(() => {
1374
+ });
1375
+ } catch (error) {
1376
+ await relinka.error(`\u274C Failed to start dev server: ${error}`);
1377
+ throw error;
1378
+ }
1379
+ }
1380
+ return collectAllResults(packages, options);
1381
+ }
1382
+ if (verbose) {
1383
+ await relinka.info("\u{1F680} Starting build process...\n");
1384
+ }
1385
+ const summary = await collectAllResults(packages, options, cache);
1386
+ await formatOutput(summary, verbose);
1387
+ return summary;
1388
+ })();
1389
+ return result;
1390
+ };