@sanity/pkg-utils
Version:
Simple utilities for modern npm packages.
872 lines (870 loc) • 33.4 kB
JavaScript
import chalk from "chalk";
import { Observable, from } from "rxjs";
import path from "node:path";
import * as rimraf from "rimraf";
import { rimraf as rimraf$1 } from "rimraf";
import ts from "typescript";
import fs, { readFile } from "node:fs/promises";
import { ExtractorConfig, Extractor } from "@microsoft/api-extractor";
import { mkdirp } from "mkdirp";
import * as prettier from "prettier";
import { createRequire } from "node:module";
import { TSDocConfigFile } from "@microsoft/tsdoc-config";
import { parse } from "jsonc-parser";
import { parse as parse$1, print } from "recast";
import typeScriptParser from "recast/parsers/typescript.js";
import { createConsoleSpy, resolveConfigProperty, pkgExtMap } from "./consoleSpy.js";
import { rollup, watch } from "rollup";
import { optimizeLodashImports } from "@optimize-lodash/rollup-plugin";
import alias from "@rollup/plugin-alias";
import { babel, getBabelOutputPlugin } from "@rollup/plugin-babel";
import commonjs from "@rollup/plugin-commonjs";
import json from "@rollup/plugin-json";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import replace from "@rollup/plugin-replace";
import terser from "@rollup/plugin-terser";
import esbuild from "rollup-plugin-esbuild";
function printExtractMessages(ctx, messages) {
const { cwd, logger } = ctx, warnings = messages.filter((msg) => msg.logLevel === "warning");
warnings.length && logger.log();
for (const msg of warnings) {
const sourceFilePath = msg.sourceFilePath && path.relative(cwd, msg.sourceFilePath);
msg.messageId !== "TS6307" && logger.log(
[
`${chalk.cyan(sourceFilePath || "?")}`,
`:${chalk.yellow(msg.sourceFileLine)}:${chalk.yellow(msg.sourceFileColumn)}`,
` - ${chalk.yellow("warning")} ${chalk.gray(msg.messageId)}
`,
msg.text,
`
`
].join("")
);
}
const errors = messages.filter((msg) => msg.logLevel === "error");
!warnings.length && errors.length && logger.log("");
for (const msg of errors) {
const sourceFilePath = msg.sourceFilePath && path.relative(cwd, msg.sourceFilePath);
logger.log(
[
`${chalk.cyan(sourceFilePath || "?")}`,
`:${chalk.yellow(msg.sourceFileLine)}:${chalk.yellow(msg.sourceFileColumn)}`,
` - ${chalk.red("error")} ${chalk.gray(msg.messageId)}
`,
msg.text,
`
`
].join("")
);
}
errors.length && process.exit(1);
}
var printExtractMessages$1 = /* @__PURE__ */ Object.freeze({
__proto__: null,
printExtractMessages
});
function printDiagnostic(options) {
const { cwd, logger, diagnostic } = options;
if (diagnostic.file && diagnostic.start) {
const { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), message = ts.flattenDiagnosticMessageText(diagnostic.messageText, `
`), file = path.relative(cwd, diagnostic.file.fileName), output = [
`${chalk.yellow(file)}:${chalk.blue(line + 1)}:${chalk.blue(character + 1)} - `,
`${chalk.gray(`TS${diagnostic.code}:`)} ${message}`
].join("");
diagnostic.category === ts.DiagnosticCategory.Error && logger.error(output), diagnostic.category === ts.DiagnosticCategory.Warning && logger.warn(output), diagnostic.category === ts.DiagnosticCategory.Message && logger.log(output), diagnostic.category === ts.DiagnosticCategory.Suggestion && logger.log(output);
} else
logger.log(ts.flattenDiagnosticMessageText(diagnostic.messageText, `
`));
}
async function buildTypes(options) {
const { cwd, logger, outDir, tsconfig, strict = !1 } = options, compilerOptions = {
...tsconfig.options,
declaration: !0,
declarationDir: outDir,
emitDeclarationOnly: !0,
noEmit: !1,
noEmitOnError: strict ? !0 : tsconfig.options.noEmitOnError ?? !0,
noCheck: tsconfig.options.noCheck ?? tsconfig.options.isolatedDeclarations,
outDir
}, program = ts.createProgram(tsconfig.fileNames, compilerOptions), emitResult = program.emit(), allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
for (const diagnostic of allDiagnostics)
printDiagnostic({ cwd, logger, diagnostic });
if (emitResult.emitSkipped && allDiagnostics.filter((diag) => diag.category === ts.DiagnosticCategory.Error).length)
throw new Error("failed to compile TypeScript definitions");
}
class DtsError extends Error {
messages;
constructor(message, messages) {
super(message), this.messages = messages;
}
}
function createApiExtractorConfig(options) {
const {
bundledPackages,
distPath,
exportPath,
filePath,
messages,
projectFolder,
mainEntryPointFilePath,
tsconfig,
tsconfigPath,
dtsRollupEnabled
} = options;
return {
apiReport: {
enabled: !1,
reportFileName: "<unscopedPackageName>.api.md"
},
bundledPackages,
// 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`),
compiler: tsconfig.options.paths ? {
overrideTsconfig: {
extends: tsconfigPath,
compilerOptions: {
// An empty object replaces whatever is in the original tsconfig file
paths: {}
}
}
} : { tsconfigFilePath: tsconfigPath },
docModel: {
enabled: !1,
apiJsonFilePath: path.resolve(distPath, `${exportPath}.api.json`)
},
dtsRollup: {
enabled: dtsRollupEnabled,
untrimmedFilePath: path.resolve(distPath, filePath)
// betaTrimmedFilePath: path.resolve(distPath, filePath.replace('.d.ts', '-beta.d.ts')),
// publicTrimmedFilePath: path.resolve(distPath, filePath.replace('.d.ts', '-public.d.ts')),
},
tsdocMetadata: {
enabled: !1
},
messages,
mainEntryPointFilePath,
projectFolder
};
}
var createApiExtractorConfig$1 = /* @__PURE__ */ Object.freeze({
__proto__: null,
createApiExtractorConfig
});
const require2 = createRequire(import.meta.url);
async function createTSDocConfig(opts) {
const { customTags } = opts;
if (customTags.length === 0)
return;
const tsDocBaseBuf = await readFile(
require2.resolve("@microsoft/api-extractor/extends/tsdoc-base.json")
), tsDocBaseConfig = parse(tsDocBaseBuf.toString()), tagDefinitions = (tsDocBaseConfig.tagDefinitions || []).concat(
customTags.map((t) => ({
tagName: `@${t.name}`,
syntaxKind: t.syntaxKind,
allowMultiple: t.allowMultiple
}))
), supportForTags = { ...tsDocBaseConfig.supportForTags };
for (const customTag of customTags)
supportForTags[`@${customTag.name}`] = !0;
return TSDocConfigFile.loadFromObject({
...tsDocBaseConfig,
noStandardTags: !1,
tagDefinitions,
supportForTags
});
}
var createTSDocConfig$1 = /* @__PURE__ */ Object.freeze({
__proto__: null,
createTSDocConfig
});
async function extractModuleBlocksFromTypes({
tsOutDir,
extractResult
}) {
const program = extractResult.compilerState.program, moduleBlocks = [], sourceFiles = [...program.getSourceFiles()].filter((sourceFile) => sourceFile.fileName.includes(tsOutDir));
for (const sourceFile of sourceFiles)
sourceFile.text.includes("declare module") && moduleBlocks.push(...extractModuleBlocks(sourceFile.text));
return moduleBlocks;
}
function extractModuleBlocks(fileContent) {
return parse$1(fileContent, {
parser: typeScriptParser
}).program.body.filter((node) => node.type === "TSModuleDeclaration").map((node) => print(node).code);
}
const LOG_LEVELS = {
error: "error",
info: "info",
off: "none",
warn: "warning"
};
function getExtractMessagesConfig(options) {
const { rules, disabled = !1 } = options;
function ruleToLogLevel(key, defaultLevel) {
const r = rules?.[key];
return r ? LOG_LEVELS[r] : defaultLevel || "warning";
}
return {
compilerMessageReporting: {
default: {
logLevel: disabled ? "none" : "warning"
}
},
extractorMessageReporting: disabled ? {
default: {
logLevel: "none",
addToApiReportFile: !1
}
} : {
default: {
logLevel: "warning",
addToApiReportFile: !1
},
"ae-forgotten-export": {
/**
* This is hardcoded to `none` as it's no longer needed since TypeScript 5.5 https://github.com/microsoft/TypeScript/issues/42873
* 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
*/
logLevel: "none",
addToApiReportFile: !1
},
"ae-incompatible-release-tags": {
logLevel: ruleToLogLevel("ae-incompatible-release-tags", "error"),
addToApiReportFile: !1
},
"ae-internal-missing-underscore": {
logLevel: ruleToLogLevel("ae-internal-missing-underscore"),
addToApiReportFile: !1
},
"ae-missing-release-tag": {
logLevel: ruleToLogLevel("ae-missing-release-tag", "error"),
addToApiReportFile: !1
},
"ae-wrong-input-file-type": {
logLevel: "none",
addToApiReportFile: !1
}
},
tsdocMessageReporting: disabled ? {
default: {
logLevel: "none",
addToApiReportFile: !1
}
} : {
default: {
logLevel: "warning",
addToApiReportFile: !1
},
"tsdoc-link-tag-unescaped-text": {
logLevel: ruleToLogLevel(
"tsdoc-link-tag-unescaped-text",
"warning"
),
addToApiReportFile: !1
},
"tsdoc-undefined-tag": {
logLevel: ruleToLogLevel("tsdoc-undefined-tag", "error"),
addToApiReportFile: !1
},
"tsdoc-unsupported-tag": {
logLevel: ruleToLogLevel("tsdoc-unsupported-tag", "none"),
addToApiReportFile: !1
}
}
};
}
var getExtractMessagesConfig$1 = /* @__PURE__ */ Object.freeze({
__proto__: null,
getExtractMessagesConfig
});
async function extractTypes(options) {
const {
bundledPackages,
customTags,
distPath,
exportPath,
files,
filePaths,
projectPath,
rules,
sourceTypesPath,
tmpPath,
tsconfig,
tsconfigPath,
extractorDisabled
} = options, tsdocConfigFile = await createTSDocConfig({
customTags: customTags || []
}), filePath = filePaths[0].replace(/\.d\.[mc]ts$/, ".d.ts"), shouldCleanUpDts = !filePaths.includes(filePath), extractorConfig = ExtractorConfig.prepare({
configObject: createApiExtractorConfig({
bundledPackages,
distPath,
exportPath,
filePath,
messages: getExtractMessagesConfig({ rules, disabled: extractorDisabled }),
projectFolder: projectPath,
mainEntryPointFilePath: sourceTypesPath,
tsconfig,
tsconfigPath,
dtsRollupEnabled: !0
}),
configObjectFullPath: void 0,
tsdocConfigFile,
packageJsonFullPath: path.resolve(projectPath, "package.json")
}), messages = [], extractorResult = Extractor.invoke(extractorConfig, {
// Equivalent to the "--local" command-line parameter
localBuild: !0,
// Equivalent to the "--verbose" command-line parameter
showVerboseMessages: !0,
// handle messages
messageCallback(message) {
messages.push(message), message.handled = !0;
}
}), typesPath = path.resolve(distPath, filePath), typesBuf = await fs.readFile(typesPath), prettierConfig = await prettier.resolveConfig(typesPath);
await mkdirp(path.dirname(typesPath));
const moduleBlocks = await extractModuleBlocksFromTypes({
extractResult: extractorResult,
tsOutDir: tmpPath
}), code = [typesBuf.toString(), ...moduleBlocks].join(`
`), prettyCode = await prettier.format(code, {
...prettierConfig,
filepath: typesPath
});
for (const expFilePath of filePaths) {
const expTypesPath = path.resolve(distPath, expFilePath);
await fs.writeFile(expTypesPath, prettyCode), files.push({
type: "types",
path: expTypesPath
});
}
return shouldCleanUpDts && await fs.unlink(typesPath), { extractorResult, messages };
}
async function doExtract(ctx, task) {
const { config, cwd, files, logger, strict, ts: ts2, bundledPackages } = ctx;
if (!ts2.config || !ts2.configPath)
return { type: "dts", messages: [], results: [] };
const { outDir, rootDir = cwd } = ts2.config.options;
if (!outDir)
throw new Error("tsconfig.json is missing `compilerOptions.outDir`");
const tmpPath = path.resolve(outDir, "__tmp__");
await buildTypes({ cwd, logger, outDir: tmpPath, strict, tsconfig: ts2.config });
const messages = [], results = [];
for (const entry of task.entries) {
const exportPath = entry.exportPath === "." ? "./index" : entry.exportPath, sourceTypesPath = path.resolve(
tmpPath,
path.relative(rootDir, path.resolve(cwd, entry.sourcePath)).replace(/\.ts$/, ".d.ts")
), targetPaths = entry.targetPaths.map((targetPath) => path.resolve(cwd, targetPath)), filePaths = targetPaths.map((targetPath) => path.relative(outDir, targetPath)), result = await extractTypes({
bundledPackages: bundledPackages || [],
customTags: config?.extract?.customTags,
distPath: outDir,
exportPath,
files,
filePaths,
projectPath: cwd,
rules: config?.extract?.rules,
sourceTypesPath,
tsconfig: ts2.config,
tmpPath,
tsconfigPath: path.resolve(cwd, ts2.configPath || "tsconfig.json"),
extractorDisabled: config?.extract?.enabled === !1
});
messages.push(...result.messages);
const errors = result.messages.filter((msg) => msg.logLevel === "error");
if (errors.length > 0)
throw await rimraf$1(tmpPath), new DtsError(`encountered ${errors.length} errors when extracting types`, errors);
results.push({ sourcePath: path.resolve(cwd, entry.sourcePath), filePaths: targetPaths });
}
return await rimraf$1(tmpPath), { type: "dts", messages, results };
}
const dtsTask = {
name: (ctx, task) => [
`Build type definitions with ${chalk.bold(ctx.dts)}...`,
" entries:",
...task.entries.map((entry) => entry.targetPaths.map((targetPath) => [
` - ${chalk.cyan(entry.importId)}: `,
`${chalk.yellow(entry.sourcePath)} ${chalk.gray("\u2192")} ${chalk.yellow(targetPath)}`
].join("")).join(`
`))
].join(`
`),
exec: (ctx, task) => new Observable((observer) => {
doExtract(ctx, task).then((result) => {
observer.next(result), observer.complete();
}).catch((err) => {
observer.error(err);
});
}),
complete: (ctx, _task, result) => {
printExtractMessages(ctx, result.messages);
},
error: (ctx, _task, err) => {
const { logger } = ctx;
err instanceof DtsError ? printExtractMessages(ctx, err.messages) : err instanceof Error && logger.error(err);
}
}, dtsWatchTask = {
name: (_ctx, task) => [
"build type definitions",
...task.entries.map((entry) => entry.targetPaths.map((targetPath) => [
` - ${chalk.cyan(entry.importId)}: `,
`${chalk.yellow(entry.sourcePath)} ${chalk.gray("\u2192")} ${chalk.yellow(targetPath)}`
].join("")))
].join(`
`),
exec: (ctx, task) => {
const { config, cwd, files, logger, strict, ts: tsContext, bundledPackages } = ctx;
return new Observable((observer) => {
if (!tsContext.config || !tsContext.configPath) {
observer.next({ type: "dts", messages: [], results: [] }), observer.complete();
return;
}
const { outDir, rootDir = cwd } = tsContext.config.options;
if (!outDir) {
observer.error(new Error("tsconfig.json is missing `compilerOptions.outDir`"));
return;
}
const tmpPath = path.resolve(outDir, "__tmp__");
buildTypes({
cwd,
logger,
outDir: tmpPath,
tsconfig: tsContext.config,
strict
}).catch((err) => {
observer.error(err);
});
const host = ts.createWatchCompilerHost(
tsContext.configPath,
{
...tsContext.config.options,
declaration: !0,
declarationDir: tmpPath,
emitDeclarationOnly: !0,
noEmit: !1,
noEmitOnError: strict ? !0 : tsContext.config.options.noEmitOnError ?? !0,
outDir: tmpPath
},
ts.sys,
ts.createEmitAndSemanticDiagnosticsBuilderProgram,
(diagnostic) => {
logger.error(ts.flattenDiagnosticMessageText(diagnostic.messageText, `
`));
},
(diagnostic) => {
logger.info(ts.flattenDiagnosticMessageText(diagnostic.messageText, `
`));
}
), origPostProgramCreate = host.afterProgramCreate;
host.afterProgramCreate = async (program) => {
origPostProgramCreate?.(program);
const messages = [], results = [];
for (const entry of task.entries) {
const exportPath = entry.exportPath === "." ? "./index" : entry.exportPath, sourceTypesPath = path.resolve(
tmpPath,
path.relative(rootDir, path.resolve(cwd, entry.sourcePath)).replace(/\.ts$/, ".d.ts")
), targetPaths = entry.targetPaths.map((targetPath) => path.resolve(cwd, targetPath)), filePaths = targetPaths.map((targetPath) => path.relative(outDir, targetPath));
try {
const result = await extractTypes({
bundledPackages: bundledPackages || [],
customTags: config?.extract?.customTags,
cwd,
distPath: outDir,
exportPath,
files,
filePaths,
projectPath: cwd,
rules: config?.extract?.rules,
sourceTypesPath,
tsconfig: tsContext.config,
tmpPath,
tsconfigPath: path.resolve(cwd, tsContext.configPath || "tsconfig.json"),
extractorDisabled: config?.extract?.enabled === !1
});
messages.push(...result.messages), results.push({ sourcePath: path.resolve(cwd, entry.sourcePath), filePaths: targetPaths });
} catch (err) {
if (err instanceof DtsError)
messages.push(...err.messages);
else {
observer.error(err);
return;
}
}
}
observer.next({ type: "dts", messages, results });
};
const watchProgram = ts.createWatchProgram(host);
return () => {
watchProgram.close(), rimraf.sync(tmpPath);
};
});
},
complete: (ctx, task, result) => {
const { logger } = ctx;
printExtractMessages(ctx, result.messages), logger.success(
`build type definitions
${task.entries.map(
(entry) => ` - ${chalk.cyan(entry.importId)}: ${chalk.yellow(entry.sourcePath)} ${chalk.gray("\u2192")} ${chalk.yellow(entry.targetPaths.join(", "))}`
).join(`
`)}`
), logger.log("");
},
error: (ctx, _task, err) => {
const { logger } = ctx;
err instanceof DtsError ? printExtractMessages(ctx, err.messages) : err instanceof Error && logger.error(err);
}
}, rolldownDtsTask = {
name: (ctx, task) => {
const bundleEntries = task.entries.filter((e) => e.path.includes("__$$bundle_")), entries = task.entries.filter((e) => !e.path.includes("__$$bundle_")), targetLines = task.target.length ? [" target:", ...task.target.map((t) => ` - ${chalk.yellow(t)}`)] : [], bundlesLines = bundleEntries.length ? [
" bundles:",
...bundleEntries.map(
(e) => [
" - ",
`${chalk.yellow(e.source)} ${chalk.gray("\u2192")} ${chalk.yellow(replaceFileEnding(e.output))}`
].join("")
)
] : [], entriesLines = entries.length ? [
" entries:",
...entries.map(
(e) => [
" - ",
`${chalk.cyan(path.join(ctx.pkg.name, e.path))}: `,
`${chalk.yellow(e.source)} ${chalk.gray("\u2192")} ${chalk.yellow(replaceFileEnding(e.output))}`
].join("")
)
] : [];
return [
`Build type definitions with ${chalk.bold("rolldown")}...`,
` format: ${chalk.yellow(task.format)}`,
...targetLines,
...bundlesLines,
...entriesLines
].join(`
`);
},
exec: (ctx, task) => from(execPromise$1(ctx, task)),
complete: () => {
},
error: (_ctx, _task, err) => {
console.error(err);
}
};
async function execPromise$1(ctx, task) {
const [{ rolldown }, { resolveRolldownConfig }] = await Promise.all([
import("rolldown"),
import("./resolveRolldownConfig.js")
]), { distPath, files, logger } = ctx, outDir = path.relative(ctx.cwd, distPath), consoleSpy = createConsoleSpy({
onRestored: (messages) => {
for (const msg of messages) {
const text = String(msg.args[0]);
msg.code !== "CIRCULAR_DEPENDENCY" && (text.startsWith("Dynamic import can only") || text.startsWith("Sourcemap is likely to be incorrect") || (msg.type === "log" && logger.info(...msg.args), msg.type === "warn" && logger.warn(...msg.args), msg.type === "error" && logger.error(...msg.args)));
}
}
});
try {
const { inputOptions, outputOptions } = resolveRolldownConfig(ctx, task), bundle = await rolldown({
...inputOptions,
onwarn(warning) {
consoleSpy.messages.push({
type: "warn",
code: warning.code,
args: [warning.message]
});
}
}), { output } = await bundle.generate(outputOptions);
for (const chunkOrAsset of output)
chunkOrAsset.type === "asset" ? files.push({
type: "asset",
path: path.resolve(outDir, chunkOrAsset.fileName)
}) : files.push({
type: "chunk",
path: path.resolve(outDir, chunkOrAsset.fileName)
});
await bundle.write(outputOptions), await bundle.close(), consoleSpy.restore();
} catch (err) {
throw consoleSpy.restore(), err;
}
}
function replaceFileEnding(path2) {
switch (!0) {
case path2.endsWith(".mjs"):
return path2.replace(/\.mjs$/, ".d.mts");
case path2.endsWith(".cjs"):
return path2.replace(/\.cjs$/, ".d.cts");
default:
return path2.replace(/\.js$/, ".d.ts");
}
}
function resolveRollupConfig(ctx, buildTask) {
const { format, runtime, target } = buildTask, { config, cwd, exports: _exports, external, distPath, logger, pkg, ts: ts2 } = ctx, outputExt = pkgExtMap[pkg.type || "commonjs"][format], minify = config?.minify ?? !1, outDir = path.relative(cwd, distPath), pathAliases = Object.fromEntries(
Object.entries(ts2.config?.options.paths || {}).map(([key, val]) => [key, path.resolve(cwd, ts2.config?.options.baseUrl || ".", val[0])])
), entries = buildTask.entries.map((entry) => ({
...entry,
name: path.relative(outDir, entry.output).replace(/\.[^/.]+$/, "")
}), {}), exportIds = _exports && Object.keys(_exports).map((exportPath) => path.join(pkg.name, exportPath)), sourcePaths = _exports && Object.values(_exports).map((e) => path.resolve(cwd, e.source)), replacements = Object.fromEntries(
Object.entries(config?.define || {}).map(([key, val]) => [key, JSON.stringify(val)])
), { optimizeLodash: enableOptimizeLodash = hasDependency(pkg, "lodash") } = config?.rollup || {}, defaultPlugins = [
replace({
preventAssignment: !0,
values: pkg.name === "@sanity/pkg-utils" ? { ...replacements } : {
"process.env.PKG_FILE_PATH": (arg) => {
const sourcePath = `./${path.relative(cwd, arg)}`, entry = entries.find((e) => e.source === sourcePath);
return entry ? JSON.stringify(
path.relative(cwd, path.resolve(outDir, entry.name + outputExt))
) : (console.error(`could not find source entry: ${sourcePath}`), "null");
},
"process.env.PKG_FORMAT": JSON.stringify(format),
"process.env.PKG_RUNTIME": JSON.stringify(runtime),
"process.env.PKG_VERSION": JSON.stringify(process.env.PKG_VERSION || pkg.version),
...replacements
}
}),
alias({
entries: { ...pathAliases }
}),
nodeResolve({
browser: runtime === "browser",
extensions: [".cjs", ".mjs", ".js", ".jsx", ".json", ".node"],
preferBuiltins: !0
}),
commonjs(),
json(),
(config?.babel?.reactCompiler || config?.babel?.styledComponents) && babel({
babelrc: !1,
presets: ["@babel/preset-typescript"],
babelHelpers: "bundled",
extensions: [".ts", ".tsx", ".js", ".jsx"],
plugins: [
// The styled-components plugin needs to run before the react-compiler plugin, in case the css prop is used
config?.babel?.styledComponents && [
"babel-plugin-styled-components",
{
// Unnecessary, as the way we use styled-components in Sanity is usually by wrapping `@sanity/ui` primitives, not declaring new ones like "const Button = styled.button``"
fileName: !1,
// Native template literals take less space than this transpilation
transpileTemplateLiterals: !1,
// Massively helps dead code elimination and tree-shaking
pure: !0,
// disabled, as pkg-utils tends to be used for npm publishing, while other tooling, like `sanity dev`, `next dev`, etc are used for testing
cssProp: !1,
...typeof config.babel.styledComponents == "object" ? config.babel.styledComponents : {}
}
],
config?.babel?.reactCompiler && [
"babel-plugin-react-compiler",
config?.reactCompilerOptions || {}
]
].filter(Boolean)
}),
esbuild({
jsx: config?.jsx ?? "automatic",
jsxFactory: config?.jsxFactory ?? "createElement",
jsxFragment: config?.jsxFragment ?? "Fragment",
jsxImportSource: config?.jsxImportSource ?? "react",
target,
tsconfig: ctx.ts.configPath || "tsconfig.json",
treeShaking: !0,
minifySyntax: config?.minify !== !1,
supported: {
"template-literal": !0
}
}),
Array.isArray(config?.babel?.plugins) && getBabelOutputPlugin({
babelrc: !1,
plugins: config.babel.plugins
}),
enableOptimizeLodash && optimizeLodashImports({
useLodashEs: format === "esm" && hasDependency(pkg, "lodash-es") ? !0 : void 0,
...typeof config?.rollup?.optimizeLodash == "boolean" ? {} : config?.rollup?.optimizeLodash
}),
minify && terser({
compress: { directives: !1, passes: 10 },
ecma: 2020,
output: {
comments: (_node, comment) => {
const text = comment.value;
return comment.type === "comment2" ? /@preserve|@license|@cc_on/i.test(text) : !1;
},
preserve_annotations: !0
}
})
].filter(Boolean), userPlugins = config?.rollup?.plugins, plugins = Array.isArray(userPlugins) ? defaultPlugins.concat(userPlugins) : resolveConfigProperty(config?.rollup?.plugins, defaultPlugins), hashChunkFileNames = config?.rollup?.hashChunkFileNames ?? !1, chunkFileNames = `${hashChunkFileNames ? "_chunks" : "_chunks-[format]"}/${hashChunkFileNames ? "[name]-[hash]" : "[name]"}${outputExt}`, entryFileNames = `[name]${outputExt}`;
return {
inputOptions: {
context: cwd,
external: (id, importer) => {
if (exportIds?.includes(id))
return !0;
if (importer && (id.startsWith(".") || id.startsWith("/"))) {
const idPath = path.resolve(path.dirname(importer), id);
if (sourcePaths?.includes(idPath))
return logger.warn(
`detected self-referencing import \u2013 treating as external: ${path.relative(
cwd,
idPath
)}`
), !0;
}
const idParts = id.split("/"), name = idParts[0].startsWith("@") ? `${idParts[0]}/${idParts[1]}` : idParts[0];
return !!(name && external.includes(name));
},
input: entries.reduce(
(acc, entry) => Object.assign(acc, { [entry.name]: entry.source }),
{}
),
watch: {
chokidar: {
usePolling: !0
}
},
plugins,
treeshake: {
preset: "recommended",
propertyReadSideEffects: !1,
moduleSideEffects: "no-external",
annotations: !0,
...config?.rollup?.treeshake
},
experimentalLogSideEffects: config?.rollup?.experimentalLogSideEffects
},
outputOptions: {
chunkFileNames,
compact: minify,
dir: outDir,
entryFileNames,
esModule: !0,
format,
interop: "compat",
sourcemap: config?.sourcemap ?? !0,
hoistTransitiveImports: !1,
minifyInternalExports: minify,
...config?.rollup?.output
}
};
}
function hasDependency(pkg, packageName) {
return pkg.dependencies ? packageName in pkg.dependencies : pkg.peerDependencies ? packageName in pkg.peerDependencies : !1;
}
const rollupTask = {
name: (ctx, task) => {
const bundleEntries = task.entries.filter((e) => e.path.includes("__$$bundle_")), entries = task.entries.filter((e) => !e.path.includes("__$$bundle_")), targetLines = task.target.length ? [" target:", ...task.target.map((t) => ` - ${chalk.yellow(t)}`)] : [], bundlesLines = bundleEntries.length ? [
" bundles:",
...bundleEntries.map(
(e) => [
" - ",
`${chalk.yellow(e.source)} ${chalk.gray("\u2192")} ${chalk.yellow(e.output)}`
].join("")
)
] : [], entriesLines = entries.length ? [
" entries:",
...entries.map(
(e) => [
" - ",
`${chalk.cyan(path.join(ctx.pkg.name, e.path))}: `,
`${chalk.yellow(e.source)} ${chalk.gray("\u2192")} ${chalk.yellow(e.output)}`
].join("")
)
] : [];
return [
"Build javascript files...",
` format: ${chalk.yellow(task.format)}`,
...targetLines,
...bundlesLines,
...entriesLines
].join(`
`);
},
exec: (ctx, task) => new Observable((observer) => {
execPromise(ctx, task).then((result) => {
observer.next(result), observer.complete();
}).catch((err) => observer.error(err));
}),
complete: () => {
},
error: (_ctx, _task, err) => {
console.error(err);
}
};
async function execPromise(ctx, task) {
const { distPath, files, logger } = ctx, outDir = path.relative(ctx.cwd, distPath), consoleSpy = createConsoleSpy({
onRestored: (messages) => {
for (const msg of messages) {
const text = String(msg.args[0]);
msg.code !== "CIRCULAR_DEPENDENCY" && (text.startsWith("Dynamic import can only") || text.startsWith("Sourcemap is likely to be incorrect") || (msg.type === "log" && logger.info(...msg.args), msg.type === "warn" && logger.warn(...msg.args), msg.type === "error" && logger.error(...msg.args)));
}
}
});
try {
const { inputOptions, outputOptions } = resolveRollupConfig(ctx, task), bundle = await rollup({
...inputOptions,
onwarn(warning) {
consoleSpy.messages.push({
type: "warn",
code: warning.code,
args: [warning.message]
});
}
}), { output } = await bundle.generate(outputOptions);
for (const chunkOrAsset of output)
chunkOrAsset.type === "asset" ? files.push({
type: "asset",
path: path.resolve(outDir, chunkOrAsset.fileName)
}) : files.push({
type: "chunk",
path: path.resolve(outDir, chunkOrAsset.fileName)
});
await bundle.write(outputOptions), await bundle.close(), consoleSpy.restore();
} catch (err) {
throw consoleSpy.restore(), err;
}
}
const rollupWatchTask = {
name: (ctx, task) => `build javascript files (target ${task.target.join(" + ")}, format ${task.format})
${task.entries.map((e) => `${chalk.blue(path.join(ctx.pkg.name, e.path))}: ${e.source} -> ${e.output}`).join(`
`)}`,
exec: (ctx, task) => {
const { inputOptions, outputOptions } = resolveRollupConfig(ctx, task);
return new Observable((observer) => {
const watchOptions = {
...inputOptions,
output: outputOptions
}, watcher = watch(watchOptions);
return watcher.on("event", (event) => {
observer.next(event);
}), () => {
watcher.close();
};
});
},
complete: (ctx, task, event) => {
const { logger } = ctx;
if (event.code === "BUNDLE_END") {
logger.success(
`build javascript files (target ${task.target.join(" + ")}, format ${task.format})
${task.entries.map((e) => `${chalk.blue(path.join(ctx.pkg.name, e.path))}: ${e.source} -> ${e.output}`).join(`
`)}`
), logger.log("");
return;
}
if (event.code !== "BUNDLE_START" && event.code !== "END" && event.code === "ERROR") {
logger.error(event.code, event);
return;
}
},
error: (ctx, _task, err) => {
const { logger } = ctx;
err instanceof Error && logger.log(err);
}
}, buildTaskHandlers = {
"build:dts": dtsTask,
"build:js": rollupTask,
"rolldown:dts": rolldownDtsTask
}, watchTaskHandlers = {
"watch:dts": dtsWatchTask,
"watch:js": rollupWatchTask
};
export {
buildTaskHandlers,
createApiExtractorConfig$1 as createApiExtractorConfig,
createTSDocConfig$1 as createTSDocConfig,
getExtractMessagesConfig,
getExtractMessagesConfig$1,
printExtractMessages$1 as printExtractMessages,
watchTaskHandlers
};
//# sourceMappingURL=index.js.map