better-commits 1.21.0 → 1.23.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/branch.js +10 -10
- package/dist/chunk-43H72S6V.js +1 -0
- package/dist/chunk-B7AGSPP3.js +261 -0
- package/dist/index.js +28 -24
- package/dist/init.js +1 -1
- package/package.json +2 -2
- package/readme.md +27 -7
- package/src/args.test.ts +26 -0
- package/src/args.ts +23 -4
- package/src/branch-args.test.ts +3 -0
- package/src/branch-args.ts +4 -3
- package/src/branch-help.ts +13 -2
- package/src/branch.ts +2 -0
- package/src/default-config-template.ts +19 -3
- package/src/help.ts +16 -9
- package/src/index.ts +1 -0
- package/src/prompts/autocomplete-multiselect.test.ts +129 -0
- package/src/prompts/autocomplete-multiselect.ts +249 -0
- package/src/prompts/branch-scope.prompt.ts +59 -0
- package/src/prompts/branch-type.prompt.ts +4 -1
- package/src/prompts/commit-scope.prompt.ts +20 -2
- package/src/prompts/commit-status.prompt.ts +14 -11
- package/src/prompts/commit-type.prompt.ts +4 -1
- package/src/utils/build-branch.test.ts +23 -5
- package/src/utils/build-branch.ts +3 -1
- package/src/utils/infer.test.ts +93 -2
- package/src/utils/infer.ts +47 -1
- package/src/utils/messages.ts +1 -1
- package/src/utils/no-interactive-branch-validation.test.ts +23 -0
- package/src/utils/no-interactive-validation.ts +25 -2
- package/src/valibot-consts.ts +3 -0
- package/src/valibot-state.test.ts +9 -0
- package/src/valibot-state.ts +15 -4
- package/dist/chunk-2JVEMMKH.js +0 -245
- package/dist/chunk-EANV5ZZP.js +0 -1
package/dist/branch.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
import{c as
|
|
3
|
-
`)}function
|
|
4
|
-
${c.green("\uF489 better-branch")} ${c.gray("v"+
|
|
2
|
+
import{c as q,e as j,f as U,g as W,j as m}from"./chunk-43H72S6V.js";import{a as F,e as E,j as G,k as L,l as V,m as f,o as l,r as H,s as D}from"./chunk-B7AGSPP3.js";import gt from"configstore";import{chdir as ut}from"process";import{ValiError as _t,parse as J}from"valibot";var s=class{constructor(t,e,n){this.config=t;this.branch_state=e;this.prompt_cache=n}};import*as b from"@clack/prompts";var d=class extends s{async run(){if(this.#e){let t=await b.select({message:this.#t,initialValue:this.#r,options:G});b.isCancel(t)&&process.exit(),this.#n(t)}}get#t(){return"Checkout a branch or create a worktree?"}get#e(){return this.config.worktrees.enable}get#r(){return this.branch_state.checkout||this.config.branch_action_default}#n(t){this.branch_state.checkout=t}};import*as v from"@clack/prompts";var y=class extends s{async run(){if(!this.#t)return;let t=await v.text({message:this.#r,placeholder:"",initialValue:this.#n,validate:e=>this.#i(e)});v.isCancel(t)&&process.exit(0),this.#o(t??"")}get#t(){return this.config.branch_user.enable}get#e(){return this.config.branch_user.required}get#r(){return this.#e?"Type your git username":m("Type your git username")}get#n(){return this.branch_state.user||H(this.prompt_cache,"username")}#i(t){if(this.#e&&!t)return"Please enter a username"}#o(t){this.branch_state.user=t.replace(/\s+/g,"-").toLowerCase(),D(this.prompt_cache,"username",this.branch_state.user)}};import*as g from"@clack/prompts";var k=class extends s{async run(){if(!this.#t)return;let e=await(this.config.branch_type.autocomplete?g.autocomplete:g.select)({message:this.#e,initialValue:this.#r,options:this.#n});g.isCancel(e)&&process.exit(0),this.#i(e)}get#t(){return this.config.branch_type.enable}get#e(){return"Select a branch type"}get#r(){return this.branch_state.type||this.config.commit_type.initial_value}get#n(){return this.config.commit_type.options}#i(t){this.branch_state.type=t}};import*as p from"@clack/prompts";var w=class extends s{async run(){if(!this.#t)return;let e=await(this.config.branch_scope.autocomplete?p.autocomplete:p.select)({message:this.#e,initialValue:this.#r,options:this.#n});p.isCancel(e)&&process.exit(0),await this.#o(e)}get#t(){return this.config.branch_scope.enable}get#e(){return"Select a branch scope"}get#r(){return this.branch_state.scope||this.config.commit_scope.initial_value}get#n(){return this.config.commit_scope.options}get#i(){return this.config.commit_scope.custom_scope}async#o(t){let e=t;if(e===F&&this.#i){let n=await p.text({message:"Write a custom scope",placeholder:""});p.isCancel(n)&&process.exit(0),e=n??""}this.branch_state.scope=e}};import*as C from"@clack/prompts";var x=class extends s{async run(){if(!this.#t)return;let t=await C.text({message:this.#r,placeholder:"",validate:e=>this.#n(e),initialValue:this.branch_state.ticket});C.isCancel(t)&&process.exit(0),this.#i(t??"")}get#t(){return this.config.branch_ticket.enable}get#e(){return this.config.branch_ticket.required}get#r(){return this.#e?"Type ticket / issue number":m("Type ticket / issue number")}#n(t){if(this.#e&&!t)return"Please enter a ticket / issue"}#i(t){this.branch_state.ticket=t}};import*as S from"@clack/prompts";var $=class extends s{async run(){if(!this.#t)return;let t=await S.text({message:this.#r,placeholder:"",validate:e=>this.#n(e),initialValue:this.branch_state.version});S.isCancel(t)&&process.exit(0),this.#i(t??"")}get#t(){return this.config.branch_version.enable}get#e(){return this.config.branch_version.required}get#r(){return this.#e?"Type version number":m("Type version number")}#n(t){if(this.#e&&!t)return"Please enter a version"}#i(t){this.branch_state.version=t}};import*as O from"@clack/prompts";var I=class extends s{async run(){let t=await O.text({message:this.#t,placeholder:"",validate:e=>this.#r(e),initialValue:this.branch_state.description});O.isCancel(t)&&process.exit(0),this.#n(t??"")}get#t(){return"Type a short description"}get#e(){return this.config.branch_description.max_length}#r(t){if(!t)return"Please enter a description";if(t.length>this.#e)return`Exceeded max length. Description max [${this.#e}]`}#n(t){this.branch_state.description=t.replace(/\s+/g,"-").toLowerCase()}};import*as u from"@clack/prompts";import{execSync as B}from"child_process";import h from"picocolors";import{chdir as at}from"process";import{parse as rt}from"@bomb.sh/args";var M=["user","type","scope","description","ticket","branch-version","checkout"],nt=["git-dir","work-tree"],it=["interactive","dry-run","help","version"],T=class{#t;constructor(t){this.#t=t}get interactive(){return!this.#t.no_interactive}get dry_run(){return this.#t.dry_run}get help(){return this.#t.help}get version(){return this.#t.version}get git_args(){return this.#t.git_args}get branch_state(){return this.#t.branch_state}},a=new T(ot(process.argv.slice(2)));function ot(r){let t=rt(r,{alias:{h:"help",v:"version"},boolean:it,string:[...M,...nt]}),e={};return M.forEach(n=>{let i=t[n];if(i){let o=n==="branch-version"?"version":n.replace("-","_");o==="checkout"?e[o]=i??"branch":e[o]=i}}),{help:t.help===!0,version:t.version===!0,git_args:st(t["git-dir"],t["work-tree"]),no_interactive:t.interactive===!1,dry_run:t["dry-run"]===!0,branch_state:e}}function st(r,t){return`${r?`--git-dir=${r}`:""} ${t?`--work-tree=${t}`:""}`.trim()}function K(r,t){let e="";return t.branch_order.forEach(n=>{let i=`branch_${n}`;r[n]&&(e+=r[n]+t[i].separator)}),e.endsWith("-")||e.endsWith("/")||e.endsWith("_")?e.slice(0,-1).trim():e.trim()}function Y(r,t,e){let n=e.split("/").pop()||"repo",i=t.worktrees.folder_template;i=i.replace("{{repo_name}}",n).replace("{{branch_description}}",r.description).replace("{{user}}",r.user||"").replace("{{type}}",r.type||"").replace("{{scope}}",r.scope||"").replace("{{ticket}}",r.ticket||"").replace("{{version}}",r.version||""),i=i.replace(/\s/g,"").replace(/--+/g,"-").replace(/^-+|-+$/g,"");let o=t.worktrees.base_path;return`${o}${o.endsWith("/")?"":"/"}${i}`}var _=class extends s{async run(){this.#i(),this.#o(),this.#a()}get#t(){return this.branch_state.checkout==="worktree"}get#e(){return this.#t?this.config.worktree_pre_commands:this.config.branch_pre_commands}get#r(){return this.#t?this.config.worktree_post_commands:this.config.branch_post_commands}get#n(){return K(this.branch_state,this.config)}#i(){this.#s(this.#e,"Something went wrong when executing pre-commands: ")}#o(){let t=this.#n,e=this.#c(t);if(!this.#t){try{B(`git ${a.git_args} checkout ${e} ${t}`,{stdio:"inherit"}),u.log.info(`Switched to a new branch '${h.bgGreen(" "+h.black(t)+" ")}'`)}catch{process.exit(0)}return}try{let n=Y(this.branch_state,this.config,f(a.git_args));B(`git ${a.git_args} worktree add ${n} ${e} ${t}`,{stdio:"inherit"}),u.log.info(`Created a new worktree ${h.bgGreen(" "+h.black(n)+" ")}, checked out branch ${h.bgGreen(" "+h.black(t)+" ")}`),u.log.info(h.bgMagenta(h.black(` cd ${n} `))+" to navigate to your new worktree"),at(n)}catch{process.exit(0)}}#a(){this.#s(this.#r,"Something went wrong when executing post-commands: ")}#s(t,e){t.forEach(n=>{try{B(n,{stdio:"inherit"})}catch(i){u.log.error(e+i),process.exit(0)}})}#c(t){let e="";try{B(`git ${a.git_args} show-ref ${t}`,{encoding:"utf-8"}),u.log.warning(h.yellow(`${t} already exists! Checking out existing branch.`))}catch{e="-b"}return e}};import{execSync as ct}from"child_process";import c from"picocolors";var pt={"--interactive":"Run in interactive prompt mode (default behavior).","--dry-run":"Print branch commands without creating a branch or worktree.","--help":"Show help information and exit."},ht={"--user":"Set branch username segment.","--type":"Set branch type (for example feat, fix, docs).","--scope":"Set branch scope segment.","--description":"Set branch description segment.","--ticket":"Set branch ticket/issue segment.","--branch-version":"Set branch version segment.","--checkout":"Choose branch or worktree checkout mode."},mt={"--git-dir":"Set the path to the .git directory.","--work-tree":"Set the path to the working tree root."};function A(r){let n=" ";return Object.entries(r).map(([i,o])=>{let P=Math.max(2,26-i.length);return`${n}${i}${" ".repeat(P)}${o}`}).join(`
|
|
3
|
+
`)}function z(r,t){let e=l(),n="(none)";try{n=ct(`git ${a.git_args} branch --show-current`,{stdio:"pipe"}).toString().trim()||"(none)"}catch{}let i=j(r.commit_type.options,a.git_args)||"Unknown",o=r.check_ticket.infer_ticket?U({append_hashtag:r.check_ticket.append_hashtag,prepend_hashtag:r.check_ticket.prepend_hashtag},a.git_args)||"Unknown":"Infer Disabled",P=r.commit_scope.infer_scope_from_branch?W(r.commit_scope.options,a.git_args)||"Unknown":"Infer Disabled",Q=r.commit_type.options.map(N=>N.value).join(", ").trim(),X=r.commit_scope.options.map(N=>N.value).join(", ").trim(),Z=A(pt),tt=A(mt),et=A(ht);console.log(`
|
|
4
|
+
${c.green("\uF489 better-branch")} ${c.gray("v"+e)}
|
|
5
5
|
|
|
6
6
|
${c.gray("BRANCH")}
|
|
7
7
|
${n}
|
|
8
|
-
${c.gray("Type")} ${c.blue(i)} ${c.gray("\xB7")} ${c.gray("Ticket")} ${c.magenta(o)}
|
|
8
|
+
${c.gray("Type")} ${c.blue(i)} ${c.gray("\xB7")} ${c.gray("Scope")} ${c.cyan(P)} ${c.gray("\xB7")} ${c.gray("Ticket")} ${c.magenta(o)}
|
|
9
9
|
|
|
10
10
|
${c.gray("CONFIGURATION")}
|
|
11
11
|
${t}
|
|
12
12
|
|
|
13
13
|
${c.gray("Types")}
|
|
14
|
-
${
|
|
14
|
+
${Q}
|
|
15
15
|
|
|
16
16
|
${c.gray("Scopes")}
|
|
17
|
-
${
|
|
17
|
+
${X}
|
|
18
18
|
|
|
19
19
|
${c.gray("CLI FLAGS")}
|
|
20
|
-
${
|
|
20
|
+
${Z}
|
|
21
21
|
|
|
22
22
|
${c.gray("Branch Flags")}
|
|
23
|
-
${
|
|
23
|
+
${et}
|
|
24
24
|
|
|
25
25
|
${c.gray("Git Flags (Advanced)")}
|
|
26
|
-
${
|
|
26
|
+
${tt}
|
|
27
27
|
|
|
28
|
-
`)}import*as
|
|
28
|
+
`)}import*as R from"@clack/prompts";var ft=[d,y,k,x,w,$,I,_],{config:lt,config_source:dt}=V(" better-branch ",a.git_args);bt(lt,dt);async function bt(r,t){if(ut(f(a.git_args)),a.version){let o=l();R.log.step("Better Commits v"+o);return}if(a.help){z(r,t);return}let e=J(E,a.branch_state);if(!a.interactive)try{J(q(r),e)}catch(o){o instanceof _t?R.log.error(`Invalid branch input: ${o.message}`):R.log.error(`Failed to validate branch input: ${o}`),process.exit(0)}let n=r.cache_last_value?new gt("better-commits"):L,i=a.interactive?ft:[_];for(let o of i)await new o(r,e,n).run()}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as _,b as u,d as l,f as p}from"./chunk-B7AGSPP3.js";import*as s from"valibot";function g(t,n){let r=t.scope?t.scope.length+2:0,e=t.type?.length??0,i=n.include_ticket?t.ticket?.length??0:0,o=t.title?.length??0;return r+e+i+o}function a(t){return t.map(r=>r===""?'"" (none)':`"${r}"`).join(", ")}function G(t){let n=t.commit_type.options.map(e=>e.value),r=t.commit_scope.options.map(e=>e.value);return s.pipe(s.object(u),s.rawCheck(({dataset:e,addIssue:i})=>{if(!e.typed)return;let o=e.value.type?`"${e.value.type}"`:"(empty)";e.value.type&&!n.includes(e.value.type)&&i({message:`Invalid --type ${o}. Valid types: ${a(n)}.`})}),s.rawCheck(({dataset:e,addIssue:i})=>{if(!e.typed)return;let o=e.value.scope?`"${e.value.scope}"`:"(empty)";e.value.scope&&!t.commit_scope.custom_scope&&!r.includes(e.value.scope)&&i({message:`Invalid --scope ${o}. Valid scopes: ${a(r)}.`})}),s.rawCheck(({dataset:e,addIssue:i})=>{!e.typed||e.value.title.trim()||i({message:"Missing --title. Provide a non-empty commit title."})}),s.rawCheck(({dataset:e,addIssue:i})=>{if(!e.typed)return;let o=g(e.value,{include_ticket:t.check_ticket.add_to_title});o>t.commit_title.max_size&&i({message:`Title exceeds max width. Current size is ${o}, max is ${t.commit_title.max_size} (includes type, scope, and ticket when enabled).`})}),s.rawCheck(({dataset:e,addIssue:i})=>{e.typed&&t.commit_body.required&&!e.value.body.trim()&&i({message:"Missing --body. commit_body.required is enabled in config."})}),s.rawCheck(({dataset:e,addIssue:i})=>{e.typed&&e.value.closes&&!e.value.ticket&&i({message:'Invalid footer values: --closes requires --ticket (for example: --ticket "ABC-123").'})}),s.rawCheck(({dataset:e,addIssue:i})=>{e.typed&&e.value.breaking_body&&!e.value.breaking_title&&i({message:"Invalid breaking change values: --breaking-body requires --breaking-title."})}),s.rawCheck(({dataset:e,addIssue:i})=>{e.typed&&e.value.deprecates_body&&!e.value.deprecates_title&&i({message:"Invalid deprecation values: --deprecates-body requires --deprecates-title."})}))}function N(t){let n=t.commit_type.options.map(e=>e.value),r=t.commit_scope.options.map(e=>e.value);return s.pipe(s.object(l),s.rawCheck(({dataset:e,addIssue:i})=>{if(!e.typed)return;let o=e.value.type?`"${e.value.type}"`:"(empty)";e.value.type&&!n.includes(e.value.type)&&i({message:`Invalid --type ${o}. Valid types: ${a(n)}.`})}),s.rawCheck(({dataset:e,addIssue:i})=>{if(!e.typed)return;let o=e.value.scope?`"${e.value.scope}"`:"(empty)";e.value.scope&&!t.commit_scope.custom_scope&&!r.includes(e.value.scope)&&i({message:`Invalid --scope ${o}. Valid scopes: ${a(r)}.`})}),s.rawCheck(({dataset:e,addIssue:i})=>{!e.typed||e.value.description.trim()||i({message:"Missing --description. Provide a non-empty branch description."})}),s.rawCheck(({dataset:e,addIssue:i})=>{if(!e.typed)return;let o=e.value.description.trim();o.length>t.branch_description.max_length&&i({message:`Description exceeds max length. Current length is ${o.length}, max is ${t.branch_description.max_length}.`})}),s.rawCheck(({dataset:e,addIssue:i})=>{e.typed&&t.branch_user.required&&!e.value.user.trim()&&i({message:"Missing --user. branch_user.required is enabled in config."})}),s.rawCheck(({dataset:e,addIssue:i})=>{e.typed&&t.branch_ticket.required&&!e.value.ticket.trim()&&i({message:"Missing --ticket. branch_ticket.required is enabled in config."})}),s.rawCheck(({dataset:e,addIssue:i})=>{e.typed&&t.branch_version.required&&!e.value.version.trim()&&i({message:"Missing --branch-version. branch_version.required is enabled in config."})}))}import{execSync as h}from"child_process";var v=/\/(\w+-\d+)/,y=/^(\w+-\d+)/,k=/^([A-Z]+-[\[a-zA-Z\]\d]+)_/,b=/\/([A-Z]+-[\[a-zA-Z\]\d]+)_/,$=/\/(\d+)/,C=/^(\d+)/;function V(t){if(p.interactive)return;let n={ticket:"",type:"",scope:""};if(t.check_ticket.infer_ticket){let e=w({append_hashtag:t.check_ticket.append_hashtag,prepend_hashtag:t.check_ticket.prepend_hashtag},p.git_args);n.ticket=e}let r=x(t.commit_type.options,p.git_args);if(n.type=r,t.commit_scope.enable&&t.commit_scope.infer_scope_from_branch){let e=E(t.commit_scope.options,p.git_args);n.scope=e}return n}function x(t,n){let r=m(n);return r?T(r,t.map(e=>e.value)):""}function w(t,n){let r=m(n);return r?S(r,t):""}function E(t,n){let r=m(n);return r?z(r,t):""}function S(t,n){let r=[t.match(k),t.match(b),t.match(v),t.match($),t.match(y),t.match(C)].filter(e=>e!=null).map(e=>e&&e.length>=2?e[1]:"");return!r.length||!r[0]?"":n.append_hashtag||n.prepend_hashtag==="Always"?`#${r[0]}`:r[0]}function T(t,n){return n.find(e=>{let i=new RegExp(`^${e}-`),o=new RegExp(`-${e}-`),d=new RegExp(`${e}/`);return[t.match(i),t.match(o),t.match(d)].filter(f=>f!=null).length>0})??""}function A(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function z(t,n){return n.map(i=>i.value).filter(i=>i&&i!==_).sort((i,o)=>o.length-i.length).find(i=>new RegExp(`(?:^|[/_-])${A(i)}(?=$|[/_-])`).test(t))??""}function m(t){try{return h(`git ${t} branch --show-current`,{stdio:"pipe"}).toString().trim()}catch{return""}}import c from"picocolors";function D(t){return`${t} ${c.dim("\xB7 restored from cache")}`}function L(t){return`${t} ${c.dim("\xB7 inferred from branch")}`}function B(t){return`${t} ${c.dim("\xB7 optional")}`}function K(t){return`${t} ${c.dim("\xB7 <space> to select")}`}function Y(t){return`${t} ${c.dim("\xB7 <space> to select \xB7 <a> to select all")}`}function F(t){return`${t} ${c.dim("\xB7 dry run - changes will not be committed")}`}export{g as a,G as b,N as c,V as d,x as e,w as f,E as g,D as h,L as i,B as j,K as k,Y as l,F as m};
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import*as e from"valibot";import*as s from"valibot";var c="custom",d=["closes","trailer","breaking-change","deprecated","custom"],m=s.picklist(["branch","worktree"]),_=s.picklist(["closes","trailer","breaking-change","deprecated","custom"]),C=s.picklist(["user","version","type","scope","ticket","description"]),K=s.picklist(["branch_user","branch_version","branch_type","branch_scope","branch_ticket","branch_description"]),y=["user","version","type","ticket","scope","description"],k=[{value:"app",label:"app"},{value:"shared",label:"shared"},{value:"server",label:"server"},{value:"tools",label:"tools"},{value:"",label:"none"}],O=[{value:"feat",label:"feat",hint:"A new feature",emoji:"\u{1F31F}",trailer:"Changelog: feature"},{value:"fix",label:"fix",hint:"A bug fix",emoji:"\u{1F41B}",trailer:"Changelog: fix"},{value:"docs",label:"docs",hint:"Documentation only changes",emoji:"\u{1F4DA}",trailer:"Changelog: documentation"},{value:"refactor",label:"refactor",hint:"A code change that neither fixes a bug nor adds a feature",emoji:"\u{1F528}",trailer:"Changelog: refactor"},{value:"perf",label:"perf",hint:"A code change that improves performance",emoji:"\u{1F680}",trailer:"Changelog: performance"},{value:"test",label:"test",hint:"Adding missing tests or correcting existing tests",emoji:"\u{1F6A8}",trailer:"Changelog: test"},{value:"build",label:"build",hint:"Changes that affect the build system or external dependencies",emoji:"\u{1F6A7}",trailer:"Changelog: build"},{value:"ci",label:"ci",hint:"Changes to our CI configuration files and scripts",emoji:"\u{1F916}",trailer:"Changelog: ci"},{value:"chore",label:"chore",hint:"Other changes that do not modify src or test files",emoji:"\u{1F9F9}",trailer:"Changelog: chore"},{value:"",label:"none"}];var N=e.pipe(e.optional(e.object({enable:e.optional(e.boolean(),!0),initial_value:e.optional(e.string(),"feat"),max_items:e.optional(e.pipe(e.number(),e.minValue(1)),20),infer_type_from_branch:e.optional(e.boolean(),!0),append_emoji_to_label:e.optional(e.boolean(),!1),append_emoji_to_commit:e.optional(e.boolean(),!1),emoji_commit_position:e.optional(e.picklist(["Start","After-Colon"]),"Start"),autocomplete:e.optional(e.boolean(),!0),options:e.optional(e.array(e.object({value:e.string(),label:e.optional(e.string()),hint:e.optional(e.string()),emoji:e.optional(e.pipe(e.string(),e.emoji())),trailer:e.optional(e.string())})),O)}),{}),e.rawCheck(({dataset:o,addIssue:t})=>{o.typed&&!o.value.options.some(r=>r.value===o.value.initial_value)&&t({message:`Type: initial_value "${o.value.initial_value}" must exist in options`})}),e.transform(o=>({...o,options:o.options.map(t=>({...t,label:t.emoji&&o.append_emoji_to_label?`${t.emoji} ${t.label}`:t.label}))}))),R=e.pipe(e.optional(e.object({enable:e.optional(e.boolean(),!0),custom_scope:e.optional(e.boolean(),!1),max_items:e.optional(e.pipe(e.number(),e.minValue(1)),20),initial_value:e.optional(e.string(),"app"),infer_scope_from_branch:e.optional(e.boolean(),!0),autocomplete:e.optional(e.boolean(),!0),options:e.optional(e.array(e.object({value:e.string(),label:e.optional(e.string()),hint:e.optional(e.string())})),k)}),{}),e.rawCheck(({dataset:o,addIssue:t})=>{if(!o.typed)return;let r=o.value.options.map(n=>n.value);o.value.custom_scope&&r.push(c),r.includes(o.value.initial_value)||t({message:`Scope: initial_value "${o.value.initial_value}" must exist in options`})}),e.transform(o=>{let t=o.options.map(r=>r.value);return o.custom_scope&&!t.includes(c)?{...o,options:[...o.options,{label:c,value:c,hint:"Write a custom scope"}]}:o})),f=e.object({check_status:e.optional(e.boolean(),!0),check_status_autocomplete:e.optional(e.boolean(),!0),commit_type:N,commit_scope:R,check_ticket:e.optional(e.object({infer_ticket:e.optional(e.boolean(),!0),confirm_ticket:e.optional(e.boolean(),!0),add_to_title:e.optional(e.boolean(),!0),append_hashtag:e.optional(e.boolean(),!1),prepend_hashtag:e.optional(e.picklist(["Never","Always","Prompt"]),"Never"),surround:e.optional(e.picklist(["","()","[]","{}"]),""),title_position:e.optional(e.picklist(["start","end","before-colon","beginning"]),"start")}),{}),commit_title:e.optional(e.object({max_size:e.optional(e.pipe(e.number(),e.minValue(1)),70)}),{}),commit_body:e.optional(e.object({enable:e.optional(e.boolean(),!0),required:e.optional(e.boolean(),!1),split_by_period:e.optional(e.boolean(),!1)}),{}),commit_footer:e.optional(e.object({enable:e.optional(e.boolean(),!0),initial_value:e.optional(e.array(_),[]),options:e.optional(e.array(_),d)}),{}),breaking_change:e.optional(e.object({add_exclamation_to_title:e.optional(e.boolean(),!0)}),{}),cache_last_value:e.optional(e.boolean(),!0),confirm_with_editor:e.optional(e.boolean(),!1),confirm_commit:e.optional(e.boolean(),!0),print_commit_output:e.optional(e.boolean(),!0),branch_pre_commands:e.optional(e.array(e.string()),[]),branch_post_commands:e.optional(e.array(e.string()),[]),worktree_pre_commands:e.optional(e.array(e.string()),[]),worktree_post_commands:e.optional(e.array(e.string()),[]),branch_user:e.optional(e.object({enable:e.optional(e.boolean(),!0),required:e.optional(e.boolean(),!1),separator:e.optional(e.picklist(["/","-","_"]),"/")}),{}),branch_type:e.optional(e.object({enable:e.optional(e.boolean(),!0),separator:e.optional(e.picklist(["/","-","_"]),"/"),autocomplete:e.optional(e.boolean(),!0)}),{}),branch_scope:e.optional(e.object({enable:e.optional(e.boolean(),!0),separator:e.optional(e.picklist(["/","-","_"]),"-"),autocomplete:e.optional(e.boolean(),!0)}),{}),branch_version:e.optional(e.object({enable:e.optional(e.boolean(),!1),required:e.optional(e.boolean(),!1),separator:e.optional(e.picklist(["/","-","_"]),"/")}),{}),branch_ticket:e.optional(e.object({enable:e.optional(e.boolean(),!0),required:e.optional(e.boolean(),!1),separator:e.optional(e.picklist(["/","-","_"]),"-")}),{}),branch_description:e.optional(e.object({max_length:e.optional(e.pipe(e.number(),e.minValue(1)),70),separator:e.optional(e.picklist(["","/","-","_"]),"")}),{}),branch_action_default:e.optional(m,"branch"),branch_order:e.optional(e.array(C),y),enable_worktrees:e.optional(e.boolean(),!0),worktrees:e.optional(e.object({enable:e.optional(e.boolean(),!0),base_path:e.optional(e.string(),".."),folder_template:e.optional(e.string(),"{{repo_name}}-{{ticket}}-{{branch_description}}")}),{}),overrides:e.optional(e.object({shell:e.optional(e.string())}),{})}),P={type:e.optional(e.string(),""),scope:e.optional(e.string(),""),title:e.optional(e.string(),""),body:e.optional(e.string(),""),closes:e.optional(e.string(),""),ticket:e.optional(e.string(),""),breaking_title:e.optional(e.string(),""),breaking_body:e.optional(e.string(),""),deprecates:e.optional(e.string(),""),deprecates_title:e.optional(e.string(),""),deprecates_body:e.optional(e.string(),""),custom_footer:e.optional(e.string(),""),trailer:e.optional(e.string(),"")},X=e.optional(e.object(P),{}),F={user:e.optional(e.string(),""),type:e.optional(e.string(),""),scope:e.optional(e.string(),""),ticket:e.optional(e.string(),""),description:e.optional(e.string(),""),version:e.optional(e.string(),""),checkout:e.optional(m,"branch")},Z=e.optional(e.object(F),{});import{parse as L}from"@bomb.sh/args";var S=["type","scope","title","body","ticket","closes","trailer","breaking-title","breaking-body","deprecates-title","deprecates-body","custom-footer"],D=["git-dir","work-tree"],$=["interactive","dry-run","help","version"],g=class{#e;constructor(t){this.#e=t}get git_args(){return this.#e.git_args}get interactive(){return!this.#e.no_interactive}get dry_run(){return this.#e.dry_run}get help(){return this.#e.help}get version(){return this.#e.version}get commit_state(){return this.#e.commit_state}},b=new g(M(process.argv.slice(2)));function M(o){let t=L(o,{alias:{h:"help",v:"version"},boolean:$,string:[...S,...D]}),r={};return S.forEach(n=>{let a=t[n],l=V(n,a);if(l!==void 0){let u=n.replace("-","_");r[u]=l}}),{help:t.help===!0,version:t.version===!0,git_args:B(t["git-dir"],t["work-tree"]),no_interactive:t.interactive===!1,dry_run:t["dry-run"]===!0,commit_state:r}}function V(o,t){if(t===void 0)return;if(o!=="closes")return t;let r=t.trim().toLowerCase();if(r!=="false"&&(t===""||r))return"Closes:"}function B(o,t){return`${o?`--git-dir=${o}`:""} ${t?`--work-tree=${t}`:""}`.trim()}var x=`{
|
|
2
|
+
// Run interactive \`git status\` before composing a commit
|
|
3
|
+
"check_status": true,
|
|
4
|
+
"check_status_autocomplete": true,
|
|
5
|
+
|
|
6
|
+
/* COMMIT FIELDS */
|
|
7
|
+
"commit_type": {
|
|
8
|
+
"enable": true,
|
|
9
|
+
|
|
10
|
+
// Default selected type from options
|
|
11
|
+
"initial_value": "feat",
|
|
12
|
+
|
|
13
|
+
"max_items": 20,
|
|
14
|
+
|
|
15
|
+
// Infer type from the current branch name: user/TYPE/my-branch
|
|
16
|
+
"infer_type_from_branch": true,
|
|
17
|
+
|
|
18
|
+
// Include emoji in prompt label
|
|
19
|
+
"append_emoji_to_label": false,
|
|
20
|
+
|
|
21
|
+
// Include emoji from prompt label in commit message
|
|
22
|
+
"append_emoji_to_commit": false,
|
|
23
|
+
|
|
24
|
+
// "Start" | "After-Colon"
|
|
25
|
+
"emoji_commit_position": "Start",
|
|
26
|
+
|
|
27
|
+
"autocomplete": true,
|
|
28
|
+
|
|
29
|
+
"options": [
|
|
30
|
+
{
|
|
31
|
+
"value": "feat",
|
|
32
|
+
"label": "feat",
|
|
33
|
+
"hint": "A new feature",
|
|
34
|
+
"emoji": "\u{1F31F}",
|
|
35
|
+
"trailer": "Changelog: feature"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"value": "fix",
|
|
39
|
+
"label": "fix",
|
|
40
|
+
"hint": "A bug fix",
|
|
41
|
+
"emoji": "\u{1F41B}",
|
|
42
|
+
"trailer": "Changelog: fix"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"value": "docs",
|
|
46
|
+
"label": "docs",
|
|
47
|
+
"hint": "Documentation only changes",
|
|
48
|
+
"emoji": "\u{1F4DA}",
|
|
49
|
+
"trailer": "Changelog: documentation"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"value": "refactor",
|
|
53
|
+
"label": "refactor",
|
|
54
|
+
"hint": "A code change that neither fixes a bug nor adds a feature",
|
|
55
|
+
"emoji": "\u{1F528}",
|
|
56
|
+
"trailer": "Changelog: refactor"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"value": "perf",
|
|
60
|
+
"label": "perf",
|
|
61
|
+
"hint": "A code change that improves performance",
|
|
62
|
+
"emoji": "\u{1F680}",
|
|
63
|
+
"trailer": "Changelog: performance"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"value": "test",
|
|
67
|
+
"label": "test",
|
|
68
|
+
"hint": "Adding missing tests or correcting existing tests",
|
|
69
|
+
"emoji": "\u{1F6A8}",
|
|
70
|
+
"trailer": "Changelog: test"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"value": "build",
|
|
74
|
+
"label": "build",
|
|
75
|
+
"hint": "Changes that affect the build system or external dependencies",
|
|
76
|
+
"emoji": "\u{1F6A7}",
|
|
77
|
+
"trailer": "Changelog: build"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"value": "ci",
|
|
81
|
+
"label": "ci",
|
|
82
|
+
"hint": "Changes to our CI configuration files and scripts",
|
|
83
|
+
"emoji": "\u{1F916}",
|
|
84
|
+
"trailer": "Changelog: ci"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"value": "chore",
|
|
88
|
+
"label": "chore",
|
|
89
|
+
"hint": "Other changes that do not modify src or test files",
|
|
90
|
+
"emoji": "\u{1F9F9}",
|
|
91
|
+
"trailer": "Changelog: chore"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"value": "",
|
|
95
|
+
"label": "none"
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
"commit_scope": {
|
|
101
|
+
"enable": true,
|
|
102
|
+
|
|
103
|
+
// If true, users can type a scope not listed in options
|
|
104
|
+
"custom_scope": false,
|
|
105
|
+
|
|
106
|
+
// Default selected scope from options
|
|
107
|
+
"initial_value": "app",
|
|
108
|
+
|
|
109
|
+
// Infer scope from the current branch name: user/type/ticket-SCOPE-my-branch
|
|
110
|
+
"infer_scope_from_branch": true,
|
|
111
|
+
|
|
112
|
+
"max_items": 20,
|
|
113
|
+
"autocomplete": true,
|
|
114
|
+
"options": [
|
|
115
|
+
{ "value": "app", "label": "app" },
|
|
116
|
+
{ "value": "shared", "label": "shared" },
|
|
117
|
+
{ "value": "server", "label": "server" },
|
|
118
|
+
{ "value": "tools", "label": "tools" },
|
|
119
|
+
{ "value": "", "label": "none" }
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
"check_ticket": {
|
|
124
|
+
// Infer ticket / issue from the branch name - user/type/TICKET-my-branch
|
|
125
|
+
"infer_ticket": true,
|
|
126
|
+
|
|
127
|
+
// Prompt for confirmation / edit before using an inferred ticket
|
|
128
|
+
"confirm_ticket": true,
|
|
129
|
+
|
|
130
|
+
// Add the ticket to the commit title - feat(app): TICKET my commit title
|
|
131
|
+
"add_to_title": true,
|
|
132
|
+
|
|
133
|
+
// Deprecated, prefer \`prepend_hashtag\`
|
|
134
|
+
"append_hashtag": false,
|
|
135
|
+
|
|
136
|
+
// "Never" | "Prompt" | "Always" - 12345 --> #12345
|
|
137
|
+
"prepend_hashtag": "Never",
|
|
138
|
+
|
|
139
|
+
// Wrap the ticket in the commit title: "" | "[]" | "()" | "{}"
|
|
140
|
+
"surround": "",
|
|
141
|
+
|
|
142
|
+
// "start" | "end" | "before-colon" | "beginning"
|
|
143
|
+
"title_position": "start"
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
"commit_title": {
|
|
147
|
+
// Includes total size of title + type + scope + ticket
|
|
148
|
+
"max_size": 70
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
"commit_body": {
|
|
152
|
+
"enable": true,
|
|
153
|
+
"required": false,
|
|
154
|
+
|
|
155
|
+
// Split sentences into multiple lines automatically
|
|
156
|
+
"split_by_period": false
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
"commit_footer": {
|
|
160
|
+
"enable": true,
|
|
161
|
+
"initial_value": [],
|
|
162
|
+
|
|
163
|
+
// "closes", "trailer", "breaking-change", "deprecated", "custom"
|
|
164
|
+
"options": ["closes", "trailer", "breaking-change", "deprecated", "custom"]
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
"breaking_change": {
|
|
168
|
+
// Adds \`!\` to the commit title when a breaking change is selected
|
|
169
|
+
"add_exclamation_to_title": true
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
// Confirm / edit with $GIT_EDITOR or $EDITOR
|
|
173
|
+
"confirm_with_editor": false,
|
|
174
|
+
|
|
175
|
+
// Show a final confirmation prompt before running git commit
|
|
176
|
+
"confirm_commit": true,
|
|
177
|
+
|
|
178
|
+
// Reuse the last known value from a previous canceled or failed commit
|
|
179
|
+
"cache_last_value": true,
|
|
180
|
+
|
|
181
|
+
// Pretty-print the final commit preview before execution
|
|
182
|
+
"print_commit_output": true,
|
|
183
|
+
|
|
184
|
+
/* BRANCH FIELDS */
|
|
185
|
+
// Optional shell commands to run before / after creating branches or worktrees
|
|
186
|
+
"branch_pre_commands": [],
|
|
187
|
+
"branch_post_commands": [],
|
|
188
|
+
"worktree_pre_commands": [],
|
|
189
|
+
"worktree_post_commands": [],
|
|
190
|
+
|
|
191
|
+
"branch_user": {
|
|
192
|
+
"enable": true,
|
|
193
|
+
"required": false,
|
|
194
|
+
|
|
195
|
+
// "/" | "-" | "_" - user/feat/my-branch
|
|
196
|
+
"separator": "/"
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
"branch_type": {
|
|
200
|
+
"enable": true,
|
|
201
|
+
"separator": "/",
|
|
202
|
+
"autocomplete": true,
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
"branch_scope": {
|
|
206
|
+
"enable": true,
|
|
207
|
+
"separator": "-",
|
|
208
|
+
"autocomplete": true,
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
"branch_ticket": {
|
|
212
|
+
"enable": true,
|
|
213
|
+
"required": false,
|
|
214
|
+
"separator": "-"
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
"branch_version": {
|
|
218
|
+
"enable": false,
|
|
219
|
+
"required": false,
|
|
220
|
+
"separator": "/"
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
"branch_description": {
|
|
224
|
+
// Maximum length for the description segment of the branch name
|
|
225
|
+
"max_length": 70,
|
|
226
|
+
|
|
227
|
+
// Allowed values: "" | "/" | "-" | "_"
|
|
228
|
+
"separator": ""
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
// "branch" | "worktree"
|
|
232
|
+
"branch_action_default": "branch",
|
|
233
|
+
|
|
234
|
+
// Order of values in the final branch name
|
|
235
|
+
"branch_order": ["user", "version", "type", "ticket", "scope", "description"],
|
|
236
|
+
|
|
237
|
+
// Deprecated, prefer \`worktrees.enable\`
|
|
238
|
+
"enable_worktrees": true,
|
|
239
|
+
|
|
240
|
+
"worktrees": {
|
|
241
|
+
// If false, always create a branch instead of prompting for a worktree
|
|
242
|
+
"enable": true,
|
|
243
|
+
|
|
244
|
+
// Directory where worktrees are created
|
|
245
|
+
"base_path": "..",
|
|
246
|
+
|
|
247
|
+
// Available template variables include:
|
|
248
|
+
// {{repo_name}}, {{branch_description}}, {{user}}, {{type}}, {{scope}}, {{ticket}}, {{version}}
|
|
249
|
+
"folder_template": "{{repo_name}}-{{ticket}}-{{branch_description}}"
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
/* OTHER FIELDS */
|
|
253
|
+
"overrides": {
|
|
254
|
+
// Useful on Windows or for shells with different multiline behavior
|
|
255
|
+
"shell": "/bin/sh"
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
`;import*as i from"@clack/prompts";import{execSync as H}from"child_process";import p from"fs";import{homedir as I}from"os";import{parse as U}from"jsonc-parser";import h from"picocolors";import{ValiError as G,parse as A}from"valibot";var E=[".better-commits.jsonc",".better-commits.json"],j=E[0],_e=[{value:"closes",label:"closes <issue/ticket>",hint:"Attempts to infer ticket from branch"},{value:"trailer",label:"trailer",hint:"Appends trailer based on commit type"},{value:"breaking-change",label:"breaking change",hint:"Add breaking change"},{value:"deprecated",label:"deprecated",hint:"Add deprecated change"},{value:"custom",label:"custom",hint:"Add a custom footer"}],fe=[{value:"branch",label:"Branch"},{value:"worktree",label:"Worktree"}],ge={get:()=>"",set:(o,t)=>{},clear:()=>{}};function be(o=" better-commits ",t=b.git_args){console.clear(),i.intro(`${h.bgCyan(h.black(o))}`);let r=null,n=W();p.existsSync(n)&&(r=T(n));let a=z(t),l=Y(a);if(l){i.log.step("Reading from Repository Config");let v=T(l);return{config:r?{...v,overrides:r.overrides.shell?r.overrides:v.overrides,confirm_with_editor:r.confirm_with_editor,cache_last_value:r.cache_last_value}:v,config_source:"repository"}}if(r)return i.log.step("Reading from Global Config"),{config:r,config_source:"global"};let u=A(f,{});return i.log.step(`Config not found. Generating default ${j} at $HOME`),p.writeFileSync(n,x),{config:u,config_source:"none"}}function T(o){let t=null;try{t=U(p.readFileSync(o,"utf8"))}catch(r){i.log.error(`Invalid JSON/JSONC config file at ${o}. Exiting.
|
|
259
|
+
`+r),process.exit(0)}return q(t)}function q(o){try{return A(f,o)}catch(t){if(t instanceof G){let n=(t.issues[0].path??[]).map(a=>a.key).filter(a=>typeof a=="string"||typeof a=="number").join(".");i.log.error(`Invalid Configuration: ${h.red(n)}
|
|
260
|
+
`+t.message)}process.exit(0)}}function z(o=b.git_args){let t=".";try{t=H(`git ${o} rev-parse --show-toplevel`).toString().trim()}catch{i.log.warn("Could not find git root. If in a --bare repository, ignore this warning.")}return t}function W(){return w(I())??I()+"/"+j}function Y(o){return w(o)}function w(o){for(let t of E){let r=`${o}/${t}`;if(p.existsSync(r))return r}return null}function he(){try{return JSON.parse(p.readFileSync(new URL("../package.json",import.meta.url),"utf8")).version??"unknown"}catch{return"unknown"}}function de(o,t){return t===o.length-1?"":`
|
|
261
|
+
`}function Ce(o){let t=o.trim();return t.endsWith(".")?t.substring(0,t.length-1).trim():o.trim()}function ye(o,t){try{return o.get(t)??""}catch{i.log.warn(`Could not access ${t} from cache. Check that "~/.config" exists. Set "cache_last_value" to false to disable.`)}return""}function ke(o,t,r){try{o.set(t,r)}catch{i.log.warn(`Could not access ${t} from cache. Check that "~/.config" exists. Set "cache_last_value" to false to disable.`)}}export{c as a,P as b,X as c,F as d,Z as e,b as f,x as g,j as h,_e as i,fe as j,ge as k,be as l,z as m,Y as n,he as o,de as p,Ce as q,ye as r,ke as s};
|
package/dist/index.js
CHANGED
|
@@ -1,57 +1,61 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
import{a as
|
|
3
|
-
`):t}#
|
|
2
|
+
import{a as dt,b as ft,d as ht,e as T,f as N,g as j,h as f,i as I,j as w,k as Z,l as bt,m as z}from"./chunk-43H72S6V.js";import{a as at,c as ct,f as n,i as mt,k as lt,l as pt,m as _t,o as R,p as ut,q as gt,r as g,s as d}from"./chunk-B7AGSPP3.js";import{chdir as qt}from"process";import*as J from"@clack/prompts";import{ValiError as Kt,parse as wt}from"valibot";import Ht from"configstore";import*as V from"@clack/prompts";var p=class{constructor(t,e,o){this.config=t;this.commit_state=e;this.prompt_cache=o}};var D=class extends p{async run(){if(this.#i){let{initial_value:t,message:e}=this.#e,s=await(this.config.commit_type.autocomplete?V.autocomplete:V.select)({message:e,initialValue:t,maxItems:this.#s,options:this.#t});V.isCancel(s)&&process.exit(0),this.#r(s)}}get#i(){return this.config.commit_type.enable}get#e(){let t=g(this.prompt_cache,"commit_type");if(t)return{initial_value:t,message:f("Commit type")};if(this.config.commit_type.infer_type_from_branch){let e=T(this.#t,n.git_args);if(e)return{message:I("Commit type"),initial_value:e}}return{initial_value:this.config.commit_type.initial_value,message:"Select a commit type"}}get#t(){return this.config.commit_type.options}get#o(){return this.#t.reduce((t,e)=>({...t,[e.value]:{emoji:e.emoji??"",trailer:e.trailer??""}}),{})}get#s(){return this.config.commit_type.max_items}#r(t){d(this.prompt_cache,"commit_type",t);let e=this.#o;this.commit_state.trailer=e[t].trailer,this.commit_state.type=this.config.commit_type.append_emoji_to_commit&&this.config.commit_type.emoji_commit_position==="Start"?`${e[t].emoji} ${t}`.trim():t}};import*as k from"@clack/prompts";var L=class extends p{async run(){if(!this.#i)return;let{initial_value:t,message:e}=this.#e(),s=await(this.config.commit_scope.autocomplete?k.autocomplete:k.select)({message:e,initialValue:t,maxItems:this.#t,options:this.#o});k.isCancel(s)&&process.exit(0),await this.#r(s)}get#i(){return this.config.commit_scope.enable}#e(){let t=g(this.prompt_cache,"commit_scope");if(t)return{initial_value:t,message:f("Commit scope")};if(this.config.commit_scope.infer_scope_from_branch){let e=j(this.#o,n.git_args);if(e)return{initial_value:e,message:I("Commit scope")}}return{initial_value:this.config.commit_scope.initial_value,message:"Select a commit scope"}}get#t(){return this.config.commit_scope.max_items}get#o(){return this.config.commit_scope.options}get#s(){return this.config.commit_scope.custom_scope}async#r(t){d(this.prompt_cache,"commit_scope",t);let e=t;if(e===at&&this.#s){let o=await k.text({message:"Write a custom scope",placeholder:""});k.isCancel(o)&&process.exit(0),e=o??""}this.commit_state.scope=e}};import*as M from"@clack/prompts";var G=class extends p{async run(){let{initial_value:t,message:e}=this.#o();if(this.commit_state.ticket=t,this.#e){let o=await M.text({message:e,placeholder:"",initialValue:t});M.isCancel(o)&&process.exit(0),d(this.prompt_cache,"commit_ticket",o),this.commit_state.ticket=o??""}this.#t&&this.commit_state.ticket&&!this.commit_state.ticket.startsWith("#")&&(this.commit_state.ticket="#"+this.commit_state.ticket)}get#i(){return this.config.check_ticket.infer_ticket}get#e(){return this.config.check_ticket.confirm_ticket}get#t(){return this.config.check_ticket.prepend_hashtag==="Always"}#o(){let t=g(this.prompt_cache,"commit_ticket");if(t)return{initial_value:t,message:f("Ticket / issue")};if(this.#i){let e=N({append_hashtag:this.config.check_ticket.append_hashtag,prepend_hashtag:this.config.check_ticket.prepend_hashtag},n.git_args);if(e)return{initial_value:e,message:I("Ticket / issue")}}return{initial_value:this.commit_state.ticket,message:w("Add ticket / issue")}}};import*as W from"@clack/prompts";var B=class extends p{async run(){let{initial_value:t,message:e}=this.#i(),o=await W.text({message:e,initialValue:t,placeholder:"",validate:s=>this.#e(s)});W.isCancel(o)&&process.exit(0),this.#n(o??"")}#i(){let t=g(this.prompt_cache,"commit_title");return t?{initial_value:t,message:f("Commit title")}:{initial_value:this.commit_state.title,message:"Write a brief title describing the commit"}}#e(t){if(!t)return"Please enter a title";if(this.#o(t)>this.#t)return`Exceeded max length. Title max [${this.#t}]`}get#t(){return this.config.commit_title.max_size}#o(t){return dt({type:this.commit_state.type,scope:this.commit_state.scope,ticket:this.commit_state.ticket,title:t},{include_ticket:this.config.check_ticket.add_to_title})}get#s(){return this.config.commit_type.options.reduce((t,e)=>({...t,[e.value]:{emoji:e.emoji??""}}),{})}#r(t){return this.config.commit_type.append_emoji_to_commit&&this.config.commit_type.emoji_commit_position==="After-Colon"?`${this.#s[this.commit_state.type]?.emoji??""} ${t}`.trim():t}#n(t){d(this.prompt_cache,"commit_title",t),this.commit_state.title=gt(this.#r(t))}};import*as K from"@clack/prompts";var q=class extends p{async run(){if(!this.#i)return;let{initial_value:t,message:e}=this.#e(),o=await K.text({message:e,initialValue:t,placeholder:"",validate:s=>this.#t(s)});K.isCancel(o)&&process.exit(0),this.#s(o??"")}get#i(){return this.config.commit_body.enable}#e(){let t=g(this.prompt_cache,"commit_body");return t?{initial_value:t,message:f("Commit body")}:{initial_value:"",message:w("Write a detailed description of the changes")}}#t(t){if(this.config.commit_body.required&&!t)return"Please enter a description"}#o(t){return this.config.commit_body.split_by_period?t.split(/\.\s+/).map(o=>o.trim()).join(`.
|
|
3
|
+
`):t}#s(t){d(this.prompt_cache,"commit_body",t),this.commit_state.body=this.#o(t)}};import*as $ from"@clack/prompts";var H=class extends p{async run(){if(!this.#i)return;let{initial_values:t,message:e}=this.#o(),o=await $.multiselect({message:e,initialValues:t,options:this.#e,required:!1});$.isCancel(o)&&process.exit(0);let s=this.#r(o),r=await this.#n(s);this.#m(o,s,r)}get#i(){return this.config.commit_footer.enable}get#e(){let t=new Set(this.config.commit_footer.options);return mt.filter(e=>t.has(e.value))}get#t(){return this.#e.map(t=>t.value)}#o(){let t=g(this.prompt_cache,"commit_footer");return t?{initial_values:this.#s(t),message:Z(f("Commit footers"))}:{initial_values:this.config.commit_footer.initial_value.filter(o=>this.#t.includes(o)),message:Z(w("Select optional footers"))}}#s(t){return t.split(",").map(e=>e.trim()).filter(e=>this.#t.includes(e))}#r(t){return{includes_breaking_change:t.includes("breaking-change"),includes_deprecated:t.includes("deprecated"),includes_closes:t.includes("closes"),includes_custom:t.includes("custom"),includes_trailer:t.includes("trailer")}}async#n(t){let e={breaking_title:"",breaking_body:"",deprecated_title:"",deprecated_body:"",custom_footer:""};return t.includes_breaking_change&&(e.breaking_title=await this.#c("Breaking changes: Write a short title / summary"),e.breaking_body=await this.#a(w("Breaking Changes: Write a description & migration instructions"))),t.includes_deprecated&&(e.deprecated_title=await this.#c("Deprecated: Write a short title / summary"),e.deprecated_body=await this.#a(w("Deprecated: Write a description"))),t.includes_custom&&(e.custom_footer=await this.#a("Write a custom footer")),e}async#c(t){let e=await $.text({message:t,placeholder:"",validate:o=>{if(!o)return"Please enter a title / summary"}});return $.isCancel(e)&&process.exit(0),e??""}async#a(t){let e=await $.text({message:t,placeholder:""});return $.isCancel(e)&&process.exit(0),e??""}#m(t,e,o){d(this.prompt_cache,"commit_footer",t.join(",")),this.commit_state.breaking_title=o.breaking_title,this.commit_state.breaking_body=o.breaking_body,this.commit_state.deprecates_title=o.deprecated_title,this.commit_state.deprecates_body=o.deprecated_body,this.commit_state.custom_footer=o.custom_footer,this.commit_state.closes=e.includes_closes?"Closes:":"",e.includes_trailer||(this.commit_state.trailer="")}};import*as b from"@clack/prompts";import{execSync as yt}from"child_process";import u from"picocolors";function tt({commit_state:i,config:t,colorize:e=!1,escape_quotes:o=!1,include_trailer:s=!1}){let r="";if(i.type&&(r+=e?u.blue(i.type):i.type),i.scope){let m=e?u.cyan(i.scope):i.scope;r+=`(${m})`}let a=i.ticket,l=t.check_ticket.surround;if(i.ticket&&l){let m=l.charAt(0),h=l.charAt(1);a=`${m}${i.ticket}${h}`}let x=t.check_ticket.title_position==="beginning";a&&t.check_ticket.add_to_title&&x&&(r=`${e?u.magenta(a):a} ${r}`);let S=t.check_ticket.title_position==="before-colon";if(a&&t.check_ticket.add_to_title&&S){let m=i.scope||i.type&&!t.check_ticket.surround?" ":"";r+=e?u.magenta(m+a):m+a}i.breaking_title&&t.breaking_change.add_exclamation_to_title&&(r+=e?u.red("!"):"!"),(i.scope||i.type||a&&S)&&(r+=": ");let y=t.check_ticket.title_position==="start",A=t.check_ticket.title_position==="end";if(a&&t.check_ticket.add_to_title&&y&&(r+=e?u.magenta(a)+" ":a+" "),i.title&&(r+=e?u.reset(i.title):i.title),a&&t.check_ticket.add_to_title&&A&&(r+=" "+(e?u.magenta(a):a)),i.body){let h=i.body.split("\\n").map(O=>e?u.reset(O.trim()):O.trim()).join(`
|
|
4
4
|
`);r+=`
|
|
5
5
|
|
|
6
|
-
${
|
|
6
|
+
${h}`}if(i.breaking_title){let m=e?u.red(`BREAKING CHANGE: ${i.breaking_title}`):`BREAKING CHANGE: ${i.breaking_title}`;r+=`
|
|
7
7
|
|
|
8
|
-
${
|
|
8
|
+
${m}`}if(i.breaking_body){let m=e?u.red(i.breaking_body):i.breaking_body;r+=`
|
|
9
9
|
|
|
10
|
-
${
|
|
10
|
+
${m}`}if(i.deprecates_title){let m=e?u.yellow(`DEPRECATED: ${i.deprecates_title}`):`DEPRECATED: ${i.deprecates_title}`;r+=`
|
|
11
11
|
|
|
12
|
-
${
|
|
12
|
+
${m}`}if(i.deprecates_body){let m=e?u.yellow(i.deprecates_body):i.deprecates_body;r+=`
|
|
13
13
|
|
|
14
|
-
${
|
|
14
|
+
${m}`}if(i.custom_footer){let h=i.custom_footer.split("\\n").map(O=>e?u.reset(O.trim()):O.trim()).join(`
|
|
15
15
|
`);r+=`
|
|
16
16
|
|
|
17
|
-
${
|
|
17
|
+
${h}`}return i.closes&&i.ticket&&(r+=e?`
|
|
18
18
|
|
|
19
|
-
${
|
|
19
|
+
${u.reset(i.closes)} ${u.magenta(i.ticket)}`:`
|
|
20
20
|
|
|
21
|
-
${i.closes} ${i.ticket}`),
|
|
21
|
+
${i.closes} ${i.ticket}`),s&&i.trailer&&(r+=e?`
|
|
22
22
|
|
|
23
|
-
${
|
|
23
|
+
${u.dim(i.trailer)}`:`
|
|
24
24
|
|
|
25
|
-
${i.trailer}`),o&&(r=r.replaceAll('"','\\"').replaceAll("`","\\`")),r}var
|
|
26
|
-
`),e=[],o=[];return t.forEach(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
`)}
|
|
25
|
+
${i.trailer}`),o&&(r=r.replaceAll('"','\\"').replaceAll("`","\\`")),r}var F=class extends p{async run(){this.#i&&(yt(`${this.#n} --edit`,this.#o),process.exit(0)),this.#e&&b.note(tt({commit_state:this.commit_state,config:this.config,colorize:!0,escape_quotes:!1,include_trailer:!0}),"Commit Preview"),await this.#a()||(b.log.info("Exiting without commit"),process.exit(0));try{b.log.info(n.dry_run?z("Committing changes..."):"Committing changes..."),yt(this.#n,n.dry_run?this.#s:this.#o)}catch(e){b.log.error("Something went wrong when committing: "+e);return}this.#m()}get#i(){return n.interactive&&this.config.confirm_with_editor}get#e(){return this.config.print_commit_output}get#t(){return this.config.confirm_commit}get#o(){return this.config.overrides.shell?{shell:this.config.overrides.shell,stdio:"inherit"}:{stdio:"inherit"}}get#s(){return this.config.overrides.shell?{shell:this.config.overrides.shell,stdio:"pipe"}:{stdio:"pipe"}}get#r(){return this.commit_state.trailer?`--trailer="${this.commit_state.trailer}"`:""}get#n(){return`git ${n.git_args} commit -m "${tt({commit_state:this.commit_state,config:this.config,colorize:!1,escape_quotes:!0,include_trailer:!1})}" ${this.#r} ${this.#c}`.trim()}get#c(){return n.dry_run?"--dry-run --porcelain --untracked-files=no":""}async#a(){if(!n.interactive||!this.#t)return!0;let t=await b.confirm({message:n.dry_run?z("Confirm Commit?"):"Confirm Commit?"});return b.isCancel(t)&&process.exit(0),t}#m(){b.log.success("Commit Complete");let t=this.prompt_cache.get("username");this.prompt_cache.clear(),t&&this.prompt_cache.set("username",t)}};import*as C from"@clack/prompts";import E from"picocolors";import{execSync as kt}from"child_process";import*as U from"@clack/prompts";import et from"picocolors";var vt=["M","T","R","D","A","C"];function it(){let i="";try{i=kt(`git ${n.git_args} status --porcelain`,{stdio:"pipe"}).toString()}catch(s){return U.log.error(et.red("Failed to git status"+s)),{index:[],work_tree:[]}}let t=i.split(`
|
|
26
|
+
`),e=[],o=[];return t.forEach(s=>{let r=s.trimEnd();if(!r)return;let a=r.substring(2).trim(),l=r.charAt(0).trim(),x=r.charAt(1).trim();(l==="?"||x==="?")&&e.push(a),vt.includes(l)&&o.push(a),vt.includes(x)&&e.push(a)}),{index:o,work_tree:e}}function $t(i){let t=i.join(" ");if(t)try{kt(`git ${n.git_args} add ${t}`,{stdio:"pipe"}).toString(),U.log.success(et.green("Changes successfully staged"))}catch{U.log.error(et.red("Failed to stage changes"))}}import{styleText as c}from"node:util";import{AutocompletePrompt as Ft}from"@clack/core";import{S_BAR as P,S_BAR_END as Pt,S_CHECKBOX_INACTIVE as Ct,S_CHECKBOX_SELECTED as Et,limitOptions as Rt,settings as Tt,symbol as Nt}from"@clack/prompts";function jt(i,t){if(!i)return!0;let e=(t.label??String(t.value??"")).toLowerCase(),o=(t.hint??"").toLowerCase(),s=String(t.value).toLowerCase(),r=i.toLowerCase();return e.includes(r)||o.includes(r)||s.includes(r)}function Dt(i,t){return i===""||t.ctrl===!0&&t.name==="a"}var ot=class extends Ft{constructor(e){super({options:e.options,multiple:!0,filter:e.filter??((o,s)=>jt(o,s)),validate:o=>e.required&&(!Array.isArray(o)||o.length===0)?"Please select at least one item":e.validate?.(o),initialValue:e.initialValues,signal:e.signal,input:e.input,output:e.output,render(){let o=e.withGuide??Tt.withGuide,s=`${o?`${c("gray",P)}
|
|
27
|
+
`:""}${Nt(this.state)} ${e.message}
|
|
28
|
+
`,r=this.userInput,a=this.userInputWithCursor,l=this.options,x=this.filteredOptions.length!==l.length?c("dim",` (${this.filteredOptions.length} match${this.filteredOptions.length===1?"":"es"})`):"";switch(this.state){case"submit":return`${s}${o?`${c("gray",P)} `:""}${c("dim",`${this.selectedValues.length} items selected`)}`;case"cancel":return`${s}${o?`${c("gray",P)} `:""}${c(["strikethrough","dim"],r)}`;default:{let S=this.state==="error"?"yellow":"cyan",y=o?`${c(S,P)} `:"",A=o?c(S,Pt):"",m=[`${c("dim","\u2191/\u2193")} to navigate`,`${c("dim","Space/Tab:")} select`,`${c("dim","Ctrl+a:")} select visible`,`${c("dim","Enter:")} confirm`,`${c("dim","Type:")} to search`],h=this.filteredOptions.length===0&&r?[`${y}${c("yellow","No matches found")}`]:[],O=this.state==="error"?[`${y}${c("yellow",this.error)}`]:[],st=[...`${s}${o?c(S,P):""}`.split(`
|
|
29
|
+
`),`${y}${c("dim","Search:")} ${a}${x}`,...h,...O],rt=[`${y}${m.join(" \u2022 ")}`,A],Ot=Rt({cursor:this.cursor,options:this.filteredOptions,style:(v,It)=>{let Vt=this.selectedValues.includes(v.value),Q=v.label??String(v.value??""),At=v.hint&&this.focusedValue!==void 0&&v.value===this.focusedValue?c("dim",` (${v.hint})`):"",nt=Vt?c("green",Et):c("dim",Ct);return v.disabled?`${c("gray",Ct)} ${c(["strikethrough","gray"],Q)}`:It?`${nt} ${Q}${At}`:`${nt} ${c("dim",Q)}`},maxItems:e.maxItems,output:e.output,rowPadding:st.length+rt.length});return[...st,...Ot.map(v=>`${y}${v}`),...rt].join(`
|
|
30
|
+
`)}}}});this.promptOptions=e;this.on("key",(o,s)=>{if(s.name==="space"&&!this.isNavigating&&this.focusedValue!==void 0){this.toggleSelected(this.focusedValue),this.#e();return}Dt(o,s)&&(this.#i(),this.isNavigating=!0,this.#e())})}_isActionKey(e,o){return super._isActionKey(e,o)||this.multiple&&o.name==="space"&&e!==void 0&&e!==""}#i(){let e=this.filteredOptions.filter(s=>!s.disabled).map(s=>s.value);if(!e.length)return;let o=e.every(s=>this.selectedValues.includes(s));this.selectedValues=o?this.selectedValues.filter(s=>!e.includes(s)):[...this.selectedValues,...e.filter(s=>!this.selectedValues.includes(s))]}#e(){let e=this.rl;e?.write("",{ctrl:!0,name:"e"}),this._cursor=e?.cursor??this.userInput.length}};function xt(i){return new ot(i).prompt()}var X=class extends p{async run(){if(!this.#i)return;let t=it();if(this.#e(t),t.work_tree.length){let e=await this.#o(t.work_tree);e.length&&$t(e)}this.#s()}get#i(){return this.config.check_status}#e(t){C.log.step(E.black(E.bgGreen(" Checking Git Status ")));let e=this.#t(t.index,E.green);if(C.log.success(`Changes to be committed:
|
|
31
|
+
`+e),!t.work_tree.length)return;let o=this.#t(t.work_tree,E.red);C.log.error(`Changes not staged for commit:
|
|
32
|
+
`+o)}#t(t,e){return t.reduce((o,s,r)=>e(o+s+ut(t,r)),"")}async#o(t){let e=this.config.check_status_autocomplete?await xt({message:"Some files have not been staged, add them now?",options:t.map(o=>({value:o,label:o})),required:!1}):await C.multiselect({message:bt("Some files have not been staged, add them now?"),options:t.map(o=>({value:o,label:o})),required:!1});return C.isCancel(e)&&process.exit(0),e}#s(){it().index.length||(C.log.error(E.red('no changes added to commit (use "git add" and/or "git commit -a")')),process.exit(0))}};import{execSync as Lt}from"child_process";import _ from"picocolors";var Gt={"better-branch":"Create a branch or worktree from a guided prompt flow.","better-commits-init":"Create a .better-commits.jsonc config in this repository."},Mt={"--no-interactive":"Run without tui prompts.","--dry-run":"Print the commit command without creating a commit.","--help":"Show help information and exit."},Bt={"--type":"Set commit type (can be inferred from branch).","--scope":"Set commit scope (can be inferred from branch).","--title":"Set commit title/description.","--body":"Set commit body text.","--ticket":"Set ticket / issue (can be inferred from branch).","--closes":"Set closes footer (true/false).","--trailer":"Set trailer footer value.","--breaking-title":"Set breaking-change title footer.","--breaking-body":"Set breaking-change body footer.","--deprecates-title":"Set deprecates footer title text.","--deprecates-body":"Set deprecates footer body text.","--custom-footer":"Set a custom footer line."},Wt={"--git-dir":"Set the path to the .git directory.","--work-tree":"Set the path to the working tree root."};function Y(i){let o=" ";return Object.entries(i).map(([s,r])=>{let a=Math.max(2,26-s.length);return`${o}${s}${" ".repeat(a)}${r}`}).join(`
|
|
33
|
+
`)}function St(i,t){let e=R(),o="(none)";try{o=Lt(`git ${n.git_args} branch --show-current`,{stdio:"pipe"}).toString().trim()||"(none)"}catch{}let s=T(i.commit_type.options,n.git_args)||"Unknown",r=i.check_ticket.infer_ticket?N({append_hashtag:i.check_ticket.append_hashtag,prepend_hashtag:i.check_ticket.prepend_hashtag},n.git_args)||"Unknown":"Infer Disabled",a=i.commit_scope.infer_scope_from_branch?j(i.commit_scope.options,n.git_args)||"Unknown":"Infer Disabled",l=i.commit_type.options.map(h=>h.value).join(", ").trim(),x=i.commit_scope.options.map(h=>h.value).join(", ").trim(),S=Y(Mt),y=Y(Wt),A=Y(Bt),m=Y(Gt);console.log(`
|
|
30
34
|
${_.green("\uF489 better-commits")} ${_.gray("v"+e)}
|
|
31
35
|
|
|
32
36
|
${_.gray("BRANCH")}
|
|
33
37
|
${o}
|
|
34
|
-
${_.gray("Type")} ${_.blue(a)} ${_.gray("\xB7")} ${_.gray("Ticket")} ${_.magenta(r)}
|
|
38
|
+
${_.gray("Type")} ${_.blue(s)} ${_.gray("\xB7")} ${_.gray("Scope")} ${_.cyan(a)} ${_.gray("\xB7")} ${_.gray("Ticket")} ${_.magenta(r)}
|
|
35
39
|
|
|
36
40
|
${_.gray("CONFIGURATION")}
|
|
37
41
|
${t}
|
|
38
42
|
|
|
39
43
|
${_.gray("Types")}
|
|
40
|
-
${
|
|
44
|
+
${l}
|
|
41
45
|
|
|
42
46
|
${_.gray("Scopes")}
|
|
43
|
-
${
|
|
47
|
+
${x}
|
|
44
48
|
|
|
45
49
|
${_.gray("CLI FLAGS")}
|
|
46
|
-
${
|
|
50
|
+
${S}
|
|
47
51
|
|
|
48
52
|
${_.gray("Commit Flags")}
|
|
49
|
-
${
|
|
53
|
+
${A}
|
|
50
54
|
|
|
51
55
|
${_.gray("Git Flags (Advanced)")}
|
|
52
|
-
${
|
|
56
|
+
${y}
|
|
53
57
|
|
|
54
58
|
${_.gray("ADDITIONAL COMMANDS")}
|
|
55
|
-
${
|
|
59
|
+
${m}
|
|
56
60
|
|
|
57
|
-
`)}var
|
|
61
|
+
`)}var Ut=[X,D,L,G,B,q,H,F],{config:Xt,config_source:Yt}=pt();Jt(Xt,Yt);async function Jt(i,t){if(qt(_t()),n.version){let l=R();J.log.step("Better Commits v"+l);return}if(n.help){St(i,t);return}let e=ht(i),o={...n.commit_state,type:(n.commit_state.type||e?.type)??"",scope:(n.commit_state.scope||e?.scope)??"",ticket:(n.commit_state.ticket||e?.ticket)??""},s=wt(ct,o);if(!n.interactive)try{wt(ft(i),s)}catch(l){l instanceof Kt?J.log.error(`Invalid commit input: ${l.message}`):J.log.error(`Failed to validate commit input: ${l}`),process.exit(0)}let r=i.cache_last_value?new Ht("better-commits"):lt,a=n.interactive?Ut:[F];for(let l of a)await new l(i,s,r).run()}export{Jt as main};
|
package/dist/init.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
import{g as c,h as e,m as a,n as p}from"./chunk-
|
|
2
|
+
import{g as c,h as e,m as a,n as p}from"./chunk-B7AGSPP3.js";import*as t from"@clack/prompts";import l from"fs";import o from"picocolors";await m();async function m(){console.clear(),t.intro(`${o.bgCyan(o.black(" better-commits-init "))}`);let r=a(),i=p(r),s=`${r}/${e}`;if(i){let n=await t.confirm({message:`${i.split("/").pop()} already exists. Replace with default ${e}?`});if(t.isCancel(n)||!n){t.outro("Cancelled");return}}try{l.writeFileSync(s,c)}catch{t.log.error(`${o.red("Could not determine git root folder. better-commits-init must be used in a git repository")}`)}t.log.success(`${o.green(`Successfully created ${s.split("/").pop()}`)}`),t.outro(`Run ${o.bgBlack(o.white("better-commits"))} to start the CLI`)}export{m as create_init_config};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "better-commits",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.23.0",
|
|
5
5
|
"description": "A CLI for creating better commits following the conventional commits specification",
|
|
6
6
|
"author": "Erik Verduin (https://github.com/everduin94)",
|
|
7
7
|
"type": "module",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@semantic-release/git": "^10.0.1",
|
|
47
47
|
"@semantic-release/npm": "^13.1.3",
|
|
48
48
|
"@types/configstore": "^6.0.0",
|
|
49
|
-
"@types/node": "^
|
|
49
|
+
"@types/node": "^24.10.1",
|
|
50
50
|
"jiti": "^1.17.0",
|
|
51
51
|
"prettier": "3.2.5",
|
|
52
52
|
"semantic-release": "^25.0.2",
|