UNPKG

@sanity/pkg-utils

Version:

Simple utilities for modern npm packages.

525 lines 15.9 kB
import { PluginItem } from "@babel/core"; import { OptimizeLodashOptions } from "@optimize-lodash/rollup-plugin"; import { NormalizedOutputOptions, Plugin, Plugin as RollupPlugin, TreeshakingOptions } from "rollup"; import { IExtractorMessagesConfig } from "@microsoft/api-extractor"; /** * Build the distribution files of a npm package. * * @example * ```ts * import {build} from '@sanity/pkg-utils' * * build({ * cwd: process.cwd(), * tsconfig: 'tsconfig.dist.json, * }).then(() => { * console.log('successfully built') * }).catch((err) => { * console.log(`build error: ${err.message}`) * }) * ``` * * @public */ declare function build(options: { cwd: string; emitDeclarationOnly?: boolean; strict?: boolean; tsconfig?: string; clean?: boolean; quiet?: boolean; }): Promise<void>; /** @public */ declare function check(options: { cwd: string; strict?: boolean; tsconfig?: string; }): Promise<void>; type ToggleType = 'error' | 'warn' | 'off'; /** * @public */ interface StrictOptions { /** * Disallows a top level `typings` field in `package.json` if it is equal to `exports['.'].source`. * @defaultValue 'error' */ noPackageJsonTypings: ToggleType; /** * Requires specifying `sideEffects` in `package.json`. * @defaultValue 'warn' */ noImplicitSideEffects: ToggleType; /** * Requires specifying `browserslist` in `package.json`, instead of relying on it implicitly being: * @example * ``` * "browserslist": "extends @sanity/browserslist-config" * ``` * @defaultValue 'warn' */ noImplicitBrowsersList: ToggleType; /** * If typescript is used then `types` in `package.json` should be specified for npm listings to show the TS icon. * @defaultValue 'error' */ alwaysPackageJsonTypes: ToggleType; /** * A lot of analysis tooling requiers the `main` field to work (like bundlephobia) and so it's best practice to always include it * @defaultValue 'error' */ alwaysPackageJsonMain: ToggleType; /** * Using `.npmignore` is error prone, it's best practice to always declare `files` instead * @defaultValue 'error' */ alwaysPackageJsonFiles: ToggleType; /** * It's slow to perform type checking while generating dts files, so it's best practice to disable it with a `"noCheck": true` in the tsconfig.json file used by `package.config.ts` * @defaultValue 'warn' */ noCheckTypes: ToggleType; } /** @alpha */ declare function parseStrictOptions(input: unknown): StrictOptions; /** @public */ type PkgFormat = 'commonjs' | 'esm'; /** @public */ type PkgRuntime = '*' | 'browser' | 'node'; /** @public */ interface PkgExport { /** @internal */ _exported?: boolean; browser?: { source: string; import?: string; require?: string; }; // electron?: { // node?: string // default?: string // } node?: { source?: string; import?: string; require?: string; }; types?: string; source: string; import?: string; require?: string; default: string; } /** @public */ type PkgConfigPropertyResolver<T> = (prev: T) => T; /** @public */ type PkgConfigProperty<T> = PkgConfigPropertyResolver<T> | T; /** @public */ interface PkgBundle { source: string; import?: string; require?: string; runtime?: PkgRuntime; } /** @public */ interface PkgExports { [path: string]: PkgExport; } /** @public */ type PkgRuleLevel = 'error' | 'warn' | 'info' | 'off'; /** @public */ interface TSDocCustomTag { name: string; syntaxKind: 'block' | 'modifier'; allowMultiple?: boolean; } /** * Until these types are on npm: https://github.com/facebook/react/blob/0bc30748730063e561d87a24a4617526fdd38349/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts#L39-L122 * @alpha */ interface ReactCompilerOptions { logger?: ReactCompilerLogger | null; panicThreshold?: 'ALL_ERRORS' | 'CRITICAL_ERRORS' | 'NONE'; compilationMode?: 'infer' | 'syntax' | 'annotation' | 'all'; /* * If enabled, Forget will import `useMemoCache` from the given module * instead of `react/compiler-runtime`. * * ``` * // If set to "react-compiler-runtime" * import {c as useMemoCache} from 'react-compiler-runtime'; * ``` */ runtimeModule?: string | null | undefined; /** * By default React Compiler will skip compilation of code that suppresses the default * React ESLint rules, since this is a strong indication that the code may be breaking React rules * in some way. * * Use eslintSuppressionRules to pass a custom set of rule names: any code which suppresses the * provided rules will skip compilation. To disable this feature (never bailout of compilation * even if the default ESLint is suppressed), pass an empty array. */ eslintSuppressionRules?: Array<string> | null | undefined; sources?: Array<string> | ((filename: string) => boolean) | null; /** * The minimum major version of React that the compiler should emit code for. If the target is 19 * or higher, the compiler emits direct imports of React runtime APIs needed by the compiler. On * versions prior to 19, an extra runtime package react-compiler-runtime is necessary to provide * a userspace approximation of runtime APIs. */ target: '17' | '18' | '19'; } /** * @alpha * Represents 'events' that may occur during compilation. Events are only * recorded when a logger is set (through the config). * These are the different types of events: * CompileError: * Forget skipped compilation of a function / file due to a known todo, * invalid input, or compiler invariant being broken. * CompileSuccess: * Forget successfully compiled a function. * PipelineError: * Unexpected errors that occurred during compilation (e.g. failures in * babel or other unhandled exceptions). */ type ReactCompilerLoggerEvent = { kind: 'CompileError'; fnLoc: unknown; detail: unknown; } | { kind: 'CompileDiagnostic'; fnLoc: unknown; detail: unknown; } | { kind: 'CompileSuccess'; fnLoc: unknown; fnName: string | null; memoSlots: number; memoBlocks: number; memoValues: number; prunedMemoBlocks: number; prunedMemoValues: number; } | { kind: 'PipelineError'; fnLoc: unknown; data: string; }; /** * @alpha */ type ReactCompilerLogger = { logEvent: (filename: string | null, event: ReactCompilerLoggerEvent) => void; }; type DtsType = 'api-extractor' | 'rolldown'; /** @public */ interface PkgConfigOptions { /** @alpha */ babel?: { plugins?: PluginItem[] | null | undefined; /** @alpha */ reactCompiler?: boolean; /** @alpha */ styledComponents?: boolean | { /** @defaultValue true */ displayName?: boolean; /** * @defaultValue [] * @example ["\@xstyled/styled-components", "\@xstyled/styled-components/*"] */ topLevelImportPaths?: string[]; /** @defaultValue true */ ssr?: boolean; /** @defaultValue fale */ fileName?: boolean; /** @defaultValue ["index"] */ meaninglessFileNames?: string[]; /** @defaultValue true */ minify?: boolean; /** @defaultValue false */ transpileTemplateLiterals?: boolean; namespace?: string; /** @defaultValue true */ pure?: boolean; }; }; /** * Configure the React Compiler. * To enable it, either: * - set `babel.reactCompiler` to `true` * - add a `react-compiler` export condition, before any `browser`, `require` or `import` conditions. After any `react-server` and `node` conditions * @alpha */ reactCompilerOptions?: ReactCompilerOptions; bundles?: PkgBundle[]; /** @alpha */ define?: Record<string, string | number | boolean | undefined | null>; /** * Directory of distributed & bundled files. */ dist?: string; exports?: PkgConfigProperty<PkgExports>; /** * Runs `@microsoft/api-extractor` to check that TSDoc tags are valid, and release tags are correct. * This is useful for packages that need to be consumed by TSDoc-based tooling. * It's enabled by default, it can be disabled by setting `extract: {enabled: false}` */ extract?: { /** * @defaultValue true */ enabled?: boolean; /** * Packages in `devDependencies` that are not in `external` are automatically added to the `bundledPackages` config. * You can exclude a package from being bundled by using a callback: * ``` * bundledPackages: (prev) => prev.filter(package => package !== 'sanity') * ``` */ bundledPackages?: PkgConfigProperty<string[]>; customTags?: TSDocCustomTag[]; rules?: { /** * @deprecated as it's no longer needed since TypeScript 5.5 https://github.com/microsoft/TypeScript/issues/42873 */ 'ae-forgotten-export'?: never; 'ae-incompatible-release-tags'?: PkgRuleLevel; 'ae-internal-missing-underscore'?: PkgRuleLevel; 'ae-missing-release-tag'?: PkgRuleLevel; 'tsdoc-link-tag-unescaped-text'?: PkgRuleLevel; 'tsdoc-undefined-tag'?: PkgRuleLevel; 'tsdoc-unsupported-tag'?: PkgRuleLevel; }; }; /** * Packages to exclude from bundles. * Provide an array to merge with default exclusions, use a function to replace them: * ``` * exclude: (prev) => prev.filter(package => package !== 'foo') * ``` */ external?: PkgConfigProperty<string[]>; /** * Defaults to `"automatic"` */ jsx?: 'transform' | 'preserve' | 'automatic'; /** * Defaults to `"createElement"` */ jsxFactory?: string; /** * Defaults to `"Fragment"` */ jsxFragment?: string; /** * Defaults to `"react"` */ jsxImportSource?: string; /** * @deprecated no longer supported */ legacyExports?: never; minify?: boolean; /** @alpha */ rollup?: { plugins?: PkgConfigProperty<Plugin[]>; output?: Partial<NormalizedOutputOptions>; /** * Default options are `preset: 'recommended'` and `propertyReadSideEffects: false` * @alpha */ treeshake?: TreeshakingOptions; /** @alpha */ experimentalLogSideEffects?: boolean; /** * Adds [hash] to chunk filenames, generally only useful if `@sanity/pkg-utils` is used to deploy a package directly to a CDN. * It's not needed when publishing to npm for consumption by other libraries, bundlers and frameworks. * @defaultValue false */ hashChunkFileNames?: boolean; /** * Optimizes lodash imports using `@optimize-lodash/rollup-plugin` when set to `true`. * It's enabled if `lodash` is found in `dependencies` or `peerDependencies`. * It will use `lodash-es` for ESM targets if found in `dependencies` or `peerDependencies`. * @defaultValue true * @alpha */ optimizeLodash?: boolean | OptimizeLodashOptions; }; /** * Default runtime of package exports */ runtime?: PkgRuntime; sourcemap?: boolean; /** * Directory of source files. */ src?: string; tsconfig?: string; /** * Configure what checks are made when running `--strict` builds and checks */ strictOptions?: Partial<StrictOptions>; /** * .d.ts files can be generated either by using `@microsoft/api-extractor` or `rolldown`. * `rolldown` is the faster option, but is not yet stable. * @defaultValue 'api-extractor' */ dts?: DtsType; } /** @public */ declare function defineConfig<const T extends PkgConfigOptions>(configOptions: T): T; /** @alpha */ declare function loadConfig(options: { cwd: string; }): Promise<PkgConfigOptions | undefined>; /** @public */ declare const DEFAULT_BROWSERSLIST_QUERY: string[]; /** @alpha */ interface PackageJSON { type?: 'commonjs' | 'module' | undefined; version: string; private?: boolean; author?: string | { name: string; email?: string; url?: string; }; name: string; description?: string; keywords?: string[]; bin?: Record<string, string>; dependencies?: Record<string, string | undefined>; devDependencies?: Record<string, string | undefined>; peerDependencies?: Record<string, string | undefined>; exports?: Record<string, `./${string}.json` | `./${string}.css` | { source?: string; types?: string; browser?: { source: string; import?: string; require?: string; }; node?: { source?: string; module?: string; import?: string; require?: string; }; module?: string; import?: string; require?: string; default: string; } | { types?: string; svelte: string; default?: string; }>; main?: string; browser?: Record<string, string>; source?: string; module?: string; types?: string; files?: string[]; scripts?: Record<string, string | undefined>; browserslist?: string | string[]; sideEffects?: boolean | string[]; engines?: { node?: string; npm?: string; }; repository?: string | { type: 'git'; url: string; }; bugs?: string | { url: string; email?: string; }; homepage?: string; license?: string; } /** @internal */ declare function loadPkg(options: { cwd: string; }): Promise<PackageJSON>; /** @alpha */ interface Logger { log: (...args: unknown[]) => void; info: (...args: unknown[]) => void; warn: (...args: unknown[]) => void; error: (...args: unknown[]) => void; success: (...args: unknown[]) => void; } /** @alpha */ declare function createLogger(quiet?: boolean): Logger; /** @alpha */ declare function loadPkgWithReporting(options: { cwd: string; logger: Logger; strict: boolean; }): Promise<PackageJSON>; /** @alpha */ declare function parseExports(options: { cwd: string; pkg: PackageJSON; strict: boolean; strictOptions: StrictOptions; logger: Logger; }): (PkgExport & { _path: string; })[]; /** @public */ interface PkgTemplateFile { name: string; contents: string; } /** @public */ interface PkgTemplateStringOption<T = string> { name: string; type: 'string'; description: string; initial?: T | ((options: Record<string, any>) => T); parse?: (v: string) => T | null; validate?: (v: string) => string | true; } /** @public */ type PkgTemplateOption<T = string> = PkgTemplateStringOption<T>; /** @public */ interface PkgTemplateDefinition { options: PkgTemplateStringOption<any>[]; features: { name: string; optional: boolean; initial: boolean; }[]; getFiles: (options: Record<string, any>, features: Record<string, boolean>) => Promise<PkgTemplateFile[]>; } /** @public */ type PkgTemplateResolver = (options: { cwd: string; /** @internal */ logger: Logger; packagePath: string; }) => PkgTemplateDefinition | Promise<PkgTemplateDefinition>; /** @public */ type PkgTemplate = PkgTemplateDefinition | PkgTemplateResolver; /** @public */ declare function defineTemplateOption<T>(option: PkgTemplateOption<T>): PkgTemplateOption<T>; /** @public */ declare function init(options: { cwd: string; path: string; }): Promise<void>; /** @alpha */ declare function getExtractMessagesConfig(options: { rules: NonNullable<PkgConfigOptions['extract']>['rules']; disabled?: boolean; }): IExtractorMessagesConfig; /** @public */ declare function watch(options: { cwd: string; strict?: boolean; tsconfig?: string; }): Promise<void>; export { DEFAULT_BROWSERSLIST_QUERY, PackageJSON, type PkgBundle, type PkgConfigOptions, type PkgConfigProperty, type PkgConfigPropertyResolver, type PkgExport, type PkgExports, type PkgFormat, type PkgRuleLevel, type PkgRuntime, type PkgTemplate, type PkgTemplateDefinition, type PkgTemplateFile, type PkgTemplateOption, type PkgTemplateResolver, type PkgTemplateStringOption, type ReactCompilerLogger, type ReactCompilerLoggerEvent, type ReactCompilerOptions, type RollupPlugin, type TSDocCustomTag, build, check, createLogger, defineConfig, defineTemplateOption, getExtractMessagesConfig, init, loadConfig, loadPkg, loadPkgWithReporting, parseExports, parseStrictOptions, watch };