@sanity/tsdown-config 0.22.0 → 0.24.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/README.md +114 -17
- package/dist/cssLoweringTargets-Dn_sJGip.mjs +34 -0
- package/dist/cssLoweringTargets-Dn_sJGip.mjs.map +1 -0
- package/dist/cssNodeCompatPlugin-B_ndKoRv.mjs +115 -0
- package/dist/cssNodeCompatPlugin-B_ndKoRv.mjs.map +1 -0
- package/dist/index.d.mts +100 -19
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +119 -17
- package/dist/index.mjs.map +1 -1
- package/dist/tsdoc.d.mts +47 -0
- package/dist/tsdoc.d.mts.map +1 -0
- package/dist/tsdoc.mjs +196 -0
- package/dist/tsdoc.mjs.map +1 -0
- package/dist/types-CrQ2my_P.d.mts +38 -0
- package/dist/types-CrQ2my_P.d.mts.map +1 -0
- package/package.json +15 -6
package/dist/index.mjs
CHANGED
|
@@ -9,7 +9,7 @@ async function defineConfig(options = {}) {
|
|
|
9
9
|
return typeof reactCompiler == "object" && reactCompiler.reactServer === !0 ? Promise.all([resolvePackageConfig(options, "default"), resolvePackageConfig(options, "react-server")]) : resolvePackageConfig(options, "standalone");
|
|
10
10
|
}
|
|
11
11
|
async function resolvePackageConfig(options, variant) {
|
|
12
|
-
let { entry, tsconfig, define, target, outDir,
|
|
12
|
+
let { entry, tsconfig, define, target, outDir, cwd } = options, isReactServer = variant === "react-server", dts = !isReactServer && options.dts, clean = !isReactServer && options.clean, publint = !isReactServer, platform = options.platform ?? "neutral", sourcemap = options.sourcemap ?? !0, reactCompiler = isReactServer ? !1 : options.reactCompiler ?? !1, styledComponents = options.styledComponents ?? !1, tsdoc = isReactServer ? !1 : options.tsdoc ?? !1, report = { gzip: !1 }, format = options.format ?? "esm", inputOptions = {
|
|
13
13
|
preserveEntrySignatures: "strict",
|
|
14
14
|
experimental: { attachDebugInfo: "none" },
|
|
15
15
|
...platform === "neutral" && { resolve: { mainFields: ["module", "main"] } },
|
|
@@ -29,35 +29,53 @@ async function resolvePackageConfig(options, variant) {
|
|
|
29
29
|
plugins.push(await pluginBabel({ presets: [reactCompilerPreset(reactCompilerOptions)] }));
|
|
30
30
|
}
|
|
31
31
|
if (options.vanillaExtract) {
|
|
32
|
-
let {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
import("lightningcss")
|
|
38
|
-
]);
|
|
39
|
-
lightningcss = {
|
|
40
|
-
...lightningcss,
|
|
41
|
-
targets: browserslistToTargets(browserslist(browserslistConfig))
|
|
42
|
-
};
|
|
43
|
-
}
|
|
32
|
+
let [{ vanillaExtractPlugin }, { resolveCssLoweringTargets }] = await Promise.all([import("@sanity/vanilla-extract-tsdown-plugin"), import("./cssLoweringTargets-Dn_sJGip.mjs")]), vanillaExtract = options.vanillaExtract === !0 ? {} : options.vanillaExtract, lightningcss = await resolveCssLoweringTargets({
|
|
33
|
+
cssTarget: vanillaExtract.target,
|
|
34
|
+
target,
|
|
35
|
+
lightningcss: vanillaExtract.lightningcss
|
|
36
|
+
});
|
|
44
37
|
plugins.push(vanillaExtractPlugin({
|
|
45
|
-
inject:
|
|
38
|
+
inject: !0,
|
|
39
|
+
exports: { nodeCompat: !0 },
|
|
46
40
|
minify: !0,
|
|
47
41
|
...vanillaExtract,
|
|
48
42
|
lightningcss
|
|
49
43
|
}));
|
|
50
44
|
}
|
|
45
|
+
let css;
|
|
46
|
+
if (options.css) {
|
|
47
|
+
let { exports: cssExports, ...cssOptions } = options.css, { resolveCssLoweringTargets } = await import("./cssLoweringTargets-Dn_sJGip.mjs"), lightningcss = await resolveCssLoweringTargets({
|
|
48
|
+
cssTarget: cssOptions.target,
|
|
49
|
+
target,
|
|
50
|
+
lightningcss: cssOptions.lightningcss
|
|
51
|
+
});
|
|
52
|
+
css = {
|
|
53
|
+
minify: !0,
|
|
54
|
+
...cssOptions,
|
|
55
|
+
lightningcss
|
|
56
|
+
};
|
|
57
|
+
let { cssNodeCompatPlugin } = await import("./cssNodeCompatPlugin-B_ndKoRv.mjs");
|
|
58
|
+
plugins.push(cssNodeCompatPlugin({
|
|
59
|
+
fileName: css.fileName,
|
|
60
|
+
splitting: css.splitting,
|
|
61
|
+
inject: css.inject ?? !0,
|
|
62
|
+
exports: cssExports ?? { nodeCompat: !0 }
|
|
63
|
+
})), css = {
|
|
64
|
+
...css,
|
|
65
|
+
inject: !1
|
|
66
|
+
};
|
|
67
|
+
}
|
|
51
68
|
let exports = !1;
|
|
52
69
|
if (!isReactServer) {
|
|
53
70
|
let userExports = options.exports, packageManager = userExports === void 0 || typeof userExports == "object" && userExports.devExports === void 0 ? await detect({ cwd: cwd ?? process.cwd() }) : void 0;
|
|
54
71
|
({exports} = mergeConfig({ exports: {
|
|
55
|
-
enabled:
|
|
72
|
+
enabled: !0,
|
|
56
73
|
...packageManager?.name === "pnpm" && { devExports: !0 }
|
|
57
74
|
} }, { exports: userExports })), variant === "default" && exports && (exports = withReactServerExports(exports));
|
|
58
75
|
}
|
|
59
76
|
return defineConfig$1({
|
|
60
77
|
checks: { circularDependency: !0 },
|
|
78
|
+
suppressWarnings: resolveSuppressWarnings(options.suppressWarnings),
|
|
61
79
|
clean,
|
|
62
80
|
css,
|
|
63
81
|
cwd,
|
|
@@ -67,6 +85,12 @@ async function resolvePackageConfig(options, variant) {
|
|
|
67
85
|
entry,
|
|
68
86
|
exports,
|
|
69
87
|
format,
|
|
88
|
+
...tsdoc === !1 ? {} : { hooks: createTsdocHooks({
|
|
89
|
+
tsdoc: tsdoc === !0 ? {} : tsdoc,
|
|
90
|
+
tsconfig,
|
|
91
|
+
outDir,
|
|
92
|
+
deps
|
|
93
|
+
}) },
|
|
70
94
|
inputOptions,
|
|
71
95
|
outDir,
|
|
72
96
|
outExtensions: isReactServer ? reactServerOutExtensions : void 0,
|
|
@@ -88,6 +112,86 @@ async function resolvePackageConfig(options, variant) {
|
|
|
88
112
|
});
|
|
89
113
|
}
|
|
90
114
|
/**
|
|
115
|
+
* Matches the declaration file extensions tsdown emits next to `es`/`cjs` chunks — the same
|
|
116
|
+
* extensions `rolldown-plugin-dts` gives the modules of the declaration bundling pass.
|
|
117
|
+
*/
|
|
118
|
+
const RE_DTS_FILE = /\.d\.(ts|mts|cts)$/, RE_ANSI_COLOR = /\u001B\[\d*(?:;\d+)*m/g;
|
|
119
|
+
/**
|
|
120
|
+
* Whether a warning is a `CIRCULAR_DEPENDENCY` warning whose entire cycle consists of
|
|
121
|
+
* declaration files, e.g.
|
|
122
|
+
* `Circular dependency: src/exports/index.d.ts -> src/exports/nodes.d.ts -> src/exports/index.d.ts.`
|
|
123
|
+
*
|
|
124
|
+
* Those come from the declaration bundling pass: every import between `.d.ts` modules is
|
|
125
|
+
* type-only and erased at runtime, so the cycle has none of the consequences the check exists
|
|
126
|
+
* to catch (execution-order hazards, bigger bundles), and it's unavoidable for mutually
|
|
127
|
+
* referencing public types — see https://github.com/sanity-io/sanity/pull/13753, where 109 of
|
|
128
|
+
* 136 cycle warnings were declaration-only. A cycle that includes even one runtime module is
|
|
129
|
+
* left alone.
|
|
130
|
+
*/
|
|
131
|
+
function isDtsCircularDependencyWarning(message) {
|
|
132
|
+
let plain = message.replace(RE_ANSI_COLOR, "").trim(), cycleStart = plain.indexOf("Circular dependency: ");
|
|
133
|
+
if (cycleStart === -1) return !1;
|
|
134
|
+
let modules = plain.slice(cycleStart + 21).replace(/\.$/, "").split(" -> ");
|
|
135
|
+
return modules.length > 1 && modules.every((module) => RE_DTS_FILE.test(module));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Composes the userland `suppressWarnings` value with {@link isDtsCircularDependencyWarning}:
|
|
139
|
+
* the two are OR'd, so adding a per-package suppression never drops the declaration-only
|
|
140
|
+
* cycle filter that pairs with this config's `checks.circularDependency` default.
|
|
141
|
+
*
|
|
142
|
+
* The string/`RegExp` matching mirrors tsdown's own — `includes` and `test`, against the
|
|
143
|
+
* message exactly as tsdown would see it, so a pattern behaves the same whether it goes
|
|
144
|
+
* through this option or straight into tsdown's `suppressWarnings`. `lastIndex` is reset for
|
|
145
|
+
* `/g` and `/y` patterns, which carry it between `test` calls and would otherwise skip
|
|
146
|
+
* messages (a no-op for other patterns, whose `lastIndex` `test` ignores).
|
|
147
|
+
*/
|
|
148
|
+
function resolveSuppressWarnings(suppressWarnings) {
|
|
149
|
+
if (suppressWarnings === void 0) return isDtsCircularDependencyWarning;
|
|
150
|
+
let matchesUserPattern = typeof suppressWarnings == "function" ? suppressWarnings : (message) => (Array.isArray(suppressWarnings) ? suppressWarnings : [suppressWarnings]).some((pattern) => typeof pattern == "string" ? message.includes(pattern) : ((pattern.global || pattern.sticky) && (pattern.lastIndex = 0), pattern.test(message)));
|
|
151
|
+
return (message) => isDtsCircularDependencyWarning(message) || matchesUserPattern(message);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Registers the `build:done` hook that runs `checkTsdoc` against every entry `.d.ts` file
|
|
155
|
+
* the build emitted. The checker is loaded from `./tsdoc` only when the hook runs, so
|
|
156
|
+
* importing `defineConfig` never pulls in API Extractor.
|
|
157
|
+
*/
|
|
158
|
+
function createTsdocHooks(options) {
|
|
159
|
+
let { tsdoc, outDir, deps } = options, tsconfigPath = typeof options.tsconfig == "string" ? options.tsconfig : "tsconfig.json", bundledPackages = tsdoc.bundledPackages ?? (Array.isArray(deps?.alwaysBundle) ? deps.alwaysBundle.filter((entry) => typeof entry == "string") : typeof deps?.alwaysBundle == "string" ? [deps.alwaysBundle] : void 0);
|
|
160
|
+
return (hooks) => {
|
|
161
|
+
hooks.hook("build:done", async ({ chunks, options: resolved }) => {
|
|
162
|
+
let entryDtsFiles = entryDtsFilesFromChunks(chunks);
|
|
163
|
+
if (entryDtsFiles.length === 0) return;
|
|
164
|
+
let { checkTsdoc } = await import("./tsdoc.mjs");
|
|
165
|
+
await checkTsdoc({
|
|
166
|
+
cwd: resolved.cwd,
|
|
167
|
+
entryDtsFiles,
|
|
168
|
+
tsconfig: tsconfigPath,
|
|
169
|
+
outDir: outDir ?? resolved.outDir,
|
|
170
|
+
bundledPackages,
|
|
171
|
+
customTags: tsdoc.customTags,
|
|
172
|
+
rules: tsdoc.rules,
|
|
173
|
+
logger: {
|
|
174
|
+
log: (...args) => {
|
|
175
|
+
resolved.logger.info(...args.map(String));
|
|
176
|
+
},
|
|
177
|
+
warn: (...args) => {
|
|
178
|
+
resolved.logger.warn(...args.map(String));
|
|
179
|
+
},
|
|
180
|
+
error: (...args) => {
|
|
181
|
+
resolved.logger.error(...args.map(String));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/** Absolute paths of entry declaration chunks emitted by the build. */
|
|
189
|
+
function entryDtsFilesFromChunks(chunks) {
|
|
190
|
+
let files = [];
|
|
191
|
+
for (let chunk of chunks) chunk.type !== "chunk" || !chunk.isEntry || !RE_DTS_FILE.test(chunk.fileName) || files.push(path.resolve(chunk.outDir, chunk.fileName));
|
|
192
|
+
return files;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
91
195
|
* The `outExtensions` of the `react-server` variant: tsdown's default extension for the
|
|
92
196
|
* format and package type (see `resolveJsOutputExtension` in tsdown), with `.react-server` inserted
|
|
93
197
|
* so the variant's entries sit next to the compiled ones (`index.js` ↔ `index.react-server.js`,
|
|
@@ -184,8 +288,6 @@ function withReactServerCondition(value, isEntryFile, dtsFor) {
|
|
|
184
288
|
for (let [condition, target] of conditions) !inserted && RUNTIME_CONDITIONS.has(condition) && (matched.length === 1 && missingTypes !== void 0 && (next.types = missingTypes), next["react-server"] = serverTarget, inserted = !0), next[condition] = target;
|
|
185
289
|
return inserted || (next["react-server"] = serverTarget), next;
|
|
186
290
|
}
|
|
187
|
-
/** Matches the declaration file extensions tsdown emits next to `es`/`cjs` chunks. */
|
|
188
|
-
const RE_DTS_FILE = /\.d\.(ts|mts|cts)$/;
|
|
189
291
|
/** `./dist/index.js` → `./dist/index.react-server.js` (and `.mjs`/`.cjs` accordingly). */
|
|
190
292
|
function toServerFile(file) {
|
|
191
293
|
return file.replace(RE_JS_FILE, ".react-server.$1");
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["defineTsdownConfig"],"sources":["../src/index.ts"],"sourcesContent":["import path from 'node:path'\nimport type {Options as VanillaExtractPluginOptions} from '@sanity/vanilla-extract-tsdown-plugin'\nimport type {PluginOptions as ReactCompilerPluginOptions} from 'babel-plugin-react-compiler'\nimport {detect} from 'package-manager-detector/detect'\nimport {\n defineConfig as defineTsdownConfig,\n mergeConfig,\n type PackageJsonWithPath,\n type Rolldown,\n type UserConfig,\n} from 'tsdown'\n\n/**\n * Options for the `vanillaExtract` option — the same options as\n * `@sanity/vanilla-extract-tsdown-plugin` (`identifiers`, `fileName`, `minify`, `target`,\n * `lightningcss`, and `inject`, all modeled after the `css` options of `@tsdown/css`), with\n * three Sanity-flavored defaults on top:\n *\n * - `inject` defaults to `{nodeCompat: true}` (instead of the plugin's `false`), wiring up the\n * conditional CSS export pattern that Sanity libraries ship with. Set `inject: true` for a\n * plain relative CSS import, or `inject: false` to only extract the CSS.\n * - `minify` defaults to `true` (instead of the plugin's `false`, which matches `css.minify`\n * in `@tsdown/css`): published Sanity libraries ship minified CSS. Set `minify: false` for\n * readable output.\n * - When the effective CSS syntax lowering target (`target`, falling back to the top-level\n * `target`) is undefined or names no browsers (e.g. `'node20'`, resolved from\n * `engines.node`), the lowering targets are resolved from `@sanity/browserslist-config` and\n * passed through `lightningcss.targets` — where the plugin (like `@tsdown/css`) would skip\n * lowering. `target: false` stays the explicit off switch, and a user-provided\n * `lightningcss.targets` wins over the fallback.\n * @public\n */\nexport type PackageVanillaExtractOptions = VanillaExtractPluginOptions\n\n/**\n * Options for the `styled-components` transform, the same options as `babel-plugin-styled-components`.\n * @public\n */\nexport interface StyledComponentsOptions {\n /** @defaultValue true */\n displayName?: boolean\n /**\n * @defaultValue []\n * @example [\"\\@xstyled/styled-components\", \"\\@xstyled/styled-components/*\"]\n */\n topLevelImportPaths?: string[]\n /** @defaultValue true */\n ssr?: boolean\n /** @defaultValue false */\n fileName?: boolean\n /** @defaultValue [\"index\"] */\n meaninglessFileNames?: string[]\n /** @defaultValue true */\n minify?: boolean\n /** @defaultValue false */\n transpileTemplateLiterals?: boolean\n namespace?: string\n /** @defaultValue true */\n pure?: boolean\n}\n\n/**\n * Options for the React Compiler, the same options as `babel-plugin-react-compiler`.\n * The typings resolve in userland once `babel-plugin-react-compiler` (an optional peer\n * dependency, required to use `reactCompiler`) is installed, and always match the installed\n * version of the compiler.\n *\n * On top of the compiler's own options, `reactServer` opts into the dual React Server\n * Components build — it's handled by this config and never forwarded to\n * `babel-plugin-react-compiler`.\n * @public\n */\nexport type ReactCompilerOptions = Partial<ReactCompilerPluginOptions> & {\n /**\n * Also emit an uncompiled build of every entry (`<name>.react-server.js` next to `<name>.js`),\n * wired to the `react-server` export condition in `package.json`:\n *\n * ```json\n * \".\": {\n * \"types\": \"./dist/index.d.ts\",\n * \"react-server\": \"./dist/index.react-server.js\",\n * \"default\": \"./dist/index.js\"\n * }\n * ```\n *\n * React Server Components refuse to load React Compiler output (`react/compiler-runtime`\n * throws in the `react-server` environment), so a library that ships compiled code\n * publishes two entrypoints: the compiled one (the `default` condition) and an uncompiled\n * one (the `react-server` condition) — see\n * https://github.com/facebook/react/issues/31702.\n *\n * Both builds come from the same source, and the only difference is that React Compiler\n * auto-memoization is applied to the non-`react-server` output; nothing is stripped from\n * either output. Pair it with deleting manual `useMemo`/`useCallback` calls from the\n * source: server components stop paying for memoization that can never pay off (they\n * render exactly once), and client components get the compiler's finer-grained\n * memoization instead.\n * @defaultValue false\n * @alpha This option is experimental and not covered by semver: it can change behavior or\n * be removed entirely in a minor version.\n */\n reactServer?: boolean\n}\n\n/**\n * @public\n */\nexport interface PackageOptions extends Pick<\n UserConfig,\n 'tsconfig' | 'entry' | 'format' | 'dts' | 'define' | 'target' | 'outDir'\n> {\n /**\n * @defaultValue 'neutral'\n *\n * When left at `'neutral'` (the default), two resolution tweaks compensate for rolldown's\n * strict neutral defaults: `deps.neverBundle` includes `/^node:/` (node built-ins stay external\n * so neutral does not warn about them as unresolvable; only node runtimes execute those code\n * paths), and `inputOptions.resolve.mainFields` falls back to `['module', 'main']` for inlined\n * dependencies that ship no `exports` map (e.g. `rxjs-etc/operators`). Prefer `'neutral'` over\n * `'node'` for packages that also run in the browser - `'node'` makes CommonJS-interop emit a\n * module-scope `createRequire(import.meta.url)` for inlined CJS deps, which crashes\n * browser-bundled consumers.\n */\n platform?: UserConfig['platform']\n /**\n * The working directory of the build — forwarded to tsdown's own `cwd` option, and also used\n * for the package-manager detection that decides the pnpm-gated `devExports` default of the\n * {@link PackageOptions.exports | `exports`} option (instead of `process.cwd()`).\n *\n * Config files can leave it unset; set it when driving builds programmatically for a package\n * in another directory, e.g. from a monorepo script or a tool composing this config (like\n * `@sanity/pkg-utils`).\n * @defaultValue `process.cwd()`\n */\n cwd?: UserConfig['cwd']\n /**\n * Clean directories before each build. Prefer an array of folders over a separate `\"clean\"`\n * script in `package.json` (e.g. `rimraf dist coverage`) — tsdown removes them as part of\n * `tsdown` / `pnpm build`, so packages don't need `rimraf`, a `clean` script, or\n * `prebuild`/`run-s clean build` wiring.\n *\n * - `true` (tsdown's default when left undefined) cleans `outDir` (`'dist'` by default)\n * - `false` skips cleaning\n * - a `string[]` replaces that default with the listed paths/globs — include `outDir` (e.g.\n * `'dist'`) when you still want it cleaned alongside other folders\n *\n * @defaultValue true\n * @example\n * ```ts\n * // Instead of `\"clean\": \"rimraf dist coverage\"` in package.json:\n * clean: ['dist', 'coverage']\n * ```\n */\n clean?: UserConfig['clean']\n /**\n * tsdown's `exports` option, with defaults suited for publishing Sanity libraries:\n * `enabled: 'local-only'` generates the `exports` map during local builds and skips it in CI\n * (where the committed `package.json` is already up to date). When pnpm is detected,\n * `devExports: true` also keeps the local `exports` map pointing at source files while\n * `publishConfig.exports` receives the built files.\n *\n * Userland values apply with tsdown's `mergeConfig` semantics: an object deep-merges over\n * these defaults (so individual fields can be overridden), while any other value - `false`\n * to disable exports generation, or a bare CI condition (`'ci-only'`/`'local-only'`) -\n * replaces them entirely.\n *\n * The package-manager detection behind the `devExports` default reads from\n * {@link PackageOptions.cwd | `cwd`} and only runs when the default can still apply — it is\n * skipped when the value replaces the defaults (`false`, `true`, a bare CI condition) or\n * sets `devExports` explicitly.\n * @defaultValue `{enabled: 'local-only', devExports: true}` for pnpm projects;\n * `{enabled: 'local-only'}` otherwise.\n */\n exports?: UserConfig['exports']\n /**\n * Whether to generate source map files. The same default as the `sourcemap` option in\n * `@sanity/pkg-utils` - tsdown itself defaults to `false` and does not read `sourceMap` from\n * the tsconfig.\n * @defaultValue true\n */\n sourcemap?: UserConfig['sourcemap']\n /**\n * tsdown's `deps` option. When `platform` is `'neutral'` (the default), `neverBundle` always\n * includes `/^node:/` and userland `neverBundle` entries are appended (tsdown's `mergeConfig`\n * would replace the array). Other `deps` fields pass through as-is.\n */\n deps?: UserConfig['deps']\n /**\n * tsdown's experimental [`css` option](https://tsdown.dev/options/css) (CSS modules,\n * preprocessors, Lightning CSS / PostCSS, inject, etc). Passed through as-is — requires\n * [`@tsdown/css`](https://www.npmjs.com/package/@tsdown/css) to be installed in the project.\n * Safe to combine with {@link PackageOptions.vanillaExtract}: vanilla-extract extracts into\n * `bundle.css` by default, while `@tsdown/css` merges other CSS (including `.module.css`)\n * into `style.css`, so the two pipelines do not collide.\n * @see https://tsdown.dev/reference/api/Interface.InlineConfig#css\n */\n css?: UserConfig['css']\n /**\n * Runs `babel-plugin-react-compiler` on the source files before they are bundled, so published\n * components are memoized automatically. Pass `true` to use the defaults, or an options object\n * to configure the compiler (e.g. `{target: '18'}`).\n * This is the same feature as the `babel: {reactCompiler: true}` and `reactCompilerOptions`\n * options in `@sanity/pkg-utils`. Unlike `styledComponents` there's no oxc native port of the\n * React Compiler yet, so `babel-plugin-react-compiler` needs to be installed.\n *\n * The options object also accepts `reactServer: true` (an option of this config, not the\n * compiler), which additionally emits an uncompiled build of every entry wired to the\n * `react-server` export condition, for libraries that render in React Server Components —\n * see {@link ReactCompilerOptions.reactServer}.\n * @defaultValue false\n */\n reactCompiler?: boolean | ReactCompilerOptions\n /**\n * Applies the `styled-components` transform (`displayName`, `componentId`, CSS minification, etc)\n * with the same defaults as the `babel: {styledComponents: true}` option in `@sanity/pkg-utils`.\n * Unlike `@sanity/pkg-utils` it doesn't use `babel-plugin-styled-components`, but oxc's native port of it,\n * so there's no need to install babel dependencies.\n * @defaultValue false\n */\n styledComponents?: boolean | StyledComponentsOptions\n /**\n * Enables `@sanity/vanilla-extract-tsdown-plugin` to extract CSS into a separate file,\n * minified and lowered with `lightningcss`. The lowering targets come from the effective\n * `target` (`vanillaExtract.target`, falling back to the top-level `target`) when it names\n * browsers; when it's undefined or browserless (e.g. `'node20'`), they're resolved from\n * `@sanity/browserslist-config` instead — see {@link PackageVanillaExtractOptions}. Pass\n * `true` to use the defaults, or an object to customize.\n *\n * By default (`inject: {nodeCompat: true}`) the plugin also injects the self-referential\n * `import \"<pkg>/bundle.css\"`, emits a `bundle-css.js` shim, and writes the conditional\n * `\"./bundle.css\"` export to `package.json` - see {@link PackageVanillaExtractOptions}.\n * This is the same feature as `rollup.vanillaExtract` in `@sanity/pkg-utils`.\n *\n * Combines with {@link PackageOptions.css}: enable both when a package uses vanilla-extract\n * alongside CSS modules (or other `@tsdown/css` features).\n * @alpha\n */\n vanillaExtract?: boolean | PackageVanillaExtractOptions\n}\n\n/**\n * With `reactCompiler.reactServer` the config resolves to two tsdown configs: the compiled\n * `default` variant and the uncompiled `react-server` variant.\n * @public\n */\nexport function defineConfig(\n options: PackageOptions & {reactCompiler: ReactCompilerOptions & {reactServer: true}},\n): Promise<UserConfig[]>\n/**\n * Without `reactCompiler.reactServer` the config resolves to a single tsdown config.\n * @public\n */\nexport function defineConfig(\n options: PackageOptions & {reactCompiler: ReactCompilerOptions & {reactServer?: false}},\n): Promise<UserConfig>\n/**\n * When TypeScript can't tell whether `reactCompiler.reactServer` is set (a widened `boolean`,\n * e.g. through a `ReactCompilerOptions`-typed variable), the config resolves to either shape —\n * check `Array.isArray` on the result.\n * @public\n */\nexport function defineConfig(\n options: PackageOptions & {reactCompiler: ReactCompilerOptions},\n): Promise<UserConfig | UserConfig[]>\n/**\n * @public\n */\nexport function defineConfig(options?: PackageOptions): Promise<UserConfig>\n/**\n * @public\n */\nexport async function defineConfig(\n options: PackageOptions = {},\n): Promise<UserConfig | UserConfig[]> {\n const reactCompiler = options.reactCompiler ?? false\n // `reactCompiler.reactServer` opts into the dual React Server Components build: the same\n // config twice, where the only difference is that React Compiler auto-memoization is applied\n // to the non-`react-server` variant. Both variants build in one `tsdown` run — tsdown builds\n // the configs in parallel, cleans the shared `outDir` once before either variant emits, and\n // runs `exports` generation and `publint` per `package.json` only after every build for that\n // package has finished (so the `react-server` files exist by the time they're validated).\n if (typeof reactCompiler === 'object' && reactCompiler.reactServer === true) {\n return Promise.all([\n resolvePackageConfig(options, 'default'),\n resolvePackageConfig(options, 'react-server'),\n ])\n }\n return resolvePackageConfig(options, 'standalone')\n}\n\n/**\n * The build variants {@link defineConfig} produces: the classic single build\n * (`'standalone'`), or — with `reactCompiler.reactServer` — the compiled `'default'` variant\n * and the uncompiled `'react-server'` variant of the dual React Server Components build.\n */\ntype PackageConfigVariant = 'standalone' | 'default' | 'react-server'\n\nasync function resolvePackageConfig(\n options: PackageOptions,\n variant: PackageConfigVariant,\n): Promise<UserConfig> {\n // `tsconfig`, `entry`, `dts`, `define`, `target`, `outDir`, `clean`, `css` and `cwd` are\n // passed through to tsdown as-is. When left undefined, tsdown keeps its default behavior\n // (`tsconfig` is auto-detected from the project, `dts` from `package.json`, `define`\n // replaces nothing, `target` applies no syntax downleveling, `outDir` defaults to `'dist'`,\n // `clean` defaults to `true` — cleaning `outDir` before each build — `css` stays off\n // unless `@tsdown/css` is installed and the option is set, and `cwd` defaults to\n // `process.cwd()`).\n const {entry, tsconfig, define, target, outDir, css, cwd} = options\n const isReactServer = variant === 'react-server'\n // The `react-server` variant skips d.ts generation (the compiled variant's declarations\n // serve both entries — a `types` condition specified before `react-server` points every\n // resolution mode at them), never cleans (tsdown collects the clean paths of all configs\n // and cleans once, before either variant emits, so the compiled variant's `clean` already\n // covers the run), and skips `publint` (it runs once, from the compiled variant, after\n // both builds finish).\n const dts = isReactServer ? false : options.dts\n const clean = isReactServer ? false : options.clean\n const publint = !isReactServer\n const platform = options.platform ?? 'neutral'\n const sourcemap = options.sourcemap ?? true\n // The React Compiler is what the `react-server` variant exists to avoid: compiled output\n // loads `react/compiler-runtime`, which throws in the `react-server` environment.\n const reactCompiler = isReactServer ? false : (options.reactCompiler ?? false)\n const styledComponents = options.styledComponents ?? false\n const report = {gzip: false} as const satisfies UserConfig['report']\n const format = options.format ?? 'esm'\n // When `platform` is `'neutral'`, restore the conventional `module`/`main` fallback that\n // rolldown's strict neutral defaults drop - needed for inlined deps without an `exports` map.\n const inputOptions = {\n // https://github.com/rolldown/rolldown/blob/main/packages/rolldown/src/options/docs/preserve-entry-signatures.md#strict\n preserveEntrySignatures: 'strict',\n experimental: {attachDebugInfo: 'none'},\n ...(platform === 'neutral' && {\n resolve: {mainFields: ['module', 'main']},\n }),\n ...(styledComponents !== false && {\n transform: {\n plugins: {\n styledComponents: {\n // The same defaults as `babel: {styledComponents: true}` in `@sanity/pkg-utils`:\n // `fileName` is unnecessary, as the way we use styled-components in Sanity is usually by wrapping\n // `@sanity/ui` primitives, not declaring new ones like \"const Button = styled.button``\"\n fileName: false,\n // Native template literals take less space than this transpilation, and unlike\n // `babel-plugin-styled-components`, oxc doesn't add a `@__PURE__` annotation to the\n // transpiled call expression either, so enabling it wouldn't improve tree-shaking\n transpileTemplateLiterals: false,\n // Helps dead code elimination and tree-shaking, although oxc only annotates plain call\n // expressions so far, not tagged template expressions (https://github.com/rollup/rollup/issues/4035)\n pure: true,\n // Disabled, as tsdown tends to be used for npm publishing, while other tooling,\n // like `sanity dev`, `next dev`, etc are used for testing\n cssProp: false,\n ...(typeof styledComponents === 'object' ? styledComponents : {}),\n },\n },\n },\n }),\n } satisfies UserConfig['inputOptions']\n\n // `neverBundle` is concatenated (not `mergeConfig`'d) so per-package externals add to the\n // `/^node:/` default for `platform: 'neutral'` instead of replacing it. Rolldown's\n // `ExternalOption` array form is `Array<string | RegExp>` only; a function override is composed.\n const userNeverBundle = options.deps?.neverBundle\n const nodeBuiltinExternal = platform === 'neutral' ? /^node:/ : undefined\n const neverBundle: NonNullable<UserConfig['deps']>['neverBundle'] =\n userNeverBundle == null\n ? nodeBuiltinExternal && [nodeBuiltinExternal]\n : nodeBuiltinExternal == null || userNeverBundle === true\n ? userNeverBundle\n : typeof userNeverBundle === 'function'\n ? (id, importer, isResolved) =>\n nodeBuiltinExternal.test(id) || userNeverBundle(id, importer, isResolved)\n : Array.isArray(userNeverBundle)\n ? [nodeBuiltinExternal, ...userNeverBundle]\n : [nodeBuiltinExternal, userNeverBundle]\n const deps: UserConfig['deps'] =\n options.deps === undefined && neverBundle === undefined\n ? undefined\n : {\n ...options.deps,\n ...(neverBundle === undefined ? {} : {neverBundle}),\n }\n\n // `outputOptions` is left to tsdown's defaults - notably chunk filenames keep tsdown's hashed\n // default (unless userland sets `hash`), which prevents chunk/entry filename collisions\n // (https://github.com/sanity-io/ui/issues/2262).\n const plugins: Rolldown.Plugin[] = []\n if (reactCompiler !== false) {\n // Follows the official tsdown recipe for the React Compiler:\n // https://tsdown.dev/recipes/react-support#enabling-react-compiler\n // The plugins are lazy loaded so they're only paid for when the React Compiler is enabled.\n // `babel-plugin-react-compiler` itself is resolved by Babel from the consumer package during\n // the build, which is why it can be an optional peer dependency. Once rolldown ships its rust\n // port of the React Compiler this can be swapped out for an oxc transform, like `styledComponents`.\n const [{default: pluginBabel}, {reactCompilerPreset}] = await Promise.all([\n import('@rolldown/plugin-babel'),\n import('@vitejs/plugin-react'),\n ])\n // `reactServer` belongs to this config, not the compiler — drop it before handing the\n // options over to the babel preset.\n const {reactServer: _reactServer, ...reactCompilerOptions} =\n typeof reactCompiler === 'object' ? reactCompiler : {}\n plugins.push(\n await pluginBabel({\n presets: [reactCompilerPreset(reactCompilerOptions)],\n }),\n )\n }\n if (options.vanillaExtract) {\n // Lazy loaded, like `reactCompiler`, so the CSS toolchain is only paid for when the option is\n // enabled. The plugin compiles the `.css.ts` files and extracts the CSS into a single file.\n // Its `inject` option is general purpose (and, like `css.inject` in `@tsdown/css`, disabled\n // by default), so this config supplies the default most Sanity libraries want:\n // `{nodeCompat: true}` wires up the whole conditional CSS export pattern - the\n // self-referential CSS import, the no-op JS shim, and the conditional `./<fileName>` export\n // written through this config's `exports` option (which the plugin's `tsdownConfig` hook\n // composes into).\n const {esbuildTargetToLightningCSS, vanillaExtractPlugin} =\n await import('@sanity/vanilla-extract-tsdown-plugin')\n const vanillaExtract = options.vanillaExtract === true ? {} : options.vanillaExtract\n\n // The plugin follows `@tsdown/css`: without browser targets, CSS syntax lowering is\n // skipped. The extracted CSS always runs in browsers, so when the effective target\n // (`vanillaExtract.target`, falling back to the top-level `target`) is undefined or names\n // no browsers (e.g. `'node20'` - also what tsdown derives from `engines.node`, which\n // speaks to the JS runtime), this config resolves the lowering targets from\n // `@sanity/browserslist-config` and passes them through `lightningcss.targets` instead.\n // `target: false` stays the explicit off switch, and a user-provided\n // `lightningcss.targets` wins over the fallback.\n const cssTarget = vanillaExtract.target ?? target\n let {lightningcss} = vanillaExtract\n if (\n cssTarget !== false &&\n !lightningcss?.targets &&\n (cssTarget === undefined || !esbuildTargetToLightningCSS(cssTarget))\n ) {\n // Lazy loaded as well: `browserslistToTargets` is a pure helper, but `lightningcss` is a\n // native package that only needs to load when the fallback applies\n const [{default: browserslist}, {default: browserslistConfig}, {browserslistToTargets}] =\n await Promise.all([\n import('browserslist'),\n import('@sanity/browserslist-config'),\n import('lightningcss'),\n ])\n lightningcss = {\n ...lightningcss,\n targets: browserslistToTargets(browserslist(browserslistConfig)),\n }\n }\n\n plugins.push(\n vanillaExtractPlugin({\n inject: {nodeCompat: true},\n minify: true,\n ...vanillaExtract,\n lightningcss,\n }),\n )\n }\n\n // The `react-server` variant does not participate in `exports` generation: its files are\n // wired in through the compiled variant's `react-server` conditions instead of becoming\n // export subpaths of their own.\n let exports: UserConfig['exports'] = false\n if (!isReactServer) {\n const userExports = options.exports\n // Package-manager detection exists solely to decide the pnpm-gated `devExports: true`\n // default, so it only runs when that default can still apply. `false`, `true`, and bare\n // CI-condition strings replace the defaults entirely (mergeConfig semantics), and an\n // explicit `devExports` value overrides it — those configs skip the filesystem probing\n // and behave identically across package managers. Programmatic hosts composing this\n // config (e.g. `@sanity/pkg-utils` passing `{devExports: 'source'}`) never trigger it.\n const devExportsDefaultApplies =\n userExports === undefined ||\n (typeof userExports === 'object' && userExports.devExports === undefined)\n const packageManager = devExportsDefaultApplies\n ? await detect({cwd: cwd ?? process.cwd()})\n : undefined\n // tsdown's `exports` feature is enabled with Sanity-flavored defaults, and userland values\n // apply with tsdown's own `mergeConfig` semantics: an object deep-merges over the defaults,\n // anything else (`false`, a CI condition) replaces them.\n ;({exports} = mergeConfig(\n {\n exports: {\n enabled: 'local-only',\n // Only opt in by default when pnpm is detected: support for replacing package fields\n // from `publishConfig` is not reliable across package managers.\n ...(packageManager?.name === 'pnpm' && {devExports: true}),\n },\n },\n {exports: userExports},\n ))\n if (variant === 'default' && exports) {\n // The compiled variant owns `exports` generation for the dual build, so the\n // `react-server` conditions are composed into its `customExports`: every entry export\n // gains a `react-server` condition pointing at the `.react-server.` sibling that the\n // `react-server` variant emits.\n exports = withReactServerExports(exports)\n }\n }\n\n return defineTsdownConfig({\n // Rolldown defaults `circularDependency` to `false`; enable it so Sanity library builds\n // surface import cycles (bigger bundles / execution-order hazards) as warnings.\n // Override via `mergeConfig(..., {checks: {circularDependency: false}})`.\n // https://rolldown.rs/reference/InputOptions.checks#circulardependency\n checks: {circularDependency: true},\n clean,\n css,\n cwd,\n define,\n deps,\n dts,\n entry,\n exports,\n format,\n inputOptions,\n outDir,\n // The `react-server` variant writes its files next to the compiled ones, with `.react-server`\n // inserted before tsdown's default extension (`index.js` ↔ `index.react-server.js`). Hashed\n // chunk filenames get the suffix too, so the two variants' chunks never collide in the\n // shared `outDir`.\n outExtensions: isReactServer ? reactServerOutExtensions : undefined,\n platform,\n plugins,\n publint,\n report,\n sourcemap,\n target,\n tsconfig,\n // Compress the output (constant folding, dead code elimination) without mangling\n // identifiers or stripping whitespace: consumers' production builds minify `node_modules`\n // again anyway, so full minification here would only hurt debuggability, not final app\n // bundle sizes. `keepNames` preserves the function and class names the compress pass\n // would otherwise strip as unreferenced - e.g. the inner name in\n // `forwardRef(function Button(…) {…})`, which React DevTools reads via `Function.name`.\n // That name is the tree-shakeable alternative to a top-level `Button.displayName = '…'`\n // assignment (a side effect that pins unused components into consumer bundles, see\n // https://github.com/sanity-io/ui/pull/2435), and names stripped at publish time are\n // unrecoverable in userland.\n minify: {\n compress: {keepNames: {function: true, class: true}},\n codegen: false,\n mangle: false,\n },\n })\n}\n\n/**\n * The `outExtensions` of the `react-server` variant: tsdown's default extension for the\n * format and package type (see `resolveJsOutputExtension` in tsdown), with `.react-server` inserted\n * so the variant's entries sit next to the compiled ones (`index.js` ↔ `index.react-server.js`,\n * `index.cjs` ↔ `index.react-server.cjs`, and `.mjs` accordingly for CommonJS packages).\n */\nconst reactServerOutExtensions: NonNullable<UserConfig['outExtensions']> = ({format, pkgType}) => ({\n js:\n format === 'cjs'\n ? pkgType === 'module'\n ? '.react-server.cjs'\n : '.react-server.js'\n : pkgType === 'module'\n ? '.react-server.js'\n : '.react-server.mjs',\n})\n\ntype ExportsOptions = Extract<NonNullable<UserConfig['exports']>, object>\ntype CustomExportsFunction = Extract<\n NonNullable<ExportsOptions['customExports']>,\n (...args: never[]) => unknown\n>\ntype ExportsMap = Parameters<CustomExportsFunction>[0]\n/**\n * Wires the `react-server` conditions into tsdown's `exports` feature by composing into\n * `exports.customExports` (the same composition `@sanity/vanilla-extract-tsdown-plugin` uses\n * for its conditional CSS export): a pre-existing `customExports` applies first — both its\n * function and record forms, mirroring how tsdown itself applies them — and the\n * `react-server` conditions are inserted into the result. The composed function runs for both\n * the local `exports` map and `publishConfig.exports`; with `devExports` the local map points\n * at source files, which the entry-file matching leaves untouched (source resolves for every\n * condition in development, which is correct — uncompiled source is exactly what the\n * `react-server` condition ships).\n */\nfunction withReactServerExports(\n exportsOption: Exclude<NonNullable<UserConfig['exports']>, false>,\n): ExportsOptions {\n // Normalize the `boolean | CIOption | object` forms of the `exports` option into the\n // object form, preserving the enabled-ness (`true` and bare CI conditions mean enabled)\n const exportsOptions: ExportsOptions =\n exportsOption === true\n ? {}\n : typeof exportsOption === 'string'\n ? {enabled: exportsOption}\n : exportsOption\n const previousCustomExports = exportsOptions.customExports\n exportsOptions.customExports = async (exportsMap, context) => {\n // Apply a pre-existing `customExports` first (both its function and record forms,\n // mirroring how tsdown itself applies them), then insert the `react-server` conditions\n const base =\n typeof previousCustomExports === 'function'\n ? await previousCustomExports(exportsMap, context)\n : previousCustomExports\n ? {...exportsMap, ...previousCustomExports}\n : exportsMap\n return addReactServerConditions(base, context)\n }\n return exportsOptions\n}\n\n/** Matches the JS output extensions tsdown emits for `es`/`cjs` chunks. */\nconst RE_JS_FILE = /\\.(m?js|cjs)$/\n\n/** The conditions tsdown generates that resolve at runtime, in contrast to `types` etc. */\nconst RUNTIME_CONDITIONS = new Set(['import', 'require', 'default'])\n\n/**\n * Inserts a `react-server` condition into every entry export of an `exports`-shaped map,\n * pointing at the `.react-server.` sibling emitted by the `react-server` variant — e.g.\n * `\"./dist/index.js\"` becomes\n * `{\"types\": \"./dist/index.d.ts\", \"react-server\": \"./dist/index.react-server.js\", \"default\": \"./dist/index.js\"}`.\n *\n * The `react-server` variant emits no `.d.ts` siblings, so TypeScript's adjacent-file lookup\n * cannot resolve types for `./dist/index.react-server.js` — a `types` condition pointing at\n * the compiled variant's declarations is specified before `react-server` instead (conditions\n * match in order, so it covers every resolution mode). It's only added when the declarations\n * actually exist among the compiled variant's chunks, and an already-present `types`\n * condition is left in place.\n *\n * Entries are recognized by comparing export targets against the compiled variant's entry\n * chunks — reconstructed in the exact `./<outDir relative to the package root>/<fileName>`\n * form tsdown writes into the exports map, so entries that share a leaf name (`index.js` vs\n * `features/index.js`) can never shadow each other, and non-entry exports (`./package.json`,\n * the conditional `./bundle.css` export of `vanillaExtract`, `devExports` source paths like\n * `./src/index.ts`) pass through untouched. The `react-server` files themselves never enter\n * the map — the `react-server` variant builds with `exports: false` — so they don't become\n * export subpaths of their own.\n */\nfunction addReactServerConditions(\n exportsMap: ExportsMap,\n context: Parameters<CustomExportsFunction>[1],\n): ExportsMap {\n // tsdown always resolves the package with its path here: its own exports generation reads\n // `packageJsonPath` unconditionally from the same object it passes to `customExports` -\n // only the declared context type is the plain `PackageJson` shape.\n const pkg: Partial<PackageJsonWithPath> = context.pkg\n const pkgRoot = path.dirname(pkg.packageJsonPath ?? 'package.json')\n // Export targets of the compiled variant's entry JS and declaration chunks; the\n // `react-server` variant's files sit next to the entries with `.react-server` inserted\n // before the extension\n const entryFiles = new Set<string>()\n const dtsFiles = new Set<string>()\n for (const [format, formatChunks] of Object.entries(context.chunks)) {\n // Only `es` and `cjs` chunks become package exports (mirroring tsdown's own generation)\n if (format !== 'es' && format !== 'cjs') continue\n for (const chunk of formatChunks) {\n if (chunk.type !== 'chunk') continue\n const target = exportTarget(pkgRoot, chunk.outDir, chunk.fileName)\n if (chunk.isEntry && RE_JS_FILE.test(chunk.fileName)) {\n entryFiles.add(target)\n } else if (RE_DTS_FILE.test(chunk.fileName)) {\n dtsFiles.add(target)\n }\n }\n }\n const isEntryFile = (value: unknown): value is string =>\n typeof value === 'string' && entryFiles.has(value)\n // The `types` file for an entry export target, when the compiled variant emitted it\n const dtsFor = (value: string): string | undefined => {\n const dtsFile = toDtsFile(value)\n return dtsFiles.has(dtsFile) ? dtsFile : undefined\n }\n\n const result: ExportsMap = {}\n for (const [key, value] of Object.entries(exportsMap as Record<string, unknown>)) {\n result[key] = withReactServerCondition(value, isEntryFile, dtsFor)\n }\n return result\n}\n\n/**\n * Mirrors tsdown's own `join` for exports targets:\n * `./<outDir relative to the package root>/<fileName>`, with POSIX separators.\n */\nfunction exportTarget(pkgRoot: string, outDir: string, fileName: string): string {\n const outDirRelative = path.relative(pkgRoot, outDir).replaceAll('\\\\', '/')\n return `${outDirRelative ? `./${outDirRelative}` : '.'}/${fileName.replaceAll('\\\\', '/')}`\n}\n\nfunction withReactServerCondition(\n value: unknown,\n isEntryFile: (value: unknown) => value is string,\n dtsFor: (value: string) => string | undefined,\n): unknown {\n // A bare-string entry export (e.g. the pure-ESM publish shape `\".\": \"./dist/index.js\"`)\n // becomes a conditional export, with `types` specified before `react-server` so type\n // resolution never reaches the declaration-less `.react-server.` file\n if (isEntryFile(value)) {\n const types = dtsFor(value)\n return {\n ...(types === undefined ? {} : {types}),\n 'react-server': toServerFile(value),\n 'default': value,\n }\n }\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return value\n const conditions = Object.entries(value)\n const matched = conditions.filter(\n (entry): entry is [string, string] => RUNTIME_CONDITIONS.has(entry[0]) && isEntryFile(entry[1]),\n )\n const [firstMatch] = matched\n if (!firstMatch) return value\n const hasTypes = conditions.some(([condition]) => condition === 'types')\n // A single runtime file maps to a plain path (with a `types` condition inserted ahead of\n // `react-server` below, unless one is already specified). A dual-format entry nests its\n // `import` and `require` files under the `react-server` condition, each with its own\n // format-matched `types` — a single top-level `types` file cannot serve both resolution\n // modes, which is also why tsdown's own dual-format output relies on adjacent-file lookup.\n const missingTypes = hasTypes ? undefined : dtsFor(firstMatch[1])\n const serverTarget =\n matched.length === 1\n ? toServerFile(firstMatch[1])\n : Object.fromEntries(\n matched.map(([condition, target]) => {\n const types = hasTypes ? undefined : dtsFor(target)\n return [\n condition,\n types === undefined ? toServerFile(target) : {types, default: toServerFile(target)},\n ]\n }),\n )\n // Conditions match in order, so `react-server` is inserted right before the first runtime\n // condition (`import`/`require`/`default`), keeping `types` and custom development\n // conditions (`devExports`) ahead of it\n const next: Record<string, unknown> = {}\n let inserted = false\n for (const [condition, target] of conditions) {\n if (!inserted && RUNTIME_CONDITIONS.has(condition)) {\n if (matched.length === 1 && missingTypes !== undefined) {\n next['types'] = missingTypes\n }\n next['react-server'] = serverTarget\n inserted = true\n }\n next[condition] = target\n }\n if (!inserted) {\n next['react-server'] = serverTarget\n }\n return next\n}\n\n/** Matches the declaration file extensions tsdown emits next to `es`/`cjs` chunks. */\nconst RE_DTS_FILE = /\\.d\\.(ts|mts|cts)$/\n\n/** `./dist/index.js` → `./dist/index.react-server.js` (and `.mjs`/`.cjs` accordingly). */\nfunction toServerFile(file: string): string {\n return file.replace(RE_JS_FILE, '.react-server.$1')\n}\n\n/** `./dist/index.js` → `./dist/index.d.ts` (`.mjs` → `.d.mts`, `.cjs` → `.d.cts`). */\nfunction toDtsFile(file: string): string {\n return file.replace(RE_JS_FILE, (extension) =>\n extension === '.mjs' ? '.d.mts' : extension === '.cjs' ? '.d.cts' : '.d.ts',\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["defineTsdownConfig"],"sources":["../src/index.ts"],"sourcesContent":["import path from 'node:path'\nimport type {\n CssExportsOptions,\n Options as VanillaExtractPluginOptions,\n} from '@sanity/vanilla-extract-tsdown-plugin'\nimport type {PluginOptions as ReactCompilerPluginOptions} from 'babel-plugin-react-compiler'\nimport {detect} from 'package-manager-detector/detect'\nimport {\n defineConfig as defineTsdownConfig,\n mergeConfig,\n type PackageJsonWithPath,\n type Rolldown,\n type RolldownChunk,\n type UserConfig,\n} from 'tsdown'\nimport type {PackageTsdocOptions} from './tsdoc/types.ts'\n\nexport type {\n PackageTsdocCustomTag,\n PackageTsdocOptions,\n PackageTsdocRuleLevel,\n} from './tsdoc/types.ts'\n\n// Only types are re-exported from the plugin packages: a value re-export would make\n// `@sanity/vanilla-extract-tsdown-plugin` a static import of this entry, pulling the whole\n// vanilla-extract toolchain (the rolldown plugin, `@sanity/vanilla-extract-integration`,\n// `@vanilla-extract/css`, and the native `lightningcss` binary) into every consumer's module\n// graph — including packages with no CSS at all. Everything that needs those helpers loads\n// them through the `await import(...)` calls below.\nexport type {CssExportsOptions} from '@sanity/vanilla-extract-tsdown-plugin'\n\n/**\n * Options for the `vanillaExtract` option — the same options as\n * `@sanity/vanilla-extract-tsdown-plugin` (`identifiers`, `fileName`, `minify`, `target`,\n * `lightningcss`, `inject`, and `exports`, all modeled after the `css` options of\n * `@tsdown/css`), with three Sanity-flavored defaults on top:\n *\n * - `inject` and `exports` default to `true` and `{nodeCompat: true}` (instead of the plugin's\n * `false` for both), wiring up the conditional CSS export pattern that Sanity libraries ship\n * with. Set `exports: true` for a plain (browser-only) CSS export, `exports: false` for a\n * relative CSS import, or `inject: false` to only extract the CSS.\n * - `minify` defaults to `true` (instead of the plugin's `false`, which matches `css.minify`\n * in `@tsdown/css`): published Sanity libraries ship minified CSS. Set `minify: false` for\n * readable output.\n * - When the effective CSS syntax lowering target (`target`, falling back to the top-level\n * `target`) is undefined or names no browsers (e.g. `'node20'`, resolved from\n * `engines.node`), the lowering targets are resolved from `@sanity/browserslist-config` and\n * passed through `lightningcss.targets` — where the plugin (like `@tsdown/css`) would skip\n * lowering. `target: false` stays the explicit off switch, and a user-provided\n * `lightningcss.targets` wins over the fallback.\n * @public\n */\nexport type PackageVanillaExtractOptions = VanillaExtractPluginOptions\n\n/**\n * Options for the `css` option — tsdown's experimental\n * [`css` options](https://tsdown.dev/options/css) from `@tsdown/css` (`splitting`, `fileName`,\n * `target`, `minify`, `lightningcss`, `postcss`, `modules`, `preprocessorOptions`,\n * `transformer`, `inject`), plus an `exports` option this config implements on top, with two\n * Sanity-flavored defaults:\n *\n * - `exports` defaults to `{nodeCompat: true}`, wiring up the conditional CSS export pattern:\n * the self-referential `import \"<pkg>/style.css\"`, a no-op `style-css.js` shim with a\n * `style-css.d.ts` declaration, and the conditional `\"./style.css\"` export written to\n * `package.json`. `@tsdown/css` has no equivalent — its `inject` emits a relative\n * `import \"./style.css\"`, which throws in runtimes that cannot load `.css` files. Set\n * `exports: true` for a plain (browser-only) CSS export, or `exports: false` to fall back to\n * `@tsdown/css`'s relative injection.\n * - `minify` defaults to `true` (instead of `@tsdown/css`'s `false`): published Sanity\n * libraries ship minified CSS. Set `minify: false` for readable output.\n *\n * The CSS syntax lowering target resolves exactly like\n * {@link PackageVanillaExtractOptions | `vanillaExtract`}'s: browserless targets fall back to\n * `@sanity/browserslist-config` through `lightningcss.targets`.\n * @public\n */\nexport type PackageCssOptions = NonNullable<UserConfig['css']> & {\n /**\n * Publish each emitted CSS file as an export subpath of the package, so consumers can\n * `import \"<pkg-name>/style.css\"` — which is also the specifier `inject` then uses, instead\n * of `@tsdown/css`'s relative path.\n *\n * - `true` declares a plain `\"./style.css\": \"./dist/style.css\"` export. Enough for packages\n * that only ever run in browsers or bundlers.\n * - `{nodeCompat: true}` declares a conditional export instead, whose `browser`/`style`\n * conditions point at the stylesheet while `node`/`default` point at a no-op JS shim\n * emitted next to it, with a declaration file for the export's `types` condition. That\n * keeps the subpath resolvable in runtimes that cannot load `.css` files.\n *\n * @defaultValue `{nodeCompat: true}`\n */\n exports?: boolean | CssExportsOptions\n}\n\n/**\n * Options for the `styled-components` transform, the same options as `babel-plugin-styled-components`.\n * @public\n */\nexport interface StyledComponentsOptions {\n /** @defaultValue true */\n displayName?: boolean\n /**\n * @defaultValue []\n * @example [\"\\@xstyled/styled-components\", \"\\@xstyled/styled-components/*\"]\n */\n topLevelImportPaths?: string[]\n /** @defaultValue true */\n ssr?: boolean\n /** @defaultValue false */\n fileName?: boolean\n /** @defaultValue [\"index\"] */\n meaninglessFileNames?: string[]\n /** @defaultValue true */\n minify?: boolean\n /** @defaultValue false */\n transpileTemplateLiterals?: boolean\n namespace?: string\n /** @defaultValue true */\n pure?: boolean\n}\n\n/**\n * Options for the React Compiler, the same options as `babel-plugin-react-compiler`.\n * The typings resolve in userland once `babel-plugin-react-compiler` (an optional peer\n * dependency, required to use `reactCompiler`) is installed, and always match the installed\n * version of the compiler.\n *\n * On top of the compiler's own options, `reactServer` opts into the dual React Server\n * Components build — it's handled by this config and never forwarded to\n * `babel-plugin-react-compiler`.\n * @public\n */\nexport type ReactCompilerOptions = Partial<ReactCompilerPluginOptions> & {\n /**\n * Also emit an uncompiled build of every entry (`<name>.react-server.js` next to `<name>.js`),\n * wired to the `react-server` export condition in `package.json`:\n *\n * ```json\n * \".\": {\n * \"types\": \"./dist/index.d.ts\",\n * \"react-server\": \"./dist/index.react-server.js\",\n * \"default\": \"./dist/index.js\"\n * }\n * ```\n *\n * React Server Components refuse to load React Compiler output (`react/compiler-runtime`\n * throws in the `react-server` environment), so a library that ships compiled code\n * publishes two entrypoints: the compiled one (the `default` condition) and an uncompiled\n * one (the `react-server` condition) — see\n * https://github.com/facebook/react/issues/31702.\n *\n * Both builds come from the same source, and the only difference is that React Compiler\n * auto-memoization is applied to the non-`react-server` output; nothing is stripped from\n * either output. Pair it with deleting manual `useMemo`/`useCallback` calls from the\n * source: server components stop paying for memoization that can never pay off (they\n * render exactly once), and client components get the compiler's finer-grained\n * memoization instead.\n * @defaultValue false\n * @alpha This option is experimental and not covered by semver: it can change behavior or\n * be removed entirely in a minor version.\n */\n reactServer?: boolean\n}\n\n/**\n * @public\n */\nexport interface PackageOptions extends Pick<\n UserConfig,\n 'tsconfig' | 'entry' | 'format' | 'dts' | 'define' | 'target' | 'outDir'\n> {\n /**\n * @defaultValue 'neutral'\n *\n * When left at `'neutral'` (the default), two resolution tweaks compensate for rolldown's\n * strict neutral defaults: `deps.neverBundle` includes `/^node:/` (node built-ins stay external\n * so neutral does not warn about them as unresolvable; only node runtimes execute those code\n * paths), and `inputOptions.resolve.mainFields` falls back to `['module', 'main']` for inlined\n * dependencies that ship no `exports` map (e.g. `rxjs-etc/operators`). Prefer `'neutral'` over\n * `'node'` for packages that also run in the browser - `'node'` makes CommonJS-interop emit a\n * module-scope `createRequire(import.meta.url)` for inlined CJS deps, which crashes\n * browser-bundled consumers.\n */\n platform?: UserConfig['platform']\n /**\n * The working directory of the build — forwarded to tsdown's own `cwd` option, and also used\n * for the package-manager detection that decides the pnpm-gated `devExports` default of the\n * {@link PackageOptions.exports | `exports`} option (instead of `process.cwd()`).\n *\n * Config files can leave it unset; set it when driving builds programmatically for a package\n * in another directory, e.g. from a monorepo script or a tool composing this config (like\n * `@sanity/pkg-utils`).\n * @defaultValue `process.cwd()`\n */\n cwd?: UserConfig['cwd']\n /**\n * Clean directories before each build. Prefer an array of folders over a separate `\"clean\"`\n * script in `package.json` (e.g. `rimraf dist coverage`) — tsdown removes them as part of\n * `tsdown` / `pnpm build`, so packages don't need `rimraf`, a `clean` script, or\n * `prebuild`/`run-s clean build` wiring.\n *\n * - `true` (tsdown's default when left undefined) cleans `outDir` (`'dist'` by default)\n * - `false` skips cleaning\n * - a `string[]` replaces that default with the listed paths/globs — include `outDir` (e.g.\n * `'dist'`) when you still want it cleaned alongside other folders\n *\n * @defaultValue true\n * @example\n * ```ts\n * // Instead of `\"clean\": \"rimraf dist coverage\"` in package.json:\n * clean: ['dist', 'coverage']\n * ```\n */\n clean?: UserConfig['clean']\n /**\n * tsdown's `exports` option, with defaults suited for publishing Sanity libraries:\n * `enabled: true` generates the `exports` map on every build, whether `CI` is set or not\n * (GitHub Actions, Cursor Cloud, local shells, …). Relying on `'local-only'`/`'ci-only'`\n * surprised too many environments that set `CI=true` without meaning \"don't rewrite\n * package.json\". When pnpm is detected, `devExports: true` also keeps the local `exports`\n * map pointing at source files while `publishConfig.exports` receives the built files.\n *\n * Userland values apply with tsdown's `mergeConfig` semantics: an object deep-merges over\n * these defaults (so individual fields can be overridden), while any other value - `false`\n * to disable exports generation, or a bare CI condition (`'ci-only'`/`'local-only'`) -\n * replaces them entirely.\n *\n * The package-manager detection behind the `devExports` default reads from\n * {@link PackageOptions.cwd | `cwd`} and only runs when the default can still apply — it is\n * skipped when the value replaces the defaults (`false`, `true`, a bare CI condition) or\n * sets `devExports` explicitly.\n * @defaultValue `{enabled: true, devExports: true}` for pnpm projects;\n * `{enabled: true}` otherwise.\n */\n exports?: UserConfig['exports']\n /**\n * Whether to generate source map files. The same default as the `sourcemap` option in\n * `@sanity/pkg-utils` - tsdown itself defaults to `false` and does not read `sourceMap` from\n * the tsconfig.\n * @defaultValue true\n */\n sourcemap?: UserConfig['sourcemap']\n /**\n * tsdown's `deps` option. When `platform` is `'neutral'` (the default), `neverBundle` always\n * includes `/^node:/` and userland `neverBundle` entries are appended (tsdown's `mergeConfig`\n * would replace the array). Other `deps` fields pass through as-is.\n */\n deps?: UserConfig['deps']\n /**\n * tsdown's experimental [`css` option](https://tsdown.dev/options/css) (CSS modules,\n * preprocessors, Lightning CSS / PostCSS, inject, etc), with Sanity-flavored defaults and an\n * added `exports` option — requires\n * [`@tsdown/css`](https://www.npmjs.com/package/@tsdown/css) to be installed in the project.\n *\n * By default (`exports: {nodeCompat: true}`, `minify: true`) the emitted CSS gets the same\n * conditional CSS export treatment as {@link PackageOptions.vanillaExtract}: the\n * self-referential `import \"<pkg>/style.css\"`, a no-op `style-css.js` shim with its\n * `style-css.d.ts` declaration, and the conditional `\"./style.css\"` export written to\n * `package.json` — see {@link PackageCssOptions}.\n *\n * Safe to combine with {@link PackageOptions.vanillaExtract}: vanilla-extract extracts into\n * `bundle.css` by default, while `@tsdown/css` merges other CSS (including `.module.css`)\n * into `style.css`, so the two pipelines do not collide.\n * @see https://tsdown.dev/reference/api/Interface.InlineConfig#css\n * @alpha\n */\n css?: PackageCssOptions\n /**\n * Runs `babel-plugin-react-compiler` on the source files before they are bundled, so published\n * components are memoized automatically. Pass `true` to use the defaults, or an options object\n * to configure the compiler (e.g. `{target: '18'}`).\n * This is the same feature as the `babel: {reactCompiler: true}` and `reactCompilerOptions`\n * options in `@sanity/pkg-utils`. Unlike `styledComponents` there's no oxc native port of the\n * React Compiler yet, so `babel-plugin-react-compiler` needs to be installed.\n *\n * The options object also accepts `reactServer: true` (an option of this config, not the\n * compiler), which additionally emits an uncompiled build of every entry wired to the\n * `react-server` export condition, for libraries that render in React Server Components —\n * see {@link ReactCompilerOptions.reactServer}.\n * @defaultValue false\n */\n reactCompiler?: boolean | ReactCompilerOptions\n /**\n * Applies the `styled-components` transform (`displayName`, `componentId`, CSS minification, etc)\n * with the same defaults as the `babel: {styledComponents: true}` option in `@sanity/pkg-utils`.\n * Unlike `@sanity/pkg-utils` it doesn't use `babel-plugin-styled-components`, but oxc's native port of it,\n * so there's no need to install babel dependencies.\n * @defaultValue false\n */\n styledComponents?: boolean | StyledComponentsOptions\n /**\n * Enables `@sanity/vanilla-extract-tsdown-plugin` to extract CSS into a separate file,\n * minified and lowered with `lightningcss`. The lowering targets come from the effective\n * `target` (`vanillaExtract.target`, falling back to the top-level `target`) when it names\n * browsers; when it's undefined or browserless (e.g. `'node20'`), they're resolved from\n * `@sanity/browserslist-config` instead — see {@link PackageVanillaExtractOptions}. Pass\n * `true` to use the defaults, or an object to customize.\n *\n * By default (`inject: true` with `exports: {nodeCompat: true}`) the plugin also injects the\n * self-referential `import \"<pkg>/bundle.css\"`, emits a `bundle-css.js` shim, and writes the\n * conditional `\"./bundle.css\"` export to `package.json` - see\n * {@link PackageVanillaExtractOptions}. This is the same feature as `rollup.vanillaExtract`\n * in `@sanity/pkg-utils`.\n *\n * Combines with {@link PackageOptions.css}: enable both when a package uses vanilla-extract\n * alongside CSS modules (or other `@tsdown/css` features).\n * @alpha\n */\n vanillaExtract?: boolean | PackageVanillaExtractOptions\n /**\n * Runs `@microsoft/api-extractor` after the build (via tsdown's `build:done` hook) to check\n * that TSDoc tags are valid and release tags are correct. Useful for packages consumed by\n * TSDoc-based tooling. Off by default — set `tsdoc: true` to enable, or pass an options\n * object to customize rules and custom tags.\n * @defaultValue false\n */\n tsdoc?: boolean | PackageTsdocOptions\n /**\n * tsdown's `suppressWarnings` option: strings (matched with `includes`), regular expressions\n * (matched with `test`), or a predicate that drop build warnings before they're printed — and\n * before `failOnWarn` turns them into errors.\n *\n * Userland values are **added to** the built-in suppression instead of replacing it (which\n * `mergeConfig` would do, since it replaces functions): per-package suppressions can't\n * accidentally undo the declaration-only circular-dependency filter that this config pairs\n * with its `checks.circularDependency` default. This config always suppresses\n * `CIRCULAR_DEPENDENCY` warnings whose entire cycle consists of declaration files\n * (`.d.ts`/`.d.mts`/`.d.cts`) — those come from the declaration bundling pass, where every\n * import is type-only and erased at runtime, so the cycles are harmless and unavoidable for\n * mutually referencing public types (e.g. the schema definition types in `@sanity/types`).\n * Cycles involving a runtime module still warn.\n *\n * To drop the built-in suppression instead of adding to it, merge over the returned config —\n * `mergeConfig(await defineConfig(), {suppressWarnings: () => false})` restores every\n * warning, including the declaration-only cycles.\n * @defaultValue undefined — only the built-in declaration-only cycle suppression applies\n */\n suppressWarnings?: UserConfig['suppressWarnings']\n}\n\n/**\n * With `reactCompiler.reactServer` the config resolves to two tsdown configs: the compiled\n * `default` variant and the uncompiled `react-server` variant.\n * @public\n */\nexport function defineConfig(\n options: PackageOptions & {reactCompiler: ReactCompilerOptions & {reactServer: true}},\n): Promise<UserConfig[]>\n/**\n * Without `reactCompiler.reactServer` the config resolves to a single tsdown config.\n * @public\n */\nexport function defineConfig(\n options: PackageOptions & {reactCompiler: ReactCompilerOptions & {reactServer?: false}},\n): Promise<UserConfig>\n/**\n * When TypeScript can't tell whether `reactCompiler.reactServer` is set (a widened `boolean`,\n * e.g. through a `ReactCompilerOptions`-typed variable), the config resolves to either shape —\n * check `Array.isArray` on the result.\n * @public\n */\nexport function defineConfig(\n options: PackageOptions & {reactCompiler: ReactCompilerOptions},\n): Promise<UserConfig | UserConfig[]>\n/**\n * @public\n */\nexport function defineConfig(options?: PackageOptions): Promise<UserConfig>\n/**\n * @public\n */\nexport async function defineConfig(\n options: PackageOptions = {},\n): Promise<UserConfig | UserConfig[]> {\n const reactCompiler = options.reactCompiler ?? false\n // `reactCompiler.reactServer` opts into the dual React Server Components build: the same\n // config twice, where the only difference is that React Compiler auto-memoization is applied\n // to the non-`react-server` variant. Both variants build in one `tsdown` run — tsdown builds\n // the configs in parallel, cleans the shared `outDir` once before either variant emits, and\n // runs `exports` generation and `publint` per `package.json` only after every build for that\n // package has finished (so the `react-server` files exist by the time they're validated).\n if (typeof reactCompiler === 'object' && reactCompiler.reactServer === true) {\n return Promise.all([\n resolvePackageConfig(options, 'default'),\n resolvePackageConfig(options, 'react-server'),\n ])\n }\n return resolvePackageConfig(options, 'standalone')\n}\n\n/**\n * The build variants {@link defineConfig} produces: the classic single build\n * (`'standalone'`), or — with `reactCompiler.reactServer` — the compiled `'default'` variant\n * and the uncompiled `'react-server'` variant of the dual React Server Components build.\n */\ntype PackageConfigVariant = 'standalone' | 'default' | 'react-server'\n\nasync function resolvePackageConfig(\n options: PackageOptions,\n variant: PackageConfigVariant,\n): Promise<UserConfig> {\n // `tsconfig`, `entry`, `dts`, `define`, `target`, `outDir`, `clean`, `css` and `cwd` are\n // passed through to tsdown as-is. When left undefined, tsdown keeps its default behavior\n // (`tsconfig` is auto-detected from the project, `dts` from `package.json`, `define`\n // replaces nothing, `target` applies no syntax downleveling, `outDir` defaults to `'dist'`,\n // `clean` defaults to `true` — cleaning `outDir` before each build — `css` stays off\n // unless `@tsdown/css` is installed and the option is set, and `cwd` defaults to\n // `process.cwd()`).\n const {entry, tsconfig, define, target, outDir, cwd} = options\n const isReactServer = variant === 'react-server'\n // The `react-server` variant skips d.ts generation (the compiled variant's declarations\n // serve both entries — a `types` condition specified before `react-server` points every\n // resolution mode at them), never cleans (tsdown collects the clean paths of all configs\n // and cleans once, before either variant emits, so the compiled variant's `clean` already\n // covers the run), and skips `publint` (it runs once, from the compiled variant, after\n // both builds finish).\n const dts = isReactServer ? false : options.dts\n const clean = isReactServer ? false : options.clean\n const publint = !isReactServer\n const platform = options.platform ?? 'neutral'\n const sourcemap = options.sourcemap ?? true\n // The React Compiler is what the `react-server` variant exists to avoid: compiled output\n // loads `react/compiler-runtime`, which throws in the `react-server` environment.\n const reactCompiler = isReactServer ? false : (options.reactCompiler ?? false)\n const styledComponents = options.styledComponents ?? false\n // The `react-server` variant skips TSDoc checking (it emits no `.d.ts` files — the compiled\n // variant's declarations serve both entries), matching how it skips `publint`.\n const tsdoc = isReactServer ? false : (options.tsdoc ?? false)\n const report = {gzip: false} as const satisfies UserConfig['report']\n const format = options.format ?? 'esm'\n // When `platform` is `'neutral'`, restore the conventional `module`/`main` fallback that\n // rolldown's strict neutral defaults drop - needed for inlined deps without an `exports` map.\n const inputOptions = {\n // https://github.com/rolldown/rolldown/blob/main/packages/rolldown/src/options/docs/preserve-entry-signatures.md#strict\n preserveEntrySignatures: 'strict',\n experimental: {attachDebugInfo: 'none'},\n ...(platform === 'neutral' && {\n resolve: {mainFields: ['module', 'main']},\n }),\n ...(styledComponents !== false && {\n transform: {\n plugins: {\n styledComponents: {\n // The same defaults as `babel: {styledComponents: true}` in `@sanity/pkg-utils`:\n // `fileName` is unnecessary, as the way we use styled-components in Sanity is usually by wrapping\n // `@sanity/ui` primitives, not declaring new ones like \"const Button = styled.button``\"\n fileName: false,\n // Native template literals take less space than this transpilation, and unlike\n // `babel-plugin-styled-components`, oxc doesn't add a `@__PURE__` annotation to the\n // transpiled call expression either, so enabling it wouldn't improve tree-shaking\n transpileTemplateLiterals: false,\n // Helps dead code elimination and tree-shaking, although oxc only annotates plain call\n // expressions so far, not tagged template expressions (https://github.com/rollup/rollup/issues/4035)\n pure: true,\n // Disabled, as tsdown tends to be used for npm publishing, while other tooling,\n // like `sanity dev`, `next dev`, etc are used for testing\n cssProp: false,\n ...(typeof styledComponents === 'object' ? styledComponents : {}),\n },\n },\n },\n }),\n } satisfies UserConfig['inputOptions']\n\n // `neverBundle` is concatenated (not `mergeConfig`'d) so per-package externals add to the\n // `/^node:/` default for `platform: 'neutral'` instead of replacing it. Rolldown's\n // `ExternalOption` array form is `Array<string | RegExp>` only; a function override is composed.\n const userNeverBundle = options.deps?.neverBundle\n const nodeBuiltinExternal = platform === 'neutral' ? /^node:/ : undefined\n const neverBundle: NonNullable<UserConfig['deps']>['neverBundle'] =\n userNeverBundle == null\n ? nodeBuiltinExternal && [nodeBuiltinExternal]\n : nodeBuiltinExternal == null || userNeverBundle === true\n ? userNeverBundle\n : typeof userNeverBundle === 'function'\n ? (id, importer, isResolved) =>\n nodeBuiltinExternal.test(id) || userNeverBundle(id, importer, isResolved)\n : Array.isArray(userNeverBundle)\n ? [nodeBuiltinExternal, ...userNeverBundle]\n : [nodeBuiltinExternal, userNeverBundle]\n const deps: UserConfig['deps'] =\n options.deps === undefined && neverBundle === undefined\n ? undefined\n : {\n ...options.deps,\n ...(neverBundle === undefined ? {} : {neverBundle}),\n }\n\n // `outputOptions` is left to tsdown's defaults - notably chunk filenames keep tsdown's hashed\n // default (unless userland sets `hash`), which prevents chunk/entry filename collisions\n // (https://github.com/sanity-io/ui/issues/2262).\n const plugins: Rolldown.Plugin[] = []\n if (reactCompiler !== false) {\n // Follows the official tsdown recipe for the React Compiler:\n // https://tsdown.dev/recipes/react-support#enabling-react-compiler\n // The plugins are lazy loaded so they're only paid for when the React Compiler is enabled.\n // `babel-plugin-react-compiler` itself is resolved by Babel from the consumer package during\n // the build, which is why it can be an optional peer dependency. Once rolldown ships its rust\n // port of the React Compiler this can be swapped out for an oxc transform, like `styledComponents`.\n const [{default: pluginBabel}, {reactCompilerPreset}] = await Promise.all([\n import('@rolldown/plugin-babel'),\n import('@vitejs/plugin-react'),\n ])\n // `reactServer` belongs to this config, not the compiler — drop it before handing the\n // options over to the babel preset.\n const {reactServer: _reactServer, ...reactCompilerOptions} =\n typeof reactCompiler === 'object' ? reactCompiler : {}\n plugins.push(\n await pluginBabel({\n presets: [reactCompilerPreset(reactCompilerOptions)],\n }),\n )\n }\n if (options.vanillaExtract) {\n // Lazy loaded, like `reactCompiler`, so the CSS toolchain is only paid for when the option is\n // enabled. The plugin compiles the `.css.ts` files and extracts the CSS into a single file.\n // Its `inject`/`exports` options are general purpose (and, like `css.inject` in\n // `@tsdown/css`, disabled by default), so this config supplies the default most Sanity\n // libraries want: `exports: {nodeCompat: true}` wires up the whole conditional CSS export\n // pattern - the self-referential CSS import, the no-op JS shim, and the conditional\n // `./<fileName>` export written through this config's `exports` option (which the plugin's\n // `tsdownConfig` hook composes into).\n const [{vanillaExtractPlugin}, {resolveCssLoweringTargets}] = await Promise.all([\n import('@sanity/vanilla-extract-tsdown-plugin'),\n import('./cssLoweringTargets.ts'),\n ])\n const vanillaExtract = options.vanillaExtract === true ? {} : options.vanillaExtract\n\n const lightningcss = await resolveCssLoweringTargets({\n cssTarget: vanillaExtract.target,\n target,\n lightningcss: vanillaExtract.lightningcss,\n })\n\n plugins.push(\n vanillaExtractPlugin({\n inject: true,\n exports: {nodeCompat: true},\n minify: true,\n ...vanillaExtract,\n lightningcss,\n }),\n )\n }\n\n // `@tsdown/css` compiles CSS but has no node-shim concept, so the `exports` option (and the\n // plugin implementing it) lives here. Its `exports` key is not a `@tsdown/css` option, so it\n // is stripped before the rest is handed to tsdown.\n let css: UserConfig['css']\n if (options.css) {\n const {exports: cssExports, ...cssOptions} = options.css\n const {resolveCssLoweringTargets} = await import('./cssLoweringTargets.ts')\n const lightningcss = await resolveCssLoweringTargets({\n cssTarget: cssOptions.target,\n target,\n lightningcss: cssOptions.lightningcss,\n })\n css = {minify: true, ...cssOptions, lightningcss}\n\n const {cssNodeCompatPlugin} = await import('./cssNodeCompatPlugin.ts')\n plugins.push(\n cssNodeCompatPlugin({\n fileName: css.fileName,\n splitting: css.splitting,\n // `@tsdown/css`'s own `inject` emits a relative import, which throws in runtimes that\n // cannot load `.css` files; the plugin below injects the self-referential specifier of\n // the conditional CSS export instead.\n inject: css.inject ?? true,\n exports: cssExports ?? {nodeCompat: true},\n }),\n )\n css = {...css, inject: false}\n }\n\n // The `react-server` variant does not participate in `exports` generation: its files are\n // wired in through the compiled variant's `react-server` conditions instead of becoming\n // export subpaths of their own.\n let exports: UserConfig['exports'] = false\n if (!isReactServer) {\n const userExports = options.exports\n // Package-manager detection exists solely to decide the pnpm-gated `devExports: true`\n // default, so it only runs when that default can still apply. `false`, `true`, and bare\n // CI-condition strings replace the defaults entirely (mergeConfig semantics), and an\n // explicit `devExports` value overrides it — those configs skip the filesystem probing\n // and behave identically across package managers. Programmatic hosts composing this\n // config (e.g. `@sanity/pkg-utils` passing `{devExports: 'source'}`) never trigger it.\n const devExportsDefaultApplies =\n userExports === undefined ||\n (typeof userExports === 'object' && userExports.devExports === undefined)\n const packageManager = devExportsDefaultApplies\n ? await detect({cwd: cwd ?? process.cwd()})\n : undefined\n // tsdown's `exports` feature is enabled with Sanity-flavored defaults, and userland values\n // apply with tsdown's own `mergeConfig` semantics: an object deep-merges over the defaults,\n // anything else (`false`, a CI condition) replaces them.\n ;({exports} = mergeConfig(\n {\n exports: {\n // Always on: `'local-only'`/`'ci-only'` surprise environments that set `CI=true`\n // (Cursor Cloud, etc.) without intending to skip package.json rewrites. Keep the\n // object shape so mergeConfig never swaps between a scalar `true` and `{devExports}`.\n enabled: true,\n // Only opt in by default when pnpm is detected: support for replacing package fields\n // from `publishConfig` is not reliable across package managers.\n ...(packageManager?.name === 'pnpm' && {devExports: true}),\n },\n },\n {exports: userExports},\n ))\n if (variant === 'default' && exports) {\n // The compiled variant owns `exports` generation for the dual build, so the\n // `react-server` conditions are composed into its `customExports`: every entry export\n // gains a `react-server` condition pointing at the `.react-server.` sibling that the\n // `react-server` variant emits.\n exports = withReactServerExports(exports)\n }\n }\n\n return defineTsdownConfig({\n // Rolldown defaults `circularDependency` to `false`; enable it so Sanity library builds\n // surface import cycles (bigger bundles / execution-order hazards) as warnings. The\n // declaration bundling pass gets the same check, where cycles are type-only and harmless,\n // so `suppressWarnings` filters those out below.\n // Override via `mergeConfig(..., {checks: {circularDependency: false}})`.\n // https://rolldown.rs/reference/InputOptions.checks#circulardependency\n checks: {circularDependency: true},\n // Drops the `CIRCULAR_DEPENDENCY` warnings of the declaration bundling pass (userland\n // patterns are OR'd in, never replacing the built-in filter).\n suppressWarnings: resolveSuppressWarnings(options.suppressWarnings),\n clean,\n css,\n cwd,\n define,\n deps,\n dts,\n entry,\n exports,\n format,\n // When `tsdoc` is enabled, run API Extractor against the entry `.d.ts` files after the\n // build. The function form of `hooks` registers via hookable so a later `mergeConfig` that\n // also uses the function form can compose — an object-form `hooks: {'build:done': …}`\n // override still replaces this (tsdown's `mergeConfig` replaces functions).\n ...(tsdoc !== false\n ? {\n hooks: createTsdocHooks({\n tsdoc: tsdoc === true ? {} : tsdoc,\n tsconfig,\n outDir,\n deps,\n }),\n }\n : {}),\n inputOptions,\n outDir,\n // The `react-server` variant writes its files next to the compiled ones, with `.react-server`\n // inserted before tsdown's default extension (`index.js` ↔ `index.react-server.js`). Hashed\n // chunk filenames get the suffix too, so the two variants' chunks never collide in the\n // shared `outDir`.\n outExtensions: isReactServer ? reactServerOutExtensions : undefined,\n platform,\n plugins,\n publint,\n report,\n sourcemap,\n target,\n tsconfig,\n // Compress the output (constant folding, dead code elimination) without mangling\n // identifiers or stripping whitespace: consumers' production builds minify `node_modules`\n // again anyway, so full minification here would only hurt debuggability, not final app\n // bundle sizes. `keepNames` preserves the function and class names the compress pass\n // would otherwise strip as unreferenced - e.g. the inner name in\n // `forwardRef(function Button(…) {…})`, which React DevTools reads via `Function.name`.\n // That name is the tree-shakeable alternative to a top-level `Button.displayName = '…'`\n // assignment (a side effect that pins unused components into consumer bundles, see\n // https://github.com/sanity-io/ui/pull/2435), and names stripped at publish time are\n // unrecoverable in userland.\n minify: {\n compress: {keepNames: {function: true, class: true}},\n codegen: false,\n mangle: false,\n },\n })\n}\n\n/**\n * Matches the declaration file extensions tsdown emits next to `es`/`cjs` chunks — the same\n * extensions `rolldown-plugin-dts` gives the modules of the declaration bundling pass.\n */\nconst RE_DTS_FILE = /\\.d\\.(ts|mts|cts)$/\n\n/** Strips the SGR color codes rolldown formats warning messages with. */\n// oxlint-disable-next-line eslint/no-control-regex -- matching the ESC of a CSI sequence\nconst RE_ANSI_COLOR = /\\u001B\\[\\d*(?:;\\d+)*m/g\n\n/** The `CircularDependency` diagnostic of rolldown, ahead of the cycle's ` -> `-joined modules. */\nconst CIRCULAR_DEPENDENCY_PREFIX = 'Circular dependency: '\n\n/**\n * Whether a warning is a `CIRCULAR_DEPENDENCY` warning whose entire cycle consists of\n * declaration files, e.g.\n * `Circular dependency: src/exports/index.d.ts -> src/exports/nodes.d.ts -> src/exports/index.d.ts.`\n *\n * Those come from the declaration bundling pass: every import between `.d.ts` modules is\n * type-only and erased at runtime, so the cycle has none of the consequences the check exists\n * to catch (execution-order hazards, bigger bundles), and it's unavoidable for mutually\n * referencing public types — see https://github.com/sanity-io/sanity/pull/13753, where 109 of\n * 136 cycle warnings were declaration-only. A cycle that includes even one runtime module is\n * left alone.\n */\nfunction isDtsCircularDependencyWarning(message: string): boolean {\n // The message arrives pre-formatted, with a color-coded `[CIRCULAR_DEPENDENCY] ` code prefix\n // and a trailing newline\n const plain = message.replace(RE_ANSI_COLOR, '').trim()\n const cycleStart = plain.indexOf(CIRCULAR_DEPENDENCY_PREFIX)\n if (cycleStart === -1) return false\n const modules = plain\n .slice(cycleStart + CIRCULAR_DEPENDENCY_PREFIX.length)\n // The trailing period of the diagnostic, never part of a `.d.ts` extension\n .replace(/\\.$/, '')\n .split(' -> ')\n return modules.length > 1 && modules.every((module) => RE_DTS_FILE.test(module))\n}\n\n/**\n * Composes the userland `suppressWarnings` value with {@link isDtsCircularDependencyWarning}:\n * the two are OR'd, so adding a per-package suppression never drops the declaration-only\n * cycle filter that pairs with this config's `checks.circularDependency` default.\n *\n * The string/`RegExp` matching mirrors tsdown's own — `includes` and `test`, against the\n * message exactly as tsdown would see it, so a pattern behaves the same whether it goes\n * through this option or straight into tsdown's `suppressWarnings`. `lastIndex` is reset for\n * `/g` and `/y` patterns, which carry it between `test` calls and would otherwise skip\n * messages (a no-op for other patterns, whose `lastIndex` `test` ignores).\n */\nfunction resolveSuppressWarnings(\n suppressWarnings: UserConfig['suppressWarnings'],\n): (message: string) => boolean {\n if (suppressWarnings === undefined) return isDtsCircularDependencyWarning\n const matchesUserPattern =\n typeof suppressWarnings === 'function'\n ? suppressWarnings\n : (message: string): boolean =>\n (Array.isArray(suppressWarnings) ? suppressWarnings : [suppressWarnings]).some(\n (pattern) => {\n if (typeof pattern === 'string') return message.includes(pattern)\n if (pattern.global || pattern.sticky) pattern.lastIndex = 0\n return pattern.test(message)\n },\n )\n return (message) => isDtsCircularDependencyWarning(message) || matchesUserPattern(message)\n}\n\n/**\n * Registers the `build:done` hook that runs `checkTsdoc` against every entry `.d.ts` file\n * the build emitted. The checker is loaded from `./tsdoc` only when the hook runs, so\n * importing `defineConfig` never pulls in API Extractor.\n */\nfunction createTsdocHooks(options: {\n tsdoc: PackageTsdocOptions\n tsconfig: UserConfig['tsconfig']\n outDir: UserConfig['outDir']\n deps: UserConfig['deps']\n}): NonNullable<UserConfig['hooks']> {\n const {tsdoc, outDir, deps} = options\n // `tsconfig: false` means \"don't use a tsconfig\"; fall back to the conventional name so\n // API Extractor still has a project root. A string path is forwarded as-is.\n const tsconfigPath = typeof options.tsconfig === 'string' ? options.tsconfig : 'tsconfig.json'\n const bundledPackages =\n tsdoc.bundledPackages ??\n (Array.isArray(deps?.alwaysBundle)\n ? deps.alwaysBundle.filter((entry): entry is string => typeof entry === 'string')\n : typeof deps?.alwaysBundle === 'string'\n ? [deps.alwaysBundle]\n : undefined)\n\n return (hooks) => {\n hooks.hook('build:done', async ({chunks, options: resolved}) => {\n const entryDtsFiles = entryDtsFilesFromChunks(chunks)\n if (entryDtsFiles.length === 0) return\n\n // Lazy-load the `/tsdoc` entry so `@microsoft/api-extractor` and friends stay out of\n // the root module graph until a build with `tsdoc` enabled actually finishes.\n const {checkTsdoc} = await import('./tsdoc/index.ts')\n await checkTsdoc({\n cwd: resolved.cwd,\n entryDtsFiles,\n tsconfig: tsconfigPath,\n outDir: outDir ?? resolved.outDir,\n bundledPackages,\n customTags: tsdoc.customTags,\n rules: tsdoc.rules,\n logger: {\n log: (...args) => {\n resolved.logger.info(...args.map(String))\n },\n warn: (...args) => {\n resolved.logger.warn(...args.map(String))\n },\n error: (...args) => {\n resolved.logger.error(...args.map(String))\n },\n },\n })\n })\n }\n}\n\n/** Absolute paths of entry declaration chunks emitted by the build. */\nfunction entryDtsFilesFromChunks(chunks: RolldownChunk[]): string[] {\n const files: string[] = []\n for (const chunk of chunks) {\n if (chunk.type !== 'chunk' || !chunk.isEntry || !RE_DTS_FILE.test(chunk.fileName)) continue\n files.push(path.resolve(chunk.outDir, chunk.fileName))\n }\n return files\n}\n\n/**\n * The `outExtensions` of the `react-server` variant: tsdown's default extension for the\n * format and package type (see `resolveJsOutputExtension` in tsdown), with `.react-server` inserted\n * so the variant's entries sit next to the compiled ones (`index.js` ↔ `index.react-server.js`,\n * `index.cjs` ↔ `index.react-server.cjs`, and `.mjs` accordingly for CommonJS packages).\n */\nconst reactServerOutExtensions: NonNullable<UserConfig['outExtensions']> = ({format, pkgType}) => ({\n js:\n format === 'cjs'\n ? pkgType === 'module'\n ? '.react-server.cjs'\n : '.react-server.js'\n : pkgType === 'module'\n ? '.react-server.js'\n : '.react-server.mjs',\n})\n\ntype ExportsOptions = Extract<NonNullable<UserConfig['exports']>, object>\ntype CustomExportsFunction = Extract<\n NonNullable<ExportsOptions['customExports']>,\n (...args: never[]) => unknown\n>\ntype ExportsMap = Parameters<CustomExportsFunction>[0]\n/**\n * Wires the `react-server` conditions into tsdown's `exports` feature by composing into\n * `exports.customExports` (the same composition `@sanity/vanilla-extract-tsdown-plugin` uses\n * for its conditional CSS export): a pre-existing `customExports` applies first — both its\n * function and record forms, mirroring how tsdown itself applies them — and the\n * `react-server` conditions are inserted into the result. The composed function runs for both\n * the local `exports` map and `publishConfig.exports`; with `devExports` the local map points\n * at source files, which the entry-file matching leaves untouched (source resolves for every\n * condition in development, which is correct — uncompiled source is exactly what the\n * `react-server` condition ships).\n */\nfunction withReactServerExports(\n exportsOption: Exclude<NonNullable<UserConfig['exports']>, false>,\n): ExportsOptions {\n // Normalize the `boolean | CIOption | object` forms of the `exports` option into the\n // object form, preserving the enabled-ness (`true` and bare CI conditions mean enabled)\n const exportsOptions: ExportsOptions =\n exportsOption === true\n ? {}\n : typeof exportsOption === 'string'\n ? {enabled: exportsOption}\n : exportsOption\n const previousCustomExports = exportsOptions.customExports\n exportsOptions.customExports = async (exportsMap, context) => {\n // Apply a pre-existing `customExports` first (both its function and record forms,\n // mirroring how tsdown itself applies them), then insert the `react-server` conditions\n const base =\n typeof previousCustomExports === 'function'\n ? await previousCustomExports(exportsMap, context)\n : previousCustomExports\n ? {...exportsMap, ...previousCustomExports}\n : exportsMap\n return addReactServerConditions(base, context)\n }\n return exportsOptions\n}\n\n/** Matches the JS output extensions tsdown emits for `es`/`cjs` chunks. */\nconst RE_JS_FILE = /\\.(m?js|cjs)$/\n\n/** The conditions tsdown generates that resolve at runtime, in contrast to `types` etc. */\nconst RUNTIME_CONDITIONS = new Set(['import', 'require', 'default'])\n\n/**\n * Inserts a `react-server` condition into every entry export of an `exports`-shaped map,\n * pointing at the `.react-server.` sibling emitted by the `react-server` variant — e.g.\n * `\"./dist/index.js\"` becomes\n * `{\"types\": \"./dist/index.d.ts\", \"react-server\": \"./dist/index.react-server.js\", \"default\": \"./dist/index.js\"}`.\n *\n * The `react-server` variant emits no `.d.ts` siblings, so TypeScript's adjacent-file lookup\n * cannot resolve types for `./dist/index.react-server.js` — a `types` condition pointing at\n * the compiled variant's declarations is specified before `react-server` instead (conditions\n * match in order, so it covers every resolution mode). It's only added when the declarations\n * actually exist among the compiled variant's chunks, and an already-present `types`\n * condition is left in place.\n *\n * Entries are recognized by comparing export targets against the compiled variant's entry\n * chunks — reconstructed in the exact `./<outDir relative to the package root>/<fileName>`\n * form tsdown writes into the exports map, so entries that share a leaf name (`index.js` vs\n * `features/index.js`) can never shadow each other, and non-entry exports (`./package.json`,\n * the conditional `./bundle.css` export of `vanillaExtract`, `devExports` source paths like\n * `./src/index.ts`) pass through untouched. The `react-server` files themselves never enter\n * the map — the `react-server` variant builds with `exports: false` — so they don't become\n * export subpaths of their own.\n */\nfunction addReactServerConditions(\n exportsMap: ExportsMap,\n context: Parameters<CustomExportsFunction>[1],\n): ExportsMap {\n // tsdown always resolves the package with its path here: its own exports generation reads\n // `packageJsonPath` unconditionally from the same object it passes to `customExports` -\n // only the declared context type is the plain `PackageJson` shape.\n const pkg: Partial<PackageJsonWithPath> = context.pkg\n const pkgRoot = path.dirname(pkg.packageJsonPath ?? 'package.json')\n // Export targets of the compiled variant's entry JS and declaration chunks; the\n // `react-server` variant's files sit next to the entries with `.react-server` inserted\n // before the extension\n const entryFiles = new Set<string>()\n const dtsFiles = new Set<string>()\n for (const [format, formatChunks] of Object.entries(context.chunks)) {\n // Only `es` and `cjs` chunks become package exports (mirroring tsdown's own generation)\n if (format !== 'es' && format !== 'cjs') continue\n for (const chunk of formatChunks) {\n if (chunk.type !== 'chunk') continue\n const target = exportTarget(pkgRoot, chunk.outDir, chunk.fileName)\n if (chunk.isEntry && RE_JS_FILE.test(chunk.fileName)) {\n entryFiles.add(target)\n } else if (RE_DTS_FILE.test(chunk.fileName)) {\n dtsFiles.add(target)\n }\n }\n }\n const isEntryFile = (value: unknown): value is string =>\n typeof value === 'string' && entryFiles.has(value)\n // The `types` file for an entry export target, when the compiled variant emitted it\n const dtsFor = (value: string): string | undefined => {\n const dtsFile = toDtsFile(value)\n return dtsFiles.has(dtsFile) ? dtsFile : undefined\n }\n\n const result: ExportsMap = {}\n for (const [key, value] of Object.entries(exportsMap as Record<string, unknown>)) {\n result[key] = withReactServerCondition(value, isEntryFile, dtsFor)\n }\n return result\n}\n\n/**\n * Mirrors tsdown's own `join` for exports targets:\n * `./<outDir relative to the package root>/<fileName>`, with POSIX separators.\n */\nfunction exportTarget(pkgRoot: string, outDir: string, fileName: string): string {\n const outDirRelative = path.relative(pkgRoot, outDir).replaceAll('\\\\', '/')\n return `${outDirRelative ? `./${outDirRelative}` : '.'}/${fileName.replaceAll('\\\\', '/')}`\n}\n\nfunction withReactServerCondition(\n value: unknown,\n isEntryFile: (value: unknown) => value is string,\n dtsFor: (value: string) => string | undefined,\n): unknown {\n // A bare-string entry export (e.g. the pure-ESM publish shape `\".\": \"./dist/index.js\"`)\n // becomes a conditional export, with `types` specified before `react-server` so type\n // resolution never reaches the declaration-less `.react-server.` file\n if (isEntryFile(value)) {\n const types = dtsFor(value)\n return {\n ...(types === undefined ? {} : {types}),\n 'react-server': toServerFile(value),\n 'default': value,\n }\n }\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return value\n const conditions = Object.entries(value)\n const matched = conditions.filter(\n (entry): entry is [string, string] => RUNTIME_CONDITIONS.has(entry[0]) && isEntryFile(entry[1]),\n )\n const [firstMatch] = matched\n if (!firstMatch) return value\n const hasTypes = conditions.some(([condition]) => condition === 'types')\n // A single runtime file maps to a plain path (with a `types` condition inserted ahead of\n // `react-server` below, unless one is already specified). A dual-format entry nests its\n // `import` and `require` files under the `react-server` condition, each with its own\n // format-matched `types` — a single top-level `types` file cannot serve both resolution\n // modes, which is also why tsdown's own dual-format output relies on adjacent-file lookup.\n const missingTypes = hasTypes ? undefined : dtsFor(firstMatch[1])\n const serverTarget =\n matched.length === 1\n ? toServerFile(firstMatch[1])\n : Object.fromEntries(\n matched.map(([condition, target]) => {\n const types = hasTypes ? undefined : dtsFor(target)\n return [\n condition,\n types === undefined ? toServerFile(target) : {types, default: toServerFile(target)},\n ]\n }),\n )\n // Conditions match in order, so `react-server` is inserted right before the first runtime\n // condition (`import`/`require`/`default`), keeping `types` and custom development\n // conditions (`devExports`) ahead of it\n const next: Record<string, unknown> = {}\n let inserted = false\n for (const [condition, target] of conditions) {\n if (!inserted && RUNTIME_CONDITIONS.has(condition)) {\n if (matched.length === 1 && missingTypes !== undefined) {\n next['types'] = missingTypes\n }\n next['react-server'] = serverTarget\n inserted = true\n }\n next[condition] = target\n }\n if (!inserted) {\n next['react-server'] = serverTarget\n }\n return next\n}\n\n/** `./dist/index.js` → `./dist/index.react-server.js` (and `.mjs`/`.cjs` accordingly). */\nfunction toServerFile(file: string): string {\n return file.replace(RE_JS_FILE, '.react-server.$1')\n}\n\n/** `./dist/index.js` → `./dist/index.d.ts` (`.mjs` → `.d.mts`, `.cjs` → `.d.cts`). */\nfunction toDtsFile(file: string): string {\n return file.replace(RE_JS_FILE, (extension) =>\n extension === '.mjs' ? '.d.mts' : extension === '.cjs' ? '.d.cts' : '.d.ts',\n )\n}\n"],"mappings":"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"}
|
package/dist/tsdoc.d.mts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { n as PackageTsdocOptions, r as PackageTsdocRuleLevel, t as PackageTsdocCustomTag } from "./types-CrQ2my_P.mjs";
|
|
2
|
+
import { ExtractorMessage } from "@microsoft/api-extractor";
|
|
3
|
+
/** @public */
|
|
4
|
+
interface CheckTsdocLogger {
|
|
5
|
+
log: (...args: unknown[]) => void;
|
|
6
|
+
warn: (...args: unknown[]) => void;
|
|
7
|
+
error: (...args: unknown[]) => void;
|
|
8
|
+
}
|
|
9
|
+
/** @public */
|
|
10
|
+
interface CheckTsdocOptions extends PackageTsdocOptions {
|
|
11
|
+
/** Package root (directory containing `package.json`). */
|
|
12
|
+
cwd: string;
|
|
13
|
+
/**
|
|
14
|
+
* Absolute paths to the entry `.d.ts` / `.d.mts` / `.d.cts` files to check.
|
|
15
|
+
* JS-only entries with no declarations are skipped automatically when listed.
|
|
16
|
+
*/
|
|
17
|
+
entryDtsFiles: string[];
|
|
18
|
+
/**
|
|
19
|
+
* Path to the tsconfig used for the build, relative to `cwd` or absolute.
|
|
20
|
+
* @defaultValue `'tsconfig.json'`
|
|
21
|
+
*/
|
|
22
|
+
tsconfig?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Directory of distributed files (used for API Extractor's path mapping). Defaults to the
|
|
25
|
+
* common parent of `entryDtsFiles`, or `dist` under `cwd` when the list is empty.
|
|
26
|
+
*/
|
|
27
|
+
outDir?: string;
|
|
28
|
+
/**
|
|
29
|
+
* When provided, messages are printed through this logger. Errors throw after reporting so
|
|
30
|
+
* callers (and tsdown's `build:done` hook) fail the build.
|
|
31
|
+
*/
|
|
32
|
+
logger?: CheckTsdocLogger;
|
|
33
|
+
}
|
|
34
|
+
/** @public */
|
|
35
|
+
interface CheckTsdocResult {
|
|
36
|
+
messages: ExtractorMessage[];
|
|
37
|
+
errorCount: number;
|
|
38
|
+
warningCount: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Run `@microsoft/api-extractor` against the given entry declaration files to check that TSDoc
|
|
42
|
+
* tags are valid and release tags are correct. Import from `@sanity/tsdown-config/tsdoc`.
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
declare function checkTsdoc(options: CheckTsdocOptions): Promise<CheckTsdocResult>;
|
|
46
|
+
export { type CheckTsdocLogger, type CheckTsdocOptions, type CheckTsdocResult, type PackageTsdocCustomTag, type PackageTsdocOptions, type PackageTsdocRuleLevel, checkTsdoc };
|
|
47
|
+
//# sourceMappingURL=tsdoc.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsdoc.d.mts","names":[],"sources":["../src/tsdoc/checkTsdoc.ts"],"mappings":";;;UAkBiB;EACf,SAAS;EACT,UAAU;EACV,WAAW;;;UAII,0BAA0B;;EAEzC;;;;;EAKA;;;;;EAKA;;;;;EAKA;;;;;EAKA,SAAS;;;UAIM;EACf,UAAU;EACV;EACA;;;;;;;iBAQoB,WAAW,SAAS,oBAAoB,QAAQ"}
|