@savvy-web/tsdown-plugins 0.5.0 → 0.7.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/changesets/next-versions.js +42 -0
- 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 +77 -3
- package/index.js +4 -1
- package/manifest/emit-manifest.js +4 -2
- package/manifest/transform.js +35 -0
- package/meta/config.js +7 -1
- package/meta/generate.js +4 -2
- package/meta/optimistic.js +32 -0
- package/package.json +3 -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,
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import getReleasePlan from "@changesets/get-release-plan";
|
|
2
|
+
import { getPackages } from "@manypkg/get-packages";
|
|
3
|
+
|
|
4
|
+
//#region src/changesets/next-versions.ts
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the next release version of every workspace package from pending changesets.
|
|
7
|
+
*
|
|
8
|
+
* Walks up from `cwd` to the monorepo root via `@manypkg/get-packages`, seeds the map with
|
|
9
|
+
* each package's CURRENT version, then overlays `newVersion` for changeset-affected packages
|
|
10
|
+
* via `@changesets/get-release-plan`. Never rejects: any failure (not a workspace, missing
|
|
11
|
+
* `.changeset/config.json`, parse error) degrades to current versions (or an empty map).
|
|
12
|
+
*/
|
|
13
|
+
async function resolveNextVersions(cwd) {
|
|
14
|
+
try {
|
|
15
|
+
const packages = await getPackages(cwd);
|
|
16
|
+
if (packages.tool === "root") return {
|
|
17
|
+
root: packages.root.dir,
|
|
18
|
+
versions: /* @__PURE__ */ new Map()
|
|
19
|
+
};
|
|
20
|
+
const versions = /* @__PURE__ */ new Map();
|
|
21
|
+
for (const p of packages.packages) {
|
|
22
|
+
const { name, version } = p.packageJson;
|
|
23
|
+
if (name && version) versions.set(name, version);
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const plan = await getReleasePlan(packages.root.dir);
|
|
27
|
+
for (const r of plan.releases) versions.set(r.name, r.newVersion);
|
|
28
|
+
} catch {}
|
|
29
|
+
return {
|
|
30
|
+
root: packages.root.dir,
|
|
31
|
+
versions
|
|
32
|
+
};
|
|
33
|
+
} catch {
|
|
34
|
+
return {
|
|
35
|
+
root: cwd,
|
|
36
|
+
versions: /* @__PURE__ */ new Map()
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
export { resolveNextVersions };
|
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
|
}
|
|
@@ -543,6 +564,24 @@ declare function syncPublicDir(sourceDir: string, targetDir: string): void;
|
|
|
543
564
|
*/
|
|
544
565
|
declare function resolveManifest(pkg: ManifestLike$1): Promise<ManifestLike$1>;
|
|
545
566
|
//#endregion
|
|
567
|
+
//#region src/changesets/next-versions.d.ts
|
|
568
|
+
/** Result of resolving next release versions for a workspace. */
|
|
569
|
+
interface NextVersions {
|
|
570
|
+
/** Monorepo root containing `.changeset/` (or `cwd` when no workspace was found). */
|
|
571
|
+
readonly root: string;
|
|
572
|
+
/** Canonical package name -> next release version (current version when unbumped). */
|
|
573
|
+
readonly versions: ReadonlyMap<string, string>;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Resolve the next release version of every workspace package from pending changesets.
|
|
577
|
+
*
|
|
578
|
+
* Walks up from `cwd` to the monorepo root via `@manypkg/get-packages`, seeds the map with
|
|
579
|
+
* each package's CURRENT version, then overlays `newVersion` for changeset-affected packages
|
|
580
|
+
* via `@changesets/get-release-plan`. Never rejects: any failure (not a workspace, missing
|
|
581
|
+
* `.changeset/config.json`, parse error) degrades to current versions (or an empty map).
|
|
582
|
+
*/
|
|
583
|
+
declare function resolveNextVersions(cwd: string): Promise<NextVersions>;
|
|
584
|
+
//#endregion
|
|
546
585
|
//#region src/errors.d.ts
|
|
547
586
|
declare const MetaGenerationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => import("effect/Cause").YieldableError & {
|
|
548
587
|
readonly _tag: "MetaGenerationError";
|
|
@@ -641,20 +680,30 @@ interface TsdocOptions {
|
|
|
641
680
|
}
|
|
642
681
|
/** The `meta` field on defineBuild. Absent means no api-model generation. */
|
|
643
682
|
interface MetaOptions {
|
|
644
|
-
/** Directories to copy the api-model into
|
|
683
|
+
/** Directories to copy the canonical group's api-model into after `savvy build --target prod`. */
|
|
645
684
|
readonly localPaths?: ReadonlyArray<string> | undefined;
|
|
685
|
+
/**
|
|
686
|
+
* Forward-look the meta bundle's own `version` and workspace-sibling dep versions to their
|
|
687
|
+
* NEXT release version from pending changesets. `"auto"` (default) is `false` under CI
|
|
688
|
+
* (`CI`/`GITHUB_ACTIONS` set) and `true` locally, so a local bundle matches the CI release build.
|
|
689
|
+
*/
|
|
690
|
+
readonly optimistic?: "auto" | boolean | undefined;
|
|
646
691
|
readonly tsdoc?: TsdocOptions | undefined;
|
|
647
692
|
}
|
|
648
693
|
/** Fully-resolved meta options (no optionals). */
|
|
649
694
|
interface NormalizedMeta {
|
|
650
695
|
readonly localPaths: ReadonlyArray<string>;
|
|
696
|
+
readonly optimistic: boolean;
|
|
651
697
|
readonly tsdoc: {
|
|
652
698
|
readonly suppressWarnings: ReadonlyArray<WarningSuppressionRule>;
|
|
653
699
|
readonly tagDefinitions: ReadonlyArray<TsdocTagDefinition>;
|
|
654
700
|
};
|
|
655
701
|
}
|
|
656
702
|
/** Fill defaults so downstream code never branches on undefined. */
|
|
657
|
-
declare function normalizeMetaOptions(meta: MetaOptions
|
|
703
|
+
declare function normalizeMetaOptions(meta: MetaOptions, env?: {
|
|
704
|
+
CI?: string | undefined;
|
|
705
|
+
GITHUB_ACTIONS?: string | undefined;
|
|
706
|
+
}): NormalizedMeta;
|
|
658
707
|
//#endregion
|
|
659
708
|
//#region src/targets/config.d.ts
|
|
660
709
|
/** A single object-form publish target. Uses `from` XOR `name` (never both). */
|
|
@@ -752,6 +801,8 @@ interface PackageJsonLike {
|
|
|
752
801
|
}
|
|
753
802
|
interface ExtractOptions {
|
|
754
803
|
readonly exportsAsIndexes?: boolean | undefined;
|
|
804
|
+
/** Source paths to NOT turn into JS build entries (e.g. an exe entry compiled as a SEA). */
|
|
805
|
+
readonly excludeSources?: ReadonlyArray<string> | undefined;
|
|
755
806
|
}
|
|
756
807
|
interface ExtractResult {
|
|
757
808
|
/** entry name to TS source path */
|
|
@@ -798,6 +849,14 @@ interface RunExeBuildOptions {
|
|
|
798
849
|
/** Compile each SEA binary via tsdown's exe mode. One tsdown build per spec. */
|
|
799
850
|
declare function runExeBuild(options: RunExeBuildOptions): Promise<void>;
|
|
800
851
|
//#endregion
|
|
852
|
+
//#region src/exe/filename.d.ts
|
|
853
|
+
/**
|
|
854
|
+
* The exact filename `@tsdown/exe` emits for a SEA target, mirroring tsdown's
|
|
855
|
+
* `resolveOutputFileName`: base fileName + `-<platform>-<arch>` + `.exe` on win.
|
|
856
|
+
* Single source of truth so the manifest value never drifts from the on-disk file.
|
|
857
|
+
*/
|
|
858
|
+
declare function computeExeFileName(fileName: string, target: ExeTarget): string;
|
|
859
|
+
//#endregion
|
|
801
860
|
//#region src/meta/generate.d.ts
|
|
802
861
|
interface GenerateMetaOptions {
|
|
803
862
|
readonly cwd: string;
|
|
@@ -815,6 +874,12 @@ interface GenerateMetaOptions {
|
|
|
815
874
|
/** Directories (relative to cwd) to copy the meta bundle into. */
|
|
816
875
|
readonly localPaths: ReadonlyArray<string>;
|
|
817
876
|
readonly tsdoc: NormalizedMeta["tsdoc"];
|
|
877
|
+
/**
|
|
878
|
+
* Optional transform applied to the bundle `package.json` (read from `dtsDir`) before it is
|
|
879
|
+
* written to `outMetaDir` and copied into `localPaths`. Used for the optimistic next-version
|
|
880
|
+
* rewrite. When omitted, the package.json is copied verbatim.
|
|
881
|
+
*/
|
|
882
|
+
readonly manifestTransform?: ((pkg: Record<string, unknown>) => Record<string, unknown>) | undefined;
|
|
818
883
|
}
|
|
819
884
|
interface MetaResult {
|
|
820
885
|
readonly apiJsonPath: string;
|
|
@@ -829,6 +894,15 @@ interface MetaResult {
|
|
|
829
894
|
*/
|
|
830
895
|
declare function generateMeta(options: GenerateMetaOptions): Promise<MetaResult>;
|
|
831
896
|
//#endregion
|
|
897
|
+
//#region src/meta/optimistic.d.ts
|
|
898
|
+
/**
|
|
899
|
+
* Rewrite a meta `package.json` so the package's own `version` and any workspace-sibling
|
|
900
|
+
* dependency version reflect their NEXT release version from `versions`. Pure: returns a new
|
|
901
|
+
* object, never mutates the input. External/catalog-resolved deps (names absent from `versions`)
|
|
902
|
+
* are left as-is.
|
|
903
|
+
*/
|
|
904
|
+
declare function rewriteMetaVersions(pkg: Record<string, unknown>, versions: ReadonlyMap<string, string>, selfName: string): Record<string, unknown>;
|
|
905
|
+
//#endregion
|
|
832
906
|
//#region src/meta/tsconfig-resolver.d.ts
|
|
833
907
|
/**
|
|
834
908
|
* Compiler options with enum values converted to their string equivalents.
|
|
@@ -1548,5 +1622,5 @@ declare function resolveTargets(options: {
|
|
|
1548
1622
|
baseName: string;
|
|
1549
1623
|
}): TargetResolution;
|
|
1550
1624
|
//#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 };
|
|
1625
|
+
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 NextVersions, 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, resolveNextVersions, resolvePortableTsconfig, resolveTargets, rewriteMetaVersions, runExeBuild, syncPublicDir, transformBin, transformExports, transformManifest, writeResolvedTsconfig, writeTargetsBinding };
|
|
1552
1626
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { buildTargetGroups } from "./build/build-target-groups.js";
|
|
|
10
10
|
import { ConfigValidationError, MetaGenerationError } from "./errors.js";
|
|
11
11
|
import { normalizeLooseFiles } from "./build/loose-files.js";
|
|
12
12
|
import { removeDeclarationMaps } from "./build/strip-maps.js";
|
|
13
|
+
import { resolveNextVersions } from "./changesets/next-versions.js";
|
|
13
14
|
import { ConfigValidator } from "./config-validation/ConfigValidator.js";
|
|
14
15
|
import { DEFAULT_EXE_NODE_VERSION, normalizeExeOptions } from "./exe/config.js";
|
|
15
16
|
import { isTargetObject } from "./targets/config.js";
|
|
@@ -18,10 +19,12 @@ import { ConfigValidatorLive } from "./config-validation/ConfigValidatorLive.js"
|
|
|
18
19
|
import { buildResolvedTsconfig, writeResolvedTsconfig } from "./dts/resolved-tsconfig.js";
|
|
19
20
|
import { packageJsonEntries } from "./entry/package-json-entries.js";
|
|
20
21
|
import { runExeBuild } from "./exe/build.js";
|
|
22
|
+
import { computeExeFileName } from "./exe/filename.js";
|
|
21
23
|
import { readTsconfigJsx, resolveJsxConfig } from "./jsx/config.js";
|
|
22
24
|
import { normalizeMetaOptions } from "./meta/config.js";
|
|
23
25
|
import { TsconfigResolver, resolvePortableTsconfig } from "./meta/tsconfig-resolver.js";
|
|
24
26
|
import { generateMeta } from "./meta/generate.js";
|
|
27
|
+
import { rewriteMetaVersions } from "./meta/optimistic.js";
|
|
25
28
|
import { CiAnnotationsFormatter } from "./report/formatters/ci-annotations.js";
|
|
26
29
|
import { JsonFormatter } from "./report/formatters/json.js";
|
|
27
30
|
import { MarkdownFormatter } from "./report/formatters/markdown.js";
|
|
@@ -42,4 +45,4 @@ import { generateBuildReportSchema } from "./report/schema-export.js";
|
|
|
42
45
|
import { writeTargetsBinding } from "./targets/binding.js";
|
|
43
46
|
import { CatalogAssemblyError, CatalogResolutionError } from "workspaces-effect";
|
|
44
47
|
|
|
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 };
|
|
48
|
+
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, resolveNextVersions, resolvePortableTsconfig, resolveTargets, rewriteMetaVersions, 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/meta/config.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
//#region src/meta/config.ts
|
|
2
|
+
/** Resolve `"auto"` against the environment; explicit booleans pass through. */
|
|
3
|
+
function resolveOptimistic(value, env) {
|
|
4
|
+
if (value === true || value === false) return value;
|
|
5
|
+
return !(env.CI || env.GITHUB_ACTIONS);
|
|
6
|
+
}
|
|
2
7
|
/** Fill defaults so downstream code never branches on undefined. */
|
|
3
|
-
function normalizeMetaOptions(meta) {
|
|
8
|
+
function normalizeMetaOptions(meta, env = process.env) {
|
|
4
9
|
return {
|
|
5
10
|
localPaths: meta.localPaths ?? [],
|
|
11
|
+
optimistic: resolveOptimistic(meta.optimistic, env),
|
|
6
12
|
tsdoc: {
|
|
7
13
|
suppressWarnings: meta.tsdoc?.suppressWarnings ?? [],
|
|
8
14
|
tagDefinitions: meta.tsdoc?.tagDefinitions ?? []
|
package/meta/generate.js
CHANGED
|
@@ -18,7 +18,7 @@ function unscopedName(name) {
|
|
|
18
18
|
* published-package artifact and is written into `dtsDir` (the built pkg/), not the meta bundle.
|
|
19
19
|
*/
|
|
20
20
|
async function generateMeta(options) {
|
|
21
|
-
const { cwd, packageName, tsconfigPath, dtsDir, entries, exportPaths, outMetaDir, localPaths, tsdoc } = options;
|
|
21
|
+
const { cwd, packageName, tsconfigPath, dtsDir, entries, exportPaths, outMetaDir, localPaths, tsdoc, manifestTransform } = options;
|
|
22
22
|
const tsdocConfigPath = writeTsdocConfig(cwd, tsdoc);
|
|
23
23
|
const packageJsonPath = join(cwd, "package.json");
|
|
24
24
|
mkdirSync(outMetaDir, { recursive: true });
|
|
@@ -55,7 +55,9 @@ async function generateMeta(options) {
|
|
|
55
55
|
writeFileSync(apiJsonPath, `${JSON.stringify(finalModel, null, 2)}\n`, "utf-8");
|
|
56
56
|
for (const intermediate of intermediateApiJsons) rmSync(intermediate, { force: true });
|
|
57
57
|
const bundlePackageJson = join(outMetaDir, "package.json");
|
|
58
|
-
|
|
58
|
+
const builtPkg = JSON.parse(readFileSync(join(dtsDir, "package.json"), "utf-8"));
|
|
59
|
+
const finalPkg = manifestTransform ? manifestTransform(builtPkg) : builtPkg;
|
|
60
|
+
writeFileSync(bundlePackageJson, `${JSON.stringify(finalPkg, null, 2)}\n`, "utf-8");
|
|
59
61
|
const bundleTsconfig = join(outMetaDir, "tsconfig.json");
|
|
60
62
|
const portableTsconfig = resolvePortableTsconfig(cwd, tsconfigPath);
|
|
61
63
|
writeFileSync(bundleTsconfig, `${JSON.stringify(portableTsconfig, null, 2)}\n`, "utf-8");
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/meta/optimistic.ts
|
|
2
|
+
/** Dependency map fields whose workspace-sibling versions get the optimistic bump. */
|
|
3
|
+
const DEP_FIELDS = [
|
|
4
|
+
"dependencies",
|
|
5
|
+
"peerDependencies",
|
|
6
|
+
"optionalDependencies"
|
|
7
|
+
];
|
|
8
|
+
/**
|
|
9
|
+
* Rewrite a meta `package.json` so the package's own `version` and any workspace-sibling
|
|
10
|
+
* dependency version reflect their NEXT release version from `versions`. Pure: returns a new
|
|
11
|
+
* object, never mutates the input. External/catalog-resolved deps (names absent from `versions`)
|
|
12
|
+
* are left as-is.
|
|
13
|
+
*/
|
|
14
|
+
function rewriteMetaVersions(pkg, versions, selfName) {
|
|
15
|
+
const out = { ...pkg };
|
|
16
|
+
const selfNext = versions.get(selfName);
|
|
17
|
+
if (selfNext !== void 0) out.version = selfNext;
|
|
18
|
+
for (const field of DEP_FIELDS) {
|
|
19
|
+
const deps = pkg[field];
|
|
20
|
+
if (deps === null || typeof deps !== "object") continue;
|
|
21
|
+
const next = { ...deps };
|
|
22
|
+
for (const depName of Object.keys(next)) {
|
|
23
|
+
const v = versions.get(depName);
|
|
24
|
+
if (v !== void 0) next[depName] = v;
|
|
25
|
+
}
|
|
26
|
+
out[field] = next;
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
export { rewriteMetaVersions };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@savvy-web/tsdown-plugins",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.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",
|
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
"./package.json": "./package.json"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
+
"@changesets/get-release-plan": "^4.0.16",
|
|
31
32
|
"@effect/platform-node": "^0.107.0",
|
|
33
|
+
"@manypkg/get-packages": "^1.1.3",
|
|
32
34
|
"@microsoft/api-extractor": "^7.58.9",
|
|
33
35
|
"@microsoft/tsdoc": "^0.16.0",
|
|
34
36
|
"@microsoft/tsdoc-config": "^0.18.1",
|