@cubing/dev-config 0.6.0 → 0.6.2
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/bin/package.json.ts +58 -10
- package/package.json +1 -1
package/bin/package.json.ts
CHANGED
|
@@ -255,7 +255,7 @@ function traverse<T>(
|
|
|
255
255
|
|
|
256
256
|
function field<T>(
|
|
257
257
|
breadcrumbs: Breadcrumbs,
|
|
258
|
-
type: Categorization,
|
|
258
|
+
type: Categorization | Categorization[],
|
|
259
259
|
options?: {
|
|
260
260
|
optional?: boolean;
|
|
261
261
|
additionalChecks?: { [requirementMessage: string]: (t: T) => boolean };
|
|
@@ -277,8 +277,9 @@ function field<T>(
|
|
|
277
277
|
}
|
|
278
278
|
const [value] = maybeValue;
|
|
279
279
|
|
|
280
|
+
const typeArray = Array.isArray(type) ? type : [type];
|
|
280
281
|
const category = categorize(value);
|
|
281
|
-
if (category
|
|
282
|
+
if (typeArray.includes(category)) {
|
|
282
283
|
for (const [failureMessage, fn] of Object.entries(
|
|
283
284
|
options?.additionalChecks ?? {},
|
|
284
285
|
)) {
|
|
@@ -297,9 +298,15 @@ function field<T>(
|
|
|
297
298
|
} else if (type === "undefined") {
|
|
298
299
|
console.log(`❌ ${breadcrumbString} — Present (but must not be).`);
|
|
299
300
|
} else {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
301
|
+
if (Array.isArray(type)) {
|
|
302
|
+
console.log(
|
|
303
|
+
`❌ ${breadcrumbString} — Does not match an expected type: ${type.join(", ")}`,
|
|
304
|
+
);
|
|
305
|
+
} else {
|
|
306
|
+
console.log(
|
|
307
|
+
`❌ ${breadcrumbString} — Does not match expected type: ${type}`,
|
|
308
|
+
);
|
|
309
|
+
}
|
|
303
310
|
}
|
|
304
311
|
exitCode = 1;
|
|
305
312
|
return;
|
|
@@ -327,10 +334,8 @@ field(["version"], "string", {
|
|
|
327
334
|
field(["homepage"], "string", { optional: true });
|
|
328
335
|
field(["description"], "string");
|
|
329
336
|
// TODO: format author.
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
} else {
|
|
333
|
-
field(["author"], "object");
|
|
337
|
+
field(["author"], ["string", "object"]);
|
|
338
|
+
if (categorize(packageJSON["author"]) === "object") {
|
|
334
339
|
field(["author", "name"], "string");
|
|
335
340
|
field(["author", "email"], "string");
|
|
336
341
|
field(["author", "url"], "string", {
|
|
@@ -521,6 +526,7 @@ if (packageJSON.exports) {
|
|
|
521
526
|
// biome-ignore lint/complexity/noUselessContinue: Explicit control flow.
|
|
522
527
|
continue;
|
|
523
528
|
} else if (typeof value === "string") {
|
|
529
|
+
// TODO: error?
|
|
524
530
|
checkPath(["exports", [exportPath]], {
|
|
525
531
|
expectPrefix: ResolutionPrefix.Relative,
|
|
526
532
|
});
|
|
@@ -532,7 +538,49 @@ if (packageJSON.exports) {
|
|
|
532
538
|
"❌ .exports — Must use an object (instead of an array).",
|
|
533
539
|
);
|
|
534
540
|
} else {
|
|
535
|
-
|
|
541
|
+
const keys = Object.keys(value as Record<string, string>);
|
|
542
|
+
|
|
543
|
+
checks.push(
|
|
544
|
+
(async () => {
|
|
545
|
+
const { breadcrumbString } = traverse(["exports", [exportPath]]);
|
|
546
|
+
const orderingErrorLines = [];
|
|
547
|
+
/**
|
|
548
|
+
* https://nodejs.org/api/packages.html#conditional-exports
|
|
549
|
+
*/
|
|
550
|
+
if (keys.includes("types")) {
|
|
551
|
+
if (keys[0] !== "types") {
|
|
552
|
+
orderingErrorLines.push(
|
|
553
|
+
` ↪ "types" must be the first export if present.`,
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
if (keys.includes("default")) {
|
|
558
|
+
if (keys.at(-1) !== "default") {
|
|
559
|
+
orderingErrorLines.push(
|
|
560
|
+
` ↪ "default" must be the last export if present.`,
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
for (const key of keys) {
|
|
565
|
+
// Note `"require"` is *emphatically not allowed*.
|
|
566
|
+
if (!["types", "import", "default"].includes(key)) {
|
|
567
|
+
orderingErrorLines.push(
|
|
568
|
+
` ↪ Key must not be present: ${JSON.stringify(key)}`,
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
if (orderingErrorLines) {
|
|
573
|
+
exitCode = 0;
|
|
574
|
+
return [
|
|
575
|
+
`❌ ${breadcrumbString} — Invalid keys:`,
|
|
576
|
+
...orderingErrorLines,
|
|
577
|
+
].join("\n");
|
|
578
|
+
} else {
|
|
579
|
+
return `✅ ${breadcrumbString} — Key set and ordering is okay..`;
|
|
580
|
+
}
|
|
581
|
+
})(),
|
|
582
|
+
);
|
|
583
|
+
for (const secondaryKey of keys) {
|
|
536
584
|
checkPath(["exports", [exportPath], secondaryKey], {
|
|
537
585
|
expectPrefix: ResolutionPrefix.Relative,
|
|
538
586
|
});
|