@sanity/pkg-utils 11.0.17 → 12.0.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/MIGRATE.md +152 -0
- package/README.md +114 -55
- package/dist/buildAction-D-M3KYyN.js +146 -0
- package/dist/buildAction-D-M3KYyN.js.map +1 -0
- package/dist/checkAction-B8M5CP3j.js +141 -0
- package/dist/checkAction-B8M5CP3j.js.map +1 -0
- package/dist/cli.js +22 -28
- package/dist/cli.js.map +1 -1
- package/dist/createApiExtractorConfig-CJoZqw8e.js +30 -0
- package/dist/createApiExtractorConfig-CJoZqw8e.js.map +1 -0
- package/dist/createTSDocConfig-ylfirNWP.js +25 -0
- package/dist/createTSDocConfig-ylfirNWP.js.map +1 -0
- package/dist/getExtractMessagesConfig-CXljwFbQ.js +75 -0
- package/dist/getExtractMessagesConfig-CXljwFbQ.js.map +1 -0
- package/dist/handleError-83GwKIFM.js +40 -0
- package/dist/handleError-83GwKIFM.js.map +1 -0
- package/dist/index.d.ts +141 -195
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +203 -11
- package/dist/index.js.map +1 -1
- package/dist/initAction-CmOO8eod.js +618 -0
- package/dist/initAction-CmOO8eod.js.map +1 -0
- package/dist/printExtractMessages-DyaYtByp.js +33 -0
- package/dist/printExtractMessages-DyaYtByp.js.map +1 -0
- package/dist/resolveBuildContext-CbwvYKj1.js +714 -0
- package/dist/resolveBuildContext-CbwvYKj1.js.map +1 -0
- package/dist/resolveTsdownConfig-CGE_7cMM.js +283 -0
- package/dist/resolveTsdownConfig-CGE_7cMM.js.map +1 -0
- package/dist/spinner-DAHe7SuT.js +15 -0
- package/dist/spinner-DAHe7SuT.js.map +1 -0
- package/dist/watchAction-BQG5_hhl.js +179 -0
- package/dist/watchAction-BQG5_hhl.js.map +1 -0
- package/dist/watchConfigFiles-AGBDblwf.js +43 -0
- package/dist/watchConfigFiles-AGBDblwf.js.map +1 -0
- package/package.json +12 -26
- package/dist/_chunks-es/buildAction.js +0 -195
- package/dist/_chunks-es/buildAction.js.map +0 -1
- package/dist/_chunks-es/checkAction.js +0 -198
- package/dist/_chunks-es/checkAction.js.map +0 -1
- package/dist/_chunks-es/createApiExtractorConfig.js +0 -52
- package/dist/_chunks-es/createApiExtractorConfig.js.map +0 -1
- package/dist/_chunks-es/createTSDocConfig.js +0 -31
- package/dist/_chunks-es/createTSDocConfig.js.map +0 -1
- package/dist/_chunks-es/defaults.js +0 -36
- package/dist/_chunks-es/defaults.js.map +0 -1
- package/dist/_chunks-es/define.js +0 -7
- package/dist/_chunks-es/define.js.map +0 -1
- package/dist/_chunks-es/extractModuleBlocks.js +0 -48
- package/dist/_chunks-es/extractModuleBlocks.js.map +0 -1
- package/dist/_chunks-es/fileExists.js +0 -12
- package/dist/_chunks-es/fileExists.js.map +0 -1
- package/dist/_chunks-es/getExtractMessagesConfig.js +0 -83
- package/dist/_chunks-es/getExtractMessagesConfig.js.map +0 -1
- package/dist/_chunks-es/handleError.js +0 -32
- package/dist/_chunks-es/handleError.js.map +0 -1
- package/dist/_chunks-es/index.js +0 -825
- package/dist/_chunks-es/index.js.map +0 -1
- package/dist/_chunks-es/initAction.js +0 -654
- package/dist/_chunks-es/initAction.js.map +0 -1
- package/dist/_chunks-es/printExtractMessages.js +0 -44
- package/dist/_chunks-es/printExtractMessages.js.map +0 -1
- package/dist/_chunks-es/resolveBuildContext.js +0 -717
- package/dist/_chunks-es/resolveBuildContext.js.map +0 -1
- package/dist/_chunks-es/resolveRolldownConfig.js +0 -117
- package/dist/_chunks-es/resolveRolldownConfig.js.map +0 -1
- package/dist/_chunks-es/spinner.js +0 -16
- package/dist/_chunks-es/spinner.js.map +0 -1
- package/dist/_chunks-es/watchAction.js +0 -160
- package/dist/_chunks-es/watchAction.js.map +0 -1
- package/dist/_chunks-es/watchConfigFiles.js +0 -49
- package/dist/_chunks-es/watchConfigFiles.js.map +0 -1
|
@@ -0,0 +1,714 @@
|
|
|
1
|
+
import { i as fileExists, r as isRecord } from "./handleError-83GwKIFM.js";
|
|
2
|
+
import { t as __exportAll } from "./initAction-CmOO8eod.js";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import path, { resolve } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
import { tsImport } from "tsx/esm/api";
|
|
7
|
+
import findConfig from "find-config";
|
|
8
|
+
import { ZodError, _typoMap, parseExports, parsePackage } from "@sanity/parse-package-json";
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
import fs from "node:fs/promises";
|
|
11
|
+
import browserslistToEsbuild from "browserslist-to-esbuild";
|
|
12
|
+
import config from "@sanity/browserslist-config";
|
|
13
|
+
import ts from "@typescript/typescript6";
|
|
14
|
+
import { errorMap } from "zod-validation-error/v3";
|
|
15
|
+
import { z } from "zod/v3";
|
|
16
|
+
const CONFIG_FILE_NAMES = [
|
|
17
|
+
"package.config.ts",
|
|
18
|
+
"package.config.js",
|
|
19
|
+
"package.config.cjs",
|
|
20
|
+
"package.config.mts",
|
|
21
|
+
"package.config.mjs"
|
|
22
|
+
];
|
|
23
|
+
/** @internal */
|
|
24
|
+
function findConfigFile(cwd) {
|
|
25
|
+
let pkgJsonPath = findConfig("package.json", { cwd });
|
|
26
|
+
if (!pkgJsonPath) return;
|
|
27
|
+
let pkgPath = path.dirname(pkgJsonPath);
|
|
28
|
+
for (let fileName of CONFIG_FILE_NAMES) {
|
|
29
|
+
let configPath = path.resolve(pkgPath, fileName);
|
|
30
|
+
if (fileExists(configPath)) return configPath;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Migration checks for `package.config.ts` options that were removed or deprecated in v12,
|
|
35
|
+
* when `@sanity/pkg-utils` moved from its rollup/rolldown stack onto `tsdown` +
|
|
36
|
+
* `@sanity/tsdown-config`.
|
|
37
|
+
*
|
|
38
|
+
* Removed options are "tombstoned": they stay declared on `PkgConfigOptions` (typed `never`,
|
|
39
|
+
* tagged `@deprecated`) so editors surface the migration path, and the checks below throw a
|
|
40
|
+
* runtime error with copy-pasteable migration instructions when they are set anyway — JS
|
|
41
|
+
* configs bypass the types, and the error text is written to be actionable for humans and
|
|
42
|
+
* agents alike.
|
|
43
|
+
*
|
|
44
|
+
* The checks are gated by the `legacyChecks` option, defaulting to on outside production
|
|
45
|
+
* builds (`process.env.NODE_ENV !== 'production'`) so they add no overhead where migration
|
|
46
|
+
* mistakes can no longer surface.
|
|
47
|
+
*/
|
|
48
|
+
const MIGRATION_GUIDE_URL = "https://github.com/sanity-io/pkg-utils/blob/main/packages/@sanity/pkg-utils/MIGRATE.md", tombstones = [
|
|
49
|
+
{
|
|
50
|
+
option: "tsgo",
|
|
51
|
+
migration: [
|
|
52
|
+
"The `dts` option is now passed through to tsdown as-is. Move the flag into it:",
|
|
53
|
+
"",
|
|
54
|
+
" // package.config.ts",
|
|
55
|
+
" export default defineConfig({",
|
|
56
|
+
" dts: {tsgo: true},",
|
|
57
|
+
" })"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
option: "extract",
|
|
62
|
+
migration: [
|
|
63
|
+
"TSDoc/release-tag checking is configured with the top-level `tsdoc` option:",
|
|
64
|
+
"",
|
|
65
|
+
" // extract: {enabled: false} -> tsdoc: false",
|
|
66
|
+
" // extract: {rules: {...}} -> tsdoc: {rules: {...}}",
|
|
67
|
+
" // extract: {customTags: [...]} -> tsdoc: {customTags: [...]}",
|
|
68
|
+
"",
|
|
69
|
+
"Type inlining (`extract.bundledPackages`) follows the bundling decisions now:",
|
|
70
|
+
"devDependencies that are imported are inlined automatically (types included), and",
|
|
71
|
+
"`deps: {alwaysBundle: [...]}` forces inlining a dependency/peerDependency.",
|
|
72
|
+
"",
|
|
73
|
+
"`extract.checkTypes` has no successor: type generation no longer type-checks",
|
|
74
|
+
"(run `tsc --noEmit` for type checking)."
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
option: "babel",
|
|
79
|
+
migration: [
|
|
80
|
+
"The Babel options moved to the top level:",
|
|
81
|
+
"",
|
|
82
|
+
" // babel: {reactCompiler: true} -> reactCompiler: true",
|
|
83
|
+
" // babel: {styledComponents: true} -> styledComponents: true",
|
|
84
|
+
"",
|
|
85
|
+
"`styledComponents` now uses oxc’s native port of `babel-plugin-styled-components`,",
|
|
86
|
+
"so `babel-plugin-styled-components` can be uninstalled.",
|
|
87
|
+
"",
|
|
88
|
+
"Custom Babel plugins (`babel.plugins`) run through the `plugins` option instead,",
|
|
89
|
+
"with a self-installed `@rolldown/plugin-babel`:",
|
|
90
|
+
"",
|
|
91
|
+
" import pluginBabel from \"@rolldown/plugin-babel\"",
|
|
92
|
+
" export default defineConfig({",
|
|
93
|
+
" plugins: [await pluginBabel({plugins: [\"babel-plugin-example\"]})],",
|
|
94
|
+
" })"
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
option: "rollup",
|
|
99
|
+
migration: [
|
|
100
|
+
"The rollup stack was replaced with tsdown:",
|
|
101
|
+
"",
|
|
102
|
+
" // rollup: {vanillaExtract: true} -> vanillaExtract: true",
|
|
103
|
+
" // rollup: {plugins: [...]} -> plugins: [...] (rolldown plugins; most",
|
|
104
|
+
" // Rollup plugins are compatible)",
|
|
105
|
+
"",
|
|
106
|
+
"`rollup.output`, `rollup.treeshake`, `rollup.experimentalLogSideEffects` and",
|
|
107
|
+
"`rollup.hashChunkFileNames` have no successor (chunk filenames are content-hashed now).",
|
|
108
|
+
"",
|
|
109
|
+
"`rollup.optimizeLodash` has no successor either — and neither does the implicit",
|
|
110
|
+
"lodash-import optimization that was applied whenever `lodash` was a dependency.",
|
|
111
|
+
"Preferably drop lodash altogether (see https://e18e.dev for module replacements like",
|
|
112
|
+
"`es-toolkit`), or import from `lodash-es`, which tree-shakes in consumers without",
|
|
113
|
+
"build-time rewriting."
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
option: "reactCompilerOptions",
|
|
118
|
+
migration: [
|
|
119
|
+
"Pass the compiler options to `reactCompiler` instead:",
|
|
120
|
+
"",
|
|
121
|
+
" // babel: {reactCompiler: true}, reactCompilerOptions: {target: \"18\"}",
|
|
122
|
+
" // becomes:",
|
|
123
|
+
" reactCompiler: {target: \"18\"}"
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
option: "jsx",
|
|
128
|
+
migration: [
|
|
129
|
+
"Configure JSX through `tsconfig.json` — the bundler reads it from there:",
|
|
130
|
+
"",
|
|
131
|
+
" // tsconfig.json",
|
|
132
|
+
" {\"compilerOptions\": {\"jsx\": \"react-jsx\"}}"
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
option: "jsxFactory",
|
|
137
|
+
migration: ["Configure JSX through `tsconfig.json` (`compilerOptions.jsxFactory`)."]
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
option: "jsxFragment",
|
|
141
|
+
migration: ["Configure JSX through `tsconfig.json` (`compilerOptions.jsxFragmentFactory`)."]
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
option: "jsxImportSource",
|
|
145
|
+
migration: ["Configure JSX through `tsconfig.json` (`compilerOptions.jsxImportSource`)."]
|
|
146
|
+
}
|
|
147
|
+
];
|
|
148
|
+
/**
|
|
149
|
+
* Throws for tombstoned options and warns for grandfathered ones. `config` is the raw loaded
|
|
150
|
+
* config object (before it is narrowed to `PkgConfigOptions`), so removed options are still
|
|
151
|
+
* observable.
|
|
152
|
+
* @internal
|
|
153
|
+
*/
|
|
154
|
+
function runLegacyConfigChecks(config) {
|
|
155
|
+
if (!(typeof config.legacyChecks == "boolean" ? config.legacyChecks : process.env.NODE_ENV !== "production")) return;
|
|
156
|
+
for (let { option, migration } of tombstones) if (config[option] !== void 0) throw Error([
|
|
157
|
+
`package.config.ts: the \`${option}\` option was removed in @sanity/pkg-utils v12.`,
|
|
158
|
+
"",
|
|
159
|
+
...migration,
|
|
160
|
+
"",
|
|
161
|
+
`Full migration guide: ${MIGRATION_GUIDE_URL}`,
|
|
162
|
+
"Set `legacyChecks: false` in package.config.ts to skip this validation (it is also",
|
|
163
|
+
"skipped when NODE_ENV=production)."
|
|
164
|
+
].join("\n"));
|
|
165
|
+
let dts = config.dts;
|
|
166
|
+
if (typeof dts == "string") throw Error([
|
|
167
|
+
`package.config.ts: \`dts: '${dts}'\` was removed in @sanity/pkg-utils v12 — the \`dts\``,
|
|
168
|
+
"option is now passed through to tsdown as-is (an options object, or `false`).",
|
|
169
|
+
"",
|
|
170
|
+
...dts === "rolldown" ? ["`dts: 'rolldown'` is the default behavior now: delete the option. Options that", "accompanied it move into the object, e.g. `tsgo: true` becomes `dts: {tsgo: true}`."] : [
|
|
171
|
+
"`dts: 'api-extractor'` type generation was removed. Types are generated with",
|
|
172
|
+
"tsdown (rolldown-plugin-dts); api-extractor remains as the TSDoc/release-tag",
|
|
173
|
+
"checking that runs during `pkg check` — configure it with the `tsdoc` option."
|
|
174
|
+
],
|
|
175
|
+
"",
|
|
176
|
+
`Full migration guide: ${MIGRATION_GUIDE_URL}`,
|
|
177
|
+
"Set `legacyChecks: false` in package.config.ts to skip this validation (it is also",
|
|
178
|
+
"skipped when NODE_ENV=production)."
|
|
179
|
+
].join("\n"));
|
|
180
|
+
config.external !== void 0 && console.warn([
|
|
181
|
+
"package.config.ts: `external` is deprecated. Use `deps: {neverBundle: [...]}` to mark",
|
|
182
|
+
"dependencies as external, and `deps: {alwaysBundle: [...]}` to bundle a dependency",
|
|
183
|
+
"(the callback pattern that filtered entries out of the defaults)."
|
|
184
|
+
].join("\n"));
|
|
185
|
+
}
|
|
186
|
+
/** @alpha */
|
|
187
|
+
async function loadConfig(options) {
|
|
188
|
+
let { cwd, pkgPath } = options, configFile = findConfigFile(path.dirname(pkgPath));
|
|
189
|
+
if (!configFile || !configFile.startsWith(cwd)) return;
|
|
190
|
+
let mod = await tsImport(pathToFileURL(configFile).toString(), import.meta.url), config = mod?.default || mod || void 0;
|
|
191
|
+
return config && typeof config == "object" && runLegacyConfigChecks(config), config;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* The set of dependency placement rules enforced in `--strict` mode.
|
|
195
|
+
*/
|
|
196
|
+
const dependencyPlacementRules = [
|
|
197
|
+
{
|
|
198
|
+
name: "react-is",
|
|
199
|
+
option: "noReactIsPeerDependency",
|
|
200
|
+
disallowedIn: ["peerDependencies"],
|
|
201
|
+
allowedIn: ["dependencies", "devDependencies"]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: "@sanity/ui",
|
|
205
|
+
option: "noSanityUiPeerDependency",
|
|
206
|
+
disallowedIn: ["peerDependencies"],
|
|
207
|
+
allowedIn: ["dependencies", "devDependencies"]
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: "@sanity/icons",
|
|
211
|
+
option: "noSanityIconsPeerDependency",
|
|
212
|
+
disallowedIn: ["peerDependencies"],
|
|
213
|
+
allowedIn: ["dependencies", "devDependencies"]
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: "sanity",
|
|
217
|
+
option: "noSanityDependency",
|
|
218
|
+
disallowedIn: ["dependencies"],
|
|
219
|
+
allowedIn: ["devDependencies", "peerDependencies"]
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: "styled-components",
|
|
223
|
+
option: "noStyledComponentsDependency",
|
|
224
|
+
disallowedIn: ["dependencies"],
|
|
225
|
+
allowedIn: ["devDependencies", "peerDependencies"]
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
name: "react",
|
|
229
|
+
option: "noReactDependency",
|
|
230
|
+
disallowedIn: ["dependencies"],
|
|
231
|
+
allowedIn: ["devDependencies", "peerDependencies"]
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
name: "react-dom",
|
|
235
|
+
option: "noReactDomDependency",
|
|
236
|
+
disallowedIn: ["dependencies"],
|
|
237
|
+
allowedIn: ["devDependencies", "peerDependencies"]
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
name: "@types/react",
|
|
241
|
+
option: "noReactTypesDependency",
|
|
242
|
+
disallowedIn: ["dependencies"],
|
|
243
|
+
allowedIn: ["devDependencies", "peerDependencies"],
|
|
244
|
+
requiredPeerVersion: "*"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
name: "@types/react-dom",
|
|
248
|
+
option: "noReactDomTypesDependency",
|
|
249
|
+
disallowedIn: ["dependencies"],
|
|
250
|
+
allowedIn: ["devDependencies", "peerDependencies"],
|
|
251
|
+
requiredPeerVersion: "*"
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
name: "@types/node",
|
|
255
|
+
option: "noNodeTypesDependency",
|
|
256
|
+
disallowedIn: ["dependencies"],
|
|
257
|
+
allowedIn: ["devDependencies", "peerDependencies"],
|
|
258
|
+
requiredPeerVersion: "*"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: "rxjs",
|
|
262
|
+
option: "noRxjsPeerDependency",
|
|
263
|
+
disallowedIn: ["peerDependencies"],
|
|
264
|
+
allowedIn: ["dependencies", "devDependencies"]
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: "@sanity/client",
|
|
268
|
+
option: "noSanityClientPeerDependency",
|
|
269
|
+
disallowedIn: ["peerDependencies"],
|
|
270
|
+
allowedIn: ["dependencies", "devDependencies"]
|
|
271
|
+
}
|
|
272
|
+
];
|
|
273
|
+
function formatFields(fields) {
|
|
274
|
+
let labels = fields.map((field) => `\`${field}\``);
|
|
275
|
+
return labels.length <= 1 ? labels.join("") : `${labels.slice(0, -1).join(", ")} or ${labels[labels.length - 1]}`;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Validates that well-known packages are declared in the correct `package.json` dependency
|
|
279
|
+
* fields. Returns `true` if any rule with severity `error` was violated.
|
|
280
|
+
* @internal
|
|
281
|
+
*/
|
|
282
|
+
function checkDependencyPlacement(options) {
|
|
283
|
+
let { pkg, logger, strictOptions } = options, shouldError = !1, report = (level, message) => {
|
|
284
|
+
level === "error" ? (shouldError = !0, logger.error(message)) : logger.warn(message);
|
|
285
|
+
};
|
|
286
|
+
for (let rule of dependencyPlacementRules) {
|
|
287
|
+
let level = strictOptions[rule.option];
|
|
288
|
+
if (level !== "off") {
|
|
289
|
+
for (let field of rule.disallowedIn) Object.hasOwn(pkg[field] ?? {}, rule.name) && report(level, `package.json: \`${rule.name}\` should not be in \`${field}\`. It should be in ${formatFields(rule.allowedIn)} instead.`);
|
|
290
|
+
if (rule.requiredPeerVersion !== void 0) {
|
|
291
|
+
let peerDependencies = pkg.peerDependencies ?? {};
|
|
292
|
+
Object.hasOwn(peerDependencies, rule.name) && peerDependencies[rule.name] !== rule.requiredPeerVersion && report(level, `package.json: \`${rule.name}\` in \`peerDependencies\` should be set to "${rule.requiredPeerVersion}" (got "${peerDependencies[rule.name]}").`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return shouldError;
|
|
297
|
+
}
|
|
298
|
+
/** @internal */
|
|
299
|
+
function assertLast(a, arr) {
|
|
300
|
+
let aIdx = arr.indexOf(a);
|
|
301
|
+
return aIdx === -1 || aIdx === arr.length - 1;
|
|
302
|
+
}
|
|
303
|
+
/** @internal */
|
|
304
|
+
function assertOrder(a, b, arr) {
|
|
305
|
+
let aIdx = arr.indexOf(a), bIdx = arr.indexOf(b);
|
|
306
|
+
return aIdx === -1 || bIdx === -1 || aIdx < bIdx;
|
|
307
|
+
}
|
|
308
|
+
function validatePkg(input) {
|
|
309
|
+
let pkg = parsePackage(input), invalidKey = Object.keys(input).find((key) => {
|
|
310
|
+
let needle = key.toUpperCase();
|
|
311
|
+
return _typoMap.has(needle) ? _typoMap.get(needle) !== key : !1;
|
|
312
|
+
});
|
|
313
|
+
if (invalidKey) throw TypeError(`
|
|
314
|
+
- package.json: "${invalidKey}" is not a valid key. Did you mean "${_typoMap.get(invalidKey.toUpperCase())}"?`);
|
|
315
|
+
return pkg;
|
|
316
|
+
}
|
|
317
|
+
/** @internal */
|
|
318
|
+
async function loadPkg(options) {
|
|
319
|
+
let { pkgPath } = options, raw = JSON.parse(await fs.readFile(pkgPath, "utf-8"));
|
|
320
|
+
return validatePkg(raw), raw;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Helper function to recursively compare export values, excluding source, development, and monorepo conditions
|
|
324
|
+
*/
|
|
325
|
+
function areExportValuesEqual(value1, value2) {
|
|
326
|
+
if (typeof value1 == "string" && typeof value2 == "string") return value1 === value2;
|
|
327
|
+
if (typeof value1 != typeof value2) return !1;
|
|
328
|
+
if (typeof value1 == "object" && value1 && typeof value2 == "object" && value2 && !Array.isArray(value1) && !Array.isArray(value2)) {
|
|
329
|
+
let obj1 = value1, obj2 = value2, keys1 = Object.keys(obj1).filter((k) => k !== "source" && k !== "development" && k !== "monorepo"), keys2 = Object.keys(obj2).filter((k) => k !== "source" && k !== "development" && k !== "monorepo");
|
|
330
|
+
if (keys1.length !== keys2.length) return !1;
|
|
331
|
+
for (let key of keys1) {
|
|
332
|
+
if (!keys2.includes(key)) return !1;
|
|
333
|
+
let val1 = obj1[key], val2 = obj2[key];
|
|
334
|
+
if (val1 === void 0 || val2 === void 0 || !areExportValuesEqual(val1, val2)) return !1;
|
|
335
|
+
}
|
|
336
|
+
return !0;
|
|
337
|
+
}
|
|
338
|
+
return !1;
|
|
339
|
+
}
|
|
340
|
+
/** @alpha */
|
|
341
|
+
async function loadPkgWithReporting(options) {
|
|
342
|
+
let { pkgPath, logger, strict, strictOptions } = options;
|
|
343
|
+
try {
|
|
344
|
+
let pkg = await loadPkg({ pkgPath }), shouldError = !1;
|
|
345
|
+
if (strict) {
|
|
346
|
+
if (strictOptions.preferModuleType !== "off") {
|
|
347
|
+
if (!pkg.type) {
|
|
348
|
+
let msg = "package.json: `type` field is missing. Future versions of pkg-utils will require `\"type\": \"module\"`. Consider adding `\"type\": \"module\"` to prepare for this change.";
|
|
349
|
+
strictOptions.preferModuleType === "error" ? (shouldError = !0, logger.error(msg)) : logger.warn(msg);
|
|
350
|
+
} else if (pkg.type === "commonjs") {
|
|
351
|
+
let msg = "package.json: `type` is set to \"commonjs\". Future versions of pkg-utils will require `\"type\": \"module\"`. Consider migrating to ES modules to prepare for this change.";
|
|
352
|
+
strictOptions.preferModuleType === "error" ? (shouldError = !0, logger.error(msg)) : logger.warn(msg);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (strictOptions.noPackageJsonBrowser !== "off" && pkg.browser) {
|
|
356
|
+
let msg = "package.json: the `browser` field is no longer needed. Use the `browser` condition in `exports` instead for better support across modern bundlers.";
|
|
357
|
+
strictOptions.noPackageJsonBrowser === "error" ? (shouldError = !0, logger.error(msg)) : logger.warn(msg);
|
|
358
|
+
}
|
|
359
|
+
if (strictOptions.noPackageJsonTypesVersions !== "off" && pkg.typesVersions) {
|
|
360
|
+
let msg = "package.json: the `typesVersions` field is no longer needed. TypeScript has long supported conditional exports and the `types` condition. Remove the `typesVersions` field and use the `types` condition in `exports` instead.";
|
|
361
|
+
strictOptions.noPackageJsonTypesVersions === "error" ? (shouldError = !0, logger.error(msg)) : logger.warn(msg);
|
|
362
|
+
}
|
|
363
|
+
checkDependencyPlacement({
|
|
364
|
+
pkg,
|
|
365
|
+
logger,
|
|
366
|
+
strictOptions
|
|
367
|
+
}) && (shouldError = !0);
|
|
368
|
+
}
|
|
369
|
+
if (pkg.exports) {
|
|
370
|
+
let _exports = Object.entries(pkg.exports);
|
|
371
|
+
for (let [expPath, exp] of _exports) {
|
|
372
|
+
if (typeof exp == "string" || expPath.endsWith(".css") || "svelte" in exp) continue;
|
|
373
|
+
let keys = Object.keys(exp);
|
|
374
|
+
exp.types && (shouldError = !0, logger.error(`exports["${expPath}"]: the \`types\` condition shouldn't be used as dts files are generated in such a way that both CJS and ESM is supported`)), exp.module && (shouldError = !0, logger.error(`exports["${expPath}"]: the \`module\` condition shouldn't be used as it's not well supported in all bundlers.`)), exp.development && exp.source && exp.development !== exp.source && (shouldError = !0, logger.error(`exports["${expPath}"]: the \`development\` condition must have the same value as \`source\` when both are present. Expected "${exp.source}" but got "${exp.development}"`)), exp.monorepo && exp.source && exp.monorepo !== exp.source && (shouldError = !0, logger.error(`exports["${expPath}"]: the \`monorepo\` condition must have the same value as \`source\` when both are present. Expected "${exp.source}" but got "${exp.monorepo}"`)), exp.node ? (exp.import && exp.node.import && !assertOrder("node", "import", keys) && (shouldError = !0, logger.error(`exports["${expPath}"]: the \`node\` property should come before the \`import\` property`)), exp.node.module && (shouldError = !0, logger.error(`exports["${expPath}"]: the \`node.module\` condition shouldn't be used as it's not well supported in all bundlers. A better strategy is to refactor the codebase to no longer be vulnerable to the "dual package hazard"`)), !exp.node.source && exp.node.import && (exp.node.require || exp.require) && (exp.node.import.endsWith(".cjs.js") || exp.node.import.endsWith(".cjs.mjs")) && (shouldError = !0, logger.error(`exports["${expPath}"]: the \`node.import\` re-export pattern shouldn't be used as it's not well supported in all bundlers. A better strategy is to refactor the codebase to no longer be vulnerable to the "dual package hazard"`)), exp.require && exp.node.require && exp.require === exp.node.require ? (shouldError = !0, logger.error(`exports["${expPath}"]: the \`node.require\` property isn't necessary as it's identical to \`require\``)) : exp.require && exp.node.require && !assertOrder("node", "require", keys) && (shouldError = !0, logger.error(`exports["${expPath}"]: the \`node\` property should come before the \`require\` property`))) : assertOrder("import", "require", keys) || logger.warn(`exports["${expPath}"]: the \`import\` property should come before the \`require\` property`), assertLast("default", keys) || (shouldError = !0, logger.error(`exports["${expPath}"]: the \`default\` property should be the last property`));
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (strict && pkg.exports && Object.keys(pkg.exports).length > 0 && Object.entries(pkg.exports).some(([, exp]) => typeof exp == "string" || typeof exp == "object" && "svelte" in exp ? !1 : !!(exp.source || exp.development || exp.monorepo))) if (pkg.publishConfig?.exports) {
|
|
378
|
+
let publishExports = pkg.publishConfig.exports;
|
|
379
|
+
for (let exportPath of Object.keys(pkg.exports)) exportPath in publishExports || (shouldError = !0, logger.error(`publishConfig.exports: missing export path "${exportPath}" that exists in exports`));
|
|
380
|
+
for (let exportPath of Object.keys(publishExports)) exportPath in pkg.exports || (shouldError = !0, logger.error(`publishConfig.exports: unexpected export path "${exportPath}" that does not exist in exports`));
|
|
381
|
+
for (let [exportPath, exp] of Object.entries(pkg.exports)) {
|
|
382
|
+
if (typeof exp == "string" || "svelte" in exp) {
|
|
383
|
+
let publishExp = publishExports[exportPath];
|
|
384
|
+
typeof publishExp != "string" && (typeof publishExp != "object" || !("svelte" in publishExp)) && (shouldError = !0, logger.error(`publishConfig.exports["${exportPath}"]: should be a string matching exports["${exportPath}"]`));
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
let publishExp = publishExports[exportPath];
|
|
388
|
+
if (!publishExp) continue;
|
|
389
|
+
if (typeof publishExp == "string") {
|
|
390
|
+
let conditions = Object.keys(exp).filter((k) => k !== "source" && k !== "development" && k !== "monorepo");
|
|
391
|
+
if (conditions.length !== 1 || conditions[0] !== "default") shouldError = !0, logger.error(`publishConfig.exports["${exportPath}"]: is a string but exports["${exportPath}"] has multiple conditions besides source/development/monorepo: ${conditions.join(", ")}`);
|
|
392
|
+
else {
|
|
393
|
+
let expectedValue = exp.default;
|
|
394
|
+
publishExp !== expectedValue && (shouldError = !0, logger.error(`publishConfig.exports["${exportPath}"]: should be "${expectedValue}" but got "${publishExp}"`));
|
|
395
|
+
}
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
if ("svelte" in publishExp) continue;
|
|
399
|
+
let exportConditions = Object.keys(exp).filter((k) => k !== "source" && k !== "development" && k !== "monorepo"), publishConditions = Object.keys(publishExp);
|
|
400
|
+
"source" in publishExp && (shouldError = !0, logger.error(`publishConfig.exports["${exportPath}"]: should not contain the \`source\` condition`)), "development" in publishExp && (shouldError = !0, logger.error(`publishConfig.exports["${exportPath}"]: should not contain the \`development\` condition`)), "monorepo" in publishExp && (shouldError = !0, logger.error(`publishConfig.exports["${exportPath}"]: should not contain the \`monorepo\` condition`));
|
|
401
|
+
for (let condition of exportConditions) condition in publishExp || (shouldError = !0, logger.error(`publishConfig.exports["${exportPath}"]: missing \`${condition}\` condition that exists in exports["${exportPath}"]`));
|
|
402
|
+
for (let condition of publishConditions) exportConditions.includes(condition) || (shouldError = !0, logger.error(`publishConfig.exports["${exportPath}"]: unexpected \`${condition}\` condition that does not exist in exports["${exportPath}"]`));
|
|
403
|
+
for (let condition of exportConditions) if (condition in publishExp) {
|
|
404
|
+
let exportValue = exp[condition], publishValue = publishExp[condition];
|
|
405
|
+
if (!areExportValuesEqual(exportValue, publishValue)) {
|
|
406
|
+
let exportValueStr = typeof exportValue == "string" ? exportValue : JSON.stringify(exportValue), publishValueStr = typeof publishValue == "string" ? publishValue : JSON.stringify(publishValue);
|
|
407
|
+
shouldError = !0, logger.error(`publishConfig.exports["${exportPath}"].${condition}: should be ${exportValueStr} but got ${publishValueStr}`);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
} else {
|
|
412
|
+
let msg = "package.json: `publishConfig.exports` is missing. Adding it helps avoid publishing to npm with the `source`, `development`, or `monorepo` condition that points to code that cannot be used by the resolver. See https://tsdown.dev/options/package-exports#dev-exports for more information.";
|
|
413
|
+
strictOptions.noPublishConfigExports === "error" ? (shouldError = !0, logger.error(msg)) : strictOptions.noPublishConfigExports !== "off" && logger.warn(msg);
|
|
414
|
+
}
|
|
415
|
+
return shouldError && process.exit(1), pkg;
|
|
416
|
+
} catch (err) {
|
|
417
|
+
if (err instanceof ZodError) for (let issue of err.issues) {
|
|
418
|
+
if (issue.code === "invalid_type") {
|
|
419
|
+
logger.error([
|
|
420
|
+
`\`${formatPath(issue.path)}\` `,
|
|
421
|
+
`in \`./package.json\` must be of type ${chalk.magenta(issue.expected)} `,
|
|
422
|
+
`(received ${chalk.magenta(issue.received)})`
|
|
423
|
+
].join(""));
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
logger.error(issue);
|
|
427
|
+
}
|
|
428
|
+
else logger.error(err);
|
|
429
|
+
return process.exit(1);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
function formatPath(segments) {
|
|
433
|
+
return segments.map((s, idx) => idx === 0 ? s : typeof s == "number" ? `[${s}]` : s.startsWith(".") ? `["${s}"]` : `.${s}`).join("");
|
|
434
|
+
}
|
|
435
|
+
function isPkgConfigPropertyResolver(prop) {
|
|
436
|
+
return typeof prop == "function";
|
|
437
|
+
}
|
|
438
|
+
/** @internal */
|
|
439
|
+
function resolveConfigProperty(prop, initialValue) {
|
|
440
|
+
return prop ? isPkgConfigPropertyResolver(prop) ? prop(initialValue) : prop : initialValue;
|
|
441
|
+
}
|
|
442
|
+
/** @public */
|
|
443
|
+
const DEFAULT_BROWSERSLIST_QUERY = config;
|
|
444
|
+
function pathContains(containerPath, itemPath) {
|
|
445
|
+
return !path.relative(containerPath, itemPath).startsWith("..");
|
|
446
|
+
}
|
|
447
|
+
function findCommonDirPath(filePaths) {
|
|
448
|
+
let ret;
|
|
449
|
+
for (let filePath of filePaths) {
|
|
450
|
+
let dirPath = path.dirname(filePath);
|
|
451
|
+
if (!ret) {
|
|
452
|
+
ret = dirPath;
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
for (; dirPath !== ret;) {
|
|
456
|
+
if (pathContains(dirPath, ret)) {
|
|
457
|
+
ret = dirPath;
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
460
|
+
if (dirPath = path.dirname(dirPath), dirPath === ret) break;
|
|
461
|
+
if (dirPath === ".") return;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return ret;
|
|
465
|
+
}
|
|
466
|
+
/** Matches the JS output file endings pkg-utils emits (`.js`, `.mjs`, `.cjs`). @internal */
|
|
467
|
+
const fileEnding = /\.[mc]?js$/, pkgExtMap = {
|
|
468
|
+
commonjs: {
|
|
469
|
+
commonjs: ".js",
|
|
470
|
+
esm: ".mjs"
|
|
471
|
+
},
|
|
472
|
+
module: {
|
|
473
|
+
commonjs: ".cjs",
|
|
474
|
+
esm: ".js"
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
function validateExports(_exports, options) {
|
|
478
|
+
let { pkg } = options, type = pkg.type || "commonjs", ext = pkgExtMap[type], errors = [];
|
|
479
|
+
for (let exp of _exports) exp._path === "." && (exp.require && pkg.main && exp.require !== pkg.main && errors.push("package.json: mismatch between \"main\" and \"exports.require\". These must be equal."), exp.import && pkg.module && exp.import !== pkg.module && errors.push("package.json: mismatch between \"module\" and \"exports.import\". These must be equal.")), exp.require && !exp.require.endsWith(ext.commonjs) && errors.push(`package.json with \`type: "${type}"\` - \`exports["${exp._path}"].require\` must end with "${ext.commonjs}"`), exp.import && !exp.import.endsWith(ext.esm) && errors.push(`package.json with \`type: "${type}"\` - \`exports["${exp._path}"].import\` must end with "${ext.esm}"`);
|
|
480
|
+
return errors;
|
|
481
|
+
}
|
|
482
|
+
function isTruthy$1(value) {
|
|
483
|
+
return !!value;
|
|
484
|
+
}
|
|
485
|
+
/** @alpha */
|
|
486
|
+
function parseAndValidateExports(options) {
|
|
487
|
+
let { cwd, pkg, strict, strictOptions, logger } = options, type = pkg.type || "commonjs", errors = [], report = (kind, message) => {
|
|
488
|
+
kind === "warn" ? logger.warn(message) : errors.push(message);
|
|
489
|
+
};
|
|
490
|
+
if (!Array.isArray(pkg.files) && strict && strictOptions.alwaysPackageJsonFiles !== "off" && report(strictOptions.alwaysPackageJsonFiles, "package.json: `files` should be used over `.npmignore`"), pkg.source) {
|
|
491
|
+
if (strict && pkg.exports?.["."] && typeof pkg.exports["."] == "object" && "source" in pkg.exports["."] && pkg.exports["."].source === pkg.source) errors.push("package.json: the \"source\" property can be removed, as it is equal to exports[\".\"].source.");
|
|
492
|
+
else if (!pkg.exports && pkg.main) {
|
|
493
|
+
let extMap = pkgExtMap[type], importExport = pkg.main.replace(fileEnding, extMap.esm), requireExport = pkg.main.replace(fileEnding, extMap.commonjs), defaultExport = pkg.main.replace(fileEnding, ".js"), maybeBrowserCondition = [];
|
|
494
|
+
if (pkg.browser) {
|
|
495
|
+
let browserConditions = [];
|
|
496
|
+
pkg.module && pkg.browser?.[pkg.module] ? browserConditions.push(` "import": ${JSON.stringify(pkg.browser[pkg.module].replace(fileEnding, extMap.esm))}`) : pkg.browser?.[pkg.main] && browserConditions.push(` "import": ${JSON.stringify(pkg.browser[pkg.main].replace(fileEnding, extMap.esm))}`), pkg.browser?.[pkg.main] && browserConditions.push(` "require": ${JSON.stringify(pkg.browser[pkg.main].replace(fileEnding, extMap.commonjs))}`), browserConditions.length && maybeBrowserCondition.push(" \"browser\": {", ` "source": ${JSON.stringify(pkg.browser?.[pkg.source] || pkg.source)},`, ...browserConditions, " }");
|
|
497
|
+
}
|
|
498
|
+
errors.push(...[
|
|
499
|
+
"package.json: `exports` are missing, it should be:",
|
|
500
|
+
"\"exports\": {",
|
|
501
|
+
" \".\": {",
|
|
502
|
+
` "source": ${JSON.stringify(pkg.source)},`,
|
|
503
|
+
...maybeBrowserCondition.length > 0 ? maybeBrowserCondition : [],
|
|
504
|
+
type === "commonjs" && ` "import": ${JSON.stringify(importExport)},`,
|
|
505
|
+
type === "module" && ` "require": ${JSON.stringify(requireExport)},`,
|
|
506
|
+
` "default": ${JSON.stringify(defaultExport)}`,
|
|
507
|
+
" },",
|
|
508
|
+
" \"./package.json\": \"./package.json\"",
|
|
509
|
+
"}"
|
|
510
|
+
].filter(isTruthy$1));
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
if (errors.length) throw Error("\n- " + errors.join("\n- "));
|
|
514
|
+
if (!pkg.exports) throw Error("\n- " + [
|
|
515
|
+
"package.json: `exports` are missing, please set a minimal configuration, for example:",
|
|
516
|
+
"\"exports\": {",
|
|
517
|
+
" \".\": {",
|
|
518
|
+
" \"source\": \"./src/index.js\",",
|
|
519
|
+
" \"default\": \"./dist/index.js\"",
|
|
520
|
+
" },",
|
|
521
|
+
" \"./package.json\": \"./package.json\"",
|
|
522
|
+
"}"
|
|
523
|
+
].join("\n- "));
|
|
524
|
+
let _exports = parseExports({ pkg });
|
|
525
|
+
strict && strictOptions.noPackageJsonTypings !== "off" && "typings" in pkg && report(strictOptions.noPackageJsonTypings, "package.json: `typings` should be `types`"), strict && strictOptions.alwaysPackageJsonTypes !== "off" && !pkg.types && typeof pkg.exports?.["."] == "object" && "source" in pkg.exports["."] && pkg.exports["."].source?.endsWith(".ts") && report(strictOptions.alwaysPackageJsonTypes, "package.json: `types` must be declared for the npm listing to show as a TypeScript module."), strict && !pkg.exports["./package.json"] && errors.push("package.json: `exports[\"./package.json\"] must be declared.");
|
|
526
|
+
for (let [exportPath, exportEntry] of Object.entries(pkg.exports)) if (exportPath.endsWith(".json") || typeof exportEntry == "string" && exportEntry.endsWith(".json")) exportPath === "./package.json" && exportEntry !== "./package.json" && errors.push("package.json: `exports[\"./package.json\"]` must be \"./package.json\".");
|
|
527
|
+
else if (exportPath.endsWith(".css")) if (typeof exportEntry == "string") existsSync(resolve(cwd, exportEntry)) || errors.push(`package.json: \`exports[${JSON.stringify(exportPath)}]\`: file does not exist.`);
|
|
528
|
+
else if (isRecord(exportEntry)) for (let [condition, target] of Object.entries(exportEntry)) typeof target != "string" && errors.push(`package.json: \`exports[${JSON.stringify(exportPath)}][${JSON.stringify(condition)}]\`: must be a string path.`);
|
|
529
|
+
else errors.push(`package.json: \`exports[${JSON.stringify(exportPath)}]\`: must be a string path or an object of export conditions.`);
|
|
530
|
+
else if (!(isRecord(exportEntry) && "svelte" in exportEntry)) if (isPkgExport(exportEntry)) {
|
|
531
|
+
let exp = {
|
|
532
|
+
_exported: !0,
|
|
533
|
+
_path: exportPath,
|
|
534
|
+
...exportEntry
|
|
535
|
+
};
|
|
536
|
+
if (!exp.default) {
|
|
537
|
+
let fallback = type === "module" ? exp.import : exp.require;
|
|
538
|
+
fallback && (exp.default = fallback);
|
|
539
|
+
}
|
|
540
|
+
!exp.require && type === "commonjs" && exp.default && (exp.require = exp.default), !exp.import && type === "module" && exp.default && (exp.import = exp.default), exportPath === "." && (exportEntry.require && pkg.main && exportEntry.require !== pkg.main && errors.push("package.json: mismatch between \"main\" and \"exports.require\". These must be equal."), exportEntry.import && pkg.module && exportEntry.import !== pkg.module && errors.push("package.json: mismatch between \"module\" and \"exports.import\" These must be equal."));
|
|
541
|
+
} else isRecord(exportEntry) || errors.push("package.json: exports must be an object");
|
|
542
|
+
if (errors.push(...validateExports(_exports, { pkg })), errors.length) throw Error("\n- " + errors.join("\n- "));
|
|
543
|
+
return _exports;
|
|
544
|
+
}
|
|
545
|
+
function isPkgExport(value) {
|
|
546
|
+
return isRecord(value) && "source" in value && typeof value.source == "string";
|
|
547
|
+
}
|
|
548
|
+
/** @internal */
|
|
549
|
+
async function loadTSConfig(options) {
|
|
550
|
+
let { cwd, tsconfigPath } = options, configPath = ts.findConfigFile(cwd, ts.sys.fileExists, tsconfigPath);
|
|
551
|
+
if (!configPath) return;
|
|
552
|
+
let configFile = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
553
|
+
return ts.parseJsonConfigFileContent(configFile.config, ts.sys, cwd);
|
|
554
|
+
}
|
|
555
|
+
function resolveBrowserTarget(versions) {
|
|
556
|
+
let target = versions.filter((version) => version.startsWith("chrome") || version.startsWith("edge") || version.startsWith("firefox") || version.startsWith("ios") || version.startsWith("safari") || version.startsWith("opera"));
|
|
557
|
+
if (target.length !== 0) return target;
|
|
558
|
+
}
|
|
559
|
+
function resolveNodeTarget(versions) {
|
|
560
|
+
let target = versions.filter((version) => version.startsWith("node"));
|
|
561
|
+
if (target.length !== 0) return target;
|
|
562
|
+
}
|
|
563
|
+
var strict_exports = /* @__PURE__ */ __exportAll({ parseStrictOptions: () => parseStrictOptions });
|
|
564
|
+
const toggle = z.union([
|
|
565
|
+
z.literal("error"),
|
|
566
|
+
z.literal("warn"),
|
|
567
|
+
z.literal("off")
|
|
568
|
+
]), strictOptions = z.object({
|
|
569
|
+
noPackageJsonTypings: toggle.default("error"),
|
|
570
|
+
noImplicitSideEffects: toggle.default("warn"),
|
|
571
|
+
noImplicitBrowsersList: toggle.default("warn"),
|
|
572
|
+
alwaysPackageJsonTypes: toggle.default("error"),
|
|
573
|
+
alwaysPackageJsonFiles: toggle.default("error"),
|
|
574
|
+
noCheckTypes: toggle.default("warn"),
|
|
575
|
+
noPackageJsonBrowser: toggle.default("warn"),
|
|
576
|
+
noPackageJsonTypesVersions: toggle.default("warn"),
|
|
577
|
+
preferModuleType: toggle.default("warn"),
|
|
578
|
+
noPublishConfigExports: toggle.default("warn"),
|
|
579
|
+
noReactIsPeerDependency: toggle.default("error"),
|
|
580
|
+
noSanityUiPeerDependency: toggle.default("error"),
|
|
581
|
+
noSanityIconsPeerDependency: toggle.default("error"),
|
|
582
|
+
noSanityDependency: toggle.default("error"),
|
|
583
|
+
noStyledComponentsDependency: toggle.default("error"),
|
|
584
|
+
noReactDependency: toggle.default("error"),
|
|
585
|
+
noReactDomDependency: toggle.default("error"),
|
|
586
|
+
noReactTypesDependency: toggle.default("error"),
|
|
587
|
+
noReactDomTypesDependency: toggle.default("error"),
|
|
588
|
+
noNodeTypesDependency: toggle.default("error"),
|
|
589
|
+
noRxjsPeerDependency: toggle.default("error"),
|
|
590
|
+
noSanityClientPeerDependency: toggle.default("error")
|
|
591
|
+
}).strict(), validationSchema = z.object({ strictOptions: strictOptions.default({}) });
|
|
592
|
+
/** @alpha */
|
|
593
|
+
function parseStrictOptions(input) {
|
|
594
|
+
return validationSchema.parse({ strictOptions: input }, { errorMap }).strictOptions;
|
|
595
|
+
}
|
|
596
|
+
function isTruthy(value) {
|
|
597
|
+
return !!value;
|
|
598
|
+
}
|
|
599
|
+
async function resolveBuildContext(options) {
|
|
600
|
+
let { config, cwd, emitDeclarationOnly = !1, logger, pkg, strict, tsconfig: tsconfigPath } = options, tsconfig = await loadTSConfig({
|
|
601
|
+
cwd,
|
|
602
|
+
tsconfigPath
|
|
603
|
+
}), strictOptions = parseStrictOptions(config?.strictOptions ?? {}), browserslist = pkg.browserslist;
|
|
604
|
+
if (!browserslist) {
|
|
605
|
+
if (strict && strictOptions.noImplicitBrowsersList !== "off") {
|
|
606
|
+
if (strictOptions.noImplicitBrowsersList === "error") throw Error("\n- package.json: \"browserslist\" is missing, set it to `\"browserslist\": \"extends @sanity/browserslist-config\"`");
|
|
607
|
+
logger.warn("Could not detect a `browserslist` property in `package.json`, using default configuration. Add `\"browserslist\": \"extends @sanity/browserslist-config\"` to silence this warning.");
|
|
608
|
+
}
|
|
609
|
+
browserslist = DEFAULT_BROWSERSLIST_QUERY;
|
|
610
|
+
}
|
|
611
|
+
let targetVersions = browserslistToEsbuild(browserslist);
|
|
612
|
+
if (strict && strictOptions.noImplicitSideEffects !== "off" && pkg.sideEffects === void 0) {
|
|
613
|
+
let msg = "package.json: `sideEffects` is missing, see https://webpack.js.org/guides/tree-shaking/#clarifying-tree-shaking-and-sideeffects for how to define `sideEffects`";
|
|
614
|
+
if (strictOptions.noImplicitSideEffects === "error") throw Error(msg);
|
|
615
|
+
logger.warn(msg);
|
|
616
|
+
}
|
|
617
|
+
let nodeTarget = resolveNodeTarget(targetVersions), webTarget = resolveBrowserTarget(targetVersions);
|
|
618
|
+
if (!nodeTarget) throw Error("no matching `node` target");
|
|
619
|
+
if (!webTarget) throw Error("no matching `web` target");
|
|
620
|
+
let target = {
|
|
621
|
+
"*": webTarget.concat(nodeTarget),
|
|
622
|
+
browser: webTarget,
|
|
623
|
+
node: nodeTarget
|
|
624
|
+
}, parsedExports = parseAndValidateExports({
|
|
625
|
+
cwd,
|
|
626
|
+
pkg,
|
|
627
|
+
strict,
|
|
628
|
+
strictOptions,
|
|
629
|
+
logger
|
|
630
|
+
}).reduce((acc, { _path: exportPath, ...exportEntry }) => Object.assign(acc, { [exportPath]: exportEntry }), {}), exports = resolveConfigProperty(config?.exports, parsedExports), parsedExternal = [...pkg.dependencies ? Object.keys(pkg.dependencies) : [], ...pkg.peerDependencies ? Object.keys(pkg.peerDependencies) : []], external = config && Array.isArray(config.external) ? [...parsedExternal, ...config.external] : resolveConfigProperty(config?.external, parsedExternal), packagePattern = (name) => RegExp(`^${escapeRegExp(name)}(/|$)`), neverBundleAdditions = external.filter((name) => !parsedExternal.includes(name)).map(packagePattern);
|
|
631
|
+
neverBundleAdditions.push(packagePattern(pkg.name));
|
|
632
|
+
let alwaysBundleNames = parsedExternal.filter((name) => !external.includes(name)), deps = mergeDeps(config?.deps, {
|
|
633
|
+
neverBundle: neverBundleAdditions,
|
|
634
|
+
alwaysBundle: alwaysBundleNames.map(packagePattern)
|
|
635
|
+
}), externalWithTypes = /* @__PURE__ */ new Set([
|
|
636
|
+
pkg.name,
|
|
637
|
+
...external,
|
|
638
|
+
...external.map(transformPackageName)
|
|
639
|
+
]), bundledPackages = [
|
|
640
|
+
...(pkg.devDependencies ? Object.keys(pkg.devDependencies) : []).filter((_) => !externalWithTypes.has(_)),
|
|
641
|
+
...alwaysBundleNames,
|
|
642
|
+
...Array.isArray(config?.deps?.alwaysBundle) ? config.deps.alwaysBundle.filter((entry) => typeof entry == "string") : typeof config?.deps?.alwaysBundle == "string" ? [config.deps.alwaysBundle] : []
|
|
643
|
+
], commonDistPath = findCommonDirPath(Object.values(exports).flatMap((exportEntry) => [
|
|
644
|
+
exportEntry.import,
|
|
645
|
+
exportEntry.require,
|
|
646
|
+
exportEntry.browser?.import,
|
|
647
|
+
exportEntry.browser?.require,
|
|
648
|
+
exportEntry.node?.source && exportEntry.node.import,
|
|
649
|
+
exportEntry.node?.source && exportEntry.node.require
|
|
650
|
+
].filter(isTruthy)).map((p) => path.resolve(cwd, p)));
|
|
651
|
+
if (commonDistPath === cwd) throw Error("all output files must share a common parent directory which is not the root package directory");
|
|
652
|
+
if (commonDistPath && !pathContains(cwd, commonDistPath)) throw Error("all output files must be located within the package");
|
|
653
|
+
let configDistPath = config?.dist ? path.resolve(cwd, config.dist) : void 0;
|
|
654
|
+
if (configDistPath && commonDistPath && configDistPath !== commonDistPath && !pathContains(configDistPath, commonDistPath)) throw logger.log(`did you mean to configure \`dist: './${path.relative(cwd, commonDistPath)}'\`?`), Error("all output files must be located with the configured `dist` path");
|
|
655
|
+
let distPath = configDistPath || commonDistPath;
|
|
656
|
+
if (!distPath) throw Error("could not detect `dist` path");
|
|
657
|
+
return {
|
|
658
|
+
config,
|
|
659
|
+
cwd,
|
|
660
|
+
deps,
|
|
661
|
+
distPath,
|
|
662
|
+
emitDeclarationOnly,
|
|
663
|
+
exports,
|
|
664
|
+
external,
|
|
665
|
+
bundledPackages,
|
|
666
|
+
logger,
|
|
667
|
+
pkg,
|
|
668
|
+
runtime: config?.runtime ?? "*",
|
|
669
|
+
strict,
|
|
670
|
+
target,
|
|
671
|
+
ts: {
|
|
672
|
+
config: tsconfig,
|
|
673
|
+
configPath: tsconfigPath
|
|
674
|
+
}
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Merges the `deps` additions derived from the deprecated `external` option (and the
|
|
679
|
+
* self-reference external) into the userland `deps` passthrough. Array forms concatenate, a
|
|
680
|
+
* userland function is composed with the derived additions (the additions carry pipeline
|
|
681
|
+
* invariants like the self-reference external, which must survive customization — the same
|
|
682
|
+
* composition `@sanity/tsdown-config` applies to its `/^node:/` default), and a blanket
|
|
683
|
+
* `true` (externalize all of `node_modules`) wins as the broadest request.
|
|
684
|
+
* @internal Exported for tests.
|
|
685
|
+
*/
|
|
686
|
+
function mergeDeps(configDeps, additions) {
|
|
687
|
+
let userNeverBundle = configDeps?.neverBundle, neverBundle;
|
|
688
|
+
if (userNeverBundle === void 0) neverBundle = additions.neverBundle;
|
|
689
|
+
else if (userNeverBundle === !0) neverBundle = userNeverBundle;
|
|
690
|
+
else if (typeof userNeverBundle == "function") {
|
|
691
|
+
let patterns = additions.neverBundle;
|
|
692
|
+
neverBundle = (id, importer, isResolved) => patterns.some((pattern) => typeof pattern == "string" ? pattern === id : pattern.test(id)) || userNeverBundle(id, importer, isResolved);
|
|
693
|
+
} else neverBundle = Array.isArray(userNeverBundle) ? [...additions.neverBundle, ...userNeverBundle] : [...additions.neverBundle, userNeverBundle];
|
|
694
|
+
let userAlwaysBundle = configDeps?.alwaysBundle, alwaysBundle;
|
|
695
|
+
return alwaysBundle = userAlwaysBundle === void 0 ? additions.alwaysBundle.length ? additions.alwaysBundle : void 0 : typeof userAlwaysBundle == "function" ? userAlwaysBundle : Array.isArray(userAlwaysBundle) ? [...additions.alwaysBundle, ...userAlwaysBundle] : [...additions.alwaysBundle, userAlwaysBundle], {
|
|
696
|
+
...configDeps,
|
|
697
|
+
neverBundle,
|
|
698
|
+
...alwaysBundle === void 0 ? {} : { alwaysBundle }
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
function escapeRegExp(value) {
|
|
702
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
703
|
+
}
|
|
704
|
+
function transformPackageName(packageName) {
|
|
705
|
+
if (packageName.startsWith("@types/")) return packageName;
|
|
706
|
+
if (packageName.startsWith("@")) {
|
|
707
|
+
let [scope, name] = packageName.split("/");
|
|
708
|
+
return `@types/${scope?.slice(1)}__${name}`;
|
|
709
|
+
}
|
|
710
|
+
return `@types/${packageName}`;
|
|
711
|
+
}
|
|
712
|
+
export { loadPkgWithReporting as a, pkgExtMap as i, strict_exports as n, loadConfig as o, fileEnding as r, resolveBuildContext as t };
|
|
713
|
+
|
|
714
|
+
//# sourceMappingURL=resolveBuildContext-CbwvYKj1.js.map
|