@sanity/pkg-utils 6.0.2 → 6.2.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/index.js CHANGED
@@ -132,10 +132,23 @@ const pkgSchema = z.object({
132
132
  )
133
133
  ),
134
134
  browserslist: z.optional(z.union([z.string(), z.array(z.string())])),
135
- sideEffects: z.optional(z.union([z.boolean(), z.array(z.string())]))
136
- });
135
+ sideEffects: z.optional(z.union([z.boolean(), z.array(z.string())])),
136
+ // @TODO type this properly
137
+ typesVersions: z.optional(z.any())
138
+ }), typoMap = /* @__PURE__ */ new Map();
139
+ for (const key of pkgSchema.keyof()._def.values)
140
+ typoMap.set(key.toUpperCase(), key);
137
141
  function validatePkg(input) {
138
- return pkgSchema.parse(input);
142
+ const pkg = pkgSchema.parse(input), invalidKey = Object.keys(input).find((key) => {
143
+ const needle = key.toUpperCase();
144
+ return typoMap.has(needle) ? typoMap.get(needle) !== key : !1;
145
+ });
146
+ if (invalidKey)
147
+ throw new TypeError(
148
+ `
149
+ - package.json: "${invalidKey}" is not a valid key. Did you mean "${typoMap.get(invalidKey.toUpperCase())}"?`
150
+ );
151
+ return pkg;
139
152
  }
140
153
  async function loadPkg(options2) {
141
154
  const { cwd } = options2, pkgPath = await pkgUp({ cwd });
@@ -212,7 +225,7 @@ async function loadPkgWithReporting(options2) {
212
225
  function formatPath(segments) {
213
226
  return segments.map((s, idx) => idx === 0 ? s : typeof s == "number" ? `[${s}]` : s.startsWith(".") ? `["${s}"]` : `.${s}`).join("");
214
227
  }
215
- const fileEnding = /\.[mc]?js$/, dtsEnding = ".d.ts", legacyEnding = ".esm.js", mtsEnding = ".d.mts", ctsEnding = ".d.cts";
228
+ const fileEnding = /\.[mc]?js$/, dtsEnding = ".d.ts", defaultEnding = ".js", legacyEnding = `.esm${defaultEnding}`, mjsEnding = ".mjs", cjsEnding = ".cjs", mtsEnding = ".d.mts", ctsEnding = ".d.cts";
216
229
  function getTargetPaths(_type, expOrBundle) {
217
230
  const type = _type === "module" ? "module" : "commonjs", set = /* @__PURE__ */ new Set();
218
231
  return expOrBundle?.import && set.add(expOrBundle.import.replace(fileEnding, type === "module" ? dtsEnding : mtsEnding)), expOrBundle?.require && set.add(expOrBundle.require.replace(fileEnding, type === "commonjs" ? dtsEnding : ctsEnding)), isPkgExport(expOrBundle) && (expOrBundle.browser?.source || (expOrBundle.browser?.import && set.add(
@@ -234,13 +247,13 @@ function isPkgExport(exp) {
234
247
  const pkgExtMap = {
235
248
  // pkg.type: "commonjs"
236
249
  commonjs: {
237
- commonjs: ".js",
238
- esm: ".mjs"
250
+ commonjs: defaultEnding,
251
+ esm: mjsEnding
239
252
  },
240
253
  // pkg.type: "module"
241
254
  module: {
242
- commonjs: ".cjs",
243
- esm: ".js"
255
+ commonjs: cjsEnding,
256
+ esm: defaultEnding
244
257
  },
245
258
  // package.config.legacyExports: true
246
259
  legacy: legacyEnding
@@ -256,55 +269,121 @@ function validateExports(_exports, options2) {
256
269
  return errors;
257
270
  }
258
271
  function parseExports(options2) {
259
- const { pkg, strict, legacyExports } = options2, rootExport = {
260
- _exported: !0,
261
- _path: ".",
262
- source: pkg.source || "",
263
- browser: pkg.browser && {
264
- source: pkg.source || "",
265
- require: pkg.main && pkg.browser[pkg.main],
266
- import: pkg.module && pkg.browser[pkg.module]
267
- },
268
- require: pkg.main,
269
- import: pkg.module,
270
- default: pkg.module || pkg.main || ""
271
- }, extraExports = [], errors = [];
272
- if (strict && "typings" in pkg && errors.push("package.json: `typings` should be `types`"), pkg.exports) {
273
- strict && !pkg.types && pkg.source?.endsWith(".ts") && errors.push(
274
- "package.json: `types` must be declared for the npm listing to show as a TypeScript module."
275
- ), strict && !pkg.exports["./package.json"] && errors.push('package.json: `exports["./package.json"] must be declared.');
276
- for (const [exportPath, exportEntry] of Object.entries(pkg.exports))
277
- if (exportPath.endsWith(".json"))
278
- exportPath === "./package.json" && exportEntry !== "./package.json" && errors.push('package.json: `exports["./package.json"] must be "./package.json".');
279
- else if (!(isRecord(exportEntry) && "svelte" in exportEntry))
280
- if (isRecord(exportEntry))
281
- if (exportPath === ".") {
282
- if (exportEntry.require && rootExport.require && exportEntry.require !== rootExport.require && errors.push(
283
- 'package.json: mismatch between "main" and "exports.require". These must be equal.'
284
- ), legacyExports) {
285
- const indexLegacyExport = (exportEntry.browser?.import || exportEntry.import || exportEntry.browser?.require || exportEntry.require || "").replace(/(\.esm)?\.[mc]?js$/, legacyEnding);
286
- indexLegacyExport !== rootExport.import && errors.push(
287
- `package.json: "module" should be "${indexLegacyExport}" when "legacyExports" is true`
288
- );
289
- } else
290
- exportEntry.import && rootExport.import && exportEntry.import !== rootExport.import && errors.push(
291
- 'package.json: mismatch between "module" and "exports.import" These must be equal.'
292
- );
293
- exportEntry.source && rootExport.source && exportEntry.source !== rootExport.source && errors.push(
294
- 'package.json: mismatch between "source" and "exports.source". These must be equal.'
295
- ), Object.assign(rootExport, exportEntry);
296
- } else {
297
- const extraExport = {
298
- _exported: !0,
299
- _path: exportPath,
300
- ...exportEntry
301
- };
302
- extraExports.push(extraExport);
303
- }
304
- else
305
- errors.push("package.json: exports must be an object");
272
+ const { pkg, strict, legacyExports } = options2, type = pkg.type || "commonjs", errors = [];
273
+ if (pkg.source) {
274
+ if (strict && pkg.exports?.["."] && typeof pkg.exports["."] == "object" && "source" in pkg.exports["."] && pkg.exports["."].source === pkg.source)
275
+ errors.push(
276
+ 'package.json: the "source" property can be removed, as it is equal to exports["."].source.'
277
+ );
278
+ else if (!pkg.exports && pkg.main) {
279
+ const extMap = pkgExtMap[type], importExport = pkg.main.replace(fileEnding, extMap.esm), requireExport = pkg.main.replace(fileEnding, extMap.commonjs), defaultExport = pkg.main.replace(fileEnding, defaultEnding), maybeBrowserCondition = [];
280
+ if (pkg.browser) {
281
+ const browserConditions = [];
282
+ if (pkg.module && pkg.browser?.[pkg.module])
283
+ browserConditions.push(
284
+ ` "import": ${JSON.stringify(pkg.browser[pkg.module].replace(fileEnding, extMap.esm))}`
285
+ );
286
+ else if (pkg.browser?.[pkg.main])
287
+ browserConditions.push(
288
+ ` "import": ${JSON.stringify(pkg.browser?.[pkg.main].replace(fileEnding, extMap.esm))}`
289
+ );
290
+ else if (legacyExports) {
291
+ const browserImport = pkg.main.replace(fileEnding, `.browser${extMap.esm}`);
292
+ browserConditions.push(` "import": ${JSON.stringify(browserImport)}`);
293
+ }
294
+ if (pkg.browser?.[pkg.main])
295
+ browserConditions.push(
296
+ ` "require": ${JSON.stringify(pkg.browser[pkg.main].replace(fileEnding, extMap.commonjs))}`
297
+ );
298
+ else if (legacyExports) {
299
+ const browserRequire = pkg.main.replace(fileEnding, `.browser${extMap.commonjs}`);
300
+ browserConditions.push(` "require": ${JSON.stringify(browserRequire)}`);
301
+ }
302
+ browserConditions.length && maybeBrowserCondition.push(
303
+ ' "browser": {',
304
+ ` "source": ${JSON.stringify(pkg.browser?.[pkg.source] || pkg.source)},`,
305
+ ...browserConditions,
306
+ " }"
307
+ );
308
+ }
309
+ errors.push(
310
+ ...[
311
+ "package.json: `exports` are missing, it should be:",
312
+ '"exports": {',
313
+ ' ".": {',
314
+ ` "source": ${JSON.stringify(pkg.source)},`,
315
+ // If browser conditions are detected then add them to the suggestion
316
+ ...maybeBrowserCondition.length > 0 ? maybeBrowserCondition : [],
317
+ // If legacy exports are enabled we suggest the full list of exports, if not we can use the terse version
318
+ (legacyExports || type === "commonjs") && ` "import": ${JSON.stringify(importExport)},`,
319
+ (legacyExports || type === "module") && ` "require": ${JSON.stringify(requireExport)},`,
320
+ ` "default": ${JSON.stringify(defaultExport)}`,
321
+ " },",
322
+ ' "./package.json": "./package.json"',
323
+ "}"
324
+ ].filter(Boolean)
325
+ );
326
+ }
306
327
  }
307
- const _exports = [rootExport, ...extraExports];
328
+ if (errors.length)
329
+ throw new Error(`
330
+ - ` + errors.join(`
331
+ - `));
332
+ if (!pkg.exports)
333
+ throw new Error(
334
+ `
335
+ - ` + [
336
+ "package.json: `exports` are missing, please set a minimal configuration, for example:",
337
+ '"exports": {',
338
+ ' ".": {',
339
+ ' "source": "./src/index.js",',
340
+ ' "default": "./dist/index.js"',
341
+ " },",
342
+ ' "./package.json": "./package.json"',
343
+ "}"
344
+ ].join(`
345
+ - `)
346
+ );
347
+ const _exports = [];
348
+ strict && "typings" in pkg && errors.push("package.json: `typings` should be `types`"), strict && !pkg.types && pkg.source?.endsWith(".ts") && errors.push(
349
+ "package.json: `types` must be declared for the npm listing to show as a TypeScript module."
350
+ ), strict && !pkg.exports["./package.json"] && errors.push('package.json: `exports["./package.json"] must be declared.');
351
+ for (const [exportPath, exportEntry] of Object.entries(pkg.exports))
352
+ if (exportPath.endsWith(".json"))
353
+ exportPath === "./package.json" && exportEntry !== "./package.json" && errors.push('package.json: `exports["./package.json"] must be "./package.json".');
354
+ else if (!(isRecord(exportEntry) && "svelte" in exportEntry))
355
+ if (isRecord(exportEntry)) {
356
+ const exp = {
357
+ _exported: !0,
358
+ _path: exportPath,
359
+ ...exportEntry
360
+ };
361
+ if (!exp.default) {
362
+ const fallback = type === "module" ? exp.import : exp.require;
363
+ fallback && (exp.default = fallback), legacyExports && (fallback ? errors.push(
364
+ `package.json - \`exports["${exp._path}"].default\` should be set to "${fallback}" when "legacyExports" is true`
365
+ ) : errors.push(
366
+ `package.json - \`exports["${exp._path}"].default\` should be specified when "legacyExports" is true`
367
+ ));
368
+ }
369
+ if (!exp.require && type === "commonjs" && exp.default && (exp.require = exp.default), !exp.import && type === "module" && exp.default && (exp.import = exp.default), exportPath === ".")
370
+ if (exportEntry.require && pkg.main && exportEntry.require !== pkg.main && errors.push(
371
+ 'package.json: mismatch between "main" and "exports.require". These must be equal.'
372
+ ), legacyExports) {
373
+ const indexLegacyExport = (exportEntry.import || exportEntry.require || "").replace(
374
+ /(\.esm)?\.[mc]?js$/,
375
+ legacyEnding
376
+ );
377
+ indexLegacyExport !== pkg.module && errors.push(
378
+ `package.json: "module" should be "${indexLegacyExport}" when "legacyExports" is true`
379
+ );
380
+ } else
381
+ exportEntry.import && pkg.module && exportEntry.import !== pkg.module && errors.push(
382
+ 'package.json: mismatch between "module" and "exports.import" These must be equal.'
383
+ );
384
+ _exports.push(exp);
385
+ } else
386
+ errors.push("package.json: exports must be an object");
308
387
  if (errors.push(...validateExports(_exports, { pkg })), errors.length)
309
388
  throw new Error(`
310
389
  - ` + errors.join(`