@savvy-web/tsdown-plugins 0.5.0 → 0.6.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/build/build-target-groups.js +2 -1
- package/entry/extract.js +7 -2
- package/entry/package-json-entries.js +4 -1
- package/exe/build.js +29 -14
- package/exe/filename.js +12 -0
- package/index.d.ts +32 -1
- package/index.js +2 -1
- package/manifest/emit-manifest.js +4 -2
- package/manifest/transform.js +35 -0
- package/package.json +1 -1
|
@@ -78,7 +78,8 @@ async function buildTargetGroups(options) {
|
|
|
78
78
|
transform: options.transform,
|
|
79
79
|
sourceDir: options.cwd,
|
|
80
80
|
dual: options.dualExports ?? js.format.includes("cjs"),
|
|
81
|
-
...options.subdirExports !== void 0 ? { subdirExports: options.subdirExports } : {}
|
|
81
|
+
...options.subdirExports !== void 0 ? { subdirExports: options.subdirExports } : {},
|
|
82
|
+
...options.exeRewrite !== void 0 ? { exeRewrite: options.exeRewrite } : {}
|
|
82
83
|
}) : void 0;
|
|
83
84
|
await build({
|
|
84
85
|
config: false,
|
package/entry/extract.js
CHANGED
|
@@ -30,9 +30,12 @@ function extractEntries(pkg, options = {}) {
|
|
|
30
30
|
const entries = {};
|
|
31
31
|
const exportPaths = {};
|
|
32
32
|
const exportsAsIndexes = options.exportsAsIndexes ?? false;
|
|
33
|
+
const stripDot = (p) => p.replace(/^\.\//, "");
|
|
34
|
+
const excluded = new Set((options.excludeSources ?? []).map(stripDot));
|
|
35
|
+
const isExcluded = (src) => excluded.has(stripDot(src));
|
|
33
36
|
const exports = pkg.exports;
|
|
34
37
|
if (typeof exports === "string") {
|
|
35
|
-
if (isTypeScriptFile(exports)) {
|
|
38
|
+
if (isTypeScriptFile(exports) && !isExcluded(exports)) {
|
|
36
39
|
entries.index = exports;
|
|
37
40
|
exportPaths.index = ".";
|
|
38
41
|
}
|
|
@@ -42,6 +45,7 @@ function extractEntries(pkg, options = {}) {
|
|
|
42
45
|
if (!sourcePath) continue;
|
|
43
46
|
const resolved = resolveToTypeScript(sourcePath);
|
|
44
47
|
if (!isTypeScriptFile(resolved)) continue;
|
|
48
|
+
if (isExcluded(sourcePath) || isExcluded(resolved)) continue;
|
|
45
49
|
const name = createEntryName(key, exportsAsIndexes);
|
|
46
50
|
if (name in entries) {
|
|
47
51
|
const previousKey = exportPaths[name];
|
|
@@ -53,10 +57,11 @@ function extractEntries(pkg, options = {}) {
|
|
|
53
57
|
const bin = pkg.bin;
|
|
54
58
|
if (typeof bin === "string") {
|
|
55
59
|
const resolved = resolveToTypeScript(bin);
|
|
56
|
-
if (isTypeScriptFile(resolved)) entries["bin/cli"] = resolved;
|
|
60
|
+
if (isTypeScriptFile(resolved) && !isExcluded(bin) && !isExcluded(resolved)) entries["bin/cli"] = resolved;
|
|
57
61
|
} else if (bin && typeof bin === "object") for (const [command, p] of Object.entries(bin)) {
|
|
58
62
|
if (typeof p !== "string") continue;
|
|
59
63
|
const resolved = resolveToTypeScript(p);
|
|
64
|
+
if (isExcluded(p) || isExcluded(resolved)) continue;
|
|
60
65
|
if (isTypeScriptFile(resolved)) entries[`bin/${command}`] = resolved;
|
|
61
66
|
}
|
|
62
67
|
return {
|
|
@@ -5,7 +5,10 @@ import { readFileSync } from "node:fs";
|
|
|
5
5
|
//#region src/entry/package-json-entries.ts
|
|
6
6
|
/** Derive a tsdown `entry` record (name to source path) from a package.json. */
|
|
7
7
|
function packageJsonEntries(options = {}) {
|
|
8
|
-
return extractEntries(options.pkg ?? JSON.parse(readFileSync(resolve(options.cwd ?? process.cwd(), "package.json"), "utf-8")), {
|
|
8
|
+
return extractEntries(options.pkg ?? JSON.parse(readFileSync(resolve(options.cwd ?? process.cwd(), "package.json"), "utf-8")), {
|
|
9
|
+
exportsAsIndexes: options.exportsAsIndexes,
|
|
10
|
+
excludeSources: options.excludeSources
|
|
11
|
+
}).entries;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
//#endregion
|
package/exe/build.js
CHANGED
|
@@ -1,22 +1,37 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
|
|
1
5
|
//#region src/exe/build.ts
|
|
2
6
|
/** Compile each SEA binary via tsdown's exe mode. One tsdown build per spec. */
|
|
3
7
|
async function runExeBuild(options) {
|
|
4
8
|
const build = options.build ?? (await import("tsdown")).build;
|
|
5
|
-
for (const spec of options.specs)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
for (const spec of options.specs) {
|
|
10
|
+
const scratch = mkdtempSync(join(tmpdir(), "savvy-exe-"));
|
|
11
|
+
try {
|
|
12
|
+
await build({
|
|
13
|
+
cwd: options.cwd,
|
|
14
|
+
config: false,
|
|
15
|
+
entry: [spec.entry],
|
|
16
|
+
format: "esm",
|
|
17
|
+
platform: "node",
|
|
18
|
+
clean: false,
|
|
19
|
+
outDir: scratch,
|
|
20
|
+
deps: { alwaysBundle: (id) => !id.startsWith("node:") },
|
|
21
|
+
exe: {
|
|
22
|
+
fileName: spec.fileName,
|
|
23
|
+
outDir: options.outDir,
|
|
24
|
+
seaConfig: spec.seaConfig,
|
|
25
|
+
targets: spec.targets
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
} finally {
|
|
29
|
+
rmSync(scratch, {
|
|
30
|
+
recursive: true,
|
|
31
|
+
force: true
|
|
32
|
+
});
|
|
18
33
|
}
|
|
19
|
-
}
|
|
34
|
+
}
|
|
20
35
|
}
|
|
21
36
|
|
|
22
37
|
//#endregion
|
package/exe/filename.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/exe/filename.ts
|
|
2
|
+
/**
|
|
3
|
+
* The exact filename `@tsdown/exe` emits for a SEA target, mirroring tsdown's
|
|
4
|
+
* `resolveOutputFileName`: base fileName + `-<platform>-<arch>` + `.exe` on win.
|
|
5
|
+
* Single source of truth so the manifest value never drifts from the on-disk file.
|
|
6
|
+
*/
|
|
7
|
+
function computeExeFileName(fileName, target) {
|
|
8
|
+
return `${fileName}${`-${target.platform}-${target.arch}`}${target.platform === "win" ? ".exe" : ""}`;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
export { computeExeFileName };
|
package/index.d.ts
CHANGED
|
@@ -67,6 +67,19 @@ declare function defaultManifestTransform({
|
|
|
67
67
|
}: {
|
|
68
68
|
pkg: Json;
|
|
69
69
|
}): Json;
|
|
70
|
+
/**
|
|
71
|
+
* Describes a SEA binary the bundler compiled for this package. When present,
|
|
72
|
+
* {@link transformManifest} rewrites every `exports`/`bin` value equal to `source`
|
|
73
|
+
* to the emitted binary path and adds it to `files` so it ships in the tarball.
|
|
74
|
+
*/
|
|
75
|
+
interface ExeRewrite {
|
|
76
|
+
/** The exe entry source path (matches exports/bin values to rewrite). */
|
|
77
|
+
readonly source: string;
|
|
78
|
+
/** The emitted SEA filename (already suffixed, incl. .exe on win). */
|
|
79
|
+
readonly fileName: string;
|
|
80
|
+
/** Relative dir the binary is emitted into (e.g. "bin"). */
|
|
81
|
+
readonly dir: string;
|
|
82
|
+
}
|
|
70
83
|
/**
|
|
71
84
|
* Rewrite an exports map: TS string targets become a types/import conditions object.
|
|
72
85
|
* Each TS condition also gets a `require` entry when `dual` is `true` (uniform) or when
|
|
@@ -90,6 +103,8 @@ interface TransformManifestOptions {
|
|
|
90
103
|
readonly dual?: DualExports | undefined;
|
|
91
104
|
/** Export keys built into a `<key>/index.*` subdir (e.g. an RSPress `./runtime`). */
|
|
92
105
|
readonly subdirExports?: ReadonlySet<string> | undefined;
|
|
106
|
+
/** When set, rewrite exports/bin values equal to `source` to the SEA path and add it to `files`. */
|
|
107
|
+
readonly exeRewrite?: ExeRewrite | undefined;
|
|
93
108
|
}
|
|
94
109
|
/** Apply the full standard manifest transform (excluding catalog resolution, done upstream). */
|
|
95
110
|
declare function transformManifest(pkg: Json, options?: TransformManifestOptions): Json;
|
|
@@ -113,6 +128,8 @@ interface BuildEmittedManifestOptions {
|
|
|
113
128
|
readonly dual?: DualExports | undefined;
|
|
114
129
|
/** Export keys built into a `<key>/index.*` subdir (e.g. an RSPress `./runtime`). */
|
|
115
130
|
readonly subdirExports?: ReadonlySet<string> | undefined;
|
|
131
|
+
/** When set, rewrite exports/bin values equal to the exe source to the SEA path and add it to `files`. */
|
|
132
|
+
readonly exeRewrite?: ExeRewrite | undefined;
|
|
116
133
|
}
|
|
117
134
|
/** Compute the final manifest bytes for a TargetGroup (catalog resolution + standard transforms). */
|
|
118
135
|
declare function buildEmittedManifest(options: BuildEmittedManifestOptions): Promise<Json>;
|
|
@@ -129,6 +146,8 @@ interface EmitManifestOptions {
|
|
|
129
146
|
readonly dual?: DualExports | undefined;
|
|
130
147
|
/** Export keys built into a `<key>/index.*` subdir (e.g. an RSPress `./runtime`). */
|
|
131
148
|
readonly subdirExports?: ReadonlySet<string> | undefined;
|
|
149
|
+
/** When set, rewrite exports/bin values equal to the exe source to the SEA path and add it to `files`. */
|
|
150
|
+
readonly exeRewrite?: ExeRewrite | undefined;
|
|
132
151
|
}
|
|
133
152
|
/** Rolldown plugin: emit the transformed package.json + LICENSE/README into the output pkg/ root. */
|
|
134
153
|
declare function emitManifest(options: EmitManifestOptions): Plugin;
|
|
@@ -414,6 +433,8 @@ interface BuildTargetGroupsOptions {
|
|
|
414
433
|
readonly dualExports?: DualExports | undefined;
|
|
415
434
|
/** Export keys built into a `<key>/index.*` subdir (e.g. an RSPress `./runtime`). */
|
|
416
435
|
readonly subdirExports?: ReadonlySet<string> | undefined;
|
|
436
|
+
/** When set, rewrite the emitted manifest's exports/bin values equal to the exe source to the SEA path and add it to `files`. */
|
|
437
|
+
readonly exeRewrite?: ExeRewrite | undefined;
|
|
417
438
|
/** Injectable for tests; defaults to tsdown's build. */
|
|
418
439
|
readonly build?: TsdownBuild;
|
|
419
440
|
}
|
|
@@ -752,6 +773,8 @@ interface PackageJsonLike {
|
|
|
752
773
|
}
|
|
753
774
|
interface ExtractOptions {
|
|
754
775
|
readonly exportsAsIndexes?: boolean | undefined;
|
|
776
|
+
/** Source paths to NOT turn into JS build entries (e.g. an exe entry compiled as a SEA). */
|
|
777
|
+
readonly excludeSources?: ReadonlyArray<string> | undefined;
|
|
755
778
|
}
|
|
756
779
|
interface ExtractResult {
|
|
757
780
|
/** entry name to TS source path */
|
|
@@ -798,6 +821,14 @@ interface RunExeBuildOptions {
|
|
|
798
821
|
/** Compile each SEA binary via tsdown's exe mode. One tsdown build per spec. */
|
|
799
822
|
declare function runExeBuild(options: RunExeBuildOptions): Promise<void>;
|
|
800
823
|
//#endregion
|
|
824
|
+
//#region src/exe/filename.d.ts
|
|
825
|
+
/**
|
|
826
|
+
* The exact filename `@tsdown/exe` emits for a SEA target, mirroring tsdown's
|
|
827
|
+
* `resolveOutputFileName`: base fileName + `-<platform>-<arch>` + `.exe` on win.
|
|
828
|
+
* Single source of truth so the manifest value never drifts from the on-disk file.
|
|
829
|
+
*/
|
|
830
|
+
declare function computeExeFileName(fileName: string, target: ExeTarget): string;
|
|
831
|
+
//#endregion
|
|
801
832
|
//#region src/meta/generate.d.ts
|
|
802
833
|
interface GenerateMetaOptions {
|
|
803
834
|
readonly cwd: string;
|
|
@@ -1548,5 +1579,5 @@ declare function resolveTargets(options: {
|
|
|
1548
1579
|
baseName: string;
|
|
1549
1580
|
}): TargetResolution;
|
|
1550
1581
|
//#endregion
|
|
1551
|
-
export { type BuildEmittedManifestOptions, type BuildFormat, type BuildGroupSpec, type BuildPlatform, type BuildReport, BuildReport as BuildReportSchema, type BuildTargetGroupsOptions, CatalogAssemblyError, CatalogResolutionError, CiAnnotationsFormatter, ConfigValidationError, ConfigValidator, ConfigValidatorLive, type CssOptions, DEFAULT_EXE_NODE_VERSION, type DeriveOptions, type DerivedTsdownOptions, type DualExports, type EmitManifestOptions, type EntryOverride, type Environment, EnvironmentDetector, EnvironmentDetectorLive, type ExeBuild, type ExeConfig, type ExeSeaConfig, type ExeTarget, type ExeTargetInput, type Executor, ExecutorResolver, ExecutorResolverLive, type ExtractOptions, type ExtractResult, FormatSelector, FormatSelectorLive, type Formatter, type FormatterContext, type GenerateMetaOptions, type Json, JsonFormatter, type JsxConfig, type LooseFileSpec, type LooseFiles, type ManifestLike, MarkdownFormatter, MetaGenerationError, type MetaOptions, type MetaResult, type NormalizedExe, type NormalizedLooseFile, type NormalizedMeta, type OutputFormat, OutputRenderer, OutputRendererLive, type PackageJsonEntriesOptions, type PackageJsonLike, type PkgOsCpu, type PortableTsconfig, type PublishTargetObject, type PublishTargetValue, type PublishTargets, type RenderReportOptions, type RenderedOutput, ReportPipelineLive, ReportTimings, type ResolvedCompilerOptions, type ResolvedGroup, type ResolvedTarget, type ResolvedTsconfig, type ResolvedTsconfigOptions, type RunExeBuildOptions, SilentFormatter, type TargetGroupId, type TargetGroupRef, type TargetGroupReport, TargetGroupReport as TargetGroupReportSchema, type TargetResolution, TerminalFormatter, type Timer, type TransformManifestOptions, type TsconfigJsx, TsconfigResolver, type TsdocOptions, type TsdocTagDefinition, type TsdownBuild, type ValidationInput, type WarningSuppressionRule, buildEmittedManifest, buildResolvedTsconfig, buildTargetGroups, cjsDefaultInterop, createEntryName, createTimer, defaultManifestTransform, deriveTargetGroupOptions, emitManifest, extractEntries, formatTime, generateBuildReportSchema, generateMeta, isTargetObject, nodeBuiltinDefaultInterop, normalizeBinPaths, normalizeExeOptions, normalizeLooseFiles, normalizeMetaOptions, packageJsonEntries, readTsconfigJsx, removeDeclarationMaps, renderReport, resolveJsxConfig, resolveManifest, resolvePortableTsconfig, resolveTargets, runExeBuild, syncPublicDir, transformBin, transformExports, transformManifest, writeResolvedTsconfig, writeTargetsBinding };
|
|
1582
|
+
export { type BuildEmittedManifestOptions, type BuildFormat, type BuildGroupSpec, type BuildPlatform, type BuildReport, BuildReport as BuildReportSchema, type BuildTargetGroupsOptions, CatalogAssemblyError, CatalogResolutionError, CiAnnotationsFormatter, ConfigValidationError, ConfigValidator, ConfigValidatorLive, type CssOptions, DEFAULT_EXE_NODE_VERSION, type DeriveOptions, type DerivedTsdownOptions, type DualExports, type EmitManifestOptions, type EntryOverride, type Environment, EnvironmentDetector, EnvironmentDetectorLive, type ExeBuild, type ExeConfig, type ExeRewrite, type ExeSeaConfig, type ExeTarget, type ExeTargetInput, type Executor, ExecutorResolver, ExecutorResolverLive, type ExtractOptions, type ExtractResult, FormatSelector, FormatSelectorLive, type Formatter, type FormatterContext, type GenerateMetaOptions, type Json, JsonFormatter, type JsxConfig, type LooseFileSpec, type LooseFiles, type ManifestLike, MarkdownFormatter, MetaGenerationError, type MetaOptions, type MetaResult, type NormalizedExe, type NormalizedLooseFile, type NormalizedMeta, type OutputFormat, OutputRenderer, OutputRendererLive, type PackageJsonEntriesOptions, type PackageJsonLike, type PkgOsCpu, type PortableTsconfig, type PublishTargetObject, type PublishTargetValue, type PublishTargets, type RenderReportOptions, type RenderedOutput, ReportPipelineLive, ReportTimings, type ResolvedCompilerOptions, type ResolvedGroup, type ResolvedTarget, type ResolvedTsconfig, type ResolvedTsconfigOptions, type RunExeBuildOptions, SilentFormatter, type TargetGroupId, type TargetGroupRef, type TargetGroupReport, TargetGroupReport as TargetGroupReportSchema, type TargetResolution, TerminalFormatter, type Timer, type TransformManifestOptions, type TsconfigJsx, TsconfigResolver, type TsdocOptions, type TsdocTagDefinition, type TsdownBuild, type ValidationInput, type WarningSuppressionRule, buildEmittedManifest, buildResolvedTsconfig, buildTargetGroups, cjsDefaultInterop, computeExeFileName, createEntryName, createTimer, defaultManifestTransform, deriveTargetGroupOptions, emitManifest, extractEntries, formatTime, generateBuildReportSchema, generateMeta, isTargetObject, nodeBuiltinDefaultInterop, normalizeBinPaths, normalizeExeOptions, normalizeLooseFiles, normalizeMetaOptions, packageJsonEntries, readTsconfigJsx, removeDeclarationMaps, renderReport, resolveJsxConfig, resolveManifest, resolvePortableTsconfig, resolveTargets, runExeBuild, syncPublicDir, transformBin, transformExports, transformManifest, writeResolvedTsconfig, writeTargetsBinding };
|
|
1552
1583
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -18,6 +18,7 @@ import { ConfigValidatorLive } from "./config-validation/ConfigValidatorLive.js"
|
|
|
18
18
|
import { buildResolvedTsconfig, writeResolvedTsconfig } from "./dts/resolved-tsconfig.js";
|
|
19
19
|
import { packageJsonEntries } from "./entry/package-json-entries.js";
|
|
20
20
|
import { runExeBuild } from "./exe/build.js";
|
|
21
|
+
import { computeExeFileName } from "./exe/filename.js";
|
|
21
22
|
import { readTsconfigJsx, resolveJsxConfig } from "./jsx/config.js";
|
|
22
23
|
import { normalizeMetaOptions } from "./meta/config.js";
|
|
23
24
|
import { TsconfigResolver, resolvePortableTsconfig } from "./meta/tsconfig-resolver.js";
|
|
@@ -42,4 +43,4 @@ import { generateBuildReportSchema } from "./report/schema-export.js";
|
|
|
42
43
|
import { writeTargetsBinding } from "./targets/binding.js";
|
|
43
44
|
import { CatalogAssemblyError, CatalogResolutionError } from "workspaces-effect";
|
|
44
45
|
|
|
45
|
-
export { BuildReport as BuildReportSchema, CatalogAssemblyError, CatalogResolutionError, CiAnnotationsFormatter, ConfigValidationError, ConfigValidator, ConfigValidatorLive, DEFAULT_EXE_NODE_VERSION, EnvironmentDetector, EnvironmentDetectorLive, ExecutorResolver, ExecutorResolverLive, FormatSelector, FormatSelectorLive, JsonFormatter, MarkdownFormatter, MetaGenerationError, OutputRenderer, OutputRendererLive, ReportPipelineLive, ReportTimings, SilentFormatter, TargetGroupReport as TargetGroupReportSchema, TerminalFormatter, TsconfigResolver, buildEmittedManifest, buildResolvedTsconfig, buildTargetGroups, cjsDefaultInterop, createEntryName, createTimer, defaultManifestTransform, deriveTargetGroupOptions, emitManifest, extractEntries, formatTime, generateBuildReportSchema, generateMeta, isTargetObject, nodeBuiltinDefaultInterop, normalizeBinPaths, normalizeExeOptions, normalizeLooseFiles, normalizeMetaOptions, packageJsonEntries, readTsconfigJsx, removeDeclarationMaps, renderReport, resolveJsxConfig, resolveManifest, resolvePortableTsconfig, resolveTargets, runExeBuild, syncPublicDir, transformBin, transformExports, transformManifest, writeResolvedTsconfig, writeTargetsBinding };
|
|
46
|
+
export { BuildReport as BuildReportSchema, CatalogAssemblyError, CatalogResolutionError, CiAnnotationsFormatter, ConfigValidationError, ConfigValidator, ConfigValidatorLive, DEFAULT_EXE_NODE_VERSION, EnvironmentDetector, EnvironmentDetectorLive, ExecutorResolver, ExecutorResolverLive, FormatSelector, FormatSelectorLive, JsonFormatter, MarkdownFormatter, MetaGenerationError, OutputRenderer, OutputRendererLive, ReportPipelineLive, ReportTimings, SilentFormatter, TargetGroupReport as TargetGroupReportSchema, TerminalFormatter, TsconfigResolver, buildEmittedManifest, buildResolvedTsconfig, buildTargetGroups, cjsDefaultInterop, computeExeFileName, createEntryName, createTimer, defaultManifestTransform, deriveTargetGroupOptions, emitManifest, extractEntries, formatTime, generateBuildReportSchema, generateMeta, isTargetObject, nodeBuiltinDefaultInterop, normalizeBinPaths, normalizeExeOptions, normalizeLooseFiles, normalizeMetaOptions, packageJsonEntries, readTsconfigJsx, removeDeclarationMaps, renderReport, resolveJsxConfig, resolveManifest, resolvePortableTsconfig, resolveTargets, runExeBuild, syncPublicDir, transformBin, transformExports, transformManifest, writeResolvedTsconfig, writeTargetsBinding };
|
|
@@ -20,7 +20,8 @@ async function buildEmittedManifest(options) {
|
|
|
20
20
|
targetGroup
|
|
21
21
|
}) : void 0,
|
|
22
22
|
dual: options.dual ?? false,
|
|
23
|
-
subdirExports: options.subdirExports
|
|
23
|
+
subdirExports: options.subdirExports,
|
|
24
|
+
exeRewrite: options.exeRewrite
|
|
24
25
|
});
|
|
25
26
|
}
|
|
26
27
|
/** Rolldown plugin: emit the transformed package.json + LICENSE/README into the output pkg/ root. */
|
|
@@ -35,7 +36,8 @@ function emitManifest(options) {
|
|
|
35
36
|
devManifest: options.devManifest ?? "preserve",
|
|
36
37
|
transform: options.transform,
|
|
37
38
|
dual: options.dual,
|
|
38
|
-
subdirExports: options.subdirExports
|
|
39
|
+
subdirExports: options.subdirExports,
|
|
40
|
+
exeRewrite: options.exeRewrite
|
|
39
41
|
});
|
|
40
42
|
this.emitFile({
|
|
41
43
|
type: "asset",
|
package/manifest/transform.js
CHANGED
|
@@ -42,6 +42,26 @@ function defaultManifestTransform({ pkg }) {
|
|
|
42
42
|
return out;
|
|
43
43
|
}
|
|
44
44
|
const stripLeadingDotSlash = (p) => p.startsWith("./") ? p.slice(2) : p;
|
|
45
|
+
const sameSource = (a, b) => stripLeadingDotSlash(a) === stripLeadingDotSlash(b);
|
|
46
|
+
/** The export-path ("./bin/<file>") and files-entry ("bin/<file>") forms for a SEA. */
|
|
47
|
+
const exeRelPath = (r) => {
|
|
48
|
+
const filesEntry = `${r.dir}/${r.fileName}`;
|
|
49
|
+
return {
|
|
50
|
+
exportPath: `./${filesEntry}`,
|
|
51
|
+
filesEntry
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/** Rewrite exports values that equal the exe source to a plain SEA-path string. */
|
|
55
|
+
const rewriteExeExports = (exports, r) => {
|
|
56
|
+
const { exportPath } = exeRelPath(r);
|
|
57
|
+
if (typeof exports === "string") return sameSource(exports, r.source) ? exportPath : exports;
|
|
58
|
+
if (exports && typeof exports === "object") {
|
|
59
|
+
const out = {};
|
|
60
|
+
for (const [key, value] of Object.entries(exports)) out[key] = typeof value === "string" && sameSource(value, r.source) ? exportPath : value;
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
return exports;
|
|
64
|
+
};
|
|
45
65
|
/**
|
|
46
66
|
* Built .js output basename for an export, derived from the entry NAME (the basename
|
|
47
67
|
* the build actually emits) rather than the source path. The entry namer flattens
|
|
@@ -116,6 +136,21 @@ function transformManifest(pkg, options = {}) {
|
|
|
116
136
|
...rest,
|
|
117
137
|
private: isPrivate
|
|
118
138
|
};
|
|
139
|
+
if (options.exeRewrite) {
|
|
140
|
+
const r = options.exeRewrite;
|
|
141
|
+
const { exportPath, filesEntry } = exeRelPath(r);
|
|
142
|
+
if (result.exports !== void 0 && result.exports !== null) result.exports = rewriteExeExports(result.exports, r);
|
|
143
|
+
if (typeof result.bin === "string") {
|
|
144
|
+
if (sameSource(result.bin, r.source)) result.bin = exportPath;
|
|
145
|
+
} else if (result.bin && typeof result.bin === "object") {
|
|
146
|
+
const nextBin = {};
|
|
147
|
+
for (const [cmd, val] of Object.entries(result.bin)) nextBin[cmd] = sameSource(val, r.source) ? exportPath : val;
|
|
148
|
+
result.bin = nextBin;
|
|
149
|
+
}
|
|
150
|
+
const files = Array.isArray(result.files) ? result.files.slice() : [];
|
|
151
|
+
if (!files.includes(filesEntry)) files.push(filesEntry);
|
|
152
|
+
result.files = files;
|
|
153
|
+
}
|
|
119
154
|
if (result.exports !== void 0 && result.exports !== null) {
|
|
120
155
|
const original = result.exports;
|
|
121
156
|
const transformed = transformExports(original, options.dual ?? false, options.subdirExports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@savvy-web/tsdown-plugins",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Interface-only tsdown/rolldown plugin pack powering @savvy-web/bundler",
|
|
6
6
|
"homepage": "https://github.com/savvy-web/systems/tree/main/packages/tsdown-plugins",
|