@savvy-web/rslib-builder 0.1.0

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/index.js ADDED
@@ -0,0 +1,1521 @@
1
+ /*! For license information please see index.js.LICENSE.txt */
2
+ import * as __rspack_external_node_path_c5b9b54f from "node:path";
3
+ import { __webpack_require__ } from "./rslib-runtime.js";
4
+ import { constants, existsSync, writeFileSync } from "node:fs";
5
+ import { defineConfig } from "@rslib/core";
6
+ import { access, copyFile, mkdir, readFile as promises_readFile, readdir, rm, stat as promises_stat, unlink, writeFile } from "node:fs/promises";
7
+ import { getWorkspaceRoot } from "workspace-tools";
8
+ import { logger as core_logger } from "@rsbuild/core";
9
+ import picocolors from "picocolors";
10
+ import { spawn } from "node:child_process";
11
+ import { createCompilerHost, findConfigFile, formatDiagnostic, parseJsonConfigFileContent, readConfigFile, sys } from "typescript";
12
+ import { createRequire } from "node:module";
13
+ import { inspect } from "node:util";
14
+ import sort_package_json from "sort-package-json";
15
+ import { createExportableManifest } from "@pnpm/exportable-manifest";
16
+ import { parse } from "yaml";
17
+ __webpack_require__.add({
18
+ "node:path" (module) {
19
+ module.exports = __rspack_external_node_path_c5b9b54f;
20
+ }
21
+ });
22
+ const external_node_path_ = __webpack_require__("node:path");
23
+ async function fileExistAsync(assetName) {
24
+ const assetPath = (0, external_node_path_.join)(process.cwd(), assetName);
25
+ const assetExists = !!await promises_stat(assetPath).catch(()=>false);
26
+ return {
27
+ assetName,
28
+ assetPath,
29
+ assetExists
30
+ };
31
+ }
32
+ async function packageJsonVersion() {
33
+ const { assetExists, assetPath } = await fileExistAsync("package.json");
34
+ if (!assetExists) throw new Error("package.json not found in project root");
35
+ try {
36
+ const json = await promises_readFile(assetPath, "utf-8");
37
+ const { version } = JSON.parse(json);
38
+ return version;
39
+ } catch {
40
+ throw new Error("Failed to read version from package.json");
41
+ }
42
+ }
43
+ function getApiExtractorPath() {
44
+ const cwd = process.cwd();
45
+ const localApiExtractor = (0, external_node_path_.join)(cwd, "node_modules", "@microsoft", "api-extractor");
46
+ if (existsSync(localApiExtractor)) return localApiExtractor;
47
+ const workspaceRoot = getWorkspaceRoot(cwd);
48
+ if (workspaceRoot) {
49
+ const workspaceApiExtractor = (0, external_node_path_.join)(workspaceRoot, "node_modules", "@microsoft", "api-extractor");
50
+ if (existsSync(workspaceApiExtractor)) return workspaceApiExtractor;
51
+ }
52
+ throw new Error("API Extractor bundling requires @microsoft/api-extractor to be installed.\nInstall it with: pnpm add -D @microsoft/api-extractor");
53
+ }
54
+ const { cyan: cyan, dim: dim, bold: bold } = picocolors;
55
+ function formatTime(ms) {
56
+ if (ms < 1000) return `${ms}ms`;
57
+ return `${(ms / 1000).toFixed(2)}s`;
58
+ }
59
+ function isTestEnvironment() {
60
+ return "test" === process.env.NODE_ENV || "true" === process.env.VITEST || void 0 !== process.env.JEST_WORKER_ID || process.argv.some((arg)=>arg.includes("vitest") || arg.includes("jest"));
61
+ }
62
+ function createEnvLogger(envId) {
63
+ const isTest = isTestEnvironment();
64
+ return {
65
+ info: (message, ...args)=>{
66
+ if (!isTest) core_logger.info(`${message} (${cyan(envId)})`, ...args);
67
+ },
68
+ warn: (message, ...args)=>{
69
+ if (!isTest) core_logger.warn(`${message} (${cyan(envId)})`, ...args);
70
+ },
71
+ error: (message, ...args)=>{
72
+ if (!isTest) core_logger.error(`${message} (${cyan(envId)})`, ...args);
73
+ },
74
+ withTime: (message, time, ...args)=>{
75
+ if (!isTest) {
76
+ const env = dim(`(${envId})`);
77
+ core_logger.info(`${message} in ${bold(formatTime(time))} ${env}`, ...args);
78
+ }
79
+ },
80
+ success: (message, filename, ...args)=>{
81
+ if (!isTest) {
82
+ const coloredFilename = filename ? cyan(filename) : "";
83
+ const fullMessage = filename ? `${message} ${coloredFilename}` : message;
84
+ const env = dim(`(${envId})`);
85
+ core_logger.info(`${fullMessage} ${env}`, ...args);
86
+ }
87
+ },
88
+ fileOp: (message, files, ...args)=>{
89
+ if (!isTest) {
90
+ const coloredFiles = files.map((f)=>cyan(f)).join(", ");
91
+ const env = dim(`(${envId})`);
92
+ core_logger.info(`${message}: ${coloredFiles} ${env}`, ...args);
93
+ }
94
+ },
95
+ entries: (message, entries, ...args)=>{
96
+ if (!isTest) {
97
+ const coloredEntries = Object.entries(entries).map(([name, path])=>cyan(`${name} => ${path}`)).join(", ");
98
+ const env = dim(`(${envId})`);
99
+ core_logger.info(`${message}: ${coloredEntries} ${env}`, ...args);
100
+ }
101
+ },
102
+ global: {
103
+ info: (message, ...args)=>{
104
+ if (!isTest) core_logger.info(message, ...args);
105
+ },
106
+ warn: (message, ...args)=>{
107
+ if (!isTest) core_logger.warn(message, ...args);
108
+ },
109
+ error: (message, ...args)=>{
110
+ if (!isTest) core_logger.error(message, ...args);
111
+ }
112
+ }
113
+ };
114
+ }
115
+ class EntryExtractor {
116
+ options;
117
+ constructor(options = {}){
118
+ this.options = options;
119
+ }
120
+ extract(packageJson) {
121
+ const entries = {};
122
+ this.extractFromExports(packageJson.exports, entries);
123
+ this.extractFromBin(packageJson.bin, entries);
124
+ return {
125
+ entries
126
+ };
127
+ }
128
+ extractFromExports(exports, entries) {
129
+ if (!exports) return;
130
+ if ("string" == typeof exports) {
131
+ if (this.isTypeScriptFile(exports)) entries.index = exports;
132
+ return;
133
+ }
134
+ if ("object" != typeof exports) return;
135
+ for (const [key, value] of Object.entries(exports)){
136
+ if ("./package.json" === key || key.endsWith(".json")) continue;
137
+ const sourcePath = this.resolveSourcePath(value);
138
+ if (!sourcePath) continue;
139
+ const resolvedPath = this.resolveToTypeScript(sourcePath);
140
+ if (!this.isTypeScriptFile(resolvedPath)) continue;
141
+ const entryName = this.createEntryName(key);
142
+ entries[entryName] = resolvedPath;
143
+ }
144
+ }
145
+ extractFromBin(bin, entries) {
146
+ if (!bin) return;
147
+ if ("string" == typeof bin) {
148
+ const resolvedPath = this.resolveToTypeScript(bin);
149
+ if (this.isTypeScriptFile(resolvedPath)) entries["bin/cli"] = resolvedPath;
150
+ return;
151
+ }
152
+ if ("object" != typeof bin) return;
153
+ for (const [command, path] of Object.entries(bin)){
154
+ if ("string" != typeof path) continue;
155
+ const resolvedPath = this.resolveToTypeScript(path);
156
+ if (this.isTypeScriptFile(resolvedPath)) entries[`bin/${command}`] = resolvedPath;
157
+ }
158
+ }
159
+ resolveSourcePath(value) {
160
+ if ("string" == typeof value) return value;
161
+ if (value && "object" == typeof value) {
162
+ const exportObj = value;
163
+ return exportObj.import || exportObj.default || exportObj.types;
164
+ }
165
+ }
166
+ resolveToTypeScript(path) {
167
+ if (path.endsWith(".js") && path.includes("/dist/")) return path.replace("/dist/", "/src/").replace(/\.js$/, ".ts");
168
+ return path;
169
+ }
170
+ isTypeScriptFile(path) {
171
+ return path.endsWith(".ts") || path.endsWith(".tsx");
172
+ }
173
+ createEntryName(exportKey) {
174
+ if ("." === exportKey) return "index";
175
+ const withoutPrefix = exportKey.replace(/^\.\//, "");
176
+ if (this.options.exportsAsIndexes) return `${withoutPrefix}/index`;
177
+ return withoutPrefix.replace(/\//g, "-");
178
+ }
179
+ }
180
+ function extractEntriesFromPackageJson(packageJson, options) {
181
+ const extractor = new EntryExtractor(options);
182
+ return extractor.extract(packageJson);
183
+ }
184
+ const AutoEntryPlugin = (options)=>{
185
+ const buildStateMap = new WeakMap();
186
+ return {
187
+ name: "auto-entry-plugin",
188
+ setup (api) {
189
+ buildStateMap.set(api, {
190
+ hasLoggedEntries: false,
191
+ hasLoggedSchemas: false
192
+ });
193
+ let entrypoints = api.useExposed("entrypoints");
194
+ if (!entrypoints) {
195
+ entrypoints = new Map();
196
+ api.expose("entrypoints", entrypoints);
197
+ }
198
+ let exportToOutputMap = api.useExposed("exportToOutputMap");
199
+ if (!exportToOutputMap) {
200
+ exportToOutputMap = new Map();
201
+ api.expose("exportToOutputMap", exportToOutputMap);
202
+ }
203
+ api.onBeforeBuild(async (context)=>{
204
+ api.logger.debug(context);
205
+ });
206
+ api.modifyRsbuildConfig(async (config)=>{
207
+ const log = createEnvLogger("auto-entry");
208
+ const { assetPath, assetExists } = await fileExistAsync("package.json");
209
+ if (!assetExists) {
210
+ log.global.error("package.json not found in project root");
211
+ throw new Error("package.json not found in project root");
212
+ }
213
+ try {
214
+ const packageJsonContent = await promises_readFile(assetPath, "utf-8");
215
+ const packageJson = JSON.parse(packageJsonContent);
216
+ const { entries } = extractEntriesFromPackageJson(packageJson, {
217
+ exportsAsIndexes: options?.exportsAsIndexes
218
+ });
219
+ if (options?.exportsAsIndexes && packageJson.exports) {
220
+ const exports = packageJson.exports;
221
+ if ("object" == typeof exports && !Array.isArray(exports)) for (const pkgExportKey of Object.keys(exports)){
222
+ if ("./package.json" === pkgExportKey) continue;
223
+ const normalizedExportKey = pkgExportKey.replace(/^\.\//, "");
224
+ for (const [entryName] of Object.entries(entries)){
225
+ const normalizedEntryName = entryName.replace(/\/index$/, "");
226
+ if ("." === pkgExportKey && "index" === entryName || normalizedExportKey === normalizedEntryName) {
227
+ const outputPath = `./${entryName}.js`;
228
+ exportToOutputMap.set(pkgExportKey, outputPath);
229
+ break;
230
+ }
231
+ }
232
+ }
233
+ }
234
+ for (const [entryName, sourcePath] of Object.entries(entries)){
235
+ const outputName = `${entryName}.ts`;
236
+ entrypoints.set(outputName, sourcePath);
237
+ }
238
+ if (Object.keys(entries).length > 0) {
239
+ const environments = Object.entries(config?.environments ?? {});
240
+ environments.forEach(([_env, lib])=>{
241
+ lib.source = {
242
+ ...lib.source,
243
+ entry: {
244
+ ...lib.source?.entry,
245
+ ...entries
246
+ }
247
+ };
248
+ });
249
+ const state = buildStateMap.get(api);
250
+ if (state && !state.hasLoggedEntries) {
251
+ state.hasLoggedEntries = true;
252
+ environments.forEach(([env])=>{
253
+ const log = createEnvLogger(env);
254
+ log.entries("auto-detected entries", entries);
255
+ });
256
+ }
257
+ }
258
+ } catch (error) {
259
+ log.global.error("failed to process package.json:", error);
260
+ }
261
+ return config;
262
+ });
263
+ }
264
+ };
265
+ };
266
+ var lib_namespaceObject = JSON.parse('{"$schema":"https://json.schemastore.org/tsconfig.json","compilerOptions":{"allowSyntheticDefaultImports":true,"composite":true,"declaration":true,"declarationDir":"${configDir}/dist","declarationMap":false,"emitDeclarationOnly":false,"esModuleInterop":true,"explainFiles":false,"forceConsistentCasingInFileNames":true,"incremental":true,"isolatedDeclarations":true,"isolatedModules":true,"jsx":"preserve","lib":["esnext"],"module":"nodenext","moduleResolution":"nodenext","outDir":"${configDir}/dist","resolveJsonModule":true,"rootDir":"${configDir}","skipLibCheck":true,"sourceMap":false,"strict":true,"strictNullChecks":true,"target":"es2023","tsBuildInfoFile":"${configDir}/dist/.tsbuildinfo.lib","typeRoots":["${configDir}/node_modules/@types","${configDir}/types"],"verbatimModuleSyntax":true},"exclude":["${configDir}/node_modules","${configDir}/dist/**/*"],"include":["${configDir}/types/*.ts","${configDir}/package.json","${configDir}/*.ts","${configDir}/*.cts","${configDir}/*.mts","${configDir}/src/**/*.ts","${configDir}/src/**/*.tsx","${configDir}/src/**/*.cts","${configDir}/src/**/*.mts","${configDir}/lib/**/*.ts","${configDir}/lib/**/*.tsx","${configDir}/lib/**/*.cts","${configDir}/lib/**/*.mts","${configDir}/public/**/*.json"]}');
267
+ var root_namespaceObject = JSON.parse('{"$schema":"https://json.schemastore.org/tsconfig","compilerOptions":{"composite":true,"declaration":true,"module":"node20","outDir":"dist","resolveJsonModule":true,"strict":true,"strictNullChecks":true,"target":"es2023"}}');
268
+ const requireCJS = createRequire(import.meta.url);
269
+ const jsonImports = new Map([
270
+ [
271
+ (0, external_node_path_.join)(import.meta.dirname, "../public/tsconfig/node/ecma/lib.json"),
272
+ lib_namespaceObject
273
+ ],
274
+ [
275
+ (0, external_node_path_.join)(import.meta.dirname, "../public/tsconfig/root.json"),
276
+ root_namespaceObject
277
+ ]
278
+ ]);
279
+ function transformStringsDeep(value, transform) {
280
+ if (null == value) return value;
281
+ if ("string" == typeof value) return transform(value);
282
+ if (Array.isArray(value)) return value.map((item)=>transformStringsDeep(item, transform));
283
+ if ("object" == typeof value) {
284
+ const result = {};
285
+ for (const [key, val] of Object.entries(value))result[key] = transformStringsDeep(val, transform);
286
+ return result;
287
+ }
288
+ return value;
289
+ }
290
+ class TSConfigFile {
291
+ pathname;
292
+ description;
293
+ /* v8 ignore next -- @preserve */ get path() {
294
+ return `./${(0, external_node_path_.relative)(process.cwd(), this.pathname)}`;
295
+ }
296
+ /* v8 ignore next -- @preserve */ get bundled() {
297
+ const config = this.config;
298
+ return transformStringsDeep(config, (str)=>str.replace("${configDir}", "../../../../../.."));
299
+ }
300
+ /* v8 ignore next -- @preserve */ get config() {
301
+ const imported = jsonImports.get(this.pathname);
302
+ if (!imported) throw new Error(`Config file not found in imports: ${this.pathname}`);
303
+ return imported;
304
+ }
305
+ constructor(description, pathname){
306
+ this.pathname = pathname;
307
+ this.description = description;
308
+ Object.defineProperty(this, "path", {
309
+ enumerable: true,
310
+ get: ()=>`./${(0, external_node_path_.relative)(process.cwd(), this.pathname)}`
311
+ });
312
+ Object.defineProperty(this, "config", {
313
+ enumerable: true,
314
+ get: ()=>{
315
+ const imported = jsonImports.get(this.pathname);
316
+ if (!imported) throw new Error(`Config file not found in imports: ${this.pathname}`);
317
+ return imported;
318
+ }
319
+ });
320
+ Object.defineProperty(this, "bundled", {
321
+ enumerable: true,
322
+ get: ()=>{
323
+ const imported = jsonImports.get(this.pathname);
324
+ if (!imported) throw new Error(`Config file not found in imports: ${this.pathname}`);
325
+ return transformStringsDeep(imported, (str)=>str.replace("${configDir}", "../../../../../.."));
326
+ }
327
+ });
328
+ Object.defineProperty(this, inspect.custom, {
329
+ value: (_depth, options)=>inspect({
330
+ description: this.description,
331
+ pathname: this.pathname,
332
+ path: this.path,
333
+ config: this.config,
334
+ bundled: this.bundled
335
+ }, {
336
+ ...options,
337
+ depth: null,
338
+ colors: options.colors ?? true,
339
+ maxArrayLength: null,
340
+ breakLength: 80
341
+ })
342
+ });
343
+ }
344
+ }
345
+ class LibraryTSConfigFile extends TSConfigFile {
346
+ bundle(target) {
347
+ const config = transformStringsDeep(this.config, (str)=>str.replace("${configDir}", "../../../../../.."));
348
+ const include = config.include?.filter((pattern)=>pattern.includes("/src/") || pattern.includes("/types/") || pattern.includes("/public/") || pattern.includes("package.json")).filter((pattern)=>!pattern.includes(".tsx") && !pattern.includes(".cts"));
349
+ return {
350
+ ...config,
351
+ compilerOptions: {
352
+ ...config.compilerOptions,
353
+ outDir: "dist",
354
+ tsBuildInfoFile: `${process.cwd()}/dist/.tsbuildinfo.${target}.bundle`
355
+ },
356
+ include
357
+ };
358
+ }
359
+ writeBundleTempConfig(target) {
360
+ const cwd = process.cwd();
361
+ const config = this.bundle(target);
362
+ const toAbsolute = (path)=>{
363
+ if (path.startsWith("../") || ".." === path) return path.replace(/^((\.\.\/)+\.\.?|\.\.\/*)$/, cwd).replace(/^(\.\.\/)+/, `${cwd}/`);
364
+ return path;
365
+ };
366
+ const absoluteConfig = {
367
+ ...config,
368
+ compilerOptions: {
369
+ ...config.compilerOptions,
370
+ rootDir: cwd,
371
+ declarationMap: true,
372
+ emitDeclarationOnly: false,
373
+ declarationDir: config.compilerOptions?.declarationDir ? toAbsolute(config.compilerOptions.declarationDir) : void 0,
374
+ typeRoots: config.compilerOptions?.typeRoots?.map(toAbsolute)
375
+ },
376
+ include: config.include?.map(toAbsolute),
377
+ exclude: config.exclude?.map(toAbsolute)
378
+ };
379
+ const tmpFile = requireCJS("tmp").fileSync({
380
+ prefix: "tsconfig-bundle-",
381
+ postfix: ".json"
382
+ });
383
+ writeFileSync(tmpFile.name, JSON.stringify(absoluteConfig, null, "\t"));
384
+ return tmpFile.name;
385
+ }
386
+ }
387
+ const Root = new TSConfigFile("Root configuration for workspace setup", (0, external_node_path_.join)(import.meta.dirname, "../public/tsconfig/root.json"));
388
+ const NodeEcmaLib = new LibraryTSConfigFile("ECMAScript library build configuration", (0, external_node_path_.join)(import.meta.dirname, "../public/tsconfig/node/ecma/lib.json"));
389
+ const TSConfigs = {
390
+ root: Root,
391
+ node: {
392
+ ecma: {
393
+ lib: NodeEcmaLib
394
+ }
395
+ }
396
+ };
397
+ function getTsgoBinPath() {
398
+ const cwd = process.cwd();
399
+ const localTsgoBin = (0, external_node_path_.join)(cwd, "node_modules", ".bin", "tsgo");
400
+ if (existsSync(localTsgoBin)) return localTsgoBin;
401
+ const workspaceRoot = getWorkspaceRoot(cwd);
402
+ if (workspaceRoot) {
403
+ const workspaceTsgoBin = (0, external_node_path_.join)(workspaceRoot, "node_modules", ".bin", "tsgo");
404
+ if (existsSync(workspaceTsgoBin)) return workspaceTsgoBin;
405
+ }
406
+ return localTsgoBin;
407
+ }
408
+ function generateTsgoArgs(options) {
409
+ const { configPath, declarationDir, rootDir, tsBuildInfoFile } = options;
410
+ const args = [
411
+ "--project",
412
+ configPath,
413
+ "--declaration",
414
+ "--emitDeclarationOnly",
415
+ "--declarationMap",
416
+ "--declarationDir",
417
+ declarationDir
418
+ ];
419
+ if (rootDir) args.push("--rootDir", rootDir);
420
+ if (tsBuildInfoFile) args.push("--tsBuildInfoFile", tsBuildInfoFile);
421
+ return args;
422
+ }
423
+ async function collectDtsFiles(dir, baseDir = dir) {
424
+ const files = [];
425
+ async function walk(currentDir) {
426
+ const entries = await readdir(currentDir, {
427
+ withFileTypes: true
428
+ });
429
+ for (const entry of entries){
430
+ const fullPath = (0, external_node_path_.join)(currentDir, entry.name);
431
+ if (entry.isDirectory()) await walk(fullPath);
432
+ else if (entry.name.endsWith(".d.ts") || entry.name.endsWith(".d.ts.map")) {
433
+ const relativePath = (0, external_node_path_.relative)(baseDir, fullPath);
434
+ files.push({
435
+ path: fullPath,
436
+ relativePath
437
+ });
438
+ }
439
+ }
440
+ }
441
+ await walk(dir);
442
+ return files;
443
+ }
444
+ async function bundleDtsFiles(options) {
445
+ const { cwd, tempDtsDir, tempOutputDir, tsconfigPath, bundledPackages, entryPoints, banner, footer, apiModel } = options;
446
+ const bundledFiles = new Map();
447
+ let apiModelPath;
448
+ const apiModelEnabled = true === apiModel || "object" == typeof apiModel && (void 0 === apiModel.enabled || true === apiModel.enabled);
449
+ const apiModelFilename = "object" == typeof apiModel && apiModel.filename ? apiModel.filename : "api.model.json";
450
+ getApiExtractorPath();
451
+ const { Extractor, ExtractorConfig } = await import("@microsoft/api-extractor");
452
+ for (const [entryName, sourcePath] of entryPoints){
453
+ const normalizedSourcePath = sourcePath.replace(/^\.\//, "");
454
+ const dtsFileName = normalizedSourcePath.replace(/\.(tsx?|jsx?)$/, ".d.ts");
455
+ let tempDtsPath = (0, external_node_path_.join)(tempDtsDir, dtsFileName);
456
+ try {
457
+ await access(tempDtsPath, constants.F_OK);
458
+ } catch {
459
+ const withoutSrc = dtsFileName.replace(/^src\//, "");
460
+ if (withoutSrc !== dtsFileName) {
461
+ const alternativePath = (0, external_node_path_.join)(tempDtsDir, withoutSrc);
462
+ try {
463
+ await access(alternativePath, constants.F_OK);
464
+ tempDtsPath = alternativePath;
465
+ } catch {}
466
+ }
467
+ }
468
+ const outputFileName = `${entryName}.d.ts`;
469
+ const tempBundledPath = (0, external_node_path_.join)(tempOutputDir, outputFileName);
470
+ const generateApiModel = apiModelEnabled && "index" === entryName;
471
+ const tempApiModelPath = generateApiModel ? (0, external_node_path_.join)(tempOutputDir, apiModelFilename) : void 0;
472
+ const extractorConfig = ExtractorConfig.prepare({
473
+ configObject: {
474
+ projectFolder: cwd,
475
+ mainEntryPointFilePath: tempDtsPath,
476
+ compiler: {
477
+ tsconfigFilePath: tsconfigPath
478
+ },
479
+ dtsRollup: {
480
+ enabled: true,
481
+ untrimmedFilePath: tempBundledPath
482
+ },
483
+ docModel: generateApiModel ? {
484
+ enabled: true,
485
+ apiJsonFilePath: tempApiModelPath
486
+ } : void 0,
487
+ bundledPackages: bundledPackages
488
+ },
489
+ packageJsonFullPath: (0, external_node_path_.join)(cwd, "package.json"),
490
+ configObjectFullPath: void 0
491
+ });
492
+ const extractorResult = Extractor.invoke(extractorConfig, {
493
+ localBuild: true,
494
+ showVerboseMessages: false,
495
+ messageCallback: (message)=>{
496
+ if (message.text?.includes("Analysis will use the bundled TypeScript version") || message.text?.includes("The target project appears to use TypeScript")) {
497
+ message.logLevel = "none";
498
+ return;
499
+ }
500
+ if (message.text?.includes("You have changed the public API signature")) message.logLevel = "none";
501
+ }
502
+ });
503
+ if (!extractorResult.succeeded) throw new Error(`API Extractor failed for entry "${entryName}"`);
504
+ if (generateApiModel && tempApiModelPath) apiModelPath = tempApiModelPath;
505
+ if (banner || footer) {
506
+ let content = await promises_readFile(tempBundledPath, "utf-8");
507
+ if (banner) content = `${banner}\n${content}`;
508
+ if (footer) content = `${content}\n${footer}`;
509
+ await writeFile(tempBundledPath, content, "utf-8");
510
+ }
511
+ bundledFiles.set(entryName, tempBundledPath);
512
+ }
513
+ return {
514
+ bundledFiles,
515
+ apiModelPath
516
+ };
517
+ }
518
+ function stripSourceMapComment(content) {
519
+ return content.replace(/\/\/# sourceMappingURL=.+\.d\.ts\.map\s*$/gm, "").trim();
520
+ }
521
+ async function ensureTempDeclarationDir(cwd, name) {
522
+ const dir = (0, external_node_path_.join)(cwd, ".rslib", "declarations", name);
523
+ await rm(dir, {
524
+ recursive: true,
525
+ force: true
526
+ });
527
+ await mkdir(dir, {
528
+ recursive: true
529
+ });
530
+ return dir;
531
+ }
532
+ function findTsConfig(cwd, tsconfigPath) {
533
+ if (tsconfigPath) {
534
+ const { isAbsolute } = __webpack_require__("node:path");
535
+ if (isAbsolute(tsconfigPath) && sys.fileExists(tsconfigPath)) return tsconfigPath;
536
+ }
537
+ return findConfigFile(cwd, sys.fileExists.bind(sys), tsconfigPath) ?? null;
538
+ }
539
+ function loadTsConfig(configPath) {
540
+ const configContent = readConfigFile(configPath, sys.readFile.bind(sys));
541
+ if (configContent.error) throw new Error(`Failed to read tsconfig: ${formatDiagnostic(configContent.error, createCompilerHost({}, true))}`);
542
+ const parsedConfig = parseJsonConfigFileContent(configContent.config, sys, (0, external_node_path_.dirname)(configPath), {}, configPath);
543
+ if (parsedConfig.errors.length > 0) throw new Error(`Failed to parse tsconfig: ${parsedConfig.errors.map((err)=>formatDiagnostic(err, createCompilerHost({}, true))).join("\n")}`);
544
+ return parsedConfig;
545
+ }
546
+ function runTsgo(options) {
547
+ const { configPath, declarationDir, rootDir, tsBuildInfoFile, name } = options;
548
+ const tsgoBinPath = getTsgoBinPath();
549
+ const args = generateTsgoArgs({
550
+ configPath,
551
+ declarationDir,
552
+ rootDir,
553
+ tsBuildInfoFile
554
+ });
555
+ return new Promise((resolve)=>{
556
+ const child = spawn(tsgoBinPath, args, {
557
+ stdio: [
558
+ "inherit",
559
+ "pipe",
560
+ "pipe"
561
+ ],
562
+ shell: false
563
+ });
564
+ let stdout = "";
565
+ let stderr = "";
566
+ child.stdout?.on("data", (data)=>{
567
+ const text = data.toString();
568
+ stdout += text;
569
+ core_logger.info(`${picocolors.dim(`[${name}]`)} ${text.trim()}`);
570
+ });
571
+ child.stderr?.on("data", (data)=>{
572
+ const text = data.toString();
573
+ stderr += text;
574
+ core_logger.error(`${picocolors.dim(`[${name}]`)} ${picocolors.red(text.trim())}`);
575
+ });
576
+ child.on("close", (code)=>{
577
+ const output = stdout + stderr;
578
+ resolve({
579
+ success: 0 === code,
580
+ output
581
+ });
582
+ });
583
+ child.on("error", (err)=>{
584
+ core_logger.error(`Failed to spawn tsgo: ${err.message}`);
585
+ resolve({
586
+ success: false,
587
+ output: err.message
588
+ });
589
+ });
590
+ });
591
+ }
592
+ /* v8 ignore next -- @preserve */ const DtsPlugin = (options = {})=>{
593
+ const { abortOnError = true, dtsExtension = ".d.ts" } = options;
594
+ const state = {
595
+ tsconfigPath: null,
596
+ parsedConfig: null
597
+ };
598
+ return {
599
+ name: "dts-plugin",
600
+ setup (api) {
601
+ api.modifyRsbuildConfig(async (config)=>{
602
+ const log = createEnvLogger("dts");
603
+ const cwd = api.context.rootPath;
604
+ try {
605
+ let configTsconfigPath = options.tsconfigPath || config.source?.tsconfigPath;
606
+ if (!configTsconfigPath && options.buildTarget) {
607
+ const originalCwd = process.cwd();
608
+ try {
609
+ process.chdir(cwd);
610
+ configTsconfigPath = TSConfigs.node.ecma.lib.writeBundleTempConfig(options.buildTarget);
611
+ log.global.info(`Using tsconfig: ${configTsconfigPath}`);
612
+ } finally{
613
+ process.chdir(originalCwd);
614
+ }
615
+ }
616
+ state.tsconfigPath = findTsConfig(cwd, configTsconfigPath);
617
+ if (!state.tsconfigPath) {
618
+ const error = new Error(`Failed to resolve tsconfig file ${picocolors.cyan(`"${config.source?.tsconfigPath ?? "tsconfig.json"}"`)} from ${picocolors.cyan(cwd)}. Please ensure that the file exists.`);
619
+ error.stack = "";
620
+ throw error;
621
+ }
622
+ state.parsedConfig = loadTsConfig(state.tsconfigPath);
623
+ log.global.info(`Using tsconfig: ${picocolors.cyan((0, external_node_path_.relative)(cwd, state.tsconfigPath))}`);
624
+ } catch (error) {
625
+ log.global.error("Failed to initialize DTS plugin:", error);
626
+ throw error;
627
+ }
628
+ return config;
629
+ });
630
+ api.processAssets({
631
+ stage: "pre-process"
632
+ }, async (context)=>{
633
+ if (!state.tsconfigPath || !state.parsedConfig) return void core_logger.warn("DTS plugin not properly initialized, skipping declaration generation");
634
+ const envId = context.compilation?.name || "unknown";
635
+ const log = createEnvLogger(envId);
636
+ const cwd = api.context.rootPath;
637
+ const tempDtsDir = await ensureTempDeclarationDir(cwd, envId);
638
+ const filesArray = api.useExposed("files-array");
639
+ try {
640
+ core_logger.info(`${picocolors.dim(`[${envId}]`)} Generating declaration files...`);
641
+ const { success, output } = await runTsgo({
642
+ configPath: state.tsconfigPath,
643
+ declarationDir: tempDtsDir,
644
+ rootDir: state.parsedConfig.options.rootDir,
645
+ tsBuildInfoFile: state.parsedConfig.options.tsBuildInfoFile,
646
+ name: envId
647
+ });
648
+ if (!success) {
649
+ const errorMsg = `TypeScript declaration generation failed:\n${output}`;
650
+ if (abortOnError) throw new Error(errorMsg);
651
+ log.global.error(errorMsg);
652
+ log.global.warn("With `abortOnError` disabled, type errors will not fail the build, but proper type declaration output cannot be guaranteed.");
653
+ return;
654
+ }
655
+ const allDtsFiles = await collectDtsFiles(tempDtsDir);
656
+ const apiExtractorMapping = api.useExposed("api-extractor-temp-mapping");
657
+ if (apiExtractorMapping) {
658
+ const tempFileRelative = (0, external_node_path_.relative)(cwd, apiExtractorMapping.tempPath);
659
+ for (const file of allDtsFiles){
660
+ const expectedPath = tempFileRelative.replace(/\.ts$/, ".d.ts");
661
+ const expectedMapPath = `${expectedPath}.map`;
662
+ if (file.relativePath === expectedPath || file.relativePath === expectedMapPath) {
663
+ const ext = file.relativePath.endsWith(".map") ? ".d.ts.map" : ".d.ts";
664
+ const originalDtsPath = apiExtractorMapping.originalPath.replace(/\.ts$/, ext);
665
+ const newPath = (0, external_node_path_.join)(tempDtsDir, originalDtsPath);
666
+ await mkdir((0, external_node_path_.dirname)(newPath), {
667
+ recursive: true
668
+ });
669
+ await copyFile(file.path, newPath);
670
+ log.global.info(`Renamed ${file.relativePath} -> ${originalDtsPath} (from temp api-extractor)`);
671
+ await unlink(file.path);
672
+ }
673
+ }
674
+ allDtsFiles.length = 0;
675
+ allDtsFiles.push(...await collectDtsFiles(tempDtsDir));
676
+ }
677
+ const dtsFiles = allDtsFiles.filter((file)=>{
678
+ const path = file.relativePath;
679
+ return !path.includes("__test__/") && !path.includes(".test.d.ts");
680
+ });
681
+ if (0 === dtsFiles.length) return void log.global.warn("No declaration files were generated");
682
+ if (options.bundle) try {
683
+ const exposedPackageJson = api.useExposed("api-extractor-package-json");
684
+ let packageJson;
685
+ if (exposedPackageJson) {
686
+ log.global.info("Using in-memory package.json from api-report-plugin");
687
+ packageJson = exposedPackageJson;
688
+ } else {
689
+ const packageJsonPath = (0, external_node_path_.join)(cwd, "package.json");
690
+ const packageJsonContent = await promises_readFile(packageJsonPath, "utf-8");
691
+ packageJson = JSON.parse(packageJsonContent);
692
+ }
693
+ const entryPoints = new Map();
694
+ if (packageJson.exports) {
695
+ const exports = packageJson.exports;
696
+ const mainExport = exports["."];
697
+ if (mainExport) {
698
+ const sourcePath = "string" == typeof mainExport ? mainExport : mainExport?.default;
699
+ if (sourcePath && "string" == typeof sourcePath) {
700
+ if (sourcePath.match(/\.(ts|mts|cts|tsx)$/)) {
701
+ if (!sourcePath.includes(".test.") && !sourcePath.includes("__test__")) {
702
+ const resolvedSourcePath = sourcePath.startsWith(".") ? (0, external_node_path_.join)(cwd, sourcePath) : sourcePath;
703
+ if (resolvedSourcePath.startsWith(cwd)) {
704
+ let finalSourcePath = sourcePath;
705
+ if (apiExtractorMapping && resolvedSourcePath === apiExtractorMapping.tempPath) {
706
+ finalSourcePath = apiExtractorMapping.originalPath;
707
+ log.global.info(`Using original path for api-extractor: ${finalSourcePath}`);
708
+ }
709
+ entryPoints.set("index", finalSourcePath);
710
+ } else log.global.info(`Skipping main export (source outside package: ${sourcePath})`);
711
+ }
712
+ }
713
+ }
714
+ }
715
+ }
716
+ if (0 === entryPoints.size) log.global.warn("No main export found in package.json exports, skipping bundling");
717
+ else {
718
+ const tempBundledDir = (0, external_node_path_.join)(tempDtsDir, "bundled");
719
+ await mkdir(tempBundledDir, {
720
+ recursive: true
721
+ });
722
+ const { bundledFiles, apiModelPath } = await bundleDtsFiles({
723
+ cwd,
724
+ tempDtsDir,
725
+ tempOutputDir: tempBundledDir,
726
+ tsconfigPath: state.tsconfigPath,
727
+ bundledPackages: options.bundledPackages || [],
728
+ entryPoints,
729
+ banner: options.banner,
730
+ footer: options.footer,
731
+ apiModel: options.apiModel
732
+ });
733
+ let emittedCount = 0;
734
+ for (const [entryName, tempBundledPath] of bundledFiles){
735
+ const bundledFileName = `${entryName}.d.ts`;
736
+ let content = await promises_readFile(tempBundledPath, "utf-8");
737
+ content = stripSourceMapComment(content);
738
+ const source = new context.sources.OriginalSource(content, bundledFileName);
739
+ context.compilation.emitAsset(bundledFileName, source);
740
+ emittedCount++;
741
+ if (filesArray) filesArray.add(bundledFileName);
742
+ }
743
+ core_logger.info(`${picocolors.dim(`[${envId}]`)} Emitted ${emittedCount} bundled declaration file${1 === emittedCount ? "" : "s"} through asset pipeline`);
744
+ if (apiModelPath) {
745
+ const apiModelFilename = "object" == typeof options.apiModel && options.apiModel.filename ? options.apiModel.filename : "api.model.json";
746
+ const apiModelContent = await promises_readFile(apiModelPath, "utf-8");
747
+ const apiModelSource = new context.sources.OriginalSource(apiModelContent, apiModelFilename);
748
+ context.compilation.emitAsset(apiModelFilename, apiModelSource);
749
+ if (filesArray) filesArray.add(apiModelFilename);
750
+ core_logger.info(`${picocolors.dim(`[${envId}]`)} Emitted API model: ${apiModelFilename}`);
751
+ const shouldAddNpmIgnore = true === options.apiModel || "object" == typeof options.apiModel && false !== options.apiModel.npmIgnore;
752
+ if (shouldAddNpmIgnore) {
753
+ const npmIgnoreContent = `# Exclude API model from npm publish (used by internal tooling)\n${apiModelFilename}\n`;
754
+ const npmIgnoreSource = new context.sources.OriginalSource(npmIgnoreContent, ".npmignore");
755
+ context.compilation.emitAsset(".npmignore", npmIgnoreSource);
756
+ if (filesArray) filesArray.add(".npmignore");
757
+ core_logger.info(`${picocolors.dim(`[${envId}]`)} Emitted .npmignore to exclude ${apiModelFilename}`);
758
+ }
759
+ const isCI = "true" === process.env.GITHUB_ACTIONS || "true" === process.env.CI;
760
+ const localPaths = "object" == typeof options.apiModel ? options.apiModel.localPaths : void 0;
761
+ if (localPaths && localPaths.length > 0 && !isCI) for (const localPath of localPaths){
762
+ const resolvedPath = (0, external_node_path_.join)(cwd, localPath);
763
+ const parentDir = (0, external_node_path_.dirname)(resolvedPath);
764
+ if (!existsSync(parentDir)) {
765
+ core_logger.warn(`${picocolors.dim(`[${envId}]`)} Skipping local path: parent directory does not exist: ${parentDir}`);
766
+ continue;
767
+ }
768
+ await mkdir(resolvedPath, {
769
+ recursive: true
770
+ });
771
+ const apiModelDestPath = (0, external_node_path_.join)(resolvedPath, apiModelFilename);
772
+ await writeFile(apiModelDestPath, apiModelContent, "utf-8");
773
+ const packageJsonAsset = context.compilation.assets["package.json"];
774
+ if (packageJsonAsset) {
775
+ const rawContent = "function" == typeof packageJsonAsset.source ? packageJsonAsset.source() : packageJsonAsset.source;
776
+ const packageJsonContent = "string" == typeof rawContent ? rawContent : rawContent instanceof Buffer ? rawContent.toString("utf-8") : String(rawContent);
777
+ const packageJsonDestPath = (0, external_node_path_.join)(resolvedPath, "package.json");
778
+ await writeFile(packageJsonDestPath, packageJsonContent, "utf-8");
779
+ }
780
+ core_logger.info(`${picocolors.dim(`[${envId}]`)} Copied API model and package.json to: ${localPath}`);
781
+ }
782
+ }
783
+ for (const [entryName] of bundledFiles){
784
+ const bundledFileName = `${entryName}.d.ts`;
785
+ const mapFileName = `${bundledFileName}.map`;
786
+ for (const file of dtsFiles){
787
+ if (file.relativePath.endsWith(".d.ts.map")) continue;
788
+ let outputPath = file.relativePath;
789
+ if (outputPath.startsWith("src/")) outputPath = outputPath.slice(4);
790
+ if (".d.ts" !== dtsExtension && outputPath.endsWith(".d.ts")) outputPath = outputPath.replace(/\.d\.ts$/, dtsExtension);
791
+ const mapFileName = `${outputPath}.map`;
792
+ if (context.compilation.assets[mapFileName]) delete context.compilation.assets[mapFileName];
793
+ }
794
+ if (context.compilation.assets[mapFileName]) delete context.compilation.assets[mapFileName];
795
+ }
796
+ }
797
+ } catch (error) {
798
+ log.global.error("Failed to bundle declaration files:", error);
799
+ if (abortOnError) throw error;
800
+ }
801
+ else {
802
+ let emittedCount = 0;
803
+ for (const file of dtsFiles){
804
+ if (file.relativePath.endsWith(".d.ts.map")) continue;
805
+ let content = await promises_readFile(file.path, "utf-8");
806
+ let outputPath = file.relativePath;
807
+ if (outputPath.startsWith("src/")) outputPath = outputPath.slice(4);
808
+ if (".d.ts" !== dtsExtension && outputPath.endsWith(".d.ts")) outputPath = outputPath.replace(/\.d\.ts$/, dtsExtension);
809
+ content = stripSourceMapComment(content);
810
+ const source = new context.sources.OriginalSource(content, outputPath);
811
+ context.compilation.emitAsset(outputPath, source);
812
+ emittedCount++;
813
+ if (filesArray && outputPath.endsWith(".d.ts")) filesArray.add(outputPath);
814
+ }
815
+ core_logger.info(`${picocolors.dim(`[${envId}]`)} Emitted ${emittedCount} declaration file${1 === emittedCount ? "" : "s"} through asset pipeline`);
816
+ }
817
+ } catch (error) {
818
+ log.global.error("Failed to generate declaration files:", error);
819
+ if (abortOnError) throw error;
820
+ }
821
+ });
822
+ api.processAssets({
823
+ stage: "summarize"
824
+ }, async (compiler)=>{
825
+ const assetsToDelete = [];
826
+ for(const assetName in compiler.compilation.assets)if (assetName.endsWith(".d.ts")) {
827
+ const asset = compiler.compilation.assets[assetName];
828
+ const content = asset.source().toString();
829
+ const strippedContent = stripSourceMapComment(content);
830
+ if (strippedContent !== content) {
831
+ const source = new compiler.sources.OriginalSource(strippedContent, assetName);
832
+ compiler.compilation.assets[assetName] = source;
833
+ }
834
+ } else if (assetName.endsWith(".d.ts.map")) assetsToDelete.push(assetName);
835
+ for (const assetName of assetsToDelete)delete compiler.compilation.assets[assetName];
836
+ });
837
+ }
838
+ };
839
+ };
840
+ class TextAsset {
841
+ compiler;
842
+ _fileName;
843
+ asset;
844
+ source;
845
+ constructor(compiler, _fileName){
846
+ this.compiler = compiler;
847
+ this._fileName = _fileName;
848
+ this.asset = compiler.assets[_fileName];
849
+ this.source = this.asset.source().toString();
850
+ }
851
+ get fileName() {
852
+ return this._fileName;
853
+ }
854
+ update() {
855
+ const updatedSource = new this.compiler.sources.RawSource(this.source);
856
+ this.compiler.compilation.updateAsset(this.fileName, updatedSource);
857
+ }
858
+ static async create(context, fileName, required = true) {
859
+ let asset = context.assets[fileName];
860
+ if (asset) return new TextAsset(context, fileName);
861
+ try {
862
+ const filePath = (0, external_node_path_.join)(process.cwd(), fileName);
863
+ const content = await promises_readFile(filePath, "utf-8");
864
+ const source = new context.sources.RawSource(content);
865
+ context.compilation.emitAsset(fileName, source);
866
+ asset = source;
867
+ return new TextAsset(context, fileName);
868
+ } catch (error) {
869
+ if (required) throw new Error(`Failed to load text asset: ${fileName}: ${error instanceof Error ? error.message : String(error)}`);
870
+ return null;
871
+ }
872
+ }
873
+ }
874
+ class JsonAsset extends TextAsset {
875
+ data;
876
+ constructor(compiler, fileName){
877
+ super(compiler, fileName);
878
+ try {
879
+ this.data = JSON.parse(this.source);
880
+ } catch (error) {
881
+ throw new Error(`Failed to parse JSON in ${fileName}: ${error instanceof Error ? error.message : String(error)}`);
882
+ }
883
+ }
884
+ update() {
885
+ this.source = JSON.stringify(this.data, null, "\t");
886
+ super.update();
887
+ }
888
+ static async create(context, fileName, required = false) {
889
+ let asset = context.assets[fileName];
890
+ if (asset) return new JsonAsset(context, fileName);
891
+ try {
892
+ const filePath = (0, external_node_path_.join)(process.cwd(), fileName);
893
+ const content = await promises_readFile(filePath, "utf-8");
894
+ const source = new context.sources.RawSource(content);
895
+ context.compilation.emitAsset(fileName, source);
896
+ asset = source;
897
+ return new JsonAsset(context, fileName);
898
+ } catch (err) {
899
+ if (required) throw new Error(`Failed to load JSON asset: ${fileName}: ${err instanceof Error ? err.message : String(err)}`);
900
+ return null;
901
+ }
902
+ }
903
+ }
904
+ const FilesArrayPlugin = (options)=>({
905
+ name: "files-array-plugin",
906
+ post: [
907
+ "rsbuild:dts"
908
+ ],
909
+ setup (api) {
910
+ let filesArray = api.useExposed("files-array");
911
+ if (!filesArray) {
912
+ filesArray = new Set();
913
+ api.expose("files-array", filesArray);
914
+ }
915
+ api.processAssets({
916
+ stage: "additional"
917
+ }, async (context)=>{
918
+ const packageJson = await JsonAsset.create(context, "package.json", false);
919
+ if (packageJson) filesArray.add(packageJson.fileName);
920
+ const readme = await TextAsset.create(context, "README.md", false);
921
+ if (readme) filesArray.add(readme.fileName);
922
+ const license = await TextAsset.create(context, "LICENSE", false);
923
+ if (license) filesArray.add(license.fileName);
924
+ for (const assetName of Object.keys(context.compilation.assets))if (!assetName.endsWith(".map") && !filesArray.has(assetName)) filesArray.add(assetName);
925
+ if (options?.transformFiles) await options.transformFiles({
926
+ compilation: context.compilation,
927
+ filesArray,
928
+ target: options.target
929
+ });
930
+ });
931
+ api.processAssets({
932
+ stage: "optimize-inline"
933
+ }, async (context)=>{
934
+ const envId = context.compilation?.name || context.compilation?.options?.name || "unknown";
935
+ const log = createEnvLogger(envId);
936
+ const packageJson = await JsonAsset.create(context, "package.json", false);
937
+ if (packageJson) {
938
+ const previousFiles = new Set(packageJson.data.files || []);
939
+ const allFiles = new Set([
940
+ ...previousFiles,
941
+ ...Array.from(filesArray)
942
+ ].sort());
943
+ if (0 === allFiles.size) delete packageJson.data.files;
944
+ else {
945
+ const newFiles = new Set([
946
+ ...allFiles
947
+ ].filter((file)=>!previousFiles.has(file)));
948
+ if (newFiles.size > 0) log.fileOp("added to files array", Array.from(newFiles));
949
+ }
950
+ packageJson.data.files = Array.from(allFiles);
951
+ packageJson.update();
952
+ }
953
+ });
954
+ }
955
+ });
956
+ const CATALOG_PREFIX = "catalog:";
957
+ const WORKSPACE_PREFIX = "workspace:";
958
+ class PnpmCatalog {
959
+ catalogCache = null;
960
+ catalogCacheMtime = null;
961
+ cachedWorkspaceRoot = null;
962
+ clearCache() {
963
+ this.catalogCache = null;
964
+ this.catalogCacheMtime = null;
965
+ this.cachedWorkspaceRoot = null;
966
+ }
967
+ async getCatalog() {
968
+ try {
969
+ if (!this.cachedWorkspaceRoot) {
970
+ this.cachedWorkspaceRoot = getWorkspaceRoot(process.cwd());
971
+ if (!this.cachedWorkspaceRoot) throw new Error("Could not find workspace root - ensure you're in a workspace");
972
+ }
973
+ const workspaceFile = (0, external_node_path_.resolve)(this.cachedWorkspaceRoot, "pnpm-workspace.yaml");
974
+ const stats = await promises_stat(workspaceFile);
975
+ const currentMtime = stats.mtime.getTime();
976
+ if (null !== this.catalogCache && this.catalogCacheMtime === currentMtime) return this.catalogCache;
977
+ const content = await promises_readFile(workspaceFile, "utf-8");
978
+ const workspace = parse(content);
979
+ this.catalogCache = workspace.catalog ?? {};
980
+ this.catalogCacheMtime = currentMtime;
981
+ return this.catalogCache;
982
+ } catch (error) {
983
+ const errorMessage = error instanceof Error ? error.message : String(error);
984
+ const logger = createEnvLogger("catalog");
985
+ if (errorMessage.includes("ENOENT") && errorMessage.includes("pnpm-workspace.yaml")) {
986
+ logger.error("Failed to read pnpm catalog: workspace configuration not found");
987
+ logger.error(" -> Ensure you're in a pnpm workspace with proper configuration");
988
+ } else if (errorMessage.includes("YAML")) {
989
+ logger.error("Failed to read pnpm catalog: Invalid YAML syntax in workspace configuration");
990
+ logger.error(" -> Check workspace configuration file syntax");
991
+ } else logger.error(`Failed to read pnpm catalog from pnpm-workspace.yaml: ${errorMessage}`);
992
+ return {};
993
+ }
994
+ }
995
+ async resolvePackageJson(packageJson, dir = process.cwd()) {
996
+ const logger = createEnvLogger("pnpm");
997
+ try {
998
+ const catalog = await this.getCatalog();
999
+ const catalogDeps = this.collectDependencies(packageJson, CATALOG_PREFIX);
1000
+ const workspaceDeps = this.collectDependencies(packageJson, WORKSPACE_PREFIX);
1001
+ const hasCatalogDeps = catalogDeps.length > 0;
1002
+ const hasWorkspaceDeps = workspaceDeps.length > 0;
1003
+ if (hasCatalogDeps && 0 === Object.keys(catalog).length) {
1004
+ const error = `Package contains ${CATALOG_PREFIX} dependencies but catalog configuration is missing`;
1005
+ logger.error(error);
1006
+ logger.error(" -> Catalog dependencies found:");
1007
+ for (const { field, dependency, version } of catalogDeps)logger.error(` - ${field}.${dependency}: ${version}`);
1008
+ throw new Error(error);
1009
+ }
1010
+ if (hasCatalogDeps) logger.info(`Resolving ${catalogDeps.length} ${CATALOG_PREFIX} dependencies`);
1011
+ if (hasWorkspaceDeps) logger.info(`Resolving ${workspaceDeps.length} ${WORKSPACE_PREFIX} dependencies`);
1012
+ const result = await createExportableManifest(dir, packageJson, {
1013
+ catalogs: {
1014
+ default: catalog
1015
+ }
1016
+ });
1017
+ if (hasCatalogDeps || hasWorkspaceDeps) this.logResolvedDependencies(result, [
1018
+ ...catalogDeps,
1019
+ ...workspaceDeps
1020
+ ], logger);
1021
+ this.validateNoUnresolvedReferences(result, logger);
1022
+ return result;
1023
+ } catch (error) {
1024
+ const errorMessage = error instanceof Error ? error.message : String(error);
1025
+ if (errorMessage.startsWith("Transformation failed:") || errorMessage.includes(`Package contains ${CATALOG_PREFIX} dependencies`)) throw error;
1026
+ logger.error(`Failed to apply pnpm transformations for directory ${dir}: ${errorMessage}`);
1027
+ if (errorMessage.includes("catalog")) {
1028
+ logger.error(` -> Catalog resolution failed - check workspace configuration and ${CATALOG_PREFIX} dependencies`);
1029
+ throw new Error("Catalog resolution failed");
1030
+ }
1031
+ if (errorMessage.includes("workspace")) {
1032
+ logger.error(` -> Workspace resolution failed - check ${WORKSPACE_PREFIX} dependencies and configuration`);
1033
+ throw new Error("Workspace resolution failed");
1034
+ }
1035
+ if (errorMessage.includes("manifest")) {
1036
+ logger.error(" -> Manifest processing failed - check package.json syntax");
1037
+ throw new Error(`Manifest processing failed: ${errorMessage}`);
1038
+ }
1039
+ logger.error(" -> Cannot proceed with invalid package.json transformations");
1040
+ throw new Error(`PNPM transformation failed: ${errorMessage}`);
1041
+ }
1042
+ }
1043
+ collectDependencies(packageJson, prefix) {
1044
+ const deps = [];
1045
+ const fields = [
1046
+ "dependencies",
1047
+ "devDependencies",
1048
+ "peerDependencies",
1049
+ "optionalDependencies"
1050
+ ];
1051
+ for (const field of fields){
1052
+ const fieldDeps = packageJson[field];
1053
+ if (fieldDeps) {
1054
+ for (const [dependency, version] of Object.entries(fieldDeps))if ("string" == typeof version && version.startsWith(prefix)) deps.push({
1055
+ field,
1056
+ dependency,
1057
+ version
1058
+ });
1059
+ }
1060
+ }
1061
+ return deps;
1062
+ }
1063
+ logResolvedDependencies(resultPkg, originalDeps, logger) {
1064
+ const allResolved = {};
1065
+ for (const { field, dependency } of originalDeps){
1066
+ const deps = resultPkg[field];
1067
+ if (deps?.[dependency]) {
1068
+ if (!allResolved[field]) allResolved[field] = [];
1069
+ allResolved[field].push({
1070
+ dependency,
1071
+ version: deps[dependency]
1072
+ });
1073
+ }
1074
+ }
1075
+ if (Object.keys(allResolved).length > 0) {
1076
+ logger.info("Resolved dependencies:");
1077
+ for (const [field, deps] of Object.entries(allResolved)){
1078
+ logger.info(`- ${field}:`);
1079
+ for (const { dependency, version } of deps)logger.info(` ${dependency}: ${version}`);
1080
+ }
1081
+ }
1082
+ }
1083
+ validateNoUnresolvedReferences(resultPkg, logger) {
1084
+ const unresolvedDeps = [
1085
+ ...this.collectDependencies(resultPkg, CATALOG_PREFIX),
1086
+ ...this.collectDependencies(resultPkg, WORKSPACE_PREFIX)
1087
+ ];
1088
+ if (unresolvedDeps.length > 0) {
1089
+ const catalogRefs = unresolvedDeps.filter((dep)=>dep.version.startsWith(CATALOG_PREFIX));
1090
+ const workspaceRefs = unresolvedDeps.filter((dep)=>dep.version.startsWith(WORKSPACE_PREFIX));
1091
+ const refTypes = [];
1092
+ if (catalogRefs.length > 0) refTypes.push(CATALOG_PREFIX);
1093
+ if (workspaceRefs.length > 0) refTypes.push(WORKSPACE_PREFIX);
1094
+ const error = `Transformation failed: unresolved ${refTypes.join(" and ")} references remain in package.json`;
1095
+ logger.error(error);
1096
+ logger.error(" -> This would result in invalid package.json being published to npm");
1097
+ logger.error(" -> Unresolved dependencies:");
1098
+ for (const { field, dependency, version } of unresolvedDeps)logger.error(` - ${field}.${dependency}: ${version}`);
1099
+ throw new Error(error);
1100
+ }
1101
+ }
1102
+ }
1103
+ let defaultInstance = null;
1104
+ function getDefaultPnpmCatalog() {
1105
+ if (!defaultInstance) defaultInstance = new PnpmCatalog();
1106
+ return defaultInstance;
1107
+ }
1108
+ class PackageJsonTransformer {
1109
+ options;
1110
+ pnpmCatalog;
1111
+ constructor(options = {}){
1112
+ this.options = {
1113
+ processTSExports: options.processTSExports ?? true,
1114
+ collapseIndex: options.collapseIndex ?? false,
1115
+ entrypoints: options.entrypoints ?? new Map(),
1116
+ exportToOutputMap: options.exportToOutputMap ?? new Map()
1117
+ };
1118
+ this.pnpmCatalog = new PnpmCatalog();
1119
+ }
1120
+ transformExportPath(path) {
1121
+ let transformedPath = path;
1122
+ if (transformedPath.startsWith("./exports/")) transformedPath = `./${transformedPath.slice(10)}`;
1123
+ else if (transformedPath.startsWith("./public/")) transformedPath = `./${transformedPath.slice(9)}`;
1124
+ else if (transformedPath.startsWith("./src/")) transformedPath = `./${transformedPath.slice(6)}`;
1125
+ if (this.options.processTSExports) {
1126
+ const { collapseIndex } = this.options;
1127
+ if (collapseIndex && transformedPath.endsWith("/index.ts") && "./index.ts" !== transformedPath) transformedPath = `${transformedPath.slice(0, -9)}.js`;
1128
+ else if (collapseIndex && transformedPath.endsWith("/index.tsx") && "./index.tsx" !== transformedPath) transformedPath = `${transformedPath.slice(0, -10)}.js`;
1129
+ else if (transformedPath.endsWith(".tsx")) transformedPath = `${transformedPath.slice(0, -4)}.js`;
1130
+ else if (transformedPath.endsWith(".ts") && !transformedPath.endsWith(".d.ts")) transformedPath = `${transformedPath.slice(0, -3)}.js`;
1131
+ }
1132
+ return transformedPath;
1133
+ }
1134
+ createTypePath(jsPath) {
1135
+ const { collapseIndex } = this.options;
1136
+ if (collapseIndex && jsPath.endsWith("/index.js") && "./index.js" !== jsPath) return `${jsPath.slice(0, -9)}.d.ts`;
1137
+ if (jsPath.endsWith(".js")) return `${jsPath.slice(0, -3)}.d.ts`;
1138
+ return `${jsPath}.d.ts`;
1139
+ }
1140
+ transformExports(exports, exportKey) {
1141
+ if ("string" == typeof exports) return this.transformStringExport(exports, exportKey);
1142
+ if (Array.isArray(exports)) return exports.map((item)=>{
1143
+ const transformed = this.transformExports(item, exportKey);
1144
+ return transformed ?? item;
1145
+ });
1146
+ if (exports && "object" == typeof exports) return this.transformObjectExports(exports, exportKey);
1147
+ return exports;
1148
+ }
1149
+ transformBin(bin) {
1150
+ if ("string" == typeof bin) return this.transformExportPath(bin);
1151
+ if (bin && "object" == typeof bin) {
1152
+ const transformed = {};
1153
+ for (const [command, path] of Object.entries(bin))if (void 0 !== path) transformed[command] = this.transformExportPath(path);
1154
+ return transformed;
1155
+ }
1156
+ return bin;
1157
+ }
1158
+ async transform(packageJson, context = {}) {
1159
+ const { isProduction = false, customTransform } = context;
1160
+ let result;
1161
+ if (isProduction) {
1162
+ const pnpmTransformed = await this.applyPnpmTransformations(packageJson);
1163
+ result = this.applyRslibTransformations(pnpmTransformed, packageJson);
1164
+ } else result = this.applyRslibTransformations(packageJson, packageJson);
1165
+ if (customTransform) result = customTransform(result);
1166
+ return result;
1167
+ }
1168
+ async applyPnpmTransformations(packageJson) {
1169
+ return this.pnpmCatalog.resolvePackageJson(packageJson);
1170
+ }
1171
+ applyRslibTransformations(packageJson, originalPackageJson) {
1172
+ const { publishConfig, scripts, ...rest } = packageJson;
1173
+ let isPrivate = true;
1174
+ if (originalPackageJson.publishConfig?.access === "public") isPrivate = false;
1175
+ const processedManifest = {
1176
+ ...rest,
1177
+ private: isPrivate
1178
+ };
1179
+ if (processedManifest.exports) processedManifest.exports = this.transformExports(processedManifest.exports);
1180
+ if (processedManifest.bin) processedManifest.bin = this.transformBin(processedManifest.bin);
1181
+ if (originalPackageJson.typesVersions) {
1182
+ const transformedTypesVersions = {};
1183
+ for (const [version, paths] of Object.entries(originalPackageJson.typesVersions)){
1184
+ const transformedPaths = {};
1185
+ for (const [key, value] of Object.entries(paths))transformedPaths[key] = value.map((path)=>this.transformExportPath(path));
1186
+ transformedTypesVersions[version] = transformedPaths;
1187
+ }
1188
+ processedManifest.typesVersions = transformedTypesVersions;
1189
+ }
1190
+ if (originalPackageJson.files) processedManifest.files = originalPackageJson.files.map((file)=>{
1191
+ let transformedFile = file.startsWith("./") ? file.slice(2) : file;
1192
+ if (transformedFile.startsWith("public/")) transformedFile = transformedFile.slice(7);
1193
+ return transformedFile;
1194
+ });
1195
+ return sort_package_json(processedManifest);
1196
+ }
1197
+ transformStringExport(exportString, exportKey) {
1198
+ const { entrypoints, exportToOutputMap, processTSExports } = this.options;
1199
+ let transformedPath;
1200
+ if (exportToOutputMap.size > 0 && exportKey && exportToOutputMap.has(exportKey)) {
1201
+ const mappedPath = exportToOutputMap.get(exportKey);
1202
+ if (!mappedPath) throw new Error(`Export key "${exportKey}" has no mapped path`);
1203
+ transformedPath = mappedPath;
1204
+ } else if (entrypoints.size > 0 && exportKey) {
1205
+ const keyWithoutPrefix = exportKey.startsWith("./") ? exportKey.slice(2) : exportKey;
1206
+ transformedPath = entrypoints.has(exportKey) ? entrypoints.get(exportKey) ?? exportString : entrypoints.has(keyWithoutPrefix) ? entrypoints.get(keyWithoutPrefix) ?? exportString : this.transformExportPath(exportString);
1207
+ } else transformedPath = this.transformExportPath(exportString);
1208
+ if (processTSExports && (exportString.endsWith(".ts") || exportString.endsWith(".tsx")) && !exportString.endsWith(".d.ts")) return {
1209
+ types: this.createTypePath(transformedPath),
1210
+ import: transformedPath
1211
+ };
1212
+ return transformedPath;
1213
+ }
1214
+ transformObjectExports(exportsObject, exportKey) {
1215
+ const transformed = {};
1216
+ const isConditions = this.isConditionsObject(exportsObject);
1217
+ for (const [key, value] of Object.entries(exportsObject))transformed[key] = this.transformExportEntry(key, value, isConditions, exportKey);
1218
+ return transformed;
1219
+ }
1220
+ isConditionsObject(exports) {
1221
+ return Object.keys(exports).some((key)=>"import" === key || "require" === key || "types" === key || "default" === key);
1222
+ }
1223
+ transformExportEntry(key, value, isConditions, exportKey) {
1224
+ if (isConditions && ("import" === key || "require" === key || "types" === key || "default" === key)) {
1225
+ if ("string" == typeof value) return this.transformExportPath(value);
1226
+ if (null != value) return this.transformExports(value, exportKey);
1227
+ return value;
1228
+ }
1229
+ if (null != value) return this.transformExports(value, key);
1230
+ return value;
1231
+ }
1232
+ }
1233
+ function transformExportPath(path, processTSExports = true, collapseIndex = false) {
1234
+ let transformedPath = path;
1235
+ if (transformedPath.startsWith("./exports/")) transformedPath = `./${transformedPath.slice(10)}`;
1236
+ else if (transformedPath.startsWith("./public/")) transformedPath = `./${transformedPath.slice(9)}`;
1237
+ else if (transformedPath.startsWith("./src/")) transformedPath = `./${transformedPath.slice(6)}`;
1238
+ if (processTSExports) {
1239
+ if (collapseIndex && transformedPath.endsWith("/index.ts") && "./index.ts" !== transformedPath) transformedPath = `${transformedPath.slice(0, -9)}.js`;
1240
+ else if (collapseIndex && transformedPath.endsWith("/index.tsx") && "./index.tsx" !== transformedPath) transformedPath = `${transformedPath.slice(0, -10)}.js`;
1241
+ else if (transformedPath.endsWith(".tsx")) transformedPath = `${transformedPath.slice(0, -4)}.js`;
1242
+ else if (transformedPath.endsWith(".ts") && !transformedPath.endsWith(".d.ts")) transformedPath = `${transformedPath.slice(0, -3)}.js`;
1243
+ }
1244
+ return transformedPath;
1245
+ }
1246
+ function createTypePath(jsPath, collapseIndex = true) {
1247
+ if (collapseIndex && jsPath.endsWith("/index.js") && "./index.js" !== jsPath) return `${jsPath.slice(0, -9)}.d.ts`;
1248
+ if (jsPath.endsWith(".js")) return `${jsPath.slice(0, -3)}.d.ts`;
1249
+ return `${jsPath}.d.ts`;
1250
+ }
1251
+ function transformPackageBin(bin, processTSExports = true) {
1252
+ if ("string" == typeof bin) return transformExportPath(bin, processTSExports);
1253
+ if (bin && "object" == typeof bin) {
1254
+ const transformed = {};
1255
+ for (const [command, path] of Object.entries(bin))if (void 0 !== path) transformed[command] = transformExportPath(path, processTSExports);
1256
+ return transformed;
1257
+ }
1258
+ return bin;
1259
+ }
1260
+ function isConditionsObject(exports) {
1261
+ return Object.keys(exports).some((key)=>"import" === key || "require" === key || "types" === key || "default" === key);
1262
+ }
1263
+ function transformPackageExports(exports, processTSExports = true, exportKey, entrypoints, exportToOutputMap, collapseIndex = false) {
1264
+ if ("string" == typeof exports) return transformStringExport(exports, processTSExports, exportKey, entrypoints, exportToOutputMap, collapseIndex);
1265
+ if (Array.isArray(exports)) return exports.map((item)=>{
1266
+ const transformed = transformPackageExports(item, processTSExports, exportKey, entrypoints, exportToOutputMap, collapseIndex);
1267
+ return transformed ?? item;
1268
+ });
1269
+ if (exports && "object" == typeof exports) return transformObjectExports(exports, processTSExports, exportKey, entrypoints, exportToOutputMap, collapseIndex);
1270
+ /* v8 ignore next -- @preserve */ return exports;
1271
+ }
1272
+ function transformStringExport(exportString, processTSExports, exportKey, entrypoints, exportToOutputMap, collapseIndex = false) {
1273
+ let transformedPath;
1274
+ if (exportToOutputMap && exportKey && exportToOutputMap.has(exportKey)) {
1275
+ const mappedPath = exportToOutputMap.get(exportKey);
1276
+ if (!mappedPath) throw new Error(`Export key "${exportKey}" has no mapped path`);
1277
+ transformedPath = mappedPath;
1278
+ } else if (entrypoints && exportKey) {
1279
+ const keyWithoutPrefix = exportKey.startsWith("./") ? exportKey.slice(2) : exportKey;
1280
+ transformedPath = entrypoints.has(exportKey) ? entrypoints.get(exportKey) ?? exportString : entrypoints.has(keyWithoutPrefix) ? entrypoints.get(keyWithoutPrefix) ?? exportString : transformExportPath(exportString, processTSExports, collapseIndex);
1281
+ } else transformedPath = transformExportPath(exportString, processTSExports, collapseIndex);
1282
+ if (processTSExports && (exportString.endsWith(".ts") || exportString.endsWith(".tsx")) && !exportString.endsWith(".d.ts")) return {
1283
+ types: createTypePath(transformedPath, collapseIndex),
1284
+ import: transformedPath
1285
+ };
1286
+ return transformedPath;
1287
+ }
1288
+ function transformObjectExports(exportsObject, processTSExports, exportKey, entrypoints, exportToOutputMap, collapseIndex = false) {
1289
+ const transformed = {};
1290
+ const isConditions = isConditionsObject(exportsObject);
1291
+ for (const [key, value] of Object.entries(exportsObject))transformed[key] = transformExportEntry(key, value, isConditions, processTSExports, exportKey, entrypoints, exportToOutputMap, collapseIndex);
1292
+ return transformed;
1293
+ }
1294
+ function transformExportEntry(key, value, isConditions, processTSExports, exportKey, entrypoints, exportToOutputMap, collapseIndex = false) {
1295
+ if (isConditions && ("import" === key || "require" === key || "types" === key || "default" === key)) {
1296
+ if ("string" == typeof value) return transformExportPath(value, processTSExports, collapseIndex);
1297
+ if (null != value) return transformPackageExports(value, processTSExports, exportKey, entrypoints, exportToOutputMap, collapseIndex);
1298
+ return value;
1299
+ }
1300
+ if (null != value) return transformPackageExports(value, processTSExports, key, entrypoints, exportToOutputMap, collapseIndex);
1301
+ return value;
1302
+ }
1303
+ function applyRslibTransformations(packageJson, originalPackageJson, processTSExports = true, entrypoints, exportToOutputMap, bundle) {
1304
+ const { publishConfig, scripts, ...rest } = packageJson;
1305
+ let isPrivate = true;
1306
+ if (originalPackageJson.publishConfig?.access === "public") isPrivate = false;
1307
+ const processedManifest = {
1308
+ ...rest,
1309
+ private: isPrivate
1310
+ };
1311
+ if (processedManifest.exports) processedManifest.exports = transformPackageExports(processedManifest.exports, processTSExports, void 0, entrypoints, exportToOutputMap, bundle ?? false);
1312
+ if (processedManifest.bin) processedManifest.bin = transformPackageBin(processedManifest.bin, processTSExports);
1313
+ if (originalPackageJson.typesVersions) {
1314
+ const transformedTypesVersions = {};
1315
+ for (const [version, paths] of Object.entries(originalPackageJson.typesVersions)){
1316
+ const transformedPaths = {};
1317
+ for (const [key, value] of Object.entries(paths))transformedPaths[key] = value.map((path)=>transformExportPath(path, processTSExports, bundle ?? false));
1318
+ transformedTypesVersions[version] = transformedPaths;
1319
+ }
1320
+ processedManifest.typesVersions = transformedTypesVersions;
1321
+ }
1322
+ if (originalPackageJson.files) processedManifest.files = originalPackageJson.files.map((file)=>{
1323
+ let transformedFile = file.startsWith("./") ? file.slice(2) : file;
1324
+ if (transformedFile.startsWith("public/")) transformedFile = transformedFile.slice(7);
1325
+ return transformedFile;
1326
+ });
1327
+ return sort_package_json(processedManifest);
1328
+ }
1329
+ async function applyPnpmTransformations(packageJson, dir = process.cwd()) {
1330
+ return getDefaultPnpmCatalog().resolvePackageJson(packageJson, dir);
1331
+ }
1332
+ async function buildPackageJson(packageJson, isProduction = false, processTSExports = true, entrypoints, exportToOutputMap, bundle, transform) {
1333
+ let result;
1334
+ if (isProduction) {
1335
+ const pnpmTransformed = await applyPnpmTransformations(packageJson);
1336
+ result = applyRslibTransformations(pnpmTransformed, packageJson, processTSExports, entrypoints, exportToOutputMap, bundle);
1337
+ } else result = applyRslibTransformations(packageJson, packageJson, processTSExports, entrypoints, exportToOutputMap, bundle);
1338
+ if (transform) result = transform(result);
1339
+ return result;
1340
+ }
1341
+ const PackageJsonTransformPlugin = (options = {})=>{
1342
+ const cache = new Map();
1343
+ return {
1344
+ name: "package-json-processor",
1345
+ setup (api) {
1346
+ api.expose("files-cache", cache);
1347
+ let filesArray = api.useExposed("files-array");
1348
+ if (!filesArray) {
1349
+ filesArray = new Set();
1350
+ api.expose("files-array", filesArray);
1351
+ }
1352
+ api.processAssets({
1353
+ stage: "pre-process"
1354
+ }, async (context)=>{
1355
+ const packageJson = await JsonAsset.create(context, "package.json", true);
1356
+ if (packageJson) filesArray.add(packageJson.fileName);
1357
+ const readme = await TextAsset.create(context, "README.md", false);
1358
+ if (readme) filesArray.add(readme.fileName);
1359
+ const license = await TextAsset.create(context, "LICENSE", false);
1360
+ if (license) filesArray.add(license.fileName);
1361
+ });
1362
+ api.processAssets({
1363
+ stage: "optimize"
1364
+ }, async (context)=>{
1365
+ const packageJson = await JsonAsset.create(context, "package.json", true);
1366
+ if (!packageJson) return;
1367
+ const envId = context.compilation?.name || "unknown";
1368
+ const isProduction = "dev" !== envId;
1369
+ const entrypoints = api.useExposed("entrypoints");
1370
+ const exportToOutputMap = api.useExposed("exportToOutputMap");
1371
+ const processedPackageJson = await buildPackageJson(packageJson.data, isProduction, options.processTSExports, entrypoints, exportToOutputMap, options.bundle, options.transform);
1372
+ packageJson.data = processedPackageJson;
1373
+ if (options.forcePrivate) packageJson.data.private = true;
1374
+ const useRollupTypes = api.useExposed("use-rollup-types");
1375
+ if (useRollupTypes && packageJson.data.exports && "object" == typeof packageJson.data.exports) {
1376
+ const exports = packageJson.data.exports;
1377
+ delete exports["./api-extractor"];
1378
+ for (const [, value] of Object.entries(exports))if (value && "object" == typeof value && "types" in value) value.types = "./index.d.ts";
1379
+ }
1380
+ packageJson.update();
1381
+ });
1382
+ api.processAssets({
1383
+ stage: "optimize-inline"
1384
+ }, async (compiler)=>{
1385
+ if (options.name && true !== options.name) {
1386
+ const packageJson = await JsonAsset.create(compiler, "package.json", true);
1387
+ if (packageJson) {
1388
+ packageJson.data.name = options.name;
1389
+ packageJson.update();
1390
+ }
1391
+ }
1392
+ });
1393
+ }
1394
+ };
1395
+ };
1396
+ /* v8 ignore next -- @preserve */ class NodeLibraryBuilder {
1397
+ static DEFAULT_OPTIONS = {
1398
+ entry: void 0,
1399
+ plugins: [],
1400
+ define: {},
1401
+ copyPatterns: [],
1402
+ targets: [
1403
+ "dev",
1404
+ "npm"
1405
+ ],
1406
+ tsconfigPath: void 0,
1407
+ externals: [],
1408
+ dtsBundledPackages: void 0,
1409
+ transformFiles: void 0
1410
+ };
1411
+ static mergeOptions(options = {}) {
1412
+ const merged = {
1413
+ ...NodeLibraryBuilder.DEFAULT_OPTIONS,
1414
+ ...options,
1415
+ copyPatterns: [
1416
+ ...options.copyPatterns ?? NodeLibraryBuilder.DEFAULT_OPTIONS.copyPatterns
1417
+ ]
1418
+ };
1419
+ if (existsSync((0, external_node_path_.join)(process.cwd(), "public"))) merged.copyPatterns.unshift({
1420
+ from: "./public",
1421
+ to: "./",
1422
+ context: process.cwd()
1423
+ });
1424
+ return merged;
1425
+ }
1426
+ static create(options = {}) {
1427
+ const mergedOptions = NodeLibraryBuilder.mergeOptions(options);
1428
+ return async ({ envMode })=>{
1429
+ const target = envMode || "dev";
1430
+ const validTargets = [
1431
+ "dev",
1432
+ "npm"
1433
+ ];
1434
+ if (!validTargets.includes(target)) throw new Error(`Invalid env-mode: "${target}". Must be one of: ${validTargets.join(", ")}\nExample: rslib build --env-mode npm`);
1435
+ const targetConfig = await NodeLibraryBuilder.createSingleTarget(target, mergedOptions);
1436
+ return targetConfig;
1437
+ };
1438
+ }
1439
+ static async createSingleTarget(target, opts) {
1440
+ const options = NodeLibraryBuilder.mergeOptions(opts);
1441
+ const VERSION = await packageJsonVersion();
1442
+ const plugins = [];
1443
+ if ("dev" === target || "npm" === target) {
1444
+ if (!options.entry) plugins.push(AutoEntryPlugin({
1445
+ exportsAsIndexes: options.exportsAsIndexes
1446
+ }));
1447
+ const userTransform = options.transform;
1448
+ const transformFn = userTransform ? (pkg)=>userTransform({
1449
+ target,
1450
+ pkg
1451
+ }) : void 0;
1452
+ plugins.push(PackageJsonTransformPlugin({
1453
+ forcePrivate: "dev" === target,
1454
+ bundle: true,
1455
+ target,
1456
+ transform: transformFn
1457
+ }));
1458
+ plugins.push(FilesArrayPlugin({
1459
+ target,
1460
+ transformFiles: options.transformFiles
1461
+ }));
1462
+ }
1463
+ if (options.plugins) plugins.push(...options.plugins);
1464
+ const outputDir = `dist/${target}`;
1465
+ const entry = options.entry;
1466
+ const apiModelForTarget = "npm" === target ? options.apiModel : void 0;
1467
+ plugins.push(DtsPlugin({
1468
+ tsconfigPath: options.tsconfigPath,
1469
+ abortOnError: true,
1470
+ bundle: true,
1471
+ bundledPackages: options.dtsBundledPackages,
1472
+ buildTarget: target,
1473
+ apiModel: apiModelForTarget
1474
+ }));
1475
+ const lib = {
1476
+ id: target,
1477
+ outBase: outputDir,
1478
+ output: {
1479
+ target: "node",
1480
+ module: true,
1481
+ cleanDistPath: true,
1482
+ sourceMap: "dev" === target,
1483
+ distPath: {
1484
+ root: outputDir
1485
+ },
1486
+ copy: {
1487
+ patterns: options.copyPatterns
1488
+ },
1489
+ externals: options.externals && options.externals.length > 0 ? options.externals : void 0
1490
+ },
1491
+ format: "esm",
1492
+ experiments: {
1493
+ advancedEsm: true
1494
+ },
1495
+ bundle: true,
1496
+ plugins,
1497
+ source: {
1498
+ tsconfigPath: options.tsconfigPath,
1499
+ entry,
1500
+ define: {
1501
+ "process.env.__PACKAGE_VERSION__": JSON.stringify(VERSION),
1502
+ ...options.define
1503
+ }
1504
+ }
1505
+ };
1506
+ return defineConfig({
1507
+ lib: [
1508
+ lib
1509
+ ],
1510
+ source: {
1511
+ tsconfigPath: options.tsconfigPath
1512
+ },
1513
+ performance: {
1514
+ buildCache: {
1515
+ cacheDirectory: `.rslib/cache/${target}`
1516
+ }
1517
+ }
1518
+ });
1519
+ }
1520
+ }
1521
+ export { AutoEntryPlugin, DtsPlugin, EntryExtractor, FilesArrayPlugin, NodeLibraryBuilder, PackageJsonTransformPlugin, PackageJsonTransformer, PnpmCatalog, collectDtsFiles, ensureTempDeclarationDir, findTsConfig, generateTsgoArgs, getTsgoBinPath, stripSourceMapComment };