@sanity/pkg-utils 6.4.1 → 6.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks-cjs/consoleSpy.cjs +47 -12
- package/dist/_chunks-cjs/consoleSpy.cjs.map +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +108 -0
- package/dist/index.d.ts +108 -0
- package/dist/index.js +47 -11
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
- package/src/node/__snapshots__/strict.test.ts.snap +154 -0
- package/src/node/core/config/types.ts +7 -1
- package/src/node/core/pkg/parseExports.ts +36 -33
- package/src/node/index.ts +1 -0
- package/src/node/resolveBuildContext.ts +28 -8
- package/src/node/strict.test-d.ts +7 -0
- package/src/node/strict.ts +84 -0
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type {Plugin as RollupPlugin} from 'rollup'
|
|
|
8
8
|
import {RollupWatcherEvent} from 'rollup'
|
|
9
9
|
import type {TreeshakingOptions} from 'rollup'
|
|
10
10
|
import ts from 'typescript'
|
|
11
|
+
import {z} from 'zod'
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Build the distribution files of a npm package.
|
|
@@ -145,6 +146,11 @@ export declare function getExtractMessagesConfig(options: {
|
|
|
145
146
|
rules: NonNullable<PkgConfigOptions['extract']>['rules']
|
|
146
147
|
}): IExtractorMessagesConfig
|
|
147
148
|
|
|
149
|
+
/**
|
|
150
|
+
* @public
|
|
151
|
+
*/
|
|
152
|
+
export declare type InferredStrictOptions = z.infer<typeof strictOptions>
|
|
153
|
+
|
|
148
154
|
/** @public */
|
|
149
155
|
export declare function init(options: {cwd: string; path: string}): Promise<void>
|
|
150
156
|
|
|
@@ -260,7 +266,9 @@ export declare interface PackageJSON {
|
|
|
260
266
|
export declare function parseExports(options: {
|
|
261
267
|
pkg: PackageJSON
|
|
262
268
|
strict: boolean
|
|
269
|
+
strictOptions: InferredStrictOptions
|
|
263
270
|
legacyExports: boolean
|
|
271
|
+
logger: Logger
|
|
264
272
|
}): (PkgExport & {
|
|
265
273
|
_path: string
|
|
266
274
|
})[]
|
|
@@ -365,6 +373,10 @@ export declare interface PkgConfigOptions {
|
|
|
365
373
|
*/
|
|
366
374
|
src?: string
|
|
367
375
|
tsconfig?: string
|
|
376
|
+
/**
|
|
377
|
+
* Configure what checks are made when running `--strict` builds and checks
|
|
378
|
+
*/
|
|
379
|
+
strictOptions?: StrictOptions
|
|
368
380
|
}
|
|
369
381
|
|
|
370
382
|
/** @public */
|
|
@@ -535,6 +547,90 @@ export declare interface RollupWatchTask {
|
|
|
535
547
|
/** @internal */
|
|
536
548
|
export declare const rollupWatchTask: TaskHandler<RollupWatchTask, RollupWatcherEvent>
|
|
537
549
|
|
|
550
|
+
/**
|
|
551
|
+
* @public
|
|
552
|
+
*/
|
|
553
|
+
export declare interface StrictOptions {
|
|
554
|
+
/**
|
|
555
|
+
* Disallows a top level `typings` field in `package.json` if it is equal to `exports['.'].source`.
|
|
556
|
+
* @defaultValue 'error'
|
|
557
|
+
*/
|
|
558
|
+
noPackageJsonTypings?: ToggleType
|
|
559
|
+
/**
|
|
560
|
+
* Requires specifying `sideEffects` in `package.json`.
|
|
561
|
+
* @defaultValue 'warn'
|
|
562
|
+
*/
|
|
563
|
+
noImplicitSideEffects?: ToggleType
|
|
564
|
+
/**
|
|
565
|
+
* Requires specifying `browserslist` in `package.json`, instead of relying on it implicitly being:
|
|
566
|
+
* @example
|
|
567
|
+
* ```
|
|
568
|
+
* "browserslist": "extends @sanity/browserslist-config"
|
|
569
|
+
* ```
|
|
570
|
+
* @defaultValue 'warn'
|
|
571
|
+
*/
|
|
572
|
+
noImplicitBrowsersList?: ToggleType
|
|
573
|
+
/**
|
|
574
|
+
* If typescript is used then `types` in `package.json` should be specified for npm listings to show the TS icon.
|
|
575
|
+
* @defaultValue 'error'
|
|
576
|
+
*/
|
|
577
|
+
alwaysPackageJsonTypes?: ToggleType
|
|
578
|
+
/**
|
|
579
|
+
* A lot of analysis tooling requiers the `main` field to work (like bundlephobia) and so it's best practice to always include it
|
|
580
|
+
* @defaultValue 'error'
|
|
581
|
+
*/
|
|
582
|
+
alwaysPackageJsonMain?: ToggleType
|
|
583
|
+
/**
|
|
584
|
+
* Using `.npmignore` is error prone, it's best practice to always declare `files` instead
|
|
585
|
+
* @defaultValue 'error'
|
|
586
|
+
*/
|
|
587
|
+
alwaysPackageJsonFiles?: ToggleType
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* @public
|
|
592
|
+
*/
|
|
593
|
+
export declare const strictOptions: z.ZodObject<
|
|
594
|
+
{
|
|
595
|
+
noPackageJsonTypings: z.ZodDefault<
|
|
596
|
+
z.ZodUnion<[z.ZodLiteral<'error'>, z.ZodLiteral<'warn'>, z.ZodLiteral<'off'>]>
|
|
597
|
+
>
|
|
598
|
+
noImplicitSideEffects: z.ZodDefault<
|
|
599
|
+
z.ZodUnion<[z.ZodLiteral<'error'>, z.ZodLiteral<'warn'>, z.ZodLiteral<'off'>]>
|
|
600
|
+
>
|
|
601
|
+
noImplicitBrowsersList: z.ZodDefault<
|
|
602
|
+
z.ZodUnion<[z.ZodLiteral<'error'>, z.ZodLiteral<'warn'>, z.ZodLiteral<'off'>]>
|
|
603
|
+
>
|
|
604
|
+
alwaysPackageJsonTypes: z.ZodDefault<
|
|
605
|
+
z.ZodUnion<[z.ZodLiteral<'error'>, z.ZodLiteral<'warn'>, z.ZodLiteral<'off'>]>
|
|
606
|
+
>
|
|
607
|
+
alwaysPackageJsonMain: z.ZodDefault<
|
|
608
|
+
z.ZodUnion<[z.ZodLiteral<'error'>, z.ZodLiteral<'warn'>, z.ZodLiteral<'off'>]>
|
|
609
|
+
>
|
|
610
|
+
alwaysPackageJsonFiles: z.ZodDefault<
|
|
611
|
+
z.ZodUnion<[z.ZodLiteral<'error'>, z.ZodLiteral<'warn'>, z.ZodLiteral<'off'>]>
|
|
612
|
+
>
|
|
613
|
+
},
|
|
614
|
+
'strict',
|
|
615
|
+
z.ZodTypeAny,
|
|
616
|
+
{
|
|
617
|
+
noPackageJsonTypings: 'error' | 'warn' | 'off'
|
|
618
|
+
noImplicitSideEffects: 'error' | 'warn' | 'off'
|
|
619
|
+
noImplicitBrowsersList: 'error' | 'warn' | 'off'
|
|
620
|
+
alwaysPackageJsonTypes: 'error' | 'warn' | 'off'
|
|
621
|
+
alwaysPackageJsonMain: 'error' | 'warn' | 'off'
|
|
622
|
+
alwaysPackageJsonFiles: 'error' | 'warn' | 'off'
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
noPackageJsonTypings?: 'error' | 'warn' | 'off' | undefined
|
|
626
|
+
noImplicitSideEffects?: 'error' | 'warn' | 'off' | undefined
|
|
627
|
+
noImplicitBrowsersList?: 'error' | 'warn' | 'off' | undefined
|
|
628
|
+
alwaysPackageJsonTypes?: 'error' | 'warn' | 'off' | undefined
|
|
629
|
+
alwaysPackageJsonMain?: 'error' | 'warn' | 'off' | undefined
|
|
630
|
+
alwaysPackageJsonFiles?: 'error' | 'warn' | 'off' | undefined
|
|
631
|
+
}
|
|
632
|
+
>
|
|
633
|
+
|
|
538
634
|
/** @internal */
|
|
539
635
|
export declare type TaskHandler<Task, Result = void> = {
|
|
540
636
|
name: (ctx: BuildContext, task: Task) => string
|
|
@@ -543,6 +639,18 @@ export declare type TaskHandler<Task, Result = void> = {
|
|
|
543
639
|
error: (ctx: BuildContext, task: Task, error: unknown) => void
|
|
544
640
|
}
|
|
545
641
|
|
|
642
|
+
/**
|
|
643
|
+
* @public
|
|
644
|
+
*/
|
|
645
|
+
export declare const toggle: z.ZodUnion<
|
|
646
|
+
[z.ZodLiteral<'error'>, z.ZodLiteral<'warn'>, z.ZodLiteral<'off'>]
|
|
647
|
+
>
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* @public
|
|
651
|
+
*/
|
|
652
|
+
export declare type ToggleType = z.infer<typeof toggle>
|
|
653
|
+
|
|
546
654
|
/** @public */
|
|
547
655
|
export declare interface TSDocCustomTag {
|
|
548
656
|
name: string
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import fs, { writeFile, readFile, readdir, lstat } from "node:fs/promises";
|
|
|
10
10
|
import browserslist from "browserslist";
|
|
11
11
|
import config from "@sanity/browserslist-config";
|
|
12
12
|
import ts from "typescript";
|
|
13
|
+
import { errorMap } from "zod-validation-error";
|
|
13
14
|
import { Observable, switchMap } from "rxjs";
|
|
14
15
|
import { ExtractorConfig, Extractor } from "@microsoft/api-extractor";
|
|
15
16
|
import { mkdirp } from "mkdirp";
|
|
@@ -269,8 +270,13 @@ function validateExports(_exports, options2) {
|
|
|
269
270
|
return errors;
|
|
270
271
|
}
|
|
271
272
|
function parseExports(options2) {
|
|
272
|
-
const { pkg, strict, legacyExports } = options2, type = pkg.type || "commonjs", errors = []
|
|
273
|
-
|
|
273
|
+
const { pkg, strict, strictOptions: strictOptions2, legacyExports, logger } = options2, type = pkg.type || "commonjs", errors = [], report = (kind, message) => {
|
|
274
|
+
kind === "warn" ? logger.warn(message) : errors.push(message);
|
|
275
|
+
};
|
|
276
|
+
if (!pkg.main && strict && strictOptions2.alwaysPackageJsonMain !== "off" && report(strictOptions2.alwaysPackageJsonMain, "package.json: `main` must be declared"), !Array.isArray(pkg.files) && strict && strictOptions2.alwaysPackageJsonFiles !== "off" && report(
|
|
277
|
+
strictOptions2.alwaysPackageJsonFiles,
|
|
278
|
+
"package.json: `files` should be used over `.npmignore`"
|
|
279
|
+
), pkg.source) {
|
|
274
280
|
if (strict && pkg.exports?.["."] && typeof pkg.exports["."] == "object" && "source" in pkg.exports["."] && pkg.exports["."].source === pkg.source)
|
|
275
281
|
errors.push(
|
|
276
282
|
'package.json: the "source" property can be removed, as it is equal to exports["."].source.'
|
|
@@ -345,7 +351,8 @@ function parseExports(options2) {
|
|
|
345
351
|
- `)
|
|
346
352
|
);
|
|
347
353
|
const _exports = [];
|
|
348
|
-
strict && "typings" in pkg &&
|
|
354
|
+
strict && strictOptions2.noPackageJsonTypings !== "off" && "typings" in pkg && report(strictOptions2.noPackageJsonTypings, "package.json: `typings` should be `types`"), strict && strictOptions2.alwaysPackageJsonTypes !== "off" && !pkg.types && typeof pkg.exports?.["."] == "object" && "source" in pkg.exports["."] && pkg.exports["."].source?.endsWith(".ts") && report(
|
|
355
|
+
strictOptions2.alwaysPackageJsonTypes,
|
|
349
356
|
"package.json: `types` must be declared for the npm listing to show as a TypeScript module."
|
|
350
357
|
), strict && !pkg.exports["./package.json"] && errors.push('package.json: `exports["./package.json"] must be declared.');
|
|
351
358
|
for (const [exportPath, exportEntry] of Object.entries(pkg.exports))
|
|
@@ -520,6 +527,19 @@ function resolveNodeTarget(versions) {
|
|
|
520
527
|
if (target.length !== 0)
|
|
521
528
|
return target;
|
|
522
529
|
}
|
|
530
|
+
const toggle = z.union([z.literal("error"), z.literal("warn"), z.literal("off")]), strictOptions = z.object({
|
|
531
|
+
noPackageJsonTypings: toggle.default("error"),
|
|
532
|
+
noImplicitSideEffects: toggle.default("warn"),
|
|
533
|
+
noImplicitBrowsersList: toggle.default("warn"),
|
|
534
|
+
alwaysPackageJsonTypes: toggle.default("error"),
|
|
535
|
+
alwaysPackageJsonMain: toggle.default("error"),
|
|
536
|
+
alwaysPackageJsonFiles: toggle.default("error")
|
|
537
|
+
}).strict(), validationSchema = z.object({
|
|
538
|
+
strictOptions: strictOptions.default({})
|
|
539
|
+
});
|
|
540
|
+
function parseStrictOptions(input) {
|
|
541
|
+
return validationSchema.parse({ strictOptions: input }, { errorMap }).strictOptions;
|
|
542
|
+
}
|
|
523
543
|
async function resolveBuildContext(options2) {
|
|
524
544
|
const {
|
|
525
545
|
config: config2,
|
|
@@ -529,15 +549,27 @@ async function resolveBuildContext(options2) {
|
|
|
529
549
|
pkg,
|
|
530
550
|
strict,
|
|
531
551
|
tsconfig: tsconfigPath
|
|
532
|
-
} = options2, tsconfig = await loadTSConfig({ cwd, tsconfigPath });
|
|
552
|
+
} = options2, tsconfig = await loadTSConfig({ cwd, tsconfigPath }), strictOptions2 = parseStrictOptions(config2?.strictOptions ?? {});
|
|
533
553
|
let browserslist2 = pkg.browserslist;
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
554
|
+
if (!browserslist2) {
|
|
555
|
+
if (strict && strictOptions2.noImplicitBrowsersList !== "off") {
|
|
556
|
+
if (strictOptions2.noImplicitBrowsersList === "error")
|
|
557
|
+
throw new Error(
|
|
558
|
+
'\n- package.json: "browserslist" is missing, set it to `"browserslist": "extends @sanity/browserslist-config"`'
|
|
559
|
+
);
|
|
560
|
+
logger.warn(
|
|
561
|
+
'Could not detect a `browserslist` property in `package.json`, using default configuration. Add `"browserslist": "extends @sanity/browserslist-config"` to silence this warning.'
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
browserslist2 = DEFAULT_BROWSERSLIST_QUERY;
|
|
565
|
+
}
|
|
537
566
|
const targetVersions = browserslistToEsbuild(browserslist2);
|
|
538
|
-
strict && typeof pkg.sideEffects > "u"
|
|
539
|
-
|
|
540
|
-
|
|
567
|
+
if (strict && strictOptions2.noImplicitSideEffects !== "off" && typeof pkg.sideEffects > "u") {
|
|
568
|
+
const msg = "package.json: `sideEffects` is missing, see https://webpack.js.org/guides/tree-shaking/#clarifying-tree-shaking-and-sideeffects for how to define `sideEffects`";
|
|
569
|
+
if (strictOptions2.noImplicitSideEffects === "error")
|
|
570
|
+
throw new Error(msg);
|
|
571
|
+
logger.warn(msg);
|
|
572
|
+
}
|
|
541
573
|
const nodeTarget = resolveNodeTarget(targetVersions), webTarget = resolveBrowserTarget(targetVersions);
|
|
542
574
|
if (!nodeTarget)
|
|
543
575
|
throw new Error("no matching `node` target");
|
|
@@ -550,7 +582,9 @@ async function resolveBuildContext(options2) {
|
|
|
550
582
|
}, parsedExports = parseExports({
|
|
551
583
|
pkg,
|
|
552
584
|
strict,
|
|
553
|
-
legacyExports: config2?.legacyExports ?? !1
|
|
585
|
+
legacyExports: config2?.legacyExports ?? !1,
|
|
586
|
+
strictOptions: strictOptions2,
|
|
587
|
+
logger
|
|
554
588
|
}).reduce((acc, x) => {
|
|
555
589
|
const { _path: exportPath, ...exportEntry } = x;
|
|
556
590
|
return { ...acc, [exportPath]: exportEntry };
|
|
@@ -21585,6 +21619,8 @@ export {
|
|
|
21585
21619
|
rollupLegacyTask,
|
|
21586
21620
|
rollupTask,
|
|
21587
21621
|
rollupWatchTask,
|
|
21622
|
+
strictOptions,
|
|
21623
|
+
toggle,
|
|
21588
21624
|
watch,
|
|
21589
21625
|
watchTaskHandlers
|
|
21590
21626
|
};
|