@adbayb/stack 2.26.0 → 2.27.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.
@@ -1,4 +1,3 @@
1
- /* eslint-disable unicorn/string-content */
2
1
  import unicornPlugin from "eslint-plugin-unicorn";
3
2
 
4
3
  import { JAVASCRIPT_LIKE_EXTENSIONS } from "../constants.js";
@@ -126,16 +125,6 @@ export const config = [
126
125
  "unicorn/relative-url-style": ["error", "always"],
127
126
  "unicorn/require-array-join-separator": "error",
128
127
  "unicorn/require-number-to-fixed-digits-argument": "error",
129
- "unicorn/string-content": [
130
- "error",
131
- {
132
- patterns: {
133
- "->": "→",
134
- "\\.\\.\\.": "…",
135
- "^http:\\/\\/": String.raw`^https:\/\/`,
136
- },
137
- },
138
- ],
139
128
  "unicorn/switch-case-braces": "error",
140
129
  "unicorn/text-encoding-identifier-case": "error",
141
130
  "unicorn/throw-new-error": "error",
package/dist/index.js CHANGED
@@ -196,7 +196,7 @@ const ESLINT_EXTENSIONS = [
196
196
  "mdx"
197
197
  ];
198
198
 
199
- var version = "2.26.0";
199
+ var version = "2.27.0";
200
200
 
201
201
  const createWatchCommand = (program)=>{
202
202
  program.command({
@@ -285,7 +285,7 @@ const createInstallCommand = (program)=>{
285
285
  }).task({
286
286
  label: label$4("Install `git.commit-msg` hook"),
287
287
  async handler () {
288
- await installGitHook("commit-msg", getStackCommand("check --only commit", false));
288
+ await installGitHook("commit-msg", getStackCommand("check --filter commit", false));
289
289
  }
290
290
  }).task({
291
291
  label: label$4("Check the package manager"),
@@ -589,7 +589,7 @@ const PRESERVE_FILES = [
589
589
  "node_modules"
590
590
  ];
591
591
 
592
- const checkTypes = async ()=>{
592
+ const checkType = async ()=>{
593
593
  try {
594
594
  return await helpers.exec("pnpm --parallel exec tsc --noEmit");
595
595
  } catch (error) {
@@ -597,9 +597,9 @@ const checkTypes = async ()=>{
597
597
  }
598
598
  };
599
599
 
600
- const checkPackages = async ()=>{
600
+ const checkDependency = async ()=>{
601
601
  const stdout = await helpers.exec("pnpm recursive ls --json");
602
- const checkPackagesVersionMismatch = createPackagesVersionMismatchChecker();
602
+ const checkDependencyVersionMismatch = createPackagesVersionMismatchChecker();
603
603
  const packages = JSON.parse(stdout).map((package_)=>{
604
604
  const packagePath = join(package_.path, "package.json");
605
605
  assert(package_.name, ()=>createPackageError(`\`${packagePath}\` must have a name field.`));
@@ -616,19 +616,19 @@ const checkPackages = async ()=>{
616
616
  });
617
617
  for (const package_ of packages){
618
618
  // Check version mismatches to guarantee a single copy for a given package in the monorepo (use case: prevent singleton-like issues with React contexts)
619
- checkPackagesVersionMismatch(package_);
619
+ checkDependencyVersionMismatch(package_);
620
620
  // Check version range accordingly to our dependency guidelines (ie. dev dependencies must be pinned and dependencies must have caret)
621
- checkPackagesVersionRange(package_);
621
+ checkDependencyVersionRange(package_);
622
622
  }
623
623
  };
624
- const checkPackagesVersionRange = ({ name, dependencies, devDependencies, peerDependencies })=>{
624
+ const checkDependencyVersionRange = ({ name, dependencies, devDependencies, peerDependencies })=>{
625
625
  for (const dependencyName of Object.keys(devDependencies)){
626
626
  const version = devDependencies[dependencyName];
627
627
  assertVersion(version, {
628
628
  name: dependencyName,
629
629
  consumedBy: name
630
630
  });
631
- if (version !== "workspace:*" && !/^\d/.test(version)) throw createPackageError(`As a dev dependency, \`${dependencyName}\` version must be fixed (or set as "workspace:*" for local packages) to reduce accidental breaking change risks due to an implicit semver upgrade.`, {
631
+ if (version !== "workspace:*" && !isException(version) && !/^\d/.test(version)) throw createPackageError(`As a dev dependency, \`${dependencyName}\` version must be fixed (or set as "workspace:*" for local packages) to reduce accidental breaking change risks due to an implicit semver upgrade.`, {
632
632
  name: dependencyName,
633
633
  consumedBy: name
634
634
  });
@@ -639,7 +639,7 @@ const checkPackagesVersionRange = ({ name, dependencies, devDependencies, peerDe
639
639
  name: dependencyName,
640
640
  consumedBy: name
641
641
  });
642
- if (version !== "workspace:^" && hasNoCaret(version)) throw createPackageError(`As a dependency, \`${dependencyName}\` version must be prefixed with a caret (or set as "workspace:^" for local packages) to optimize the size (whether of installation or bundle output) on the consumer side.`, {
642
+ if (version !== "workspace:^" && !hasCaret(version) && !isException(version)) throw createPackageError(`As a dependency, \`${dependencyName}\` version must be prefixed with a caret (or set as "workspace:^" for local packages) to optimize the size (whether of installation or bundle output) on the consumer side.`, {
643
643
  name: dependencyName,
644
644
  consumedBy: name
645
645
  });
@@ -650,7 +650,7 @@ const checkPackagesVersionRange = ({ name, dependencies, devDependencies, peerDe
650
650
  name: dependencyName,
651
651
  consumedBy: name
652
652
  });
653
- if (hasNoCaret(version)) /*
653
+ if (!hasCaret(version) && !isException(version)) /*
654
654
  * Why disallowing workspace protocol as a version resolver?
655
655
  * To reduce the update frequency needs consumer-side and guarantee on our side the minimum compatible version,
656
656
  * the best practice should be to keeping an explicit number version which represents the lowest compatible version from an API perspective.
@@ -699,12 +699,12 @@ function assertVersion(version, { name, consumedBy }) {
699
699
  consumedBy
700
700
  }));
701
701
  }
702
- const isPreReleaseVersion = (version)=>/\d+\.\d+\.\d+-(alpha|beta|experimental|next|rc).*/.exec(version);
703
- const hasNoCaret = (version)=>!isPreReleaseVersion(version) && !version.startsWith("^");
704
-
705
- const checkLinter = eslint({
706
- isFixMode: false
707
- });
702
+ const isException = (version)=>{
703
+ const isPreReleaseVersion = /\d+\.\d+\.\d+-(alpha|beta|experimental|next|rc).*/.exec(version);
704
+ const isNpmProtocol = version.startsWith("npm:");
705
+ return isNpmProtocol || isPreReleaseVersion;
706
+ };
707
+ const hasCaret = (version)=>version.startsWith("^");
708
708
 
709
709
  const checkCommit = async ()=>{
710
710
  try {
@@ -714,26 +714,30 @@ const checkCommit = async ()=>{
714
714
  }
715
715
  };
716
716
 
717
+ const checkCode = eslint({
718
+ isFixMode: false
719
+ });
720
+
717
721
  const ONLY_VALUES = [
718
722
  "commit",
719
- "linter",
720
- "packages",
721
- "types"
723
+ "code",
724
+ "dependency",
725
+ "type"
722
726
  ];
723
727
  const createCheckCommand = (program)=>{
724
728
  program.command({
725
729
  name: "check",
726
730
  description: "Check code health (static analysis)"
727
731
  }).option({
728
- key: "only",
729
- name: "only",
730
- description: `Run only one specified task (accepted value: ${ONLY_VALUES.join(", ")})`,
732
+ key: "filter",
733
+ name: "filter",
734
+ description: `Filter the compliance check to run (accepted value: ${ONLY_VALUES.join(", ")})`,
731
735
  defaultValue: undefined
732
736
  }).task({
733
737
  handler (_, argv) {
734
738
  logCheckableFiles(argv.operands);
735
739
  },
736
- skip: ifOnlyDefinedAndNotEqualTo("linter")
740
+ skip: ifFilterDefinedAndNotEqualTo("code")
737
741
  }).task({
738
742
  label: label("Prepare the project"),
739
743
  async handler () {
@@ -742,46 +746,46 @@ const createCheckCommand = (program)=>{
742
746
  hasLiveOutput: false
743
747
  });
744
748
  },
745
- skip ({ only }) {
746
- return only === "commit"; // No need to build if only commit is checked
749
+ skip ({ filter }) {
750
+ return filter === "commit"; // No need to build if only commit is checked
747
751
  }
748
752
  }).task({
749
- label: label("Check package guidelines"),
753
+ label: label("Check dependency compliance"),
750
754
  async handler () {
751
- await checkPackages();
755
+ await checkDependency();
752
756
  },
753
- skip: ifOnlyDefinedAndNotEqualTo("packages")
757
+ skip: ifFilterDefinedAndNotEqualTo("dependency")
754
758
  }).task({
755
- label: label("Check linter rules"),
759
+ label: label("Check code compliance"),
756
760
  async handler (_, argv) {
757
761
  const filenames = argv.operands;
758
- await checkLinter(filenames);
762
+ await checkCode(filenames);
759
763
  },
760
- skip: ifOnlyDefinedAndNotEqualTo("linter")
764
+ skip: ifFilterDefinedAndNotEqualTo("code")
761
765
  }).task({
762
- label: label("Check types"),
766
+ label: label("Check type compliance"),
763
767
  async handler () {
764
- await checkTypes();
768
+ await checkType();
765
769
  },
766
770
  skip (context, argv) {
767
- return ifOnlyDefinedAndNotEqualTo("types")(context) || !hasDependency("typescript") || /**
771
+ return ifFilterDefinedAndNotEqualTo("type")(context) || !hasDependency("typescript") || /**
768
772
  * For now, skip type-checking if some files are passed down.
769
773
  * @see https://github.com/microsoft/TypeScript/issues/27379
770
774
  */ argv.operands.length > 0;
771
775
  }
772
776
  }).task({
773
- label: label("Check commit"),
777
+ label: label("Check commit compliance"),
774
778
  async handler () {
775
779
  await checkCommit();
776
780
  },
777
- skip ({ only }) {
778
- return only !== "commit";
781
+ skip (context) {
782
+ return context.filter !== "commit";
779
783
  }
780
784
  });
781
785
  };
782
786
  const label = (message)=>`${message} 🧐`;
783
- const ifOnlyDefinedAndNotEqualTo = (only)=>(context)=>{
784
- return context.only !== undefined && context.only !== only;
787
+ const ifFilterDefinedAndNotEqualTo = (filter)=>(context)=>{
788
+ return context.filter !== undefined && context.filter !== filter;
785
789
  };
786
790
 
787
791
  const createBuildCommand = (program)=>{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adbayb/stack",
3
- "version": "2.26.0",
3
+ "version": "2.27.0",
4
4
  "description": "My opinionated JavaScript-based toolchain",
5
5
  "keywords": [
6
6
  "stack",
@@ -40,39 +40,39 @@
40
40
  ],
41
41
  "dependencies": {
42
42
  "@changesets/changelog-github": "^0.5.1",
43
- "@changesets/cli": "^2.29.4",
43
+ "@changesets/cli": "^2.29.5",
44
44
  "@commitlint/cli": "^19.8.1",
45
45
  "@commitlint/config-conventional": "^19.8.1",
46
46
  "@eslint-react/eslint-plugin": "^1.52.2",
47
- "@eslint/compat": "^1.3.0",
47
+ "@eslint/compat": "^1.3.1",
48
48
  "@eslint/eslintrc": "^3.3.1",
49
- "@stylistic/eslint-plugin": "^4.4.1",
50
- "@vitest/eslint-plugin": "^1.2.7",
51
- "eslint": "^9.29.0",
49
+ "@stylistic/eslint-plugin": "^5.2.0",
50
+ "@vitest/eslint-plugin": "^1.3.3",
51
+ "eslint": "^9.30.0",
52
52
  "eslint-config-prettier": "^10.1.5",
53
- "eslint-import-resolver-typescript": "^4.4.3",
53
+ "eslint-import-resolver-typescript": "^4.4.4",
54
54
  "eslint-plugin-depend": "^1.2.0",
55
- "eslint-plugin-import-x": "^4.15.2",
55
+ "eslint-plugin-import-x": "^4.16.1",
56
56
  "eslint-plugin-jest-formatting": "^3.1.0",
57
- "eslint-plugin-jsdoc": "^51.0.3",
57
+ "eslint-plugin-jsdoc": "^51.3.1",
58
58
  "eslint-plugin-mdx": "^3.5.0",
59
59
  "eslint-plugin-n": "^17.20.0",
60
- "eslint-plugin-prettier": "^5.5.0",
60
+ "eslint-plugin-prettier": "^5.5.1",
61
61
  "eslint-plugin-react-hooks": "^5.2.0",
62
- "eslint-plugin-sonarjs": "^3.0.3",
62
+ "eslint-plugin-sonarjs": "^3.0.4",
63
63
  "eslint-plugin-sort-keys-custom-order": "^2.2.1",
64
64
  "eslint-plugin-unicorn": "^59.0.1",
65
65
  "fdir": "^6.4.6",
66
66
  "globals": "^16.2.0",
67
- "prettier": "^3.5.3",
68
- "prettier-plugin-packagejson": "^2.5.15",
67
+ "prettier": "^3.6.2",
68
+ "prettier-plugin-packagejson": "^2.5.17",
69
69
  "termost": "^1.4.0",
70
70
  "turbo": "^2.5.4",
71
71
  "typescript": "^5.8.3",
72
- "typescript-eslint": "^8.34.1"
72
+ "typescript-eslint": "^8.35.1"
73
73
  },
74
74
  "devDependencies": {
75
- "@types/node": "22.15.32",
75
+ "@types/node": "22.16.4",
76
76
  "quickbundle": "2.13.0"
77
77
  },
78
78
  "publishConfig": {