@sanity/tsdown-config 0.27.1 → 0.28.1
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 +1 -1
- package/dist/cssLoweringTargets-Dn_sJGip.mjs.map +1 -1
- package/dist/index.d.mts +14 -14
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/dist/tsdoc.d.mts +2 -2
- package/dist/tsdoc.d.mts.map +1 -1
- package/dist/tsdoc.mjs +1 -1
- package/dist/tsdoc.mjs.map +1 -1
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cssLoweringTargets-Dn_sJGip.mjs","names":[],"sources":["../src/cssLoweringTargets.ts"],"sourcesContent":["import {esbuildTargetToLightningCSS} from '@sanity/vanilla-extract-tsdown-plugin'\nimport type {Targets} from 'lightningcss'\n\n/** The `lightningcss` options both CSS pipelines accept, narrowed to what this helper touches. */\ninterface LightningCSSOptionsWithTargets {\n targets?: Targets | undefined\n}\n\n/**\n * Resolves the CSS syntax lowering targets for a CSS pipeline\n * (`vanillaExtract`/`css`), applying the Sanity-flavored fallback on top of the\n * `@tsdown/css` behavior both pipelines otherwise follow.\n *\n * `@tsdown/css` skips syntax lowering when it has no browser targets. Extracted CSS always runs\n * in browsers though, so when the effective target (the pipeline's own `target`, falling back to\n * the top-level `target`) is undefined or names no browsers - e.g. `'node20'`, which is also\n * what tsdown derives from `engines.node` and speaks to the JS runtime - the lowering targets\n * are resolved from `@sanity/browserslist-config` and passed through `lightningcss.targets`\n * instead.\n *\n * `target: false` stays the explicit off switch, and a user-provided `lightningcss.targets`\n * wins over the fallback.\n *\n * @internal\n */\nexport async function resolveCssLoweringTargets
|
|
1
|
+
{"version":3,"file":"cssLoweringTargets-Dn_sJGip.mjs","names":[],"sources":["../src/cssLoweringTargets.ts"],"sourcesContent":["import {esbuildTargetToLightningCSS} from '@sanity/vanilla-extract-tsdown-plugin'\nimport type {Targets} from 'lightningcss'\n\n/** The `lightningcss` options both CSS pipelines accept, narrowed to what this helper touches. */\ninterface LightningCSSOptionsWithTargets {\n targets?: Targets | undefined\n}\n\n/**\n * Resolves the CSS syntax lowering targets for a CSS pipeline\n * (`vanillaExtract`/`css`), applying the Sanity-flavored fallback on top of the\n * `@tsdown/css` behavior both pipelines otherwise follow.\n *\n * `@tsdown/css` skips syntax lowering when it has no browser targets. Extracted CSS always runs\n * in browsers though, so when the effective target (the pipeline's own `target`, falling back to\n * the top-level `target`) is undefined or names no browsers - e.g. `'node20'`, which is also\n * what tsdown derives from `engines.node` and speaks to the JS runtime - the lowering targets\n * are resolved from `@sanity/browserslist-config` and passed through `lightningcss.targets`\n * instead.\n *\n * `target: false` stays the explicit off switch, and a user-provided `lightningcss.targets`\n * wins over the fallback.\n *\n * @internal\n */\nexport async function resolveCssLoweringTargets(options: {\n /** The pipeline's own `target` option. */\n cssTarget: string | string[] | false | undefined\n /** tsdown's top-level `target`, the fallback for `cssTarget`. */\n target: string | string[] | false | undefined\n /** The pipeline's own `lightningcss` options. */\n lightningcss: LightningCSSOptionsWithTargets | undefined\n}): Promise<LightningCSSOptionsWithTargets | undefined> {\n const {target, lightningcss} = options\n const cssTarget = options.cssTarget ?? target\n\n if (\n cssTarget === false ||\n lightningcss?.targets ||\n (cssTarget !== undefined && esbuildTargetToLightningCSS(cssTarget))\n ) {\n return lightningcss\n }\n\n // Lazy loaded: `browserslistToTargets` is a pure helper, but `lightningcss` is a native\n // 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 return {\n ...lightningcss,\n targets: browserslistToTargets(browserslist(browserslistConfig)),\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyBA,eAAsB,0BAA0B,SAOQ;CACtD,IAAM,EAAC,QAAQ,iBAAgB,SACzB,YAAY,QAAQ,aAAa;CAEvC,IACE,cAAc,MACd,cAAc,WACb,cAAc,KAAA,KAAa,4BAA4B,SAAS,GAEjE,OAAO;CAKT,IAAM,CAAC,EAAC,SAAS,gBAAe,EAAC,SAAS,sBAAqB,EAAC,2BAC9D,MAAM,QAAQ,IAAI;EAChB,OAAO;EACP,OAAO;EACP,OAAO;CACT,CAAC;CACH,OAAO;EACL,GAAG;EACH,SAAS,sBAAsB,aAAa,kBAAkB,CAAC;CACjE;AACF"}
|
package/dist/index.d.mts
CHANGED
|
@@ -24,7 +24,7 @@ import { ReactCompilerOptions as ReactCompilerOptions$1 } from "oxc-transform-re
|
|
|
24
24
|
* `lightningcss.targets` wins over the fallback.
|
|
25
25
|
* @public
|
|
26
26
|
*/
|
|
27
|
-
type PackageVanillaExtractOptions = Options;
|
|
27
|
+
export type PackageVanillaExtractOptions = Options;
|
|
28
28
|
/**
|
|
29
29
|
* Options for the `css` option — tsdown's experimental
|
|
30
30
|
* [`css` options](https://tsdown.dev/options/css) from `@tsdown/css` (`splitting`, `fileName`,
|
|
@@ -47,7 +47,7 @@ type PackageVanillaExtractOptions = Options;
|
|
|
47
47
|
* `@sanity/browserslist-config` through `lightningcss.targets`.
|
|
48
48
|
* @public
|
|
49
49
|
*/
|
|
50
|
-
type PackageCssOptions = NonNullable<UserConfig["css"]> & {
|
|
50
|
+
export type PackageCssOptions = NonNullable<UserConfig["css"]> & {
|
|
51
51
|
/**
|
|
52
52
|
* Publish each emitted CSS file as an export subpath of the package, so consumers can
|
|
53
53
|
* `import "<pkg-name>/style.css"` — which is also the specifier `inject` then uses, instead
|
|
@@ -80,7 +80,7 @@ type PackageCssOptions = NonNullable<UserConfig["css"]> & {
|
|
|
80
80
|
* @public
|
|
81
81
|
* @alpha This option wraps Rolldown's experimental analyzer, whose API may change.
|
|
82
82
|
*/
|
|
83
|
-
interface PackageBundleAnalyzerOptions {
|
|
83
|
+
export interface PackageBundleAnalyzerOptions {
|
|
84
84
|
/**
|
|
85
85
|
* The filename used for the emitted analysis asset. The file is written into the same
|
|
86
86
|
* output directory as the rest of the bundle.
|
|
@@ -99,7 +99,7 @@ interface PackageBundleAnalyzerOptions {
|
|
|
99
99
|
* Options for the `styled-components` transform, the same options as `babel-plugin-styled-components`.
|
|
100
100
|
* @public
|
|
101
101
|
*/
|
|
102
|
-
interface StyledComponentsOptions {
|
|
102
|
+
export interface StyledComponentsOptions {
|
|
103
103
|
/** @defaultValue true */
|
|
104
104
|
displayName?: boolean;
|
|
105
105
|
/**
|
|
@@ -126,7 +126,7 @@ interface StyledComponentsOptions {
|
|
|
126
126
|
* forwarded to the compiler itself.
|
|
127
127
|
* @public
|
|
128
128
|
*/
|
|
129
|
-
interface ReactCompilerConfigOptions {
|
|
129
|
+
export interface ReactCompilerConfigOptions {
|
|
130
130
|
/**
|
|
131
131
|
* Also emit an uncompiled build of every entry (`<name>.react-server.js` next to `<name>.js`),
|
|
132
132
|
* wired to the `react-server` export condition in `package.json`:
|
|
@@ -163,7 +163,7 @@ interface ReactCompilerConfigOptions {
|
|
|
163
163
|
* Install it together with `@rolldown/plugin-babel` and `@babel/core`.
|
|
164
164
|
* @public
|
|
165
165
|
*/
|
|
166
|
-
interface ReactCompilerBabelOptions extends Partial<PluginOptions>, ReactCompilerConfigOptions {
|
|
166
|
+
export interface ReactCompilerBabelOptions extends Partial<PluginOptions>, ReactCompilerConfigOptions {
|
|
167
167
|
/**
|
|
168
168
|
* The reference implementation — for what the Rust port lacks: custom `jsxImportSource`,
|
|
169
169
|
* `logger`, function-valued `sources`.
|
|
@@ -176,7 +176,7 @@ interface ReactCompilerBabelOptions extends Partial<PluginOptions>, ReactCompile
|
|
|
176
176
|
* plugin's (no `logger`, no function-valued `sources`), typed once the package is installed.
|
|
177
177
|
* @public
|
|
178
178
|
*/
|
|
179
|
-
interface ReactCompilerOxcOptions extends ReactCompilerOptions$1, ReactCompilerConfigOptions {
|
|
179
|
+
export interface ReactCompilerOxcOptions extends ReactCompilerOptions$1, ReactCompilerConfigOptions {
|
|
180
180
|
/**
|
|
181
181
|
* `oxc-transform-react`, the Rust port. Its one native pass also strips TypeScript and
|
|
182
182
|
* lowers JSX (automatic runtime, `react` import source) — opt into `'babel'` for a
|
|
@@ -191,11 +191,11 @@ interface ReactCompilerOxcOptions extends ReactCompilerOptions$1, ReactCompilerC
|
|
|
191
191
|
* handled by this config, never forwarded to the compiler.
|
|
192
192
|
* @public
|
|
193
193
|
*/
|
|
194
|
-
type ReactCompilerOptions = ReactCompilerBabelOptions | ReactCompilerOxcOptions;
|
|
194
|
+
export type ReactCompilerOptions = ReactCompilerBabelOptions | ReactCompilerOxcOptions;
|
|
195
195
|
/**
|
|
196
196
|
* @public
|
|
197
197
|
*/
|
|
198
|
-
interface PackageOptions extends Pick<UserConfig, "tsconfig" | "entry" | "format" | "dts" | "define" | "target" | "outDir"> {
|
|
198
|
+
export interface PackageOptions extends Pick<UserConfig, "tsconfig" | "entry" | "format" | "dts" | "define" | "target" | "outDir"> {
|
|
199
199
|
/**
|
|
200
200
|
* @defaultValue 'neutral'
|
|
201
201
|
*
|
|
@@ -394,7 +394,7 @@ interface PackageOptions extends Pick<UserConfig, "tsconfig" | "entry" | "format
|
|
|
394
394
|
* `default` variant and the uncompiled `react-server` variant.
|
|
395
395
|
* @public
|
|
396
396
|
*/
|
|
397
|
-
declare function defineConfig(options: PackageOptions & {
|
|
397
|
+
export declare function defineConfig(options: PackageOptions & {
|
|
398
398
|
reactCompiler: ReactCompilerOptions & {
|
|
399
399
|
reactServer: true;
|
|
400
400
|
};
|
|
@@ -403,7 +403,7 @@ declare function defineConfig(options: PackageOptions & {
|
|
|
403
403
|
* Without `reactCompiler.reactServer` the config resolves to a single tsdown config.
|
|
404
404
|
* @public
|
|
405
405
|
*/
|
|
406
|
-
declare function defineConfig(options: PackageOptions & {
|
|
406
|
+
export declare function defineConfig(options: PackageOptions & {
|
|
407
407
|
reactCompiler: ReactCompilerOptions & {
|
|
408
408
|
reactServer?: false;
|
|
409
409
|
};
|
|
@@ -414,12 +414,12 @@ declare function defineConfig(options: PackageOptions & {
|
|
|
414
414
|
* check `Array.isArray` on the result.
|
|
415
415
|
* @public
|
|
416
416
|
*/
|
|
417
|
-
declare function defineConfig(options: PackageOptions & {
|
|
417
|
+
export declare function defineConfig(options: PackageOptions & {
|
|
418
418
|
reactCompiler: ReactCompilerOptions;
|
|
419
419
|
}): Promise<UserConfig | UserConfig[]>;
|
|
420
420
|
/**
|
|
421
421
|
* @public
|
|
422
422
|
*/
|
|
423
|
-
declare function defineConfig(options?: PackageOptions): Promise<UserConfig>;
|
|
424
|
-
export {
|
|
423
|
+
export declare function defineConfig(options?: PackageOptions): Promise<UserConfig>;
|
|
424
|
+
export type { CssExportsOptions, PackageTsdocCustomTag, PackageTsdocOptions, PackageTsdocRuleLevel };
|
|
425
425
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;YAqDY,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;YAwB/B,oBAAoB,YAAY;;;;;;;;;;;;;;;EAe1C,oBAAoB;;;;;;;;;;;;;;;;;;iBAmBL;;;;;;;EAOf;;;;;;EAMA;;;;;;iBAOe;;EAEf;;;;;EAKA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;EACA;;EAEA;;;;;;;iBAQe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6Bf;;;;;;;;iBAgBe,kCACP,QAAQ,gBAAkC;;;;;EAKlD;;;;;;;;iBASe,gCACP,wBAAyB;;;;;;;EAOjC;;;;;;;;YASU,uBAAuB,4BAA4B;;;;iBAK9C,uBAAuB,KACtC;;;;;;;;;;;;;EAeA,WAAW;;;;;;;;;;;EAWX,MAAM;;;;;;;;;;;;;;;;;;;EAmBN,QAAQ;;;;;;;;;;;;;;;;;;;;;EAqBR,UAAU;;;;;;;EAOV,YAAY;;;;;;EAMZ,OAAO;;;;;;;;;;;;;;;;;;;EAmBP,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BN,2BAA2B;;;;;;;;;;;;;EAa3B,0BAA0B;;;;;;;;EAQ1B,6BAA6B;;;;;;;;;;;;;;;;;;;EAmB7B,2BAA2B;;;;;;;;EAQ3B,kBAAkB;;;;;;;;;;;;;;;;;;;;;EAqBlB,mBAAmB;;;;;;;wBAQL,aACd,SAAS;EAAkB,eAAe;IAAwB;;IACjE,QAAQ;;;;;wBAKK,aACd,SAAS;EAAkB,eAAe;IAAwB;;IACjE,QAAQ;;;;;;;wBAOK,aACd,SAAS;EAAkB,eAAe;IACzC,QAAQ,aAAa;;;;wBAIR,aAAa,UAAU,iBAAiB,QAAQ"}
|
package/dist/index.mjs
CHANGED
|
@@ -20,7 +20,8 @@ async function resolvePackageConfig(options, variant) {
|
|
|
20
20
|
cssProp: !1,
|
|
21
21
|
...typeof styledComponents == "object" ? styledComponents : {}
|
|
22
22
|
} } } }
|
|
23
|
-
}, userNeverBundle = options.deps?.neverBundle, nodeBuiltinExternal = platform === "neutral" ? /^node:/ : void 0, neverBundle = userNeverBundle == null ? nodeBuiltinExternal && [nodeBuiltinExternal] : nodeBuiltinExternal == null || userNeverBundle === !0 ? userNeverBundle : typeof userNeverBundle == "function" ? (id, importer, isResolved) => nodeBuiltinExternal.test(id) || userNeverBundle(id, importer, isResolved) : Array.isArray(userNeverBundle) ? [nodeBuiltinExternal, ...userNeverBundle] : [nodeBuiltinExternal, userNeverBundle], deps =
|
|
23
|
+
}, userNeverBundle = options.deps?.neverBundle, nodeBuiltinExternal = platform === "neutral" ? /^node:/ : void 0, neverBundle = userNeverBundle == null ? nodeBuiltinExternal && [nodeBuiltinExternal] : nodeBuiltinExternal == null || userNeverBundle === !0 ? userNeverBundle : typeof userNeverBundle == "function" ? (id, importer, isResolved) => nodeBuiltinExternal.test(id) || userNeverBundle(id, importer, isResolved) : Array.isArray(userNeverBundle) ? [nodeBuiltinExternal, ...userNeverBundle] : [nodeBuiltinExternal, userNeverBundle], deps = {
|
|
24
|
+
resolveDepSubpath: !0,
|
|
24
25
|
...options.deps,
|
|
25
26
|
...neverBundle === void 0 ? {} : { neverBundle }
|
|
26
27
|
}, plugins = [];
|
|
@@ -207,7 +208,7 @@ function createTsdocHooks(options) {
|
|
|
207
208
|
/** Absolute paths of entry declaration chunks emitted by the build. */
|
|
208
209
|
function entryDtsFilesFromChunks(chunks) {
|
|
209
210
|
let files = [];
|
|
210
|
-
for (let chunk of chunks) chunk.type
|
|
211
|
+
for (let chunk of chunks) chunk.type === "chunk" && chunk.isEntry && RE_DTS_FILE.test(chunk.fileName) && files.push(path.resolve(chunk.outDir, chunk.fileName));
|
|
211
212
|
return files;
|
|
212
213
|
}
|
|
213
214
|
/**
|
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 {\n CssExportsOptions,\n Options as VanillaExtractPluginOptions,\n} from '@sanity/vanilla-extract-tsdown-plugin'\nimport type {PluginOptions as BabelReactCompilerPluginOptions} from 'babel-plugin-react-compiler'\nimport type {ReactCompilerOptions as OxcReactCompilerOptions} from 'oxc-transform-react'\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 `bundleAnalyzer` option — the same options as Rolldown's experimental\n * [`bundleAnalyzerPlugin`](https://rolldown.rs/builtin-plugins/bundle-analyzer)\n * (`fileName`, `format`).\n *\n * When enabled with `true`, defaults to `{format: 'md'}` (an LLM-friendly markdown report)\n * rather than the plugin's own `'json'` default — that's the report Sanity library builds\n * want. Pass `{format: 'json'}` for the structured data file visualizers consume.\n *\n * The report is emitted into `outDir` (`analyze-data.md` by default) and is **not** a\n * publishable artifact. Exclude it from `package.json` `files` (e.g.\n * `\"!dist/analyze-data.md\"` / `\"!lib/analyze-data.md\"`) so an accidental analyze build\n * cannot ship it.\n * @public\n * @alpha This option wraps Rolldown's experimental analyzer, whose API may change.\n */\nexport interface PackageBundleAnalyzerOptions {\n /**\n * The filename used for the emitted analysis asset. The file is written into the same\n * output directory as the rest of the bundle.\n * @defaultValue `'analyze-data.md'` when `format` is `'md'`, `'analyze-data.json'` when\n * `format` is `'json'`\n */\n fileName?: string\n /**\n * `'md'` produces an LLM-friendly markdown report (Quick Summary, largest modules, entry\n * points, dependency chains); `'json'` produces structured data for visualizers.\n * @defaultValue `'md'`\n */\n format?: 'json' | 'md'\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 * The options of this config that both React Compiler implementations share — never\n * forwarded to the compiler itself.\n * @public\n */\nexport interface ReactCompilerConfigOptions {\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// `interface … extends` on purpose, not intersection aliases: an uninstalled peer's type\n// import degrades to `any` (skipLibCheck), and in an intersection that `any` would swallow\n// the whole `ReactCompilerOptions` union, making every config match the `reactServer: true`\n// overload of `defineConfig` (the bug sanity-io/ui had to stub around). Unresolvable\n// heritage clauses are dropped instead, leaving each interface's own members (`transform`,\n// `reactServer`), so the union keeps discriminating. See `test/optional-peer-types.test.ts`.\n\n/**\n * The `transform: 'babel'` shape: `babel-plugin-react-compiler` (an optional peer dependency)\n * runs the compiler, with its own `PluginOptions` — typed once the package is installed.\n * Install it together with `@rolldown/plugin-babel` and `@babel/core`.\n * @public\n */\nexport interface ReactCompilerBabelOptions\n extends Partial<BabelReactCompilerPluginOptions>, ReactCompilerConfigOptions {\n /**\n * The reference implementation — for what the Rust port lacks: custom `jsxImportSource`,\n * `logger`, function-valued `sources`.\n */\n transform: 'babel'\n}\n\n/**\n * The default `reactCompiler` shape: `oxc-transform-react` (an optional peer dependency) runs\n * the compiler, with its own `ReactCompilerOptions` — the serializable subset of the babel\n * plugin's (no `logger`, no function-valued `sources`), typed once the package is installed.\n * @public\n */\nexport interface ReactCompilerOxcOptions\n extends OxcReactCompilerOptions, ReactCompilerConfigOptions {\n /**\n * `oxc-transform-react`, the Rust port. Its one native pass also strips TypeScript and\n * lowers JSX (automatic runtime, `react` import source) — opt into `'babel'` for a\n * custom `jsxImportSource`.\n * @defaultValue 'oxc'\n */\n transform?: 'oxc'\n}\n\n/**\n * Options for the React Compiler: the compiler's own options, plus `transform` (which\n * implementation runs) and `reactServer` (the dual React Server Components build) — both\n * handled by this config, never forwarded to the compiler.\n * @public\n */\nexport type ReactCompilerOptions = ReactCompilerBabelOptions | ReactCompilerOxcOptions\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 * Enables Rolldown's experimental\n * [`bundleAnalyzerPlugin`](https://rolldown.rs/builtin-plugins/bundle-analyzer)\n * (`rolldown/experimental`) to emit a report of what the package itself bundles — chunks,\n * modules, dependency chains — next to the build output. Pass `true` to use the defaults,\n * or an object to customize.\n *\n * Unlike the plugin's own defaults (`format: 'json'`), `true` selects `format: 'md'`: an\n * LLM-friendly markdown report (`analyze-data.md` in `outDir`). Pass `{format: 'json'}`\n * for the structured data file visualizers consume. Analysis adds work to the build, so\n * this stays off by default — typical usage is an env-gated opt-in:\n *\n * ```ts\n * bundleAnalyzer: process.env.ENABLE_BUNDLE_ANALYZER === 'true'\n * ```\n *\n * The report is **not** a publishable artifact. Exclude it from `package.json` `files`\n * (e.g. `\"!dist/analyze-data.md\"` / `\"!lib/analyze-data.md\"`) so an accidental analyze\n * build cannot ship it.\n *\n * With {@link ReactCompilerOptions.reactServer | `reactCompiler.reactServer`}, only the\n * compiled (`default`) variant is analyzed — the `react-server` variant skips it so the\n * two builds don't overwrite one report.\n * @defaultValue false\n * @alpha This option wraps Rolldown's experimental analyzer, whose API may change.\n */\n bundleAnalyzer?: boolean | PackageBundleAnalyzerOptions\n /**\n * Runs the 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\n * object (e.g. `{target: '18'}`). This is the same feature as the\n * `reactCompiler` option in `@sanity/pkg-utils`.\n *\n * `transform` picks the implementation — `'oxc'` (default, requires `oxc-transform-react`)\n * or `'babel'` (requires `babel-plugin-react-compiler`, `@rolldown/plugin-babel` and\n * `@babel/core`), see {@link ReactCompilerBabelOptions} — and `reactServer` adds the\n * uncompiled `react-server` build, see {@link ReactCompilerConfigOptions.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 the analyzer so the two parallel builds don't race on\n // one `analyze-data.md` in the shared `outDir`. The compiled variant is the published\n // client bundle — that's the report worth reading.\n const bundleAnalyzer = isReactServer ? false : (options.bundleAnalyzer ?? 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 // Lazy loaded so the toolchain is only paid for when enabled. The compiler package itself\n // (`oxc-transform-react` / `babel-plugin-react-compiler`, per `transform`) resolves from\n // the consumer package — everything babel-flavored is an optional peer dependency.\n const reactCompilerOptions: ReactCompilerOptions = reactCompiler === true ? {} : reactCompiler\n if (reactCompilerOptions.transform === 'babel') {\n // The opt-in reference implementation follows the official tsdown recipe for the React\n // Compiler: https://tsdown.dev/recipes/react-support#enabling-react-compiler\n // The compiler leaves TypeScript and JSX in place for rolldown's own transform.\n const [{default: pluginBabel}, {reactCompilerPreset}] = await Promise.all([\n import('@rolldown/plugin-babel').catch((cause: unknown) => {\n throw new Error(\n '`reactCompiler: {transform: \"babel\"}` needs `pnpm add -D @rolldown/plugin-babel @babel/core babel-plugin-react-compiler`.',\n {cause},\n )\n }),\n import('@vitejs/plugin-react'),\n ])\n const {\n reactServer: _reactServer,\n transform: _transform,\n ...compilerOptions\n } = reactCompilerOptions\n plugins.push(\n await pluginBabel({\n presets: [reactCompilerPreset(compilerOptions)],\n }),\n )\n } else {\n // The default: `@vitejs/plugin-react`'s `compiler` option — `oxc-transform-react`\n // compiles, strips TypeScript and lowers JSX in one native pass. Only the\n // `vite:react-compiler` plugin is cherry-picked — the rest of the array is Vite-only\n // (Fast Refresh wrapper, dev config). Outside Vite its defaults are what a library\n // build wants: production JSX, sourcemaps, no Fast Refresh. `transform`/`reactServer`\n // are this config's — drop before forwarding.\n const {\n reactServer: _reactServer,\n transform: _transform,\n ...compilerOptions\n } = reactCompilerOptions\n const {default: pluginReact} = await import('@vitejs/plugin-react')\n const compilerPlugin = pluginReact({\n compiler: compilerOptions,\n // Keep the one-pass transform away from rolldown-plugin-dts' generated `.d.ts` modules\n // (the default include matches them) — it would strip every type, collapsing the\n // bundled declarations to `export {}`. node_modules is restated because a userland\n // `exclude` replaces the plugin's default — with both separators, since plain rolldown\n // (unlike Vite) does not normalize Windows ids to POSIX.\n exclude: [/[\\\\/]node_modules[\\\\/]/, RE_DTS_FILE],\n }).find((plugin) => plugin.name === 'vite:react-compiler')\n if (!compilerPlugin) {\n throw new Error(\n '`@vitejs/plugin-react` returned no `vite:react-compiler` plugin — the installed version does not support the default `oxc` implementation of the `reactCompiler` option.',\n )\n }\n plugins.push(compilerPlugin)\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 if (bundleAnalyzer !== false) {\n // Lazy loaded, like `reactCompiler` / `vanillaExtract`, so `rolldown/experimental` is\n // only paid for when the option is enabled. `true` selects markdown — Rolldown's own\n // default is JSON, which is worse for humans and coding agents.\n const {bundleAnalyzerPlugin} = await import('rolldown/experimental')\n plugins.push(\n bundleAnalyzerPlugin({\n format: 'md',\n ...(typeof bundleAnalyzer === 'object' ? bundleAnalyzer : {}),\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 // 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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"}
|
|
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 BabelReactCompilerPluginOptions} from 'babel-plugin-react-compiler'\nimport type {ReactCompilerOptions as OxcReactCompilerOptions} from 'oxc-transform-react'\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 `bundleAnalyzer` option — the same options as Rolldown's experimental\n * [`bundleAnalyzerPlugin`](https://rolldown.rs/builtin-plugins/bundle-analyzer)\n * (`fileName`, `format`).\n *\n * When enabled with `true`, defaults to `{format: 'md'}` (an LLM-friendly markdown report)\n * rather than the plugin's own `'json'` default — that's the report Sanity library builds\n * want. Pass `{format: 'json'}` for the structured data file visualizers consume.\n *\n * The report is emitted into `outDir` (`analyze-data.md` by default) and is **not** a\n * publishable artifact. Exclude it from `package.json` `files` (e.g.\n * `\"!dist/analyze-data.md\"` / `\"!lib/analyze-data.md\"`) so an accidental analyze build\n * cannot ship it.\n * @public\n * @alpha This option wraps Rolldown's experimental analyzer, whose API may change.\n */\nexport interface PackageBundleAnalyzerOptions {\n /**\n * The filename used for the emitted analysis asset. The file is written into the same\n * output directory as the rest of the bundle.\n * @defaultValue `'analyze-data.md'` when `format` is `'md'`, `'analyze-data.json'` when\n * `format` is `'json'`\n */\n fileName?: string\n /**\n * `'md'` produces an LLM-friendly markdown report (Quick Summary, largest modules, entry\n * points, dependency chains); `'json'` produces structured data for visualizers.\n * @defaultValue `'md'`\n */\n format?: 'json' | 'md'\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 * The options of this config that both React Compiler implementations share — never\n * forwarded to the compiler itself.\n * @public\n */\nexport interface ReactCompilerConfigOptions {\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// `interface … extends` on purpose, not intersection aliases: an uninstalled peer's type\n// import degrades to `any` (skipLibCheck), and in an intersection that `any` would swallow\n// the whole `ReactCompilerOptions` union, making every config match the `reactServer: true`\n// overload of `defineConfig` (the bug sanity-io/ui had to stub around). Unresolvable\n// heritage clauses are dropped instead, leaving each interface's own members (`transform`,\n// `reactServer`), so the union keeps discriminating. See `test/optional-peer-types.test.ts`.\n\n/**\n * The `transform: 'babel'` shape: `babel-plugin-react-compiler` (an optional peer dependency)\n * runs the compiler, with its own `PluginOptions` — typed once the package is installed.\n * Install it together with `@rolldown/plugin-babel` and `@babel/core`.\n * @public\n */\nexport interface ReactCompilerBabelOptions\n extends Partial<BabelReactCompilerPluginOptions>, ReactCompilerConfigOptions {\n /**\n * The reference implementation — for what the Rust port lacks: custom `jsxImportSource`,\n * `logger`, function-valued `sources`.\n */\n transform: 'babel'\n}\n\n/**\n * The default `reactCompiler` shape: `oxc-transform-react` (an optional peer dependency) runs\n * the compiler, with its own `ReactCompilerOptions` — the serializable subset of the babel\n * plugin's (no `logger`, no function-valued `sources`), typed once the package is installed.\n * @public\n */\nexport interface ReactCompilerOxcOptions\n extends OxcReactCompilerOptions, ReactCompilerConfigOptions {\n /**\n * `oxc-transform-react`, the Rust port. Its one native pass also strips TypeScript and\n * lowers JSX (automatic runtime, `react` import source) — opt into `'babel'` for a\n * custom `jsxImportSource`.\n * @defaultValue 'oxc'\n */\n transform?: 'oxc'\n}\n\n/**\n * Options for the React Compiler: the compiler's own options, plus `transform` (which\n * implementation runs) and `reactServer` (the dual React Server Components build) — both\n * handled by this config, never forwarded to the compiler.\n * @public\n */\nexport type ReactCompilerOptions = ReactCompilerBabelOptions | ReactCompilerOxcOptions\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 * Enables Rolldown's experimental\n * [`bundleAnalyzerPlugin`](https://rolldown.rs/builtin-plugins/bundle-analyzer)\n * (`rolldown/experimental`) to emit a report of what the package itself bundles — chunks,\n * modules, dependency chains — next to the build output. Pass `true` to use the defaults,\n * or an object to customize.\n *\n * Unlike the plugin's own defaults (`format: 'json'`), `true` selects `format: 'md'`: an\n * LLM-friendly markdown report (`analyze-data.md` in `outDir`). Pass `{format: 'json'}`\n * for the structured data file visualizers consume. Analysis adds work to the build, so\n * this stays off by default — typical usage is an env-gated opt-in:\n *\n * ```ts\n * bundleAnalyzer: process.env.ENABLE_BUNDLE_ANALYZER === 'true'\n * ```\n *\n * The report is **not** a publishable artifact. Exclude it from `package.json` `files`\n * (e.g. `\"!dist/analyze-data.md\"` / `\"!lib/analyze-data.md\"`) so an accidental analyze\n * build cannot ship it.\n *\n * With {@link ReactCompilerOptions.reactServer | `reactCompiler.reactServer`}, only the\n * compiled (`default`) variant is analyzed — the `react-server` variant skips it so the\n * two builds don't overwrite one report.\n * @defaultValue false\n * @alpha This option wraps Rolldown's experimental analyzer, whose API may change.\n */\n bundleAnalyzer?: boolean | PackageBundleAnalyzerOptions\n /**\n * Runs the 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\n * object (e.g. `{target: '18'}`). This is the same feature as the\n * `reactCompiler` option in `@sanity/pkg-utils`.\n *\n * `transform` picks the implementation — `'oxc'` (default, requires `oxc-transform-react`)\n * or `'babel'` (requires `babel-plugin-react-compiler`, `@rolldown/plugin-babel` and\n * `@babel/core`), see {@link ReactCompilerBabelOptions} — and `reactServer` adds the\n * uncompiled `react-server` build, see {@link ReactCompilerConfigOptions.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 the analyzer so the two parallel builds don't race on\n // one `analyze-data.md` in the shared `outDir`. The compiled variant is the published\n // client bundle — that's the report worth reading.\n const bundleAnalyzer = isReactServer ? false : (options.bundleAnalyzer ?? 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 resolveDepSubpath: true,\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 // Lazy loaded so the toolchain is only paid for when enabled. The compiler package itself\n // (`oxc-transform-react` / `babel-plugin-react-compiler`, per `transform`) resolves from\n // the consumer package — everything babel-flavored is an optional peer dependency.\n const reactCompilerOptions: ReactCompilerOptions = reactCompiler === true ? {} : reactCompiler\n if (reactCompilerOptions.transform === 'babel') {\n // The opt-in reference implementation follows the official tsdown recipe for the React\n // Compiler: https://tsdown.dev/recipes/react-support#enabling-react-compiler\n // The compiler leaves TypeScript and JSX in place for rolldown's own transform.\n const [{default: pluginBabel}, {reactCompilerPreset}] = await Promise.all([\n import('@rolldown/plugin-babel').catch((cause: unknown) => {\n throw new Error(\n '`reactCompiler: {transform: \"babel\"}` needs `pnpm add -D @rolldown/plugin-babel @babel/core babel-plugin-react-compiler`.',\n {cause},\n )\n }),\n import('@vitejs/plugin-react'),\n ])\n const {\n reactServer: _reactServer,\n transform: _transform,\n ...compilerOptions\n } = reactCompilerOptions\n plugins.push(\n await pluginBabel({\n presets: [reactCompilerPreset(compilerOptions)],\n }),\n )\n } else {\n // The default: `@vitejs/plugin-react`'s `compiler` option — `oxc-transform-react`\n // compiles, strips TypeScript and lowers JSX in one native pass. Only the\n // `vite:react-compiler` plugin is cherry-picked — the rest of the array is Vite-only\n // (Fast Refresh wrapper, dev config). Outside Vite its defaults are what a library\n // build wants: production JSX, sourcemaps, no Fast Refresh. `transform`/`reactServer`\n // are this config's — drop before forwarding.\n const {\n reactServer: _reactServer,\n transform: _transform,\n ...compilerOptions\n } = reactCompilerOptions\n const {default: pluginReact} = await import('@vitejs/plugin-react')\n const compilerPlugin = pluginReact({\n compiler: compilerOptions,\n // Keep the one-pass transform away from rolldown-plugin-dts' generated `.d.ts` modules\n // (the default include matches them) — it would strip every type, collapsing the\n // bundled declarations to `export {}`. node_modules is restated because a userland\n // `exclude` replaces the plugin's default — with both separators, since plain rolldown\n // (unlike Vite) does not normalize Windows ids to POSIX.\n exclude: [/[\\\\/]node_modules[\\\\/]/, RE_DTS_FILE],\n }).find((plugin) => plugin.name === 'vite:react-compiler')\n if (!compilerPlugin) {\n throw new Error(\n '`@vitejs/plugin-react` returned no `vite:react-compiler` plugin — the installed version does not support the default `oxc` implementation of the `reactCompiler` option.',\n )\n }\n plugins.push(compilerPlugin)\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 if (bundleAnalyzer !== false) {\n // Lazy loaded, like `reactCompiler` / `vanillaExtract`, so `rolldown/experimental` is\n // only paid for when the option is enabled. `true` selects markdown — Rolldown's own\n // default is JSON, which is worse for humans and coding agents.\n const {bundleAnalyzerPlugin} = await import('rolldown/experimental')\n plugins.push(\n bundleAnalyzerPlugin({\n format: 'md',\n ...(typeof bundleAnalyzer === 'object' ? bundleAnalyzer : {}),\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 // 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
CHANGED
|
@@ -42,6 +42,6 @@ interface CheckTsdocResult {
|
|
|
42
42
|
* tags are valid and release tags are correct. Import from `@sanity/tsdown-config/tsdoc`.
|
|
43
43
|
* @public
|
|
44
44
|
*/
|
|
45
|
-
declare function checkTsdoc(options: CheckTsdocOptions): Promise<CheckTsdocResult>;
|
|
46
|
-
export {
|
|
45
|
+
export declare function checkTsdoc(options: CheckTsdocOptions): Promise<CheckTsdocResult>;
|
|
46
|
+
export type { CheckTsdocLogger, CheckTsdocOptions, CheckTsdocResult, PackageTsdocCustomTag, PackageTsdocOptions, PackageTsdocRuleLevel };
|
|
47
47
|
//# sourceMappingURL=tsdoc.d.mts.map
|
package/dist/tsdoc.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tsdoc.d.mts","names":[],"sources":["../src/tsdoc/checkTsdoc.ts"],"mappings":";;;UAmBiB;EACf,SAAS;EACT,UAAU;EACV,WAAW;;;UAII,0BAA0B;;EAEzC;;;;;EAKA;;;;;EAKA;;;;;EAKA;;;;;EAKA,SAAS;;;UAIM;EACf,UAAU;EACV;EACA;;;;;;;
|
|
1
|
+
{"version":3,"file":"tsdoc.d.mts","names":[],"sources":["../src/tsdoc/checkTsdoc.ts"],"mappings":";;;UAmBiB;EACf,SAAS;EACT,UAAU;EACV,WAAW;;;UAII,0BAA0B;;EAEzC;;;;;EAKA;;;;;EAKA;;;;;EAKA;;;;;EAKA,SAAS;;;UAIM;EACf,UAAU;EACV;EACA;;;;;;;wBAQoB,WAAW,SAAS,oBAAoB,QAAQ"}
|
package/dist/tsdoc.mjs
CHANGED
|
@@ -190,7 +190,7 @@ function parseDts(filePath) {
|
|
|
190
190
|
function collectWrapperShapedNamespaceName(statement, names) {
|
|
191
191
|
if (!ts.isModuleDeclaration(statement) || !ts.isIdentifier(statement.name) || (statement.flags & ts.NodeFlags.Namespace) === 0) return;
|
|
192
192
|
let { body } = statement;
|
|
193
|
-
|
|
193
|
+
body && ts.isModuleBlock(body) && body.statements.every((member) => ts.isExportDeclaration(member) && !member.moduleSpecifier && member.exportClause !== void 0 && ts.isNamedExports(member.exportClause)) && names.add(statement.name.text);
|
|
194
194
|
}
|
|
195
195
|
/**
|
|
196
196
|
* Collects the names a declaration with an `export` modifier exports directly, e.g.
|
package/dist/tsdoc.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tsdoc.mjs","names":[],"sources":["../src/tsdoc/createApiExtractorConfig.ts","../src/tsdoc/createTSDocConfig.ts","../src/tsdoc/getExtractMessagesConfig.ts","../src/tsdoc/synthesizedNamespaces.ts","../src/tsdoc/checkTsdoc.ts"],"sourcesContent":["import path from 'node:path'\nimport type {IConfigFile, IExtractorMessagesConfig} from '@microsoft/api-extractor'\n\n/** @internal */\nexport function createApiExtractorConfig(options: {\n bundledPackages?: string[]\n distPath: string\n exportPath: string\n filePath: string\n messages: IExtractorMessagesConfig\n projectFolder: string\n mainEntryPointFilePath: string\n /**\n * Only `compilerOptions.paths` is read: when present, API Extractor gets an override that\n * clears `paths` so self-referencing package imports resolve through `node_modules` instead.\n */\n tsconfig: {options: {paths?: unknown}}\n tsconfigPath: string\n}): IConfigFile {\n const {\n bundledPackages,\n distPath,\n exportPath,\n filePath,\n messages,\n projectFolder,\n mainEntryPointFilePath,\n tsconfig,\n tsconfigPath,\n } = options\n\n return {\n apiReport: {\n enabled: false,\n reportFileName: '<unscopedPackageName>.api.md',\n },\n bundledPackages,\n\n // If `paths` are used for self-referencing imports (e.g. the module is named `sanity`, and the `sanity/structure` export is also importing from `sanity/router`),\n compiler: tsconfig.options.paths\n ? {\n overrideTsconfig: {\n extends: tsconfigPath,\n compilerOptions: {\n // An empty object replaces whatever is in the original tsconfig file\n paths: {},\n },\n },\n }\n : {tsconfigFilePath: tsconfigPath},\n\n docModel: {\n enabled: false,\n apiJsonFilePath: path.resolve(distPath, `${exportPath}.api.json`),\n },\n dtsRollup: {\n // Types come from tsdown; this check only runs API Extractor's TSDoc/release-tag rules\n enabled: false,\n untrimmedFilePath: path.resolve(distPath, filePath),\n },\n tsdocMetadata: {\n enabled: false,\n },\n messages,\n mainEntryPointFilePath,\n projectFolder,\n }\n}\n","import {readFile} from 'node:fs/promises'\nimport {createRequire} from 'node:module'\nimport {TSDocConfigFile} from '@microsoft/tsdoc-config'\nimport {parse} from 'jsonc-parser'\nimport type {PackageTsdocCustomTag} from './types.ts'\n\nconst require = createRequire(import.meta.url)\n\n/** @internal */\nexport async function createTSDocConfig(opts: {\n customTags: PackageTsdocCustomTag[]\n}): Promise<TSDocConfigFile | undefined> {\n const {customTags} = opts\n\n if (customTags.length === 0) {\n return undefined\n }\n\n const tsDocBaseBuf = await readFile(\n require.resolve('@microsoft/api-extractor/extends/tsdoc-base.json'),\n )\n\n // Include the definitions that are required for API Extractor\n // extends: ['@microsoft/api-extractor/extends/tsdoc-base.json'],\n const tsDocBaseConfig = parse(tsDocBaseBuf.toString())\n\n // Define custom tags and specify how they should be parsed\n const tagDefinitions = (tsDocBaseConfig.tagDefinitions || []).concat(\n customTags.map((t) => ({\n tagName: `@${t.name}`,\n syntaxKind: t.syntaxKind,\n allowMultiple: t.allowMultiple,\n })),\n )\n\n // Indicate that custom tags are supported by your tooling.\n // (Without this, warnings may be reported saying that a tag is unsupported.)\n const supportForTags = {...tsDocBaseConfig.supportForTags}\n\n for (const customTag of customTags) {\n supportForTags[`@${customTag.name}`] = true\n }\n\n return TSDocConfigFile.loadFromObject({\n ...tsDocBaseConfig,\n noStandardTags: false,\n tagDefinitions,\n supportForTags,\n })\n}\n","import {ExtractorLogLevel, type IExtractorMessagesConfig} from '@microsoft/api-extractor'\nimport type {PackageTsdocOptions, PackageTsdocRuleLevel} from './types.ts'\n\nconst LOG_LEVELS: Record<PackageTsdocRuleLevel, ExtractorLogLevel> = {\n error: ExtractorLogLevel.Error,\n info: ExtractorLogLevel.Info,\n off: ExtractorLogLevel.None,\n warn: ExtractorLogLevel.Warning,\n}\n\n/** @internal */\nexport function getExtractMessagesConfig(options: {\n rules: PackageTsdocOptions['rules']\n disabled?: boolean\n}): IExtractorMessagesConfig {\n const {rules, disabled = false} = options\n\n function ruleToLogLevel(\n key: keyof NonNullable<PackageTsdocOptions['rules']>,\n defaultLevel?: ExtractorLogLevel,\n ) {\n const r = rules?.[key]\n\n return r ? LOG_LEVELS[r] : defaultLevel || ExtractorLogLevel.Warning\n }\n\n return {\n compilerMessageReporting: {\n default: {\n logLevel: disabled ? ExtractorLogLevel.None : ExtractorLogLevel.Warning,\n },\n },\n\n extractorMessageReporting: disabled\n ? {\n default: {\n logLevel: ExtractorLogLevel.None,\n addToApiReportFile: false,\n },\n }\n : {\n 'default': {\n logLevel: ExtractorLogLevel.Warning,\n addToApiReportFile: false,\n },\n\n 'ae-forgotten-export': {\n /**\n * This is hardcoded to `none` as it's no longer needed since TypeScript 5.5 https://github.com/microsoft/TypeScript/issues/42873\n * It's hardcoded to `none` since supported by API Extractor when using `module: 'Preserve'` doesn't support it well since `@microsoft/api-extractor` v7.49.0, which upgraded from TS 5.4 to 5.7 internally\n */\n logLevel: ExtractorLogLevel.None,\n addToApiReportFile: false,\n },\n\n 'ae-incompatible-release-tags': {\n logLevel: ruleToLogLevel('ae-incompatible-release-tags', ExtractorLogLevel.Error),\n addToApiReportFile: false,\n },\n\n 'ae-internal-missing-underscore': {\n logLevel: ruleToLogLevel('ae-internal-missing-underscore'),\n addToApiReportFile: false,\n },\n\n 'ae-missing-release-tag': {\n logLevel: ruleToLogLevel('ae-missing-release-tag', ExtractorLogLevel.Error),\n addToApiReportFile: false,\n },\n\n 'ae-wrong-input-file-type': {\n logLevel: ExtractorLogLevel.None,\n addToApiReportFile: false,\n },\n },\n\n tsdocMessageReporting: disabled\n ? {\n default: {\n logLevel: ExtractorLogLevel.None,\n addToApiReportFile: false,\n },\n }\n : {\n 'default': {\n logLevel: ExtractorLogLevel.Warning,\n addToApiReportFile: false,\n },\n\n 'tsdoc-link-tag-unescaped-text': {\n logLevel: ruleToLogLevel('tsdoc-link-tag-unescaped-text', ExtractorLogLevel.Warning),\n addToApiReportFile: false,\n },\n\n 'tsdoc-undefined-tag': {\n logLevel: ruleToLogLevel('tsdoc-undefined-tag', ExtractorLogLevel.Error),\n addToApiReportFile: false,\n },\n\n 'tsdoc-unsupported-tag': {\n logLevel: ruleToLogLevel('tsdoc-unsupported-tag', ExtractorLogLevel.None),\n addToApiReportFile: false,\n },\n },\n }\n}\n","import {existsSync, readFileSync} from 'node:fs'\nimport path from 'node:path'\n// The JS compiler API is loaded from the official `@typescript/typescript6` compat package\n// instead of the `typescript` peer dependency, as TypeScript 7 (the Go-native compiler) no longer\n// ships it\nimport ts from '@typescript/typescript6'\n\n/**\n * The exports-object identifiers of rolldown's namespace interop: `<module>_exports` (the\n * declaration bundling pass names them after the virtual declaration module, e.g. `inner.d.ts`\n * → `inner_d_exports`), with rolldown's `$<n>` suffix when deconflicting renames one.\n */\nconst RE_WRAPPER_NAME = /_exports(\\$\\d+)?$/\n\n/** Matches the relative specifiers of emitted sibling chunks (`./chunk-<hash>.js`). */\nconst RE_RELATIVE_SPECIFIER = /^\\.\\.?\\//\n\n/**\n * Finds the local names of the `declare namespace <name>_exports {…}` wrappers that the\n * declaration bundling pass (tsdown / rolldown-plugin-dts) synthesizes for namespace re-exports\n * like `export * as ns from './module'` (or `import * as ns` + `export {ns}`).\n *\n * Bundling loses the doc comment of the re-export statement, so the wrapper cannot carry a\n * release tag — there is no way to tag it from userland, and API Extractor would flag it with\n * `ae-missing-release-tag` (https://github.com/sanity-io/pkg-utils/issues/3281). Skipping it\n * matches how API Extractor treats the equivalent namespace of its own rollups (it never\n * checks those). The members re-exported through the wrapper keep their own doc comments in\n * the output; API Extractor does not flag them individually either way (only directly exported\n * declarations are consumable entities of the missing-release-tag check).\n *\n * A name only qualifies when all of these hold, so user-authored symbols that merely resemble\n * the interop naming stay checked:\n *\n * - it matches rolldown's `<module>_exports` naming (with an optional `$<n>` deconflict suffix)\n * - it is declared as a namespace — in the entry itself, or in a sibling chunk the entry\n * imports (a wrapper shared by several entries lives in the chunk that owns the module's\n * declarations)\n * - that namespace has the synthesized body shape: nothing but `export { … };` specifier lists\n * pointing at sibling declarations of the same file. A user-authored namespace declares its\n * own members (`declare namespace config_exports { const userValue: string; }`), and those\n * members are what the author tags — so it stays checked even when the bundler's\n * deconflicting hands it a wrapper-shaped name\n * - the entry does not export the name unaliased: a synthesized wrapper is always re-exported\n * under the alias of the original namespace re-export (`export { inner_d_exports as inner }`),\n * while an unaliased export (`export { foo_exports }`, `export declare namespace foo_exports`)\n * is a name the author chose — and can tag\n * @internal\n */\nexport function collectSynthesizedNamespaceWrappers(entryDtsFile: string): Set<string> {\n const entry = parseDts(entryDtsFile)\n if (!entry) return new Set()\n\n const unaliasedExports = new Set<string>()\n const wrapperShapedNames = new Set<string>()\n const chunkFiles = new Set<string>()\n\n for (const statement of entry.statements) {\n collectWrapperShapedNamespaceName(statement, wrapperShapedNames)\n\n if (ts.isExportDeclaration(statement)) {\n const {exportClause} = statement\n if (exportClause && ts.isNamedExports(exportClause)) {\n for (const element of exportClause.elements) {\n if (!element.propertyName || element.propertyName.text === element.name.text) {\n unaliasedExports.add(element.name.text)\n }\n }\n } else if (exportClause && ts.isNamespaceExport(exportClause)) {\n unaliasedExports.add(exportClause.name.text)\n }\n collectChunkFile(entryDtsFile, statement.moduleSpecifier, chunkFiles)\n } else if (ts.isImportDeclaration(statement)) {\n collectChunkFile(entryDtsFile, statement.moduleSpecifier, chunkFiles)\n } else {\n collectExportedDeclarationNames(statement, unaliasedExports)\n }\n }\n\n for (const chunkFile of chunkFiles) {\n const chunk = parseDts(chunkFile)\n if (!chunk) continue\n for (const statement of chunk.statements) {\n collectWrapperShapedNamespaceName(statement, wrapperShapedNames)\n }\n }\n\n const wrappers = new Set<string>()\n for (const name of wrapperShapedNames) {\n if (RE_WRAPPER_NAME.test(name) && !unaliasedExports.has(name)) wrappers.add(name)\n }\n return wrappers\n}\n\nfunction parseDts(filePath: string): ts.SourceFile | undefined {\n if (!existsSync(filePath)) return undefined\n return ts.createSourceFile(\n filePath,\n readFileSync(filePath, 'utf8'),\n ts.ScriptTarget.Latest,\n false,\n )\n}\n\n/**\n * Collects the name of a top-level `declare namespace <Identifier> {…}` statement whose body has\n * the shape the declaration bundling pass synthesizes: only `export { … };` specifier lists\n * naming sibling declarations of the same file, never members of its own. Every namespace\n * re-export the bundler rewrites comes out that way, whatever the re-exported module holds\n * (values, types, a default export, further namespace re-exports).\n */\nfunction collectWrapperShapedNamespaceName(statement: ts.Statement, names: Set<string>): void {\n if (\n !ts.isModuleDeclaration(statement) ||\n !ts.isIdentifier(statement.name) ||\n (statement.flags & ts.NodeFlags.Namespace) === 0\n ) {\n return\n }\n\n const {body} = statement\n if (!body || !ts.isModuleBlock(body)) return\n\n const onlyReExportsSiblings = body.statements.every(\n (member) =>\n ts.isExportDeclaration(member) &&\n !member.moduleSpecifier &&\n member.exportClause !== undefined &&\n ts.isNamedExports(member.exportClause),\n )\n if (!onlyReExportsSiblings) return\n\n names.add(statement.name.text)\n}\n\n/**\n * Collects the names a declaration with an `export` modifier exports directly, e.g.\n * `export declare namespace foo_exports {…}` — those names are user-chosen (the author can\n * tag them), unlike the alias-only re-export of a synthesized wrapper.\n */\nfunction collectExportedDeclarationNames(statement: ts.Statement, names: Set<string>): void {\n const modifiers = ts.canHaveModifiers(statement) ? ts.getModifiers(statement) : undefined\n if (!modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword)) return\n\n if (ts.isVariableStatement(statement)) {\n for (const declaration of statement.declarationList.declarations) {\n if (ts.isIdentifier(declaration.name)) names.add(declaration.name.text)\n }\n } else if (\n (ts.isFunctionDeclaration(statement) ||\n ts.isClassDeclaration(statement) ||\n ts.isInterfaceDeclaration(statement) ||\n ts.isTypeAliasDeclaration(statement) ||\n ts.isEnumDeclaration(statement)) &&\n statement.name\n ) {\n names.add(statement.name.text)\n } else if (ts.isModuleDeclaration(statement) && ts.isIdentifier(statement.name)) {\n names.add(statement.name.text)\n }\n}\n\n/**\n * Resolves the sibling chunk file a relative import/export specifier points at, mapping the\n * runtime extension to the declaration extension the chunk is emitted with on disk\n * (`./chunk.js` → `./chunk.d.ts`, like the declaration output of the bundling pass itself).\n */\nfunction collectChunkFile(\n entryDtsFile: string,\n moduleSpecifier: ts.Expression | undefined,\n files: Set<string>,\n): void {\n if (!moduleSpecifier || !ts.isStringLiteral(moduleSpecifier)) return\n const specifier = moduleSpecifier.text\n if (!RE_RELATIVE_SPECIFIER.test(specifier)) return\n const dtsFile = specifierToDtsFile(specifier)\n if (!dtsFile) return\n files.add(path.resolve(path.dirname(entryDtsFile), dtsFile))\n}\n\n/** `./chunk.js` → `./chunk.d.ts` (`.mjs` → `.d.mts`, `.cjs` → `.d.cts`). */\nfunction specifierToDtsFile(specifier: string): string | undefined {\n if (/\\.d\\.[mc]?ts$/.test(specifier)) return specifier\n if (specifier.endsWith('.mjs')) return `${specifier.slice(0, -4)}.d.mts`\n if (specifier.endsWith('.cjs')) return `${specifier.slice(0, -4)}.d.cts`\n if (specifier.endsWith('.js')) return `${specifier.slice(0, -3)}.d.ts`\n return undefined\n}\n","import {existsSync} from 'node:fs'\nimport path from 'node:path'\nimport {\n Extractor,\n ExtractorConfig,\n ExtractorLogLevel,\n type ExtractorMessage,\n} from '@microsoft/api-extractor'\n// The JS compiler API is loaded from the official `@typescript/typescript6` compat package\n// instead of the `typescript` peer dependency, as TypeScript 7 (the Go-native compiler) no longer\n// ships it\nimport ts from '@typescript/typescript6'\nimport {createApiExtractorConfig} from './createApiExtractorConfig.ts'\nimport {createTSDocConfig} from './createTSDocConfig.ts'\nimport {getExtractMessagesConfig} from './getExtractMessagesConfig.ts'\nimport {collectSynthesizedNamespaceWrappers} from './synthesizedNamespaces.ts'\nimport type {PackageTsdocOptions} from './types.ts'\n\n/** @public */\nexport interface CheckTsdocLogger {\n log: (...args: unknown[]) => void\n warn: (...args: unknown[]) => void\n error: (...args: unknown[]) => void\n}\n\n/** @public */\nexport interface CheckTsdocOptions extends PackageTsdocOptions {\n /** Package root (directory containing `package.json`). */\n cwd: string\n /**\n * Absolute paths to the entry `.d.ts` / `.d.mts` / `.d.cts` files to check.\n * JS-only entries with no declarations are skipped automatically when listed.\n */\n entryDtsFiles: string[]\n /**\n * Path to the tsconfig used for the build, relative to `cwd` or absolute.\n * @defaultValue `'tsconfig.json'`\n */\n tsconfig?: string\n /**\n * Directory of distributed files (used for API Extractor's path mapping). Defaults to the\n * common parent of `entryDtsFiles`, or `dist` under `cwd` when the list is empty.\n */\n outDir?: string\n /**\n * When provided, messages are printed through this logger. Errors throw after reporting so\n * callers (and tsdown's `build:done` hook) fail the build.\n */\n logger?: CheckTsdocLogger\n}\n\n/** @public */\nexport interface CheckTsdocResult {\n messages: ExtractorMessage[]\n errorCount: number\n warningCount: number\n}\n\n/**\n * Run `@microsoft/api-extractor` against the given entry declaration files to check that TSDoc\n * tags are valid and release tags are correct. Import from `@sanity/tsdown-config/tsdoc`.\n * @public\n */\nexport async function checkTsdoc(options: CheckTsdocOptions): Promise<CheckTsdocResult> {\n const {\n cwd,\n entryDtsFiles,\n bundledPackages,\n customTags = [],\n rules = {},\n logger,\n outDir: outDirOption,\n } = options\n\n const tsconfigPath = path.resolve(cwd, options.tsconfig || 'tsconfig.json')\n const tsconfig = loadTSConfig({cwd, tsconfigPath})\n // api-extractor needs a `compilerOptions.outDir` for its path mapping; tsdown does not, so\n // fall back to the configured outDir / dist folder when the tsconfig leaves it unset\n const outDir =\n tsconfig?.options.outDir ??\n (outDirOption ? path.resolve(cwd, outDirOption) : undefined) ??\n commonParentDir(entryDtsFiles) ??\n path.resolve(cwd, 'dist')\n\n const tsdocConfigFile = await createTSDocConfig({customTags})\n const messagesConfig = getExtractMessagesConfig({rules})\n const allMessages: ExtractorMessage[] = []\n\n for (const exportPath of entryDtsFiles) {\n if (!existsSync(exportPath)) continue\n\n // The declaration bundling pass synthesizes `declare namespace <name>_exports` wrappers\n // for namespace re-exports and loses the doc comment of the re-export statement, so the\n // wrappers can never carry a release tag — `ae-missing-release-tag` skips them.\n // https://github.com/sanity-io/pkg-utils/issues/3281\n const synthesizedWrappers = collectSynthesizedNamespaceWrappers(exportPath)\n const relativeDtsPath = path.relative(outDir, exportPath)\n const extractorConfig = ExtractorConfig.prepare({\n configObject: createApiExtractorConfig({\n bundledPackages,\n distPath: outDir,\n exportPath,\n filePath: relativeDtsPath,\n messages: messagesConfig,\n projectFolder: cwd,\n mainEntryPointFilePath: exportPath,\n tsconfig: tsconfig ?? {options: {}},\n tsconfigPath,\n }),\n configObjectFullPath: undefined,\n tsdocConfigFile,\n packageJsonFullPath: path.resolve(cwd, 'package.json'),\n })\n\n Extractor.invoke(extractorConfig, {\n localBuild: true,\n showVerboseMessages: true,\n messageCallback(message: ExtractorMessage) {\n message.handled = true\n if (isSynthesizedNamespaceWrapperMessage(message, synthesizedWrappers)) return\n allMessages.push(message)\n },\n })\n }\n\n const warnings = allMessages.filter((msg) => msg.logLevel === ExtractorLogLevel.Warning)\n const errors = allMessages.filter((msg) => msg.logLevel === ExtractorLogLevel.Error)\n\n if (logger) {\n reportMessages(cwd, logger, warnings, errors)\n }\n\n if (errors.length) {\n throw new Error(\n `TSDoc/release-tag check failed with ${errors.length} error${errors.length === 1 ? '' : 's'}`,\n )\n }\n\n return {\n messages: allMessages,\n errorCount: errors.length,\n warningCount: warnings.length,\n }\n}\n\nfunction loadTSConfig(options: {\n cwd: string\n tsconfigPath: string\n}): ReturnType<typeof ts.parseJsonConfigFileContent> | undefined {\n const {cwd, tsconfigPath} = options\n // Resolve a relative name from `cwd` (e.g. `tsconfig.dist.json`); an absolute path is kept.\n let configPath: string | undefined\n if (path.isAbsolute(tsconfigPath)) {\n configPath = tsconfigPath\n } else {\n // oxlint-disable-next-line unbound-method\n configPath = ts.findConfigFile(cwd, ts.sys.fileExists, tsconfigPath)\n }\n if (!configPath || !existsSync(configPath)) return undefined\n // oxlint-disable-next-line unbound-method\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile)\n // Relative `extends`/`include`/`paths` are resolved from the tsconfig's directory, not `cwd`\n return ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath))\n}\n\n/** The quoted symbol name leading api-extractor's `ae-missing-release-tag` message text. */\nconst RE_MISSING_RELEASE_TAG_SYMBOL = /^\"([^\"]+)\" is part of the package's API/\n\n/**\n * Whether a message is an `ae-missing-release-tag` complaint about a namespace wrapper the\n * declaration bundling pass synthesized (which userland can never tag). The flagged symbol is\n * only identifiable through the message text: api-extractor quotes the local name of the\n * declaration, and attaches no structured properties (its source location maps through\n * `.d.ts.map` files, often landing on an unrelated source position).\n */\nfunction isSynthesizedNamespaceWrapperMessage(\n message: ExtractorMessage,\n synthesizedWrappers: Set<string>,\n): boolean {\n if (synthesizedWrappers.size === 0 || message.messageId !== 'ae-missing-release-tag') {\n return false\n }\n const symbolName = RE_MISSING_RELEASE_TAG_SYMBOL.exec(message.text)?.[1]\n return symbolName !== undefined && synthesizedWrappers.has(symbolName)\n}\n\nfunction commonParentDir(files: string[]): string | undefined {\n if (files.length === 0) return undefined\n let dir = path.dirname(files[0]!)\n for (const file of files.slice(1)) {\n while (dir !== path.dirname(dir) && !file.startsWith(dir + path.sep) && file !== dir) {\n dir = path.dirname(dir)\n }\n }\n return dir\n}\n\nfunction reportMessages(\n cwd: string,\n logger: CheckTsdocLogger,\n warnings: ExtractorMessage[],\n errors: ExtractorMessage[],\n): void {\n if (warnings.length) {\n logger.log()\n }\n\n for (const msg of warnings) {\n if (msg.messageId === 'TS6307') {\n // Ignore this warning:\n // > TS6307: <filename> is not in project file list.\n // > Projects must list all files or use an 'include' pattern.\n continue\n }\n const sourceFilePath = msg.sourceFilePath && path.relative(cwd, msg.sourceFilePath)\n logger.warn(\n `${sourceFilePath || '?'}:${msg.sourceFileLine}:${msg.sourceFileColumn} - warning ${msg.messageId}\\n${msg.text}\\n`,\n )\n }\n\n if (!warnings.length && errors.length) {\n logger.log()\n }\n\n for (const msg of errors) {\n const sourceFilePath = msg.sourceFilePath && path.relative(cwd, msg.sourceFilePath)\n logger.error(\n `${sourceFilePath || '?'}:${msg.sourceFileLine}:${msg.sourceFileColumn} - error ${msg.messageId}\\n${msg.text}\\n`,\n )\n }\n}\n"],"mappings":";;;;;;;;;AAIA,SAAgB,yBAAyB,SAczB;CACd,IAAM,EACJ,iBACA,UACA,YACA,UACA,UACA,eACA,wBACA,UACA,iBACE;CAEJ,OAAO;EACL,WAAW;GACT,SAAS;GACT,gBAAgB;EAClB;EACA;EAGA,UAAU,SAAS,QAAQ,QACvB,EACE,kBAAkB;GAChB,SAAS;GACT,iBAAiB,EAEf,OAAO,CAAC,EACV;EACF,EACF,IACA,EAAC,kBAAkB,aAAY;EAEnC,UAAU;GACR,SAAS;GACT,iBAAiB,KAAK,QAAQ,UAAU,GAAG,WAAW,UAAU;EAClE;EACA,WAAW;GAET,SAAS;GACT,mBAAmB,KAAK,QAAQ,UAAU,QAAQ;EACpD;EACA,eAAe,EACb,SAAS,GACX;EACA;EACA;EACA;CACF;AACF;AC7DA,MAAM,UAAU,cAAc,YAAY,GAAG;;AAG7C,eAAsB,kBAAkB,MAEC;CACvC,IAAM,EAAC,eAAc;CAErB,IAAI,WAAW,WAAW,GACxB;CAGF,IAAM,eAAe,MAAM,SACzB,QAAQ,QAAQ,kDAAkD,CACpE,GAIM,kBAAkB,MAAM,aAAa,SAAS,CAAC,GAG/C,kBAAkB,gBAAgB,kBAAkB,CAAC,EAAA,CAAG,OAC5D,WAAW,KAAK,OAAO;EACrB,SAAS,IAAI,EAAE;EACf,YAAY,EAAE;EACd,eAAe,EAAE;CACnB,EAAE,CACJ,GAIM,iBAAiB,EAAC,GAAG,gBAAgB,eAAc;CAEzD,KAAK,IAAM,aAAa,YACtB,eAAe,IAAI,UAAU,UAAU;CAGzC,OAAO,gBAAgB,eAAe;EACpC,GAAG;EACH,gBAAgB;EAChB;EACA;CACF,CAAC;AACH;AC9CA,MAAM,aAA+D;CACnE,OAAO,kBAAkB;CACzB,MAAM,kBAAkB;CACxB,KAAK,kBAAkB;CACvB,MAAM,kBAAkB;AAC1B;;AAGA,SAAgB,yBAAyB,SAGZ;CAC3B,IAAM,EAAC,OAAO,WAAW,OAAS;CAElC,SAAS,eACP,KACA,cACA;EACA,IAAM,IAAI,QAAQ;EAElB,OAAO,IAAI,WAAW,KAAK,gBAAgB,kBAAkB;CAC/D;CAEA,OAAO;EACL,0BAA0B,EACxB,SAAS,EACP,UAAU,WAAW,kBAAkB,OAAO,kBAAkB,QAClE,EACF;EAEA,2BAA2B,WACvB,EACE,SAAS;GACP,UAAU,kBAAkB;GAC5B,oBAAoB;EACtB,EACF,IACA;GACE,SAAW;IACT,UAAU,kBAAkB;IAC5B,oBAAoB;GACtB;GAEA,uBAAuB;;;;;IAKrB,UAAU,kBAAkB;IAC5B,oBAAoB;GACtB;GAEA,gCAAgC;IAC9B,UAAU,eAAe,gCAAgC,kBAAkB,KAAK;IAChF,oBAAoB;GACtB;GAEA,kCAAkC;IAChC,UAAU,eAAe,gCAAgC;IACzD,oBAAoB;GACtB;GAEA,0BAA0B;IACxB,UAAU,eAAe,0BAA0B,kBAAkB,KAAK;IAC1E,oBAAoB;GACtB;GAEA,4BAA4B;IAC1B,UAAU,kBAAkB;IAC5B,oBAAoB;GACtB;EACF;EAEJ,uBAAuB,WACnB,EACE,SAAS;GACP,UAAU,kBAAkB;GAC5B,oBAAoB;EACtB,EACF,IACA;GACE,SAAW;IACT,UAAU,kBAAkB;IAC5B,oBAAoB;GACtB;GAEA,iCAAiC;IAC/B,UAAU,eAAe,iCAAiC,kBAAkB,OAAO;IACnF,oBAAoB;GACtB;GAEA,uBAAuB;IACrB,UAAU,eAAe,uBAAuB,kBAAkB,KAAK;IACvE,oBAAoB;GACtB;GAEA,yBAAyB;IACvB,UAAU,eAAe,yBAAyB,kBAAkB,IAAI;IACxE,oBAAoB;GACtB;EACF;CACN;AACF;;;;;;AC7FA,MAAM,kBAAkB,qBAGlB,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiC9B,SAAgB,oCAAoC,cAAmC;CACrF,IAAM,QAAQ,SAAS,YAAY;CACnC,IAAI,CAAC,OAAO,uBAAO,IAAI,IAAI;CAE3B,IAAM,mCAAmB,IAAI,IAAY,GACnC,qCAAqB,IAAI,IAAY,GACrC,6BAAa,IAAI,IAAY;CAEnC,KAAK,IAAM,aAAa,MAAM,YAG5B,IAFA,kCAAkC,WAAW,kBAAkB,GAE3D,GAAG,oBAAoB,SAAS,GAAG;EACrC,IAAM,EAAC,iBAAgB;EACvB,IAAI,gBAAgB,GAAG,eAAe,YAAY,GAC3C,KAAA,IAAM,WAAW,aAAa,UACjC,CAAI,CAAC,QAAQ,gBAAgB,QAAQ,aAAa,SAAS,QAAQ,KAAK,SACtE,iBAAiB,IAAI,QAAQ,KAAK,IAAI;OAGrC,AAAI,gBAAgB,GAAG,kBAAkB,YAAY,KAC1D,iBAAiB,IAAI,aAAa,KAAK,IAAI;EAE7C,iBAAiB,cAAc,UAAU,iBAAiB,UAAU;CACtE,OAAO,AAAI,GAAG,oBAAoB,SAAS,IACzC,iBAAiB,cAAc,UAAU,iBAAiB,UAAU,IAEpE,gCAAgC,WAAW,gBAAgB;CAI/D,KAAK,IAAM,aAAa,YAAY;EAClC,IAAM,QAAQ,SAAS,SAAS;EAC3B,WACL,KAAK,IAAM,aAAa,MAAM,YAC5B,kCAAkC,WAAW,kBAAkB;CAEnE;CAEA,IAAM,2BAAW,IAAI,IAAY;CACjC,KAAK,IAAM,QAAQ,oBACjB,AAAI,gBAAgB,KAAK,IAAI,KAAK,CAAC,iBAAiB,IAAI,IAAI,KAAG,SAAS,IAAI,IAAI;CAElF,OAAO;AACT;AAEA,SAAS,SAAS,UAA6C;CACxD,eAAW,QAAQ,GACxB,OAAO,GAAG,iBACR,UACA,aAAa,UAAU,MAAM,GAC7B,GAAG,aAAa,QAChB,EACF;AACF;;;;;;;;AASA,SAAS,kCAAkC,WAAyB,OAA0B;CAC5F,IACE,CAAC,GAAG,oBAAoB,SAAS,KACjC,CAAC,GAAG,aAAa,UAAU,IAAI,MAC9B,UAAU,QAAQ,GAAG,UAAU,eAAe,GAE/C;CAGF,IAAM,EAAC,SAAQ;CACX,CAAC,QAAQ,CAAC,GAAG,cAAc,IAAI,KAEL,KAAK,WAAW,OAC3C,WACC,GAAG,oBAAoB,MAAM,KAC7B,CAAC,OAAO,mBACR,OAAO,iBAAiB,KAAA,KACxB,GAAG,eAAe,OAAO,YAAY,CAEhB,KAEzB,MAAM,IAAI,UAAU,KAAK,IAAI;AAC/B;;;;;;AAOA,SAAS,gCAAgC,WAAyB,OAA0B;CAEtF,KADc,GAAG,iBAAiB,SAAS,IAAI,GAAG,aAAa,SAAS,IAAI,KAAA,EAAA,EAChE,MAAM,aAAa,SAAS,SAAS,GAAG,WAAW,aAAa,GAEhF;MAAI,GAAG,oBAAoB,SAAS,GAC7B,KAAA,IAAM,eAAe,UAAU,gBAAgB,cAClD,AAAI,GAAG,aAAa,YAAY,IAAI,KAAG,MAAM,IAAI,YAAY,KAAK,IAAI;OAEnE,EACJ,GAAG,sBAAsB,SAAS,KACjC,GAAG,mBAAmB,SAAS,KAC/B,GAAG,uBAAuB,SAAS,KACnC,GAAG,uBAAuB,SAAS,KACnC,GAAG,kBAAkB,SAAS,MAChC,UAAU,QAGD,GAAG,oBAAoB,SAAS,KAAK,GAAG,aAAa,UAAU,IAAI,MAD5E,MAAM,IAAI,UAAU,KAAK,IAAI;CAEA;AAEjC;;;;;;AAOA,SAAS,iBACP,cACA,iBACA,OACM;CACN,IAAI,CAAC,mBAAmB,CAAC,GAAG,gBAAgB,eAAe,GAAG;CAC9D,IAAM,YAAY,gBAAgB;CAClC,IAAI,CAAC,sBAAsB,KAAK,SAAS,GAAG;CAC5C,IAAM,UAAU,mBAAmB,SAAS;CACvC,WACL,MAAM,IAAI,KAAK,QAAQ,KAAK,QAAQ,YAAY,GAAG,OAAO,CAAC;AAC7D;;AAGA,SAAS,mBAAmB,WAAuC;CACjE,IAAI,gBAAgB,KAAK,SAAS,GAAG,OAAO;CAC5C,IAAI,UAAU,SAAS,MAAM,GAAG,OAAO,GAAG,UAAU,MAAM,GAAG,EAAE,EAAE;CACjE,IAAI,UAAU,SAAS,MAAM,GAAG,OAAO,GAAG,UAAU,MAAM,GAAG,EAAE,EAAE;CACjE,IAAI,UAAU,SAAS,KAAK,GAAG,OAAO,GAAG,UAAU,MAAM,GAAG,EAAE,EAAE;AAElE;;;;;;AC3HA,eAAsB,WAAW,SAAuD;CACtF,IAAM,EACJ,KACA,eACA,iBACA,aAAa,CAAC,GACd,QAAQ,CAAC,GACT,QACA,QAAQ,iBACN,SAEE,eAAe,KAAK,QAAQ,KAAK,QAAQ,YAAY,eAAe,GACpE,WAAW,aAAa;EAAC;EAAK;CAAY,CAAC,GAG3C,SACJ,UAAU,QAAQ,WACjB,eAAe,KAAK,QAAQ,KAAK,YAAY,IAAI,KAAA,MAClD,gBAAgB,aAAa,KAC7B,KAAK,QAAQ,KAAK,MAAM,GAEpB,kBAAkB,MAAM,kBAAkB,EAAC,WAAU,CAAC,GACtD,iBAAiB,yBAAyB,EAAC,MAAK,CAAC,GACjD,cAAkC,CAAC;CAEzC,KAAK,IAAM,cAAc,eAAe;EACtC,IAAI,CAAC,WAAW,UAAU,GAAG;EAM7B,IAAM,sBAAsB,oCAAoC,UAAU,GACpE,kBAAkB,KAAK,SAAS,QAAQ,UAAU,GAClD,kBAAkB,gBAAgB,QAAQ;GAC9C,cAAc,yBAAyB;IACrC;IACA,UAAU;IACV;IACA,UAAU;IACV,UAAU;IACV,eAAe;IACf,wBAAwB;IACxB,UAAU,YAAY,EAAC,SAAS,CAAC,EAAC;IAClC;GACF,CAAC;GACD,sBAAsB,KAAA;GACtB;GACA,qBAAqB,KAAK,QAAQ,KAAK,cAAc;EACvD,CAAC;EAED,UAAU,OAAO,iBAAiB;GAChC,YAAY;GACZ,qBAAqB;GACrB,gBAAgB,SAA2B;IACzC,QAAQ,UAAU,IACd,sCAAqC,SAAS,mBAAmB,KACrE,YAAY,KAAK,OAAO;GAC1B;EACF,CAAC;CACH;CAEA,IAAM,WAAW,YAAY,QAAQ,QAAQ,IAAI,aAAa,kBAAkB,OAAO,GACjF,SAAS,YAAY,QAAQ,QAAQ,IAAI,aAAa,kBAAkB,KAAK;CAMnF,IAJI,UACF,eAAe,KAAK,QAAQ,UAAU,MAAM,GAG1C,OAAO,QACT,MAAU,MACR,uCAAuC,OAAO,OAAO,QAAQ,OAAO,WAAW,IAAI,KAAK,KAC1F;CAGF,OAAO;EACL,UAAU;EACV,YAAY,OAAO;EACnB,cAAc,SAAS;CACzB;AACF;AAEA,SAAS,aAAa,SAG2C;CAC/D,IAAM,EAAC,KAAK,iBAAgB,SAExB;CAOJ,IANA,AAIE,aAJE,KAAK,WAAW,YAAY,IACjB,eAGA,GAAG,eAAe,KAAK,GAAG,IAAI,YAAY,YAAY,GAEjE,CAAC,cAAc,CAAC,WAAW,UAAU,GAAG;CAE5C,IAAM,aAAa,GAAG,eAAe,YAAY,GAAG,IAAI,QAAQ;CAEhE,OAAO,GAAG,2BAA2B,WAAW,QAAQ,GAAG,KAAK,KAAK,QAAQ,UAAU,CAAC;AAC1F;;AAGA,MAAM,gCAAgC;;;;;;;;AAStC,SAAS,qCACP,SACA,qBACS;CACT,IAAI,oBAAoB,SAAS,KAAK,QAAQ,cAAc,0BAC1D,OAAO;CAET,IAAM,aAAa,8BAA8B,KAAK,QAAQ,IAAI,CAAC,GAAG;CACtE,OAAO,eAAe,KAAA,KAAa,oBAAoB,IAAI,UAAU;AACvE;AAEA,SAAS,gBAAgB,OAAqC;CAC5D,IAAI,MAAM,WAAW,GAAG;CACxB,IAAI,MAAM,KAAK,QAAQ,MAAM,EAAG;CAChC,KAAK,IAAM,QAAQ,MAAM,MAAM,CAAC,GAC9B,OAAO,QAAQ,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,WAAW,MAAM,KAAK,GAAG,KAAK,SAAS,MAC/E,MAAM,KAAK,QAAQ,GAAG;CAG1B,OAAO;AACT;AAEA,SAAS,eACP,KACA,QACA,UACA,QACM;CACN,AAAI,SAAS,UACX,OAAO,IAAI;CAGb,KAAK,IAAM,OAAO,UAAU;EAC1B,IAAI,IAAI,cAAc,UAIpB;EAEF,IAAM,iBAAiB,IAAI,kBAAkB,KAAK,SAAS,KAAK,IAAI,cAAc;EAClF,OAAO,KACL,GAAG,kBAAkB,IAAI,GAAG,IAAI,eAAe,GAAG,IAAI,iBAAiB,aAAa,IAAI,UAAU,IAAI,IAAI,KAAK,GACjH;CACF;CAEA,AAAI,CAAC,SAAS,UAAU,OAAO,UAC7B,OAAO,IAAI;CAGb,KAAK,IAAM,OAAO,QAAQ;EACxB,IAAM,iBAAiB,IAAI,kBAAkB,KAAK,SAAS,KAAK,IAAI,cAAc;EAClF,OAAO,MACL,GAAG,kBAAkB,IAAI,GAAG,IAAI,eAAe,GAAG,IAAI,iBAAiB,WAAW,IAAI,UAAU,IAAI,IAAI,KAAK,GAC/G;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"tsdoc.mjs","names":[],"sources":["../src/tsdoc/createApiExtractorConfig.ts","../src/tsdoc/createTSDocConfig.ts","../src/tsdoc/getExtractMessagesConfig.ts","../src/tsdoc/synthesizedNamespaces.ts","../src/tsdoc/checkTsdoc.ts"],"sourcesContent":["import path from 'node:path'\nimport type {IConfigFile, IExtractorMessagesConfig} from '@microsoft/api-extractor'\n\n/** @internal */\nexport function createApiExtractorConfig(options: {\n bundledPackages?: string[]\n distPath: string\n exportPath: string\n filePath: string\n messages: IExtractorMessagesConfig\n projectFolder: string\n mainEntryPointFilePath: string\n /**\n * Only `compilerOptions.paths` is read: when present, API Extractor gets an override that\n * clears `paths` so self-referencing package imports resolve through `node_modules` instead.\n */\n tsconfig: {options: {paths?: unknown}}\n tsconfigPath: string\n}): IConfigFile {\n const {\n bundledPackages,\n distPath,\n exportPath,\n filePath,\n messages,\n projectFolder,\n mainEntryPointFilePath,\n tsconfig,\n tsconfigPath,\n } = options\n\n return {\n apiReport: {\n enabled: false,\n reportFileName: '<unscopedPackageName>.api.md',\n },\n bundledPackages,\n\n // If `paths` are used for self-referencing imports (e.g. the module is named `sanity`, and the `sanity/structure` export is also importing from `sanity/router`),\n compiler: tsconfig.options.paths\n ? {\n overrideTsconfig: {\n extends: tsconfigPath,\n compilerOptions: {\n // An empty object replaces whatever is in the original tsconfig file\n paths: {},\n },\n },\n }\n : {tsconfigFilePath: tsconfigPath},\n\n docModel: {\n enabled: false,\n apiJsonFilePath: path.resolve(distPath, `${exportPath}.api.json`),\n },\n dtsRollup: {\n // Types come from tsdown; this check only runs API Extractor's TSDoc/release-tag rules\n enabled: false,\n untrimmedFilePath: path.resolve(distPath, filePath),\n },\n tsdocMetadata: {\n enabled: false,\n },\n messages,\n mainEntryPointFilePath,\n projectFolder,\n }\n}\n","import {readFile} from 'node:fs/promises'\nimport {createRequire} from 'node:module'\nimport {TSDocConfigFile} from '@microsoft/tsdoc-config'\nimport {parse} from 'jsonc-parser'\nimport type {PackageTsdocCustomTag} from './types.ts'\n\nconst require = createRequire(import.meta.url)\n\n/** @internal */\nexport async function createTSDocConfig(opts: {\n customTags: PackageTsdocCustomTag[]\n}): Promise<TSDocConfigFile | undefined> {\n const {customTags} = opts\n\n if (customTags.length === 0) {\n return undefined\n }\n\n const tsDocBaseBuf = await readFile(\n require.resolve('@microsoft/api-extractor/extends/tsdoc-base.json'),\n )\n\n // Include the definitions that are required for API Extractor\n // extends: ['@microsoft/api-extractor/extends/tsdoc-base.json'],\n const tsDocBaseConfig = parse(tsDocBaseBuf.toString())\n\n // Define custom tags and specify how they should be parsed\n const tagDefinitions = (tsDocBaseConfig.tagDefinitions || []).concat(\n customTags.map((t) => ({\n tagName: `@${t.name}`,\n syntaxKind: t.syntaxKind,\n allowMultiple: t.allowMultiple,\n })),\n )\n\n // Indicate that custom tags are supported by your tooling.\n // (Without this, warnings may be reported saying that a tag is unsupported.)\n const supportForTags = {...tsDocBaseConfig.supportForTags}\n\n for (const customTag of customTags) {\n supportForTags[`@${customTag.name}`] = true\n }\n\n return TSDocConfigFile.loadFromObject({\n ...tsDocBaseConfig,\n noStandardTags: false,\n tagDefinitions,\n supportForTags,\n })\n}\n","import {ExtractorLogLevel, type IExtractorMessagesConfig} from '@microsoft/api-extractor'\nimport type {PackageTsdocOptions, PackageTsdocRuleLevel} from './types.ts'\n\nconst LOG_LEVELS: Record<PackageTsdocRuleLevel, ExtractorLogLevel> = {\n error: ExtractorLogLevel.Error,\n info: ExtractorLogLevel.Info,\n off: ExtractorLogLevel.None,\n warn: ExtractorLogLevel.Warning,\n}\n\n/** @internal */\nexport function getExtractMessagesConfig(options: {\n rules: PackageTsdocOptions['rules']\n disabled?: boolean\n}): IExtractorMessagesConfig {\n const {rules, disabled = false} = options\n\n function ruleToLogLevel(\n key: keyof NonNullable<PackageTsdocOptions['rules']>,\n defaultLevel?: ExtractorLogLevel,\n ) {\n const r = rules?.[key]\n\n return r ? LOG_LEVELS[r] : defaultLevel || ExtractorLogLevel.Warning\n }\n\n return {\n compilerMessageReporting: {\n default: {\n logLevel: disabled ? ExtractorLogLevel.None : ExtractorLogLevel.Warning,\n },\n },\n\n extractorMessageReporting: disabled\n ? {\n default: {\n logLevel: ExtractorLogLevel.None,\n addToApiReportFile: false,\n },\n }\n : {\n 'default': {\n logLevel: ExtractorLogLevel.Warning,\n addToApiReportFile: false,\n },\n\n 'ae-forgotten-export': {\n /**\n * This is hardcoded to `none` as it's no longer needed since TypeScript 5.5 https://github.com/microsoft/TypeScript/issues/42873\n * It's hardcoded to `none` since supported by API Extractor when using `module: 'Preserve'` doesn't support it well since `@microsoft/api-extractor` v7.49.0, which upgraded from TS 5.4 to 5.7 internally\n */\n logLevel: ExtractorLogLevel.None,\n addToApiReportFile: false,\n },\n\n 'ae-incompatible-release-tags': {\n logLevel: ruleToLogLevel('ae-incompatible-release-tags', ExtractorLogLevel.Error),\n addToApiReportFile: false,\n },\n\n 'ae-internal-missing-underscore': {\n logLevel: ruleToLogLevel('ae-internal-missing-underscore'),\n addToApiReportFile: false,\n },\n\n 'ae-missing-release-tag': {\n logLevel: ruleToLogLevel('ae-missing-release-tag', ExtractorLogLevel.Error),\n addToApiReportFile: false,\n },\n\n 'ae-wrong-input-file-type': {\n logLevel: ExtractorLogLevel.None,\n addToApiReportFile: false,\n },\n },\n\n tsdocMessageReporting: disabled\n ? {\n default: {\n logLevel: ExtractorLogLevel.None,\n addToApiReportFile: false,\n },\n }\n : {\n 'default': {\n logLevel: ExtractorLogLevel.Warning,\n addToApiReportFile: false,\n },\n\n 'tsdoc-link-tag-unescaped-text': {\n logLevel: ruleToLogLevel('tsdoc-link-tag-unescaped-text', ExtractorLogLevel.Warning),\n addToApiReportFile: false,\n },\n\n 'tsdoc-undefined-tag': {\n logLevel: ruleToLogLevel('tsdoc-undefined-tag', ExtractorLogLevel.Error),\n addToApiReportFile: false,\n },\n\n 'tsdoc-unsupported-tag': {\n logLevel: ruleToLogLevel('tsdoc-unsupported-tag', ExtractorLogLevel.None),\n addToApiReportFile: false,\n },\n },\n }\n}\n","import {existsSync, readFileSync} from 'node:fs'\nimport path from 'node:path'\n// The JS compiler API is loaded from the official `@typescript/typescript6` compat package\n// instead of the `typescript` peer dependency, as TypeScript 7 (the Go-native compiler) no longer\n// ships it\nimport ts from '@typescript/typescript6'\n\n/**\n * The exports-object identifiers of rolldown's namespace interop: `<module>_exports` (the\n * declaration bundling pass names them after the virtual declaration module, e.g. `inner.d.ts`\n * → `inner_d_exports`), with rolldown's `$<n>` suffix when deconflicting renames one.\n */\nconst RE_WRAPPER_NAME = /_exports(\\$\\d+)?$/\n\n/** Matches the relative specifiers of emitted sibling chunks (`./chunk-<hash>.js`). */\nconst RE_RELATIVE_SPECIFIER = /^\\.\\.?\\//\n\n/**\n * Finds the local names of the `declare namespace <name>_exports {…}` wrappers that the\n * declaration bundling pass (tsdown / rolldown-plugin-dts) synthesizes for namespace re-exports\n * like `export * as ns from './module'` (or `import * as ns` + `export {ns}`).\n *\n * Bundling loses the doc comment of the re-export statement, so the wrapper cannot carry a\n * release tag — there is no way to tag it from userland, and API Extractor would flag it with\n * `ae-missing-release-tag` (https://github.com/sanity-io/pkg-utils/issues/3281). Skipping it\n * matches how API Extractor treats the equivalent namespace of its own rollups (it never\n * checks those). The members re-exported through the wrapper keep their own doc comments in\n * the output; API Extractor does not flag them individually either way (only directly exported\n * declarations are consumable entities of the missing-release-tag check).\n *\n * A name only qualifies when all of these hold, so user-authored symbols that merely resemble\n * the interop naming stay checked:\n *\n * - it matches rolldown's `<module>_exports` naming (with an optional `$<n>` deconflict suffix)\n * - it is declared as a namespace — in the entry itself, or in a sibling chunk the entry\n * imports (a wrapper shared by several entries lives in the chunk that owns the module's\n * declarations)\n * - that namespace has the synthesized body shape: nothing but `export { … };` specifier lists\n * pointing at sibling declarations of the same file. A user-authored namespace declares its\n * own members (`declare namespace config_exports { const userValue: string; }`), and those\n * members are what the author tags — so it stays checked even when the bundler's\n * deconflicting hands it a wrapper-shaped name\n * - the entry does not export the name unaliased: a synthesized wrapper is always re-exported\n * under the alias of the original namespace re-export (`export { inner_d_exports as inner }`),\n * while an unaliased export (`export { foo_exports }`, `export declare namespace foo_exports`)\n * is a name the author chose — and can tag\n * @internal\n */\nexport function collectSynthesizedNamespaceWrappers(entryDtsFile: string): Set<string> {\n const entry = parseDts(entryDtsFile)\n if (!entry) return new Set()\n\n const unaliasedExports = new Set<string>()\n const wrapperShapedNames = new Set<string>()\n const chunkFiles = new Set<string>()\n\n for (const statement of entry.statements) {\n collectWrapperShapedNamespaceName(statement, wrapperShapedNames)\n\n if (ts.isExportDeclaration(statement)) {\n const {exportClause} = statement\n if (exportClause && ts.isNamedExports(exportClause)) {\n for (const element of exportClause.elements) {\n if (!element.propertyName || element.propertyName.text === element.name.text) {\n unaliasedExports.add(element.name.text)\n }\n }\n } else if (exportClause && ts.isNamespaceExport(exportClause)) {\n unaliasedExports.add(exportClause.name.text)\n }\n collectChunkFile(entryDtsFile, statement.moduleSpecifier, chunkFiles)\n } else if (ts.isImportDeclaration(statement)) {\n collectChunkFile(entryDtsFile, statement.moduleSpecifier, chunkFiles)\n } else {\n collectExportedDeclarationNames(statement, unaliasedExports)\n }\n }\n\n for (const chunkFile of chunkFiles) {\n const chunk = parseDts(chunkFile)\n if (!chunk) continue\n for (const statement of chunk.statements) {\n collectWrapperShapedNamespaceName(statement, wrapperShapedNames)\n }\n }\n\n const wrappers = new Set<string>()\n for (const name of wrapperShapedNames) {\n if (RE_WRAPPER_NAME.test(name) && !unaliasedExports.has(name)) wrappers.add(name)\n }\n return wrappers\n}\n\nfunction parseDts(filePath: string): ts.SourceFile | undefined {\n if (!existsSync(filePath)) return undefined\n return ts.createSourceFile(\n filePath,\n readFileSync(filePath, 'utf8'),\n ts.ScriptTarget.Latest,\n false,\n )\n}\n\n/**\n * Collects the name of a top-level `declare namespace <Identifier> {…}` statement whose body has\n * the shape the declaration bundling pass synthesizes: only `export { … };` specifier lists\n * naming sibling declarations of the same file, never members of its own. Every namespace\n * re-export the bundler rewrites comes out that way, whatever the re-exported module holds\n * (values, types, a default export, further namespace re-exports).\n */\nfunction collectWrapperShapedNamespaceName(statement: ts.Statement, names: Set<string>): void {\n if (\n !ts.isModuleDeclaration(statement) ||\n !ts.isIdentifier(statement.name) ||\n (statement.flags & ts.NodeFlags.Namespace) === 0\n ) {\n return\n }\n\n const {body} = statement\n if (!body || !ts.isModuleBlock(body)) return\n\n const onlyReExportsSiblings = body.statements.every(\n (member) =>\n ts.isExportDeclaration(member) &&\n !member.moduleSpecifier &&\n member.exportClause !== undefined &&\n ts.isNamedExports(member.exportClause),\n )\n if (!onlyReExportsSiblings) return\n\n names.add(statement.name.text)\n}\n\n/**\n * Collects the names a declaration with an `export` modifier exports directly, e.g.\n * `export declare namespace foo_exports {…}` — those names are user-chosen (the author can\n * tag them), unlike the alias-only re-export of a synthesized wrapper.\n */\nfunction collectExportedDeclarationNames(statement: ts.Statement, names: Set<string>): void {\n const modifiers = ts.canHaveModifiers(statement) ? ts.getModifiers(statement) : undefined\n if (!modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword)) return\n\n if (ts.isVariableStatement(statement)) {\n for (const declaration of statement.declarationList.declarations) {\n if (ts.isIdentifier(declaration.name)) names.add(declaration.name.text)\n }\n } else if (\n (ts.isFunctionDeclaration(statement) ||\n ts.isClassDeclaration(statement) ||\n ts.isInterfaceDeclaration(statement) ||\n ts.isTypeAliasDeclaration(statement) ||\n ts.isEnumDeclaration(statement)) &&\n statement.name\n ) {\n names.add(statement.name.text)\n } else if (ts.isModuleDeclaration(statement) && ts.isIdentifier(statement.name)) {\n names.add(statement.name.text)\n }\n}\n\n/**\n * Resolves the sibling chunk file a relative import/export specifier points at, mapping the\n * runtime extension to the declaration extension the chunk is emitted with on disk\n * (`./chunk.js` → `./chunk.d.ts`, like the declaration output of the bundling pass itself).\n */\nfunction collectChunkFile(\n entryDtsFile: string,\n moduleSpecifier: ts.Expression | undefined,\n files: Set<string>,\n): void {\n if (!moduleSpecifier || !ts.isStringLiteral(moduleSpecifier)) return\n const specifier = moduleSpecifier.text\n if (!RE_RELATIVE_SPECIFIER.test(specifier)) return\n const dtsFile = specifierToDtsFile(specifier)\n if (!dtsFile) return\n files.add(path.resolve(path.dirname(entryDtsFile), dtsFile))\n}\n\n/** `./chunk.js` → `./chunk.d.ts` (`.mjs` → `.d.mts`, `.cjs` → `.d.cts`). */\nfunction specifierToDtsFile(specifier: string): string | undefined {\n if (/\\.d\\.[mc]?ts$/.test(specifier)) return specifier\n if (specifier.endsWith('.mjs')) return `${specifier.slice(0, -4)}.d.mts`\n if (specifier.endsWith('.cjs')) return `${specifier.slice(0, -4)}.d.cts`\n if (specifier.endsWith('.js')) return `${specifier.slice(0, -3)}.d.ts`\n return undefined\n}\n","import {existsSync} from 'node:fs'\nimport path from 'node:path'\nimport {\n Extractor,\n ExtractorConfig,\n ExtractorLogLevel,\n type ExtractorMessage,\n} from '@microsoft/api-extractor'\n// The JS compiler API is loaded from the official `@typescript/typescript6` compat package\n// instead of the `typescript` peer dependency, as TypeScript 7 (the Go-native compiler) no longer\n// ships it\nimport ts from '@typescript/typescript6'\nimport {createApiExtractorConfig} from './createApiExtractorConfig.ts'\nimport {createTSDocConfig} from './createTSDocConfig.ts'\nimport {getExtractMessagesConfig} from './getExtractMessagesConfig.ts'\nimport {collectSynthesizedNamespaceWrappers} from './synthesizedNamespaces.ts'\nimport type {PackageTsdocOptions} from './types.ts'\n\n/** @public */\nexport interface CheckTsdocLogger {\n log: (...args: unknown[]) => void\n warn: (...args: unknown[]) => void\n error: (...args: unknown[]) => void\n}\n\n/** @public */\nexport interface CheckTsdocOptions extends PackageTsdocOptions {\n /** Package root (directory containing `package.json`). */\n cwd: string\n /**\n * Absolute paths to the entry `.d.ts` / `.d.mts` / `.d.cts` files to check.\n * JS-only entries with no declarations are skipped automatically when listed.\n */\n entryDtsFiles: string[]\n /**\n * Path to the tsconfig used for the build, relative to `cwd` or absolute.\n * @defaultValue `'tsconfig.json'`\n */\n tsconfig?: string\n /**\n * Directory of distributed files (used for API Extractor's path mapping). Defaults to the\n * common parent of `entryDtsFiles`, or `dist` under `cwd` when the list is empty.\n */\n outDir?: string\n /**\n * When provided, messages are printed through this logger. Errors throw after reporting so\n * callers (and tsdown's `build:done` hook) fail the build.\n */\n logger?: CheckTsdocLogger\n}\n\n/** @public */\nexport interface CheckTsdocResult {\n messages: ExtractorMessage[]\n errorCount: number\n warningCount: number\n}\n\n/**\n * Run `@microsoft/api-extractor` against the given entry declaration files to check that TSDoc\n * tags are valid and release tags are correct. Import from `@sanity/tsdown-config/tsdoc`.\n * @public\n */\nexport async function checkTsdoc(options: CheckTsdocOptions): Promise<CheckTsdocResult> {\n const {\n cwd,\n entryDtsFiles,\n bundledPackages,\n customTags = [],\n rules = {},\n logger,\n outDir: outDirOption,\n } = options\n\n const tsconfigPath = path.resolve(cwd, options.tsconfig || 'tsconfig.json')\n const tsconfig = loadTSConfig({cwd, tsconfigPath})\n // api-extractor needs a `compilerOptions.outDir` for its path mapping; tsdown does not, so\n // fall back to the configured outDir / dist folder when the tsconfig leaves it unset\n const outDir =\n tsconfig?.options.outDir ??\n (outDirOption ? path.resolve(cwd, outDirOption) : undefined) ??\n commonParentDir(entryDtsFiles) ??\n path.resolve(cwd, 'dist')\n\n const tsdocConfigFile = await createTSDocConfig({customTags})\n const messagesConfig = getExtractMessagesConfig({rules})\n const allMessages: ExtractorMessage[] = []\n\n for (const exportPath of entryDtsFiles) {\n if (!existsSync(exportPath)) continue\n\n // The declaration bundling pass synthesizes `declare namespace <name>_exports` wrappers\n // for namespace re-exports and loses the doc comment of the re-export statement, so the\n // wrappers can never carry a release tag — `ae-missing-release-tag` skips them.\n // https://github.com/sanity-io/pkg-utils/issues/3281\n const synthesizedWrappers = collectSynthesizedNamespaceWrappers(exportPath)\n const relativeDtsPath = path.relative(outDir, exportPath)\n const extractorConfig = ExtractorConfig.prepare({\n configObject: createApiExtractorConfig({\n bundledPackages,\n distPath: outDir,\n exportPath,\n filePath: relativeDtsPath,\n messages: messagesConfig,\n projectFolder: cwd,\n mainEntryPointFilePath: exportPath,\n tsconfig: tsconfig ?? {options: {}},\n tsconfigPath,\n }),\n configObjectFullPath: undefined,\n tsdocConfigFile,\n packageJsonFullPath: path.resolve(cwd, 'package.json'),\n })\n\n Extractor.invoke(extractorConfig, {\n localBuild: true,\n showVerboseMessages: true,\n messageCallback(message: ExtractorMessage) {\n message.handled = true\n if (isSynthesizedNamespaceWrapperMessage(message, synthesizedWrappers)) return\n allMessages.push(message)\n },\n })\n }\n\n const warnings = allMessages.filter((msg) => msg.logLevel === ExtractorLogLevel.Warning)\n const errors = allMessages.filter((msg) => msg.logLevel === ExtractorLogLevel.Error)\n\n if (logger) {\n reportMessages(cwd, logger, warnings, errors)\n }\n\n if (errors.length) {\n throw new Error(\n `TSDoc/release-tag check failed with ${errors.length} error${errors.length === 1 ? '' : 's'}`,\n )\n }\n\n return {\n messages: allMessages,\n errorCount: errors.length,\n warningCount: warnings.length,\n }\n}\n\nfunction loadTSConfig(options: {\n cwd: string\n tsconfigPath: string\n}): ReturnType<typeof ts.parseJsonConfigFileContent> | undefined {\n const {cwd, tsconfigPath} = options\n // Resolve a relative name from `cwd` (e.g. `tsconfig.dist.json`); an absolute path is kept.\n let configPath: string | undefined\n if (path.isAbsolute(tsconfigPath)) {\n configPath = tsconfigPath\n } else {\n // oxlint-disable-next-line unbound-method\n configPath = ts.findConfigFile(cwd, ts.sys.fileExists, tsconfigPath)\n }\n if (!configPath || !existsSync(configPath)) return undefined\n // oxlint-disable-next-line unbound-method\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile)\n // Relative `extends`/`include`/`paths` are resolved from the tsconfig's directory, not `cwd`\n return ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath))\n}\n\n/** The quoted symbol name leading api-extractor's `ae-missing-release-tag` message text. */\nconst RE_MISSING_RELEASE_TAG_SYMBOL = /^\"([^\"]+)\" is part of the package's API/\n\n/**\n * Whether a message is an `ae-missing-release-tag` complaint about a namespace wrapper the\n * declaration bundling pass synthesized (which userland can never tag). The flagged symbol is\n * only identifiable through the message text: api-extractor quotes the local name of the\n * declaration, and attaches no structured properties (its source location maps through\n * `.d.ts.map` files, often landing on an unrelated source position).\n */\nfunction isSynthesizedNamespaceWrapperMessage(\n message: ExtractorMessage,\n synthesizedWrappers: Set<string>,\n): boolean {\n if (synthesizedWrappers.size === 0 || message.messageId !== 'ae-missing-release-tag') {\n return false\n }\n const symbolName = RE_MISSING_RELEASE_TAG_SYMBOL.exec(message.text)?.[1]\n return symbolName !== undefined && synthesizedWrappers.has(symbolName)\n}\n\nfunction commonParentDir(files: string[]): string | undefined {\n if (files.length === 0) return undefined\n let dir = path.dirname(files[0]!)\n for (const file of files.slice(1)) {\n while (dir !== path.dirname(dir) && !file.startsWith(dir + path.sep) && file !== dir) {\n dir = path.dirname(dir)\n }\n }\n return dir\n}\n\nfunction reportMessages(\n cwd: string,\n logger: CheckTsdocLogger,\n warnings: ExtractorMessage[],\n errors: ExtractorMessage[],\n): void {\n if (warnings.length) {\n logger.log()\n }\n\n for (const msg of warnings) {\n if (msg.messageId === 'TS6307') {\n // Ignore this warning:\n // > TS6307: <filename> is not in project file list.\n // > Projects must list all files or use an 'include' pattern.\n continue\n }\n const sourceFilePath = msg.sourceFilePath && path.relative(cwd, msg.sourceFilePath)\n logger.warn(\n `${sourceFilePath || '?'}:${msg.sourceFileLine}:${msg.sourceFileColumn} - warning ${msg.messageId}\\n${msg.text}\\n`,\n )\n }\n\n if (!warnings.length && errors.length) {\n logger.log()\n }\n\n for (const msg of errors) {\n const sourceFilePath = msg.sourceFilePath && path.relative(cwd, msg.sourceFilePath)\n logger.error(\n `${sourceFilePath || '?'}:${msg.sourceFileLine}:${msg.sourceFileColumn} - error ${msg.messageId}\\n${msg.text}\\n`,\n )\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/tsdown-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.1",
|
|
4
4
|
"description": "Shared configuration for tsdown",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity-io",
|
|
@@ -36,32 +36,32 @@
|
|
|
36
36
|
"dist"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@microsoft/api-extractor": "^7.59.
|
|
40
|
-
"@microsoft/tsdoc-config": "^0.18.
|
|
39
|
+
"@microsoft/api-extractor": "^7.59.1",
|
|
40
|
+
"@microsoft/tsdoc-config": "^0.18.2",
|
|
41
41
|
"@sanity/browserslist-config": "^1.0.5",
|
|
42
|
-
"@sanity/vanilla-extract-tsdown-plugin": "^0.
|
|
42
|
+
"@sanity/vanilla-extract-tsdown-plugin": "^0.4.1",
|
|
43
43
|
"@typescript/typescript6": "^6.0.2",
|
|
44
44
|
"@vitejs/plugin-react": "^6.1.1",
|
|
45
|
-
"browserslist": "^4.
|
|
45
|
+
"browserslist": "^4.29.0",
|
|
46
46
|
"jsonc-parser": "^3.3.1",
|
|
47
47
|
"lightningcss": "^1.33.0",
|
|
48
48
|
"package-manager-detector": "^1.8.0",
|
|
49
49
|
"publint": "^0.3.24",
|
|
50
|
-
"rolldown": "~1.2.
|
|
50
|
+
"rolldown": "~1.2.9"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@babel/core": "^7.29.7",
|
|
54
|
-
"@rolldown/plugin-babel": "^0.2.
|
|
55
|
-
"@sanity/pkg-utils": "^
|
|
54
|
+
"@rolldown/plugin-babel": "^0.2.4",
|
|
55
|
+
"@sanity/pkg-utils": "^13.0.1",
|
|
56
56
|
"@sanity/tsconfig": "^2.2.1",
|
|
57
|
-
"@tsdown/css": "^0.
|
|
57
|
+
"@tsdown/css": "^0.23.0",
|
|
58
58
|
"@types/babel__core": "^7.20.5",
|
|
59
59
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
60
|
-
"oxc-transform-react": "^0.
|
|
61
|
-
"tinyexec": "^1.3.
|
|
62
|
-
"tsdown": "^0.
|
|
60
|
+
"oxc-transform-react": "^0.150.0",
|
|
61
|
+
"tinyexec": "^1.3.1",
|
|
62
|
+
"tsdown": "^0.23.0",
|
|
63
63
|
"typescript": "7.0.2",
|
|
64
|
-
"vitest": "^
|
|
64
|
+
"vitest": "^5.0.1"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"@babel/core": "*",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"@tsdown/css": "*",
|
|
70
70
|
"babel-plugin-react-compiler": "*",
|
|
71
71
|
"oxc-transform-react": "*",
|
|
72
|
-
"tsdown": "^0.
|
|
72
|
+
"tsdown": "^0.23.0",
|
|
73
73
|
"typescript": "6.x || 7.x"
|
|
74
74
|
},
|
|
75
75
|
"peerDependenciesMeta": {
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
}
|
|
91
91
|
},
|
|
92
92
|
"engines": {
|
|
93
|
-
"node": "^22.18.0 ||
|
|
93
|
+
"node": "^22.18.0 || ^24.11.0 || >=26.0.0"
|
|
94
94
|
},
|
|
95
95
|
"scripts": {
|
|
96
96
|
"build": "tsdown",
|