@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.
Files changed (2) hide show
  1. package/bin/package.json.ts +58 -10
  2. package/package.json +1 -1
@@ -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 === type) {
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
- console.log(
301
- `❌ ${breadcrumbString} — Does not match expected type: ${type}`,
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
- if (categorize(packageJSON["author"]) === "string") {
331
- field(["author"], "object");
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
- for (const secondaryKey of Object.keys(value as Record<string, string>)) {
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
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cubing/dev-config",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Common dev configs for projects.",
5
5
  "author": {
6
6
  "name": "Lucas Garron",