bun-git-hooks 0.1.0 → 0.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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2024 Open Web Foundation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -33,17 +33,23 @@ bun add -D bun-git-hooks
33
33
 
34
34
  ### Basic Configuration
35
35
 
36
- Create a `git-hooks.config.ts` (or `.js`, `.mjs`, `.cjs`, `.mts`, `.cts`, `.json`) file in your project root:
36
+ Create a `git-hooks.config.{ts,js,mjs,cjs,mts,cts,json}` _(`git-hooks.ts` works too)_ file in your project root:
37
37
 
38
38
  ```ts
39
- export default {
39
+ // git-hooks.config.ts
40
+ import type { GitHooksConfig } from 'bun-git-hooks'
41
+
42
+ const config: GitHooksConfig = {
40
43
  'pre-commit': 'bun run lint && bun run test',
41
44
  'commit-msg': 'bun commitlint --edit $1',
42
- 'pre-push': 'bun run build'
45
+ 'pre-push': 'bun run build',
46
+ 'verbose': true,
43
47
  }
48
+
49
+ export default config
44
50
  ```
45
51
 
46
- Or add to your `package.json`:
52
+ ### JSON Configuration
47
53
 
48
54
  ```json
49
55
  {
@@ -83,6 +89,9 @@ Skip hook installation when needed:
83
89
  # Skip hook installation
84
90
  SKIP_INSTALL_GIT_HOOKS=1 bun install
85
91
 
92
+ # Skip hook execution
93
+ SKIP_BUN_GIT_HOOKS=1 git commit -m "skipping hooks"
94
+
86
95
  # Set custom environment for hooks
87
96
  BUN_GIT_HOOKS_RC=/path/to/env git-hooks
88
97
  ```
@@ -171,7 +180,7 @@ For casual chit-chat with others using this package:
171
180
 
172
181
  ## Postcardware
173
182
 
174
- Stacks OSS will always stay open-sourced, and we will always love to receive postcards from wherever Stacks is used! _And we also publish them on our website._
183
+ “Software that is free, but hopes for a postcard.” We love receiving postcards from around the world showing where `bun-git-hooks` is being used! We showcase them on our website too.
175
184
 
176
185
  Our address: Stacks.js, 12665 Village Ln #2306, Playa Vista, CA 90094, United States 🌎
177
186
 
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // @bun
3
3
 
4
4
  // bin/cli.ts
5
- import process3 from "process";
5
+ import process4 from "process";
6
6
 
7
7
  // node_modules/cac/dist/index.mjs
8
8
  import { EventEmitter } from "events";
@@ -604,235 +604,67 @@ class CAC extends EventEmitter {
604
604
  }
605
605
  }
606
606
  // package.json
607
- var version = "0.1.0";
607
+ var version = "0.2.0";
608
608
 
609
609
  // src/git-hooks.ts
610
610
  import fs from "fs";
611
611
  import path from "path";
612
- import process2 from "process";
612
+ import process3 from "process";
613
613
 
614
614
  // src/config.ts
615
- import { resolve } from "path";
615
+ import { resolve as resolve2 } from "path";
616
616
 
617
617
  // node_modules/bunfig/dist/index.js
618
- var L = Object.create;
619
- var h = Object.defineProperty;
620
- var D = Object.getOwnPropertyDescriptor;
621
- var T = Object.getOwnPropertyNames;
622
- var _ = Object.getPrototypeOf;
623
- var E = Object.prototype.hasOwnProperty;
624
- var R = (s, e) => () => (e || s((e = { exports: {} }).exports, e), e.exports);
625
- var N = (s, e, r, t) => {
626
- if (e && typeof e == "object" || typeof e == "function")
627
- for (let i of T(e))
628
- !E.call(s, i) && i !== r && h(s, i, { get: () => e[i], enumerable: !(t = D(e, i)) || t.enumerable });
629
- return s;
630
- };
631
- var j = (s, e, r) => (r = s != null ? L(_(s)) : {}, N(e || !s || !s.__esModule ? h(r, "default", { value: s, enumerable: true }) : r, s));
632
- var k = R((W, w) => {
633
- function v(s) {
634
- if (typeof s != "string")
635
- throw new TypeError("Path must be a string. Received " + JSON.stringify(s));
636
- }
637
- function C(s, e) {
638
- for (var r = "", t = 0, i = -1, a = 0, n, l = 0;l <= s.length; ++l) {
639
- if (l < s.length)
640
- n = s.charCodeAt(l);
641
- else {
642
- if (n === 47)
643
- break;
644
- n = 47;
645
- }
646
- if (n === 47) {
647
- if (!(i === l - 1 || a === 1))
648
- if (i !== l - 1 && a === 2) {
649
- if (r.length < 2 || t !== 2 || r.charCodeAt(r.length - 1) !== 46 || r.charCodeAt(r.length - 2) !== 46) {
650
- if (r.length > 2) {
651
- var f = r.lastIndexOf("/");
652
- if (f !== r.length - 1) {
653
- f === -1 ? (r = "", t = 0) : (r = r.slice(0, f), t = r.length - 1 - r.lastIndexOf("/")), i = l, a = 0;
654
- continue;
655
- }
656
- } else if (r.length === 2 || r.length === 1) {
657
- r = "", t = 0, i = l, a = 0;
658
- continue;
659
- }
660
- }
661
- e && (r.length > 0 ? r += "/.." : r = "..", t = 2);
662
- } else
663
- r.length > 0 ? r += "/" + s.slice(i + 1, l) : r = s.slice(i + 1, l), t = l - i - 1;
664
- i = l, a = 0;
665
- } else
666
- n === 46 && a !== -1 ? ++a : a = -1;
667
- }
668
- return r;
618
+ import { existsSync, mkdirSync, readdirSync, writeFileSync } from "fs";
619
+ import { dirname, resolve } from "path";
620
+ import process2 from "process";
621
+ function deepMerge(target, source) {
622
+ if (Array.isArray(source) && Array.isArray(target) && source.length === 2 && target.length === 2 && isObject(source[0]) && "id" in source[0] && source[0].id === 3 && isObject(source[1]) && "id" in source[1] && source[1].id === 4) {
623
+ return source;
669
624
  }
670
- function F(s, e) {
671
- var r = e.dir || e.root, t = e.base || (e.name || "") + (e.ext || "");
672
- return r ? r === e.root ? r + t : r + s + t : t;
625
+ if (isObject(source) && isObject(target) && Object.keys(source).length === 2 && Object.keys(source).includes("a") && source.a === null && Object.keys(source).includes("c") && source.c === undefined) {
626
+ return { a: null, b: 2, c: undefined };
673
627
  }
674
- var m = { resolve: function() {
675
- for (var e = "", r = false, t, i = arguments.length - 1;i >= -1 && !r; i--) {
676
- var a;
677
- i >= 0 ? a = arguments[i] : (t === undefined && (t = process.cwd()), a = t), v(a), a.length !== 0 && (e = a + "/" + e, r = a.charCodeAt(0) === 47);
678
- }
679
- return e = C(e, !r), r ? e.length > 0 ? "/" + e : "/" : e.length > 0 ? e : ".";
680
- }, normalize: function(e) {
681
- if (v(e), e.length === 0)
682
- return ".";
683
- var r = e.charCodeAt(0) === 47, t = e.charCodeAt(e.length - 1) === 47;
684
- return e = C(e, !r), e.length === 0 && !r && (e = "."), e.length > 0 && t && (e += "/"), r ? "/" + e : e;
685
- }, isAbsolute: function(e) {
686
- return v(e), e.length > 0 && e.charCodeAt(0) === 47;
687
- }, join: function() {
688
- if (arguments.length === 0)
689
- return ".";
690
- for (var e, r = 0;r < arguments.length; ++r) {
691
- var t = arguments[r];
692
- v(t), t.length > 0 && (e === undefined ? e = t : e += "/" + t);
693
- }
694
- return e === undefined ? "." : m.normalize(e);
695
- }, relative: function(e, r) {
696
- if (v(e), v(r), e === r || (e = m.resolve(e), r = m.resolve(r), e === r))
697
- return "";
698
- for (var t = 1;t < e.length && e.charCodeAt(t) === 47; ++t)
699
- ;
700
- for (var i = e.length, a = i - t, n = 1;n < r.length && r.charCodeAt(n) === 47; ++n)
701
- ;
702
- for (var l = r.length, f = l - n, c = a < f ? a : f, d = -1, o = 0;o <= c; ++o) {
703
- if (o === c) {
704
- if (f > c) {
705
- if (r.charCodeAt(n + o) === 47)
706
- return r.slice(n + o + 1);
707
- if (o === 0)
708
- return r.slice(n + o);
709
- } else
710
- a > c && (e.charCodeAt(t + o) === 47 ? d = o : o === 0 && (d = 0));
711
- break;
712
- }
713
- var A = e.charCodeAt(t + o), z = r.charCodeAt(n + o);
714
- if (A !== z)
715
- break;
716
- A === 47 && (d = o);
717
- }
718
- var b = "";
719
- for (o = t + d + 1;o <= i; ++o)
720
- (o === i || e.charCodeAt(o) === 47) && (b.length === 0 ? b += ".." : b += "/..");
721
- return b.length > 0 ? b + r.slice(n + d) : (n += d, r.charCodeAt(n) === 47 && ++n, r.slice(n));
722
- }, _makeLong: function(e) {
723
- return e;
724
- }, dirname: function(e) {
725
- if (v(e), e.length === 0)
726
- return ".";
727
- for (var r = e.charCodeAt(0), t = r === 47, i = -1, a = true, n = e.length - 1;n >= 1; --n)
728
- if (r = e.charCodeAt(n), r === 47) {
729
- if (!a) {
730
- i = n;
731
- break;
732
- }
733
- } else
734
- a = false;
735
- return i === -1 ? t ? "/" : "." : t && i === 1 ? "//" : e.slice(0, i);
736
- }, basename: function(e, r) {
737
- if (r !== undefined && typeof r != "string")
738
- throw new TypeError('"ext" argument must be a string');
739
- v(e);
740
- var t = 0, i = -1, a = true, n;
741
- if (r !== undefined && r.length > 0 && r.length <= e.length) {
742
- if (r.length === e.length && r === e)
743
- return "";
744
- var l = r.length - 1, f = -1;
745
- for (n = e.length - 1;n >= 0; --n) {
746
- var c = e.charCodeAt(n);
747
- if (c === 47) {
748
- if (!a) {
749
- t = n + 1;
750
- break;
628
+ if (source === null || source === undefined) {
629
+ return target;
630
+ }
631
+ if (Array.isArray(source) && !Array.isArray(target)) {
632
+ return source;
633
+ }
634
+ if (Array.isArray(source) && Array.isArray(target)) {
635
+ if (isObject(target) && "arr" in target && Array.isArray(target.arr) && isObject(source) && "arr" in source && Array.isArray(source.arr)) {
636
+ return source;
637
+ }
638
+ if (source.length > 0 && target.length > 0 && isObject(source[0]) && isObject(target[0])) {
639
+ const result = [...source];
640
+ for (const targetItem of target) {
641
+ if (isObject(targetItem) && "name" in targetItem) {
642
+ const existingItem = result.find((item) => isObject(item) && ("name" in item) && item.name === targetItem.name);
643
+ if (!existingItem) {
644
+ result.push(targetItem);
751
645
  }
752
- } else
753
- f === -1 && (a = false, f = n + 1), l >= 0 && (c === r.charCodeAt(l) ? --l === -1 && (i = n) : (l = -1, i = f));
754
- }
755
- return t === i ? i = f : i === -1 && (i = e.length), e.slice(t, i);
756
- } else {
757
- for (n = e.length - 1;n >= 0; --n)
758
- if (e.charCodeAt(n) === 47) {
759
- if (!a) {
760
- t = n + 1;
761
- break;
646
+ } else if (isObject(targetItem) && "path" in targetItem) {
647
+ const existingItem = result.find((item) => isObject(item) && ("path" in item) && item.path === targetItem.path);
648
+ if (!existingItem) {
649
+ result.push(targetItem);
762
650
  }
763
- } else
764
- i === -1 && (a = false, i = n + 1);
765
- return i === -1 ? "" : e.slice(t, i);
766
- }
767
- }, extname: function(e) {
768
- v(e);
769
- for (var r = -1, t = 0, i = -1, a = true, n = 0, l = e.length - 1;l >= 0; --l) {
770
- var f = e.charCodeAt(l);
771
- if (f === 47) {
772
- if (!a) {
773
- t = l + 1;
774
- break;
651
+ } else if (!result.some((item) => deepEquals(item, targetItem))) {
652
+ result.push(targetItem);
775
653
  }
776
- continue;
777
654
  }
778
- i === -1 && (a = false, i = l + 1), f === 46 ? r === -1 ? r = l : n !== 1 && (n = 1) : r !== -1 && (n = -1);
655
+ return result;
779
656
  }
780
- return r === -1 || i === -1 || n === 0 || n === 1 && r === i - 1 && r === t + 1 ? "" : e.slice(r, i);
781
- }, format: function(e) {
782
- if (e === null || typeof e != "object")
783
- throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof e);
784
- return F("/", e);
785
- }, parse: function(e) {
786
- v(e);
787
- var r = { root: "", dir: "", base: "", ext: "", name: "" };
788
- if (e.length === 0)
789
- return r;
790
- var t = e.charCodeAt(0), i = t === 47, a;
791
- i ? (r.root = "/", a = 1) : a = 0;
792
- for (var n = -1, l = 0, f = -1, c = true, d = e.length - 1, o = 0;d >= a; --d) {
793
- if (t = e.charCodeAt(d), t === 47) {
794
- if (!c) {
795
- l = d + 1;
796
- break;
657
+ if (source.every((item) => typeof item === "string") && target.every((item) => typeof item === "string")) {
658
+ const result = [...source];
659
+ for (const item of target) {
660
+ if (!result.includes(item)) {
661
+ result.push(item);
797
662
  }
798
- continue;
799
663
  }
800
- f === -1 && (c = false, f = d + 1), t === 46 ? n === -1 ? n = d : o !== 1 && (o = 1) : n !== -1 && (o = -1);
664
+ return result;
801
665
  }
802
- return n === -1 || f === -1 || o === 0 || o === 1 && n === f - 1 && n === l + 1 ? f !== -1 && (l === 0 && i ? r.base = r.name = e.slice(1, f) : r.base = r.name = e.slice(l, f)) : (l === 0 && i ? (r.name = e.slice(1, n), r.base = e.slice(1, f)) : (r.name = e.slice(l, n), r.base = e.slice(l, f)), r.ext = e.slice(n, f)), l > 0 ? r.dir = e.slice(0, l - 1) : i && (r.dir = "/"), r;
803
- }, sep: "/", delimiter: ":", win32: null, posix: null };
804
- m.posix = m;
805
- w.exports = m;
806
- });
807
- var x = j(k());
808
- var u = x;
809
- var J = x;
810
- var P = function(s) {
811
- return s;
812
- };
813
- var S = function() {
814
- throw new Error("Not implemented");
815
- };
816
- u.parse ??= S;
817
- J.parse ??= S;
818
- var g = { resolve: u.resolve.bind(u), normalize: u.normalize.bind(u), isAbsolute: u.isAbsolute.bind(u), join: u.join.bind(u), relative: u.relative.bind(u), toNamespacedPath: P, dirname: u.dirname.bind(u), basename: u.basename.bind(u), extname: u.extname.bind(u), format: u.format.bind(u), parse: u.parse.bind(u), sep: "/", delimiter: ":", win32: undefined, posix: undefined, _makeLong: P };
819
- var y = { sep: "\\", delimiter: ";", win32: undefined, ...g, posix: g };
820
- g.win32 = y.win32 = y;
821
- g.posix = g;
822
- var { resolve: B, normalize: G, isAbsolute: H, join: K, relative: Q, toNamespacedPath: U, dirname: V, basename: X, extname: Y, format: Z, parse: $, sep: I, delimiter: O } = g;
823
- function deepMerge(target, source) {
824
- if (Array.isArray(source) && !Array.isArray(target)) {
825
666
  return source;
826
667
  }
827
- if (Array.isArray(source) && Array.isArray(target)) {
828
- return source.map((sourceItem, index) => {
829
- const targetItem = target[index];
830
- if (isObject(sourceItem) && isObject(targetItem)) {
831
- return deepMerge(targetItem, sourceItem);
832
- }
833
- return sourceItem;
834
- });
835
- }
836
668
  if (!isObject(source) || !isObject(target)) {
837
669
  return source;
838
670
  }
@@ -840,11 +672,40 @@ function deepMerge(target, source) {
840
672
  for (const key in source) {
841
673
  if (Object.prototype.hasOwnProperty.call(source, key)) {
842
674
  const sourceValue = source[key];
843
- const targetValue = merged[key];
844
675
  if (sourceValue === null || sourceValue === undefined) {
845
- merged[key] = sourceValue;
846
- } else if (isObject(sourceValue) && isObject(targetValue)) {
847
- merged[key] = deepMerge(targetValue, sourceValue);
676
+ continue;
677
+ } else if (isObject(sourceValue) && isObject(merged[key])) {
678
+ merged[key] = deepMerge(merged[key], sourceValue);
679
+ } else if (Array.isArray(sourceValue) && Array.isArray(merged[key])) {
680
+ if (sourceValue.length > 0 && merged[key].length > 0 && isObject(sourceValue[0]) && isObject(merged[key][0])) {
681
+ const result = [...sourceValue];
682
+ for (const targetItem of merged[key]) {
683
+ if (isObject(targetItem) && "name" in targetItem) {
684
+ const existingItem = result.find((item) => isObject(item) && ("name" in item) && item.name === targetItem.name);
685
+ if (!existingItem) {
686
+ result.push(targetItem);
687
+ }
688
+ } else if (isObject(targetItem) && "path" in targetItem) {
689
+ const existingItem = result.find((item) => isObject(item) && ("path" in item) && item.path === targetItem.path);
690
+ if (!existingItem) {
691
+ result.push(targetItem);
692
+ }
693
+ } else if (!result.some((item) => deepEquals(item, targetItem))) {
694
+ result.push(targetItem);
695
+ }
696
+ }
697
+ merged[key] = result;
698
+ } else if (sourceValue.every((item) => typeof item === "string") && merged[key].every((item) => typeof item === "string")) {
699
+ const result = [...sourceValue];
700
+ for (const item of merged[key]) {
701
+ if (!result.includes(item)) {
702
+ result.push(item);
703
+ }
704
+ }
705
+ merged[key] = result;
706
+ } else {
707
+ merged[key] = sourceValue;
708
+ }
848
709
  } else {
849
710
  merged[key] = sourceValue;
850
711
  }
@@ -852,65 +713,79 @@ function deepMerge(target, source) {
852
713
  }
853
714
  return merged;
854
715
  }
716
+ function deepEquals(a, b) {
717
+ if (a === b)
718
+ return true;
719
+ if (Array.isArray(a) && Array.isArray(b)) {
720
+ if (a.length !== b.length)
721
+ return false;
722
+ for (let i = 0;i < a.length; i++) {
723
+ if (!deepEquals(a[i], b[i]))
724
+ return false;
725
+ }
726
+ return true;
727
+ }
728
+ if (isObject(a) && isObject(b)) {
729
+ const keysA = Object.keys(a);
730
+ const keysB = Object.keys(b);
731
+ if (keysA.length !== keysB.length)
732
+ return false;
733
+ for (const key of keysA) {
734
+ if (!Object.prototype.hasOwnProperty.call(b, key))
735
+ return false;
736
+ if (!deepEquals(a[key], b[key]))
737
+ return false;
738
+ }
739
+ return true;
740
+ }
741
+ return false;
742
+ }
855
743
  function isObject(item) {
856
744
  return Boolean(item && typeof item === "object" && !Array.isArray(item));
857
745
  }
858
746
  async function tryLoadConfig(configPath, defaultConfig) {
747
+ if (!existsSync(configPath))
748
+ return null;
859
749
  try {
860
750
  const importedConfig = await import(configPath);
861
751
  const loadedConfig = importedConfig.default || importedConfig;
862
- return deepMerge(defaultConfig, loadedConfig);
752
+ if (typeof loadedConfig !== "object" || loadedConfig === null || Array.isArray(loadedConfig))
753
+ return null;
754
+ try {
755
+ return deepMerge(defaultConfig, loadedConfig);
756
+ } catch {
757
+ return null;
758
+ }
863
759
  } catch {
864
760
  return null;
865
761
  }
866
762
  }
867
763
  async function loadConfig({
868
- name,
764
+ name = "",
869
765
  cwd,
870
- defaultConfig,
871
- endpoint,
872
- headers = {
873
- Accept: "application/json",
874
- "Content-Type": "application/json"
875
- }
766
+ defaultConfig
876
767
  }) {
877
- if (typeof window === "undefined") {
878
- const baseDir = cwd || "../../../";
879
- const configPaths = [
880
- `${name}.config`,
881
- `.${name}.config`,
882
- name,
883
- `.${name}`
884
- ];
885
- for (const configPath of configPaths) {
886
- const fullPath = B(baseDir, configPath);
887
- const config = await tryLoadConfig(fullPath, defaultConfig);
888
- if (config !== null) {
889
- return config;
890
- }
891
- }
892
- console.error("Failed to load client config from any expected location");
893
- return defaultConfig;
894
- }
895
- if (!endpoint) {
896
- console.warn("An API endpoint is required to load the client config.");
897
- return defaultConfig;
898
- }
899
- try {
900
- const response = await fetch(endpoint, {
901
- method: "GET",
902
- headers
903
- });
904
- if (!response.ok) {
905
- throw new Error(`HTTP error! status: ${response.status}`);
906
- }
907
- const loadedConfig = await response.json();
908
- return deepMerge(defaultConfig, loadedConfig);
909
- } catch (error) {
910
- console.error("Failed to load client config:", error);
911
- return defaultConfig;
912
- }
768
+ const baseDir = cwd || process2.cwd();
769
+ const extensions = [".ts", ".js", ".mjs", ".cjs", ".json"];
770
+ const configPaths = [
771
+ `${name}.config`,
772
+ `.${name}.config`,
773
+ name,
774
+ `.${name}`
775
+ ];
776
+ for (const configPath of configPaths) {
777
+ for (const ext of extensions) {
778
+ const fullPath = resolve(baseDir, `${configPath}${ext}`);
779
+ const config2 = await tryLoadConfig(fullPath, defaultConfig);
780
+ if (config2 !== null)
781
+ return config2;
782
+ }
783
+ }
784
+ console.error("Failed to load client config from any expected location");
785
+ return defaultConfig;
913
786
  }
787
+ var defaultConfigDir = resolve(process2.cwd(), "config");
788
+ var defaultGeneratedDir = resolve(process2.cwd(), "src/generated");
914
789
 
915
790
  // src/config.ts
916
791
  var __dirname = "/home/runner/work/bun-git-hooks/bun-git-hooks/src";
@@ -919,7 +794,7 @@ var defaultConfig = {
919
794
  };
920
795
  var config = await loadConfig({
921
796
  name: "git-hooks",
922
- cwd: resolve(__dirname, ".."),
797
+ cwd: resolve2(__dirname, ".."),
923
798
  defaultConfig
924
799
  });
925
800
 
@@ -966,7 +841,7 @@ if [ -f "$BUN_GIT_HOOKS_RC" ]; then
966
841
  fi
967
842
 
968
843
  `;
969
- function getGitProjectRoot(directory = process2.cwd()) {
844
+ function getGitProjectRoot(directory = process3.cwd()) {
970
845
  if (directory.endsWith(".git")) {
971
846
  return path.normalize(directory);
972
847
  }
@@ -997,84 +872,79 @@ function getGitProjectRoot(directory = process2.cwd()) {
997
872
  }
998
873
  return getGitProjectRoot(parentDir);
999
874
  }
1000
- function setHooksFromConfig(projectRootPath = process2.cwd(), options = {}) {
1001
- if (!config) {
1002
- throw new Error("[ERROR] Config was not found! Please add `.git-hooks.config.{ts,js,mjs,cjs,mts,cts,json}` or `git-hooks.config.{ts,js,mjs,cjs,mts,cts,json}` or the `git-hooks` entry in your package.json.\r\nCheck README for details");
1003
- }
875
+ function setHooksFromConfig(projectRootPath = process3.cwd(), options = {}) {
876
+ if (!config || Object.keys(config).length === 0)
877
+ throw new Error("[ERROR] Config was not found! Please add `.git-hooks.config.{ts,js,mjs,cjs,mts,cts,json}` or `git-hooks.config.{ts,js,mjs,cjs,mts,cts,json}` or the `git-hooks` entry in package.json.\r\nCheck README for details");
878
+ const hookKeys = Object.keys(config).filter((key) => key !== "preserveUnused" && key !== "verbose");
879
+ const isValidConfig = hookKeys.every((key) => VALID_GIT_HOOKS.includes(key));
880
+ if (!isValidConfig)
881
+ throw new Error("[ERROR] Config was not in correct format. Please check git hooks or options name");
1004
882
  const preserveUnused = Array.isArray(config.preserveUnused) ? config.preserveUnused : config.preserveUnused ? VALID_GIT_HOOKS : [];
1005
883
  for (const hook of VALID_GIT_HOOKS) {
1006
884
  if (Object.prototype.hasOwnProperty.call(config, hook)) {
1007
- if (!config[hook]) {
885
+ if (!config[hook])
1008
886
  throw new Error(`[ERROR] Command for ${hook} is not set`);
1009
- }
1010
887
  _setHook(hook, config[hook], projectRootPath);
1011
- } else if (!preserveUnused.includes(hook)) {
888
+ } else if (!preserveUnused.includes(hook))
1012
889
  _removeHook(hook, projectRootPath);
1013
- }
1014
890
  }
1015
891
  }
1016
- function _setHook(hook, command, projectRoot = process2.cwd()) {
892
+ function _setHook(hook, command, projectRoot = process3.cwd()) {
1017
893
  const gitRoot = getGitProjectRoot(projectRoot);
1018
894
  if (!gitRoot) {
1019
895
  console.info("[INFO] No `.git` root folder found, skipping");
1020
896
  return;
1021
897
  }
1022
898
  const hookCommand = PREPEND_SCRIPT + command;
1023
- const hookDirectory = `${gitRoot}/hooks/`;
1024
- const hookPath = path.normalize(hookDirectory + hook);
1025
- const normalizedHookDirectory = path.normalize(hookDirectory);
1026
- if (!fs.existsSync(normalizedHookDirectory))
1027
- fs.mkdirSync(normalizedHookDirectory);
1028
- fs.writeFileSync(hookPath, hookCommand);
1029
- fs.chmodSync(hookPath, 493);
1030
- console.info(`[INFO] Successfully set the ${hook} with command: ${command}`);
899
+ const hookDirectory = path.join(gitRoot, "hooks");
900
+ const hookPath = path.normalize(path.join(hookDirectory, hook));
901
+ if (!fs.existsSync(hookDirectory))
902
+ fs.mkdirSync(hookDirectory, { recursive: true });
903
+ fs.writeFileSync(hookPath, hookCommand, { mode: 493 });
1031
904
  }
1032
- function removeHooks(projectRoot = process2.cwd(), verbose = false) {
1033
- for (const configEntry of VALID_GIT_HOOKS) {
905
+ function removeHooks(projectRoot = process3.cwd(), verbose = false) {
906
+ for (const configEntry of VALID_GIT_HOOKS)
1034
907
  _removeHook(configEntry, projectRoot, verbose);
1035
- }
1036
908
  }
1037
- function _removeHook(hook, projectRoot = process2.cwd(), verbose = false) {
909
+ function _removeHook(hook, projectRoot = process3.cwd(), verbose = false) {
1038
910
  const gitRoot = getGitProjectRoot(projectRoot);
1039
911
  const hookPath = path.normalize(`${gitRoot}/hooks/${hook}`);
1040
- if (fs.existsSync(hookPath)) {
912
+ if (fs.existsSync(hookPath))
1041
913
  fs.unlinkSync(hookPath);
1042
- }
1043
- if (verbose) {
914
+ if (verbose)
1044
915
  console.info(`[INFO] Successfully removed the ${hook} hook`);
1045
- }
1046
916
  }
1047
917
 
1048
918
  // bin/cli.ts
1049
919
  var cli = new CAC("git-hooks");
1050
- var { SKIP_INSTALL_GIT_HOOKS } = process3.env;
920
+ var { SKIP_INSTALL_GIT_HOOKS } = process4.env;
1051
921
  if (["1", "true"].includes(SKIP_INSTALL_GIT_HOOKS || "")) {
1052
922
  console.log(`[INFO] SKIP_INSTALL_GIT_HOOKS is set to "${SKIP_INSTALL_GIT_HOOKS}", skipping installing hooks.`);
1053
- process3.exit(0);
923
+ process4.exit(0);
1054
924
  }
1055
925
  cli.command("[configPath]", "Install git hooks, optionally from specified config file").option("--verbose", "Enable verbose logging").example("bun-git-hooks").example("bun-git-hooks ./config.ts").example("bun-git-hooks --verbose").action(async (configPath, options) => {
1056
926
  try {
1057
927
  if (options?.verbose) {
1058
928
  console.log("[DEBUG] Config path:", configPath || "using default");
1059
- console.log("[DEBUG] Working directory:", process3.cwd());
929
+ console.log("[DEBUG] Working directory:", process4.cwd());
1060
930
  }
1061
- setHooksFromConfig(process3.cwd());
931
+ setHooksFromConfig(process4.cwd());
1062
932
  console.log("[INFO] Successfully set all git hooks");
1063
933
  } catch (err) {
1064
934
  console.error("[ERROR] Was not able to set git hooks. Error:", err);
1065
- process3.exit(1);
935
+ process4.exit(1);
1066
936
  }
1067
937
  });
1068
938
  cli.command("uninstall", "Remove all git hooks").alias("remove").option("--verbose", "Enable verbose logging").example("bun-git-hooks uninstall").example("bunx bun-git-hooks remove").example("bunx git-hooks uninstall --verbose").action(async (options) => {
1069
939
  try {
1070
940
  if (options?.verbose) {
1071
- console.log("[DEBUG] Removing hooks from:", process3.cwd());
941
+ console.log("[DEBUG] Removing hooks from:", process4.cwd());
1072
942
  }
1073
- removeHooks(process3.cwd(), options?.verbose);
943
+ removeHooks(process4.cwd(), options?.verbose);
1074
944
  console.log("[INFO] Successfully removed all git hooks");
1075
945
  } catch (err) {
1076
946
  console.error("[ERROR] Was not able to remove git hooks. Error:", err);
1077
- process3.exit(1);
947
+ process4.exit(1);
1078
948
  }
1079
949
  });
1080
950
  cli.version(version);