relion 0.26.0 → 0.28.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/index.d.ts CHANGED
@@ -16,7 +16,7 @@ interface UserConfig {
16
16
  zeroMajorBreakingIsMinor?: boolean;
17
17
  context?: Context;
18
18
  commitsParser?: CommitsParser;
19
- prevReleaseTagPattern?: RegExp;
19
+ prevReleaseTagPattern?: '{{newTagFormat}}' | RegExp;
20
20
  dryRun?: boolean;
21
21
  profile?: string;
22
22
  logLevel?: 'info' | 'info-clean' | 'silent';
@@ -34,6 +34,7 @@ interface TransformedConfig extends Omit<MergedConfig, 'changelog'> {
34
34
  manifestFile: Bumper;
35
35
  bump?: Required<Bumper[]>;
36
36
  changelog?: ResolvedChangelogOptions;
37
+ prevReleaseTagPattern: RegExp;
37
38
  }
38
39
  interface ResolvedConfig extends TransformedConfig {
39
40
  context: ResolvedContext;
@@ -48,9 +49,8 @@ interface ChangelogOptions {
48
49
  releasePattern?: RegExp;
49
50
  commitRefLinkPattern?: RegExp;
50
51
  groupCommitsByScope?: boolean;
51
- maxLinesPerRelease?: number;
52
52
  helpers?: HelperDeclareSpec;
53
- partials?: Record<string, 'from-file' | (string & {}) | ((fallback: string) => string)>;
53
+ partials?: Record<string, string | ((fallback: string) => string)>;
54
54
  review?: boolean;
55
55
  }
56
56
  type CompleteChangelogOptions = Required<ChangelogOptions>;
@@ -101,6 +101,7 @@ interface RepoInfo {
101
101
  interface PackageInfo {
102
102
  name?: string;
103
103
  version?: string;
104
+ homepage?: string;
104
105
  [key: string]: unknown;
105
106
  }
106
107
  interface Context {
@@ -222,27 +223,22 @@ declare const defaultChangelogSections: {
222
223
  readonly breaking: {
223
224
  readonly title: "⚠️ BREAKING CHANGES";
224
225
  readonly commitType: "breaking";
225
- readonly show: "always";
226
226
  };
227
227
  readonly feat: {
228
228
  readonly title: "✨ Features";
229
229
  readonly commitType: "feat";
230
- readonly show: "always";
231
230
  };
232
231
  readonly fix: {
233
232
  readonly title: "🩹 Fixes";
234
233
  readonly commitType: "fix";
235
- readonly show: "always";
236
234
  };
237
235
  readonly perf: {
238
236
  readonly title: "⚡ Performance";
239
237
  readonly commitType: "perf";
240
- readonly show: "always";
241
238
  };
242
239
  readonly revert: {
243
240
  readonly title: "♻️ Reverts";
244
241
  readonly commitType: "revert";
245
- readonly show: "always";
246
242
  };
247
243
  readonly refactor: {
248
244
  readonly title: "🚜 Refactoring";
@@ -293,7 +289,7 @@ interface TypeGroupDefinition {
293
289
  title: string;
294
290
  commitType: 'breaking' | '*' | (string & {}) | string[];
295
291
  filter?: (commit: ResolvedCommit) => boolean;
296
- show?: 'always' | 'limit-or-breaking' | 'only-breaking' | 'never';
292
+ show?: 'only-breaking' | 'never';
297
293
  }
298
294
  type TypeGroupsMap = Record<string, TypeGroupDefinition>;
299
295
  interface ScopeGroup {
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import r from"handlebars";import i from"semver";import{createHash as a}from"node:crypto";import{execSync as o}from"node:child_process";import s from"node:readline";const c={breaking:{title:`⚠️ BREAKING CHANGES`,commitType:`breaking`,show:`always`},feat:{title:`✨ Features`,commitType:`feat`,show:`always`},fix:{title:`🩹 Fixes`,commitType:`fix`,show:`always`},perf:{title:`⚡ Performance`,commitType:`perf`,show:`always`},revert:{title:`♻️ Reverts`,commitType:`revert`,show:`always`},refactor:{title:`🚜 Refactoring`,commitType:`refactor`},build:{title:`📦 Build`,commitType:`build`},docs:{title:`📚 Documentation`,commitType:`docs`},style:{title:`🎨 Style`,commitType:`style`},test:{title:`🧪 Tests`,commitType:`test`},ci:{title:`🚀 CI`,commitType:`ci`},types:{title:`🏷️ Types`,commitType:`types`},deps:{title:`🧩 Dependencies`,commitType:`chore`,filter:e=>!!e.scope?.includes(`deps`)},chore:{title:`🛠️ Chores`,commitType:`chore`},misc:{title:`⚙️ Miscellaneous`,commitType:`*`,filter:e=>e.type!==`release`&&e.scope!==`release`}},l={file:`CHANGELOG.md`,output:`file`,commitRange:`unreleased`,extractFromFile:!1,sections:c,header:`# Changelog
1
+ import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import r from"handlebars";import i from"semver";import{createHash as a}from"node:crypto";import{execSync as o}from"node:child_process";import s from"node:readline";const c=/(?<version>\d+\.\d+\.\d+.*)/,l={breaking:{title:`⚠️ BREAKING CHANGES`,commitType:`breaking`},feat:{title:`✨ Features`,commitType:`feat`},fix:{title:`🩹 Fixes`,commitType:`fix`},perf:{title:`⚡ Performance`,commitType:`perf`},revert:{title:`♻️ Reverts`,commitType:`revert`},refactor:{title:`🚜 Refactoring`,commitType:`refactor`},build:{title:`📦 Build`,commitType:`build`},docs:{title:`📚 Documentation`,commitType:`docs`},style:{title:`🎨 Style`,commitType:`style`},test:{title:`🧪 Tests`,commitType:`test`},ci:{title:`🚀 CI`,commitType:`ci`},types:{title:`🏷️ Types`,commitType:`types`},deps:{title:`🧩 Dependencies`,commitType:`chore`,filter:e=>!!e.scope?.includes(`deps`)},chore:{title:`🛠️ Chores`,commitType:`chore`},misc:{title:`⚙️ Miscellaneous`,commitType:`*`,filter:e=>e.type!==`release`&&e.scope!==`release`}},u={file:`CHANGELOG.md`,output:`file`,commitRange:`unreleased`,extractFromFile:!1,sections:l,header:`# Changelog
2
2
 
3
3
 
4
- `,releasePattern:/(?<header>##[^\n]*?\[[^\n]*?{{version}}[^\n]*?\].*?\n\n)(?<body>.*?)(?<footer>####.*?\n\n\n)/s,commitRefLinkPattern:/\[`?(#?\w+?)`?\]\(.+?\)/g,groupCommitsByScope:!0,maxLinesPerRelease:20,review:!1,helpers:{eq:(e,t)=>e===t,repeat:(e,t)=>e.repeat(t),isArray:e=>Array.isArray(e),isSingle:e=>e.length===1,or:(...e)=>e.slice(0,-1).some(Boolean),not:e=>!e,tagToUrlFragment:e=>`--${e.replace(` `,`-`).replace(/\./g,``)}-`,toSentenceCase:function(e){let t=e.fn(this);return`${t.charAt(0).toUpperCase()}${t.slice(1)}${t.endsWith(`.`)?``:`.`}`}},partials:{br:`
4
+ `,releasePattern:/(?<header>## [^\n]*?\[[^\n]*?{{version}}[^\n]*?\].*?\n+)(?<body>.*?)(?<footer>##### .*?(?:\n+|$))/s,commitRefLinkPattern:/\[`?(#?\w+?)`?\]\(.+?\)/g,groupCommitsByScope:!0,review:!1,helpers:{eq:(e,t)=>e===t,repeat:(e,t)=>e.repeat(t),isArray:e=>Array.isArray(e),isSingle:e=>e.length===1,or:(...e)=>e.slice(0,-1).some(Boolean),not:e=>!e,tagToUrlFragment:e=>`--${e.replace(` `,`-`).replace(/(\.|@)/g,``)}-`,getChangelogUrl:e=>{let t=e.replace(/#.*/,``);return t.includes(`/blob/main`)||(t+=`/blob/main`),`${t}/CHANGELOG.md`},toSentenceCase:function(e){let t=e.fn(this);return`${t.charAt(0).toUpperCase()}${t.slice(1)}${t.endsWith(`.`)?``:`.`}`}},partials:{br:`
5
5
  `,scope:`{{#if scope}}**{{scope}}**: {{/if}}`,commit:`{{{subject}}} {{" "}}
6
6
  {{~#if @root.commitRefLinks~}}
7
7
  [\`{{hash}}\`]({{@root.repo.homepage}}/commit/{{hash}})
@@ -22,16 +22,16 @@ import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import
22
22
  {{raw}}
23
23
  {{~/if}}
24
24
  {{~#if @last}}){{else}}, {{/if}}
25
- {{~/each}}`,changelogUrl:`{{repo.homepage}}/blob/main/CHANGELOG.md#{{tagToUrlFragment tag}}`,breakingChangesIndicator:`<sup>[{{breakingChangeIndex}}]</sup>`}},u={message:`chore(release): {{newTag}}`,signOff:!1,gpgSign:!1,stageAll:!0,extraArgs:null},d={name:`{{newTag}}`,message:`{{commitMessage}}`,gpgSign:!1,force:!1,extraArgs:null},f=[...[{file:/package\.json$/,pattern:/(^.*?"name": "(?<name>.*?)".*"version": ")(?<version>.*?)(")/s,replacement:`$1{{newVersion}}$4`}],{file:/package-lock\.json$/,pattern:/(^.*?"version": "|"packages".*?"".*"version": ")(.*?)(")/gs,replacement:`$1{{newVersion}}$3`}],p={lifecycle:[`bump`,`changelog`,`commit`,`tag`],bump:[`package.json`],versionSource:`manifestFile`,manifestFile:`./package.json`,tagFormat:`v{{version}}`,commitsScope:`.`,prevReleaseTagPattern:/^v?(?<version>\d+\.\d+\.\d+)/,zeroMajorBreakingIsMinor:!0,dryRun:!1,logLevel:`info`,context:{commitRefLinks:!0,footerChangelogUrl:!1},commitsParser:{headerPattern:/^(?<type>\w+)(?:\((?<scope>.+)\))?(?<bang>!)?: (?<subject>.+)/s,breakingChangesPattern:/^BREAKING CHANGES?:\s*(?<content>.+)/ms,breakingChangeListPattern:/- (.+)/g,tagPattern:/tag: (?<tag>.*?)[,)]/g,coAuthorPattern:/Co-authored-by: (?<name>.+?) <(?<email>.+)>/g,signerPattern:/Signed-off-by: (?<name>.+?) <(?<email>.+)>/g,ghEmailPattern:/^(?:\d+\+)?(?<username>.+)@users\.noreply\.github\.com$/,remoteUrlPattern:/^(https:\/\/|git@)(?<host>[^/:]+)[/:](?<owner>.+?)\/(?<name>.+?)(?:\..*)?$/,refPattern:/^(?<action>.+?) (?<labels>.+)$/gm,refLabelPattern:/(?:(?<owner>\S+?)\/(?<repo>\S+?))?#(?<number>\d+)/g,refActionPattern:/^(Fixes|Closes|Refs)/i,dateSource:`authorDate`,dateFormat:`US`,revertCommitBodyPattern:/^This reverts commit (?<hash>.{7})/m}},m=e=>C(v(_(g(h(e))))),h=e=>{let t=e.profile??`default`,n=e[`_${t}`];if(!n){if(e.profile===void 0)return e;throw Error(`Profile "${t}" not found in configuration.`)}let r=(t,...r)=>{let i=e=>Object.prototype.toString.call(e)===`[object Object]`,a=(e,t)=>{let n=i(e),r=i(t);return n&&r?{...e,...t}:t??e},o=e[t],s=n[t],c=a(o,s);if(c!==void 0)return r.forEach(e=>{c[e]=a(o?.[e],s?.[e])}),c};return{...e,...n,commitsParser:r(`commitsParser`),changelog:r(`changelog`,`partials`,`helpers`),commit:r(`commit`),tag:r(`tag`),context:r(`context`)}},g=e=>{let t=e.lifecycle??p.lifecycle;return t=t===`all`?[`bump`,`changelog`,`commit`,`tag`]:[...new Set(t)],{...p,...e,lifecycle:t,commitsParser:{...p.commitsParser,...e.commitsParser},bump:t.includes(`bump`)?e.bump??p.bump:void 0,changelog:t.includes(`changelog`)?{...l,...e.changelog,partials:{...l.partials,...e.changelog?.partials},helpers:{...l.helpers,...e.changelog?.helpers}}:void 0,commit:t.includes(`commit`)?{...u,...e.commit}:void 0,tag:t.includes(`tag`)?{...d,...e.tag}:void 0,context:{...p.context,...e.context}}},_=e=>{let t=e=>{if(typeof e==`object`)return e;let t=f.find(t=>t.file.test(e));if(t)return{...t,file:e};throw Error(`File ${e} doesn't match any default versioned files. Please provide a custom pattern for this file.`)},n=t(e.manifestFile),r=e.changelog?.releasePattern,i=e.tag?.message;return{...e,manifestFile:n,bump:e.lifecycle.includes(`bump`)?e.bump?e.bump.map(t):[n]:void 0,changelog:e.changelog?{...e.changelog,compiledPartials:Z(e.changelog,e.context),latestReleasePattern:new RegExp(r.source.replace(`{{version}}`,``),r.flags)}:void 0,tag:e.tag?{...e.tag,message:i===`{{commitMessage}}`?e.commit?.message??i:i}:void 0}},v=e=>{let n=e.context,r=V(e.commitsParser.remoteUrlPattern),i=e.manifestFile.pattern.exec(t(e.manifestFile.file,`utf-8`))?.groups,a=n.currentVersion??(e.versionSource===`latest-release-tag`?T(W(e.prevReleaseTagPattern)[0],e.prevReleaseTagPattern)??`0.0.0`:w(e.manifestFile));q(`Current version (from ${e.versionSource===`latest-release-tag`?`latest release tag`:`'${e.manifestFile.file}'`}): '${a}'`);let o=n.currentTag??W(e.prevReleaseTagPattern)[0],s=n.newVersion??ee(e,a,e.commitsScope),c=n.newTag??(e.tagPrefix===void 0?e.tagFormat.replace(`{{version}}`,s):e.tagPrefix+s),l=e.changelog?e.changelog.commitRange:`unreleased`,u=y(n.commits?n.commits.map(t=>typeof t==`object`&&`message`in t||typeof t==`string`?M(t,e.commitsParser,e.prevReleaseTagPattern):t).filter(e=>e!=null):j(l,e.commitsParser,e.prevReleaseTagPattern,e.commitsScope),c,e.commitsParser.revertCommitBodyPattern),d=e.changelog?b(u,e.changelog.sections,e.prevReleaseTagPattern,e.changelog.groupCommitsByScope,e.changelog.maxLinesPerRelease):null,{commits:f,...p}=n;return{...e,context:{currentVersion:a,currentTag:o,newVersion:s,newTag:c,commits:u,releases:d,commitRefLinks:n.commitRefLinks??!0,footerChangelogUrl:n.footerChangelogUrl??!1,...p,repo:{...r,...e.context.repo},package:{...i,...e.context.package}}}},y=(e,t,n)=>{let r=0,i=[];return e.map(a=>{let o=null,s=e.findIndex(e=>e.type===`revert`&&n.exec(e.body??``)?.groups?.hash===a.hash),c=s===-1?void 0:e[s];if(c&&(o=c.associatedReleaseTag===a.associatedReleaseTag?`inTheSameRelease`:`inOtherRelease`),o===`inTheSameRelease`){i.push(s);return}return{...a,associatedReleaseTag:a.associatedReleaseTag??t,isReverted:a.isReverted??o,breakingChangeIndex:a.breakingChanges?++r:void 0}}).filter((e,t)=>!!e&&!i.includes(t))},b=(e,t,n,r,i)=>{i??=l.maxLinesPerRelease;let a={};return e.forEach(e=>{let t=e.associatedReleaseTag;t in a?a[t].commits.push(e):a[t]={tag:t,version:T(t,n),date:e.date,commits:[e]}}),Object.values(a).map(({commits:e,...n})=>{let a=x(e,t,r);if(Object.keys(a).length===0)return;let o=0,s=!1,c={};for(let[e,t]of Object.entries(a))t.show??=`limit-or-breaking`,o+t.commits.length>i&&Object.keys(c).length&&(s=!0),t.show!==`never`&&(t.show===`only-breaking`||t.show===`limit-or-breaking`&&s?(t.commits=t.commits.filter(e=>!!e.breakingChanges),t.commits.length&&(t.scopeGroups=S(t.commits),c[e]=t,o+=t.commits.length)):(t.show===`always`||!s)&&(c[e]=t,o+=t.commits.length));return{...n,commitTypeGroups:c}}).filter(e=>!!e)},x=(e,t,n)=>{let r=Object.fromEntries(Object.entries(t).map(([e,{filter:t,...n}])=>[e,{...n,commits:[]}]));e.forEach(e=>{let n=!!e.breakingChanges,i=!1,a=!1;for(let o in t){if(t[o].filter&&!t[o].filter(e))continue;let s=[t[o].commitType].flat();if(n&&!a&&s.includes(`breaking`)){r[o].commits.push(e),a=!0;continue}if(!i&&(s.includes(e.type)||s.includes(`*`))&&(r[o].commits.push(e),i=!0),i&&(!n||a))return}});let i=Object.entries(r).filter(([e,t])=>t.commits.length);return Object.fromEntries(n?i.map(([e,t])=>[e,{...t,scopeGroups:S(t.commits)}]):i)},S=e=>{let t={};return e.forEach(e=>{let n=e.scope??``;t[n]??=[],t[n].push(e)}),Object.entries(t).map(([e,t])=>({scope:e,commits:t}))},C=e=>({...e,commit:e.commit?{...e.commit,message:r.compile(e.commit.message)(e.context)}:e.commit,tag:e.tag?{...e.tag,name:r.compile(e.tag.name)(e.context),message:r.compile(e.tag.message)(e.context)}:e.tag}),w=e=>{let n=t(e.file,`utf8`),r=e.pattern.exec(n)?.groups?.version;if(!r)throw Error(`Version not found in '${e.file}' with pattern '${e.pattern}'`);if(!i.valid(r))throw Error(`Invalid version format in '${e.file}': '${r}'`);return r},T=(e,t)=>t.exec(e)?.groups?.version,ee=(e,t,n)=>{if(e.context.newVersion){if(!i.valid(e.context.newVersion))throw Error(`Invalid release version format: '${e.context.newVersion}'`);return e.context.newVersion}let r;e.releaseType?r=e.releaseType:(r=E(j(`unreleased`,e.commitsParser,e.prevReleaseTagPattern,n)),e.zeroMajorBreakingIsMinor&&i.major(t)===0&&r===`major`&&(r=`minor`));let a=D(t,r);return q(`Determined new version: '${a}' (release type: '${r}')`),a},E=e=>e.some(e=>e.breakingChanges)?`major`:e.some(e=>e.type===`feat`)?`minor`:`patch`,D=(e,t)=>i.inc(e,t)??(()=>{throw Error(`Failed to calculate new version from '${e}' with release type '${t}'`)})();let O=function(e){return e.G=`valid`,e.B=`bad`,e.U=`valid, unknown validity`,e.X=`valid, expired`,e.Y=`valid, made by expired key`,e.R=`valid, made by revoked key`,e.E=`cannot check (missing key)`,e.N=`no signature`,e}({});const k=new Map;let A;const j=(e,t,n,r)=>{n??=p.prevReleaseTagPattern;let i=Array.isArray(e)?e:H(e,n,r),a=t??p.commitsParser,o=i.map(e=>M(e,a,n)).filter(e=>e!==null);return A=void 0,o},M=(e,t,n)=>{t??=p.commitsParser,n??=p.prevReleaseTagPattern,typeof e==`string`&&(e={message:e});let{tagRefs:r,hash:i=N(e.message)}=e;if(k.has(i))return k.get(i)??null;let a=e.message.trim();if(!a)throw Error(`Message is missing for commit: ${JSON.stringify(e)}`);let o;try{o=P(a,t)}catch(e){return J(`Error parsing commit '${i}':`,e.message),null}let{type:s,scope:c,subject:l,body:u,breakingChanges:d,footer:f}=o,m=r?[...r.matchAll(t.tagPattern)].map(e=>e.groups?.tag??``):[],h=f?[...f.matchAll(t.signerPattern)].map(e=>e.groups):[],g=[],_=e=>{g.some(t=>t.email===e.email)||g.push(e)},v=e.authorName&&e.authorEmail?I({name:e.authorName,email:e.authorEmail},h):void 0;v&&_(v);let y=e.committerName&&e.committerEmail?I({name:e.committerName,email:e.committerEmail},h):void 0;y&&_(y),(f?[...f.matchAll(t.coAuthorPattern)].map(e=>e.groups).map(e=>I(e,h)):[]).forEach(e=>_(e));let b=L(f??``,t),x=e.gpgSigCode?{code:e.gpgSigCode,label:O[e.gpgSigCode],keyId:e.gpgSigKeyId}:void 0,S=e[t.dateSource===`committerDate`?`committerTs`:`authorTs`];typeof S==`string`&&(S=R(new Date(S*1e3),t.dateFormat));let C=m.find(e=>n.exec(e)),w=C??A;w&&(A=w);let T={hash:i,type:s,scope:c,subject:l,body:u,breakingChanges:d,footer:f,committer:y,gpgSig:x,date:S,releaseTag:C,associatedReleaseTag:w,tags:m.length?m:void 0,authors:g.length?g:void 0,refs:b.length?b:void 0};return i&&!k.has(i)&&k.set(i,T),T},N=e=>`fake_`+a(`sha256`).update(e,`utf8`).digest(`hex`).slice(0,7),P=(e,t)=>{let[n,...r]=e.split(`
25
+ {{~/each}}`,changelogUrl:`{{getChangelogUrl package.homepage}}#{{tagToUrlFragment tag}}`,breakingChangesIndicator:`<sup>[{{breakingChangeIndex}}]</sup>`}},d={message:`chore(release): {{newTag}}`,signOff:!1,gpgSign:!1,stageAll:!0,extraArgs:null},f={name:`{{newTag}}`,message:`{{commitMessage}}`,gpgSign:!1,force:!1,extraArgs:null},p=[...[{file:/package\.json$/,pattern:/(^.*?"name": "(?<name>.*?)".*"version": ")(?<version>.*?)(".*?"homepage": "(?<homepage>.*?)")/s,replacement:`$1{{newVersion}}$4`}],{file:/package-lock\.json$/,pattern:/(^.*?"version": "|"packages".*?"".*"version": ")(.*?)(")/gs,replacement:`$1{{newVersion}}$3`}],m={lifecycle:[`bump`,`changelog`,`commit`,`tag`],bump:[`package.json`],versionSource:`manifestFile`,manifestFile:`./package.json`,tagFormat:`v{{version}}`,commitsScope:`.`,prevReleaseTagPattern:`{{newTagFormat}}`,zeroMajorBreakingIsMinor:!0,dryRun:!1,logLevel:`info`,context:{commitRefLinks:!0,footerChangelogUrl:!1},commitsParser:{headerPattern:/^(?<type>\w+)(?:\((?<scope>.+)\))?(?<bang>!)?: (?<subject>.+)/s,breakingChangesPattern:/^BREAKING CHANGES?:\s*(?<content>.+)/ms,breakingChangeListPattern:/- (.+)/g,tagPattern:/tag: (?<tag>.*?)[,)]/g,coAuthorPattern:/Co-authored-by: (?<name>.+?) <(?<email>.+)>/g,signerPattern:/Signed-off-by: (?<name>.+?) <(?<email>.+)>/g,ghEmailPattern:/^(?:\d+\+)?(?<username>.+)@users\.noreply\.github\.com$/,remoteUrlPattern:/^(https:\/\/|git@)(?<host>[^/:]+)[/:](?<owner>.+?)\/(?<name>.+?)(?:\..*)?$/,refPattern:/^(?<action>.+?) (?<labels>.+)$/gm,refLabelPattern:/(?:(?<owner>\S+?)\/(?<repo>\S+?))?#(?<number>\d+)/g,refActionPattern:/^(Fixes|Closes|Refs)/i,dateSource:`authorDate`,dateFormat:`US`,revertCommitBodyPattern:/^This reverts commit (?<hash>.{7})/m}},h=e=>w(y(v(_(g(e))))),g=e=>{let t=e.profile??`default`,n=e[`_${t}`];if(!n){if(e.profile===void 0)return e;throw Error(`Profile "${t}" not found in configuration.`)}let r=(t,...r)=>{let i=e=>Object.prototype.toString.call(e)===`[object Object]`,a=(e,t)=>{let n=i(e),r=i(t);return n&&r?{...e,...t}:t??e},o=e[t],s=n[t],c=a(o,s);if(c!==void 0)return r.forEach(e=>{c[e]=a(o?.[e],s?.[e])}),c};return{...e,...n,commitsParser:r(`commitsParser`),changelog:r(`changelog`,`partials`,`helpers`),commit:r(`commit`),tag:r(`tag`),context:r(`context`)}},_=e=>{let t=e.lifecycle??m.lifecycle;return t=t===`all`?[`bump`,`changelog`,`commit`,`tag`]:[...new Set(t)],{...m,...e,lifecycle:t,commitsParser:{...m.commitsParser,...e.commitsParser},bump:t.includes(`bump`)?e.bump??m.bump:void 0,changelog:t.includes(`changelog`)?{...u,...e.changelog,partials:{...u.partials,...e.changelog?.partials},helpers:{...u.helpers,...e.changelog?.helpers}}:void 0,commit:t.includes(`commit`)?{...d,...e.commit}:void 0,tag:t.includes(`tag`)?{...f,...e.tag}:void 0,context:{...m.context,...e.context}}},v=e=>{let t=e=>{if(typeof e==`object`)return e;let t=p.find(t=>t.file.test(e));if(t)return{...t,file:e};throw Error(`File ${e} doesn't match any default versioned files. Please provide a custom pattern for this file.`)},n=t(e.manifestFile),r=e.changelog?.releasePattern,i=e.tag?.message,a=e.prevReleaseTagPattern===`{{newTagFormat}}`?e.tagPrefix===void 0?new RegExp(e.tagFormat.replace(`{{version}}`,c.source)):RegExp(`${e.tagPrefix}${c.source}`):e.prevReleaseTagPattern;return{...e,manifestFile:n,bump:e.lifecycle.includes(`bump`)?e.bump?e.bump.map(t):[n]:void 0,changelog:e.changelog?{...e.changelog,compiledPartials:Z(e.changelog,e.context),latestReleasePattern:new RegExp(r.source.replace(`{{version}}`,``),r.flags)}:void 0,tag:e.tag?{...e.tag,message:i===`{{commitMessage}}`?e.commit?.message??i:i}:void 0,prevReleaseTagPattern:a}},y=e=>{let n=e.context,r=V(e.commitsParser.remoteUrlPattern),i=e.manifestFile.pattern.exec(t(e.manifestFile.file,`utf-8`))?.groups,a=n.currentVersion??(e.versionSource===`latest-release-tag`?E(W(e.prevReleaseTagPattern)[0],e.prevReleaseTagPattern)??`0.0.0`:T(e.manifestFile));q(`Current version (from ${e.versionSource===`latest-release-tag`?`latest release tag`:`'${e.manifestFile.file}'`}): '${a}'`);let o=n.currentTag??W(e.prevReleaseTagPattern)[0],s=n.newVersion??ee(e,a,e.commitsScope),c=n.newTag??(e.tagPrefix===void 0?e.tagFormat.replace(`{{version}}`,s):e.tagPrefix+s),l=e.changelog?e.changelog.commitRange:`unreleased`,u=b(n.commits?n.commits.map(t=>typeof t==`object`&&`message`in t||typeof t==`string`?N(t,e.commitsParser,e.prevReleaseTagPattern):t).filter(e=>e!=null):M(l,e.commitsParser,e.prevReleaseTagPattern,e.commitsScope),c,e.commitsParser.revertCommitBodyPattern),d=e.changelog?x(u,e.changelog.sections,e.prevReleaseTagPattern,e.changelog.groupCommitsByScope):null,{commits:f,...p}=n;return{...e,context:{currentVersion:a,currentTag:o,newVersion:s,newTag:c,commits:u,releases:d,commitRefLinks:n.commitRefLinks??!0,footerChangelogUrl:n.footerChangelogUrl??!1,...p,repo:{...r,...e.context.repo},package:{...i,...e.context.package}}}},b=(e,t,n)=>{let r=0,i=[];return e.map(a=>{let o=null,s=e.findIndex(e=>e.type===`revert`&&n.exec(e.body??``)?.groups?.hash===a.hash),c=s===-1?void 0:e[s];if(c&&(o=c.associatedReleaseTag===a.associatedReleaseTag?`inTheSameRelease`:`inOtherRelease`),o===`inTheSameRelease`){i.push(s);return}return{...a,associatedReleaseTag:a.associatedReleaseTag??t,isReverted:a.isReverted??o,breakingChangeIndex:a.breakingChanges?++r:void 0}}).filter((e,t)=>!!e&&!i.includes(t))},x=(e,t,n,r)=>{let i={};return e.forEach(e=>{let t=e.associatedReleaseTag;t in i?i[t].commits.push(e):i[t]={tag:t,version:E(t,n),date:e.date,commits:[e]}}),Object.values(i).map(({commits:e,...n})=>{let i=S(e,t,r);if(Object.keys(i).length===0)return;let a={};for(let[e,t]of Object.entries(i))if(t.show===`never`)continue;else t.show===`only-breaking`?(t.commits=t.commits.filter(e=>!!e.breakingChanges),t.commits.length&&(t.scopeGroups=C(t.commits),a[e]=t)):a[e]=t;return{...n,commitTypeGroups:a}}).filter(e=>!!e)},S=(e,t,n)=>{let r=Object.fromEntries(Object.entries(t).map(([e,{filter:t,...n}])=>[e,{...n,commits:[]}]));e.forEach(e=>{let n=!!e.breakingChanges,i=!1,a=!1;for(let o in t){if(t[o].filter&&!t[o].filter(e))continue;let s=[t[o].commitType].flat();if(n&&!a&&s.includes(`breaking`)){r[o].commits.push(e),a=!0;continue}if(!i&&(s.includes(e.type)||s.includes(`*`))&&(r[o].commits.push(e),i=!0),i&&(!n||a))return}});let i=Object.entries(r).filter(([e,t])=>t.commits.length);return Object.fromEntries(n?i.map(([e,t])=>[e,{...t,scopeGroups:C(t.commits)}]):i)},C=e=>{let t={};return e.forEach(e=>{let n=e.scope??``;t[n]??=[],t[n].push(e)}),Object.entries(t).map(([e,t])=>({scope:e,commits:t}))},w=e=>({...e,commit:e.commit?{...e.commit,message:r.compile(e.commit.message)(e.context)}:e.commit,tag:e.tag?{...e.tag,name:r.compile(e.tag.name)(e.context),message:r.compile(e.tag.message)(e.context)}:e.tag}),T=e=>{let n=t(e.file,`utf8`),r=e.pattern.exec(n)?.groups?.version;if(!r)throw Error(`Version not found in '${e.file}' with pattern '${e.pattern}'`);if(!i.valid(r))throw Error(`Invalid version format in '${e.file}': '${r}'`);return r},E=(e,t)=>t.exec(e)?.groups?.version,ee=(e,t,n)=>{if(e.context.newVersion){if(!i.valid(e.context.newVersion))throw Error(`Invalid release version format: '${e.context.newVersion}'`);return e.context.newVersion}let r;r=e.releaseType?e.releaseType:D(M(`unreleased`,e.commitsParser,e.prevReleaseTagPattern,n),t,e.zeroMajorBreakingIsMinor);let a=O(t,r);return q(`Determined new version: '${a}' (release type: '${r}')`),a},D=(e,t,n)=>{let r=`patch`;return e.some(e=>e.breakingChanges)&&(r=`major`),e.some(e=>e.type===`feat`)&&(r=`minor`),r===`major`&&i.major(t??`1.0.0`)===0&&n?`minor`:r},O=(e,t)=>i.inc(e,t)??(()=>{throw Error(`Failed to calculate new version from '${e}' with release type '${t}'`)})();let k=function(e){return e.G=`valid`,e.B=`bad`,e.U=`valid, unknown validity`,e.X=`valid, expired`,e.Y=`valid, made by expired key`,e.R=`valid, made by revoked key`,e.E=`cannot check (missing key)`,e.N=`no signature`,e}({});const A=new Map;let j;const M=(e,t,n,r)=>{n??=c;let i=Array.isArray(e)?e:H(e,n,r),a=t??m.commitsParser,o=i.map(e=>N(e,a,n)).filter(e=>e!==null);return j=void 0,o},N=(e,t,n)=>{t??=m.commitsParser,n??=c,typeof e==`string`&&(e={message:e});let{tagRefs:r,hash:i=P(e.message)}=e;if(A.has(i))return A.get(i)??null;let a=e.message.trim();if(!a)throw Error(`Message is missing for commit: ${JSON.stringify(e)}`);let o;try{o=F(a,t)}catch(e){return J(`Error parsing commit '${i}':`,e.message),null}let{type:s,scope:l,subject:u,body:d,breakingChanges:f,footer:p}=o,h=r?[...r.matchAll(t.tagPattern)].map(e=>e.groups?.tag??``):[],g=p?[...p.matchAll(t.signerPattern)].map(e=>e.groups):[],_=[],v=e=>{_.some(t=>t.email===e.email)||_.push(e)},y=e.authorName&&e.authorEmail?I({name:e.authorName,email:e.authorEmail},g):void 0;y&&v(y);let b=e.committerName&&e.committerEmail?I({name:e.committerName,email:e.committerEmail},g):void 0;b&&v(b),(p?[...p.matchAll(t.coAuthorPattern)].map(e=>e.groups).map(e=>I(e,g)):[]).forEach(e=>v(e));let x=L(p??``,t),S=e.gpgSigCode?{code:e.gpgSigCode,label:k[e.gpgSigCode],keyId:e.gpgSigKeyId}:void 0,C=e[t.dateSource===`committerDate`?`committerTs`:`authorTs`];typeof C==`string`&&(C=R(new Date(C*1e3),t.dateFormat));let w=h.find(e=>n.exec(e)),T=w??j;T&&(j=T);let E={hash:i,type:s,scope:l,subject:u,body:d,breakingChanges:f,footer:p,committer:b,gpgSig:S,date:C,releaseTag:w,associatedReleaseTag:T,tags:h.length?h:void 0,authors:_.length?_:void 0,refs:x.length?x:void 0};return i&&!A.has(i)&&A.set(i,E),E},P=e=>`fake_`+a(`sha256`).update(e,`utf8`).digest(`hex`).slice(0,7),F=(e,t)=>{let[n,...r]=e.split(`
26
26
 
27
- `),i=t.headerPattern.exec(n);if(!i?.groups)throw Error(`Commit header '${n}' doesn't match expected format`);let{type:a,scope:o,bang:s,subject:c}=i.groups,l,u=r.find(e=>t.breakingChangesPattern.test(e));u?(l=F(u,t),r.splice(r.indexOf(u),1)):s&&(l=c);let d=r.findIndex(e=>e.match(t.refActionPattern)??e.match(t.coAuthorPattern)??e.match(t.signerPattern)),[f,p]=d===-1?[r.join(`
27
+ `),i=t.headerPattern.exec(n);if(!i?.groups)throw Error(`Commit header '${n}' doesn't match expected format`);let{type:a,scope:o,bang:s,subject:c}=i.groups,l,u=r.find(e=>t.breakingChangesPattern.test(e));u?(l=te(u,t),r.splice(r.indexOf(u),1)):s&&(l=c);let d=r.findIndex(e=>e.match(t.refActionPattern)??e.match(t.coAuthorPattern)??e.match(t.signerPattern)),[f,p]=d===-1?[r.join(`
28
28
 
29
29
  `),``]:[r.slice(0,d).join(`
30
30
 
31
31
  `),r.slice(d).join(`
32
32
 
33
- `)];return{type:a,scope:o||void 0,subject:c,body:f||void 0,breakingChanges:l,footer:p||void 0}},F=(e,t)=>{let n=t.breakingChangesPattern.exec(e)?.groups?.content;if(!n)throw Error(`Failed to extract breaking changes content from '${e}' using pattern "${t.breakingChangesPattern}"`);let r=[...n.matchAll(t.breakingChangeListPattern)];return r.length?r.map(e=>e[1]):n},I=(e,t)=>{let n=t.some(t=>t.email===e.email&&t.name===e.name);return{...e,hasSignedOff:n,ghLogin:e.name,ghUrl:`https://github.com/${e.name}`}},L=(e,t)=>[...e.matchAll(t.refPattern)].map(e=>e.groups).filter(e=>t.refActionPattern.test(e.action)).flatMap(e=>[...e.labels.matchAll(t.refLabelPattern)].map(e=>({label:e.groups,raw:e.input})).filter(({label:e})=>!!e.number).map(({label:t,raw:n})=>({raw:n,action:e.action,owner:t.owner,repo:t.repo,number:t.number}))),R=(e,t)=>{let n=e=>e.toString().padStart(2,`0`);if(t===`US`)return e.toLocaleString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`});if(t===`ISO`)return e.toISOString().split(`T`)[0];let r={YYYY:e.getUTCFullYear().toString(),MM:n(e.getUTCMonth()+1),DD:n(e.getUTCDate()),HH:n(e.getUTCHours()),mm:n(e.getUTCMinutes()),ss:n(e.getUTCSeconds())};return t.replace(/YYYY|MM|DD|HH|mm|ss/g,e=>r[e])},z=/##COMMIT##\n#HASH# (?<hash>.+)?\n#MSG# (?<message>[\s\S]*?)\n#REFS#\s+(?<tagRefs>.+)?\n#AUTHOR-NAME# (?<authorName>.+)?\n#AUTHOR-EMAIL# (?<authorEmail>.+)?\n#AUTHOR-DATE# (?<authorTs>.+)?\n#COMMITTER-NAME# (?<committerName>.+)?\n#COMMITTER-EMAIL# (?<committerEmail>.+)?\n#COMMITTER-DATE# (?<committerTs>.+)?\n#GPGSIG-CODE# (?<gpgSigCode>.+)?\n#GPGSIG-KEYID# (?<gpgSigKeyId>.+)?/g,B=new Map,V=e=>{let t=o(`git remote get-url origin`,{encoding:`utf8`}).trim(),n=e.exec(t);if(!n?.groups)throw Error(`Couldn't parse remote URL: `+t);let{host:r,owner:i,name:a}=n.groups;return{host:r,owner:i,name:a,homepage:`https://${r}/${i}/${a}`}},H=(e,t,n)=>{let r=U(),i=W(t),a=``,s=``,c=``;if(e===`all`)a=`{{firstCommit}}`,s=`HEAD`;else if(e===`unreleased`)a=i[0]??`{{firstCommit}}`,s=`HEAD`;else if(e===`latest-release`)a=i[1]??`{{firstCommit}}`,s=i[0]??`HEAD`;else if(typeof e==`object`){let t=i.indexOf(e.releaseTag);if(t===-1)throw Error(`Release tag '${e.releaseTag}' not found`);a=i[t+1]??`{{firstCommit}}`,s=i[t]}else c=e;return a&&s&&(c=a===`{{firstCommit}}`?`"${a}^!" ${s}`:`"${a}..${s}"`),c=c.replace(`{{firstCommit}}`,r),[...o(`git log ${c} --pretty="##COMMIT##%n#HASH# %h%n#MSG# %B%n#REFS# %d%n#AUTHOR-NAME# %an%n#AUTHOR-EMAIL# %ae%n#AUTHOR-DATE# %at%n#COMMITTER-NAME# %cn%n#COMMITTER-EMAIL# %ce%n#COMMITTER-DATE# %ct%n#GPGSIG-CODE# %G?%n#GPGSIG-KEYID# %GK%n" -- ${n??`.`}`,{encoding:`utf8`}).matchAll(z)].map(e=>e.groups)},U=()=>o(`git rev-list --max-parents=0 HEAD`,{encoding:`utf8`}).trim(),W=e=>{e??=p.prevReleaseTagPattern;let t=e.toString();if(B.has(t))return B.get(t)??[];let n=o(`git tag --sort=-creatordate`,{encoding:`utf8`}).split(`
34
- `).filter(t=>e.test(t));return B.set(t,n),n};let G=`info`;const K=e=>G=e,q=(...e)=>{G!==`silent`&&console.log(...e)},J=(...e)=>{G===`info`&&console.warn(...e)},Y={...c,pick(...e){return Object.fromEntries(e.map(e=>[e,this[e]]))},omit(...e){let t=new Set(e);return Object.fromEntries(Object.entries(this).filter(([e])=>!t.has(e)))},modify(e,t){return{...this,[e]:t(this[e])}}};var X=`{{~#>header~}}
33
+ `)];return{type:a,scope:o||void 0,subject:c,body:f||void 0,breakingChanges:l,footer:p||void 0}},te=(e,t)=>{let n=t.breakingChangesPattern.exec(e)?.groups?.content;if(!n)throw Error(`Failed to extract breaking changes content from '${e}' using pattern "${t.breakingChangesPattern}"`);let r=[...n.matchAll(t.breakingChangeListPattern)];return r.length?r.map(e=>e[1]):n},I=(e,t)=>{let n=t.some(t=>t.email===e.email&&t.name===e.name);return{...e,hasSignedOff:n,ghLogin:e.name,ghUrl:`https://github.com/${e.name}`}},L=(e,t)=>[...e.matchAll(t.refPattern)].map(e=>e.groups).filter(e=>t.refActionPattern.test(e.action)).flatMap(e=>[...e.labels.matchAll(t.refLabelPattern)].map(e=>({label:e.groups,raw:e.input})).filter(({label:e})=>!!e.number).map(({label:t,raw:n})=>({raw:n,action:e.action,owner:t.owner,repo:t.repo,number:t.number}))),R=(e,t)=>{let n=e=>e.toString().padStart(2,`0`);if(t===`US`)return e.toLocaleString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`});if(t===`ISO`)return e.toISOString().split(`T`)[0];let r={YYYY:e.getUTCFullYear().toString(),MM:n(e.getUTCMonth()+1),DD:n(e.getUTCDate()),HH:n(e.getUTCHours()),mm:n(e.getUTCMinutes()),ss:n(e.getUTCSeconds())};return t.replace(/YYYY|MM|DD|HH|mm|ss/g,e=>r[e])},z=/##COMMIT##\n#HASH# (?<hash>.+)?\n#MSG# (?<message>[\s\S]*?)\n#REFS#\s+(?<tagRefs>.+)?\n#AUTHOR-NAME# (?<authorName>.+)?\n#AUTHOR-EMAIL# (?<authorEmail>.+)?\n#AUTHOR-DATE# (?<authorTs>.+)?\n#COMMITTER-NAME# (?<committerName>.+)?\n#COMMITTER-EMAIL# (?<committerEmail>.+)?\n#COMMITTER-DATE# (?<committerTs>.+)?\n#GPGSIG-CODE# (?<gpgSigCode>.+)?\n#GPGSIG-KEYID# (?<gpgSigKeyId>.+)?/g,B=new Map,V=e=>{let t=o(`git remote get-url origin`,{encoding:`utf8`}).trim(),n=e.exec(t);if(!n?.groups)throw Error(`Couldn't parse remote URL: `+t);let{host:r,owner:i,name:a}=n.groups;return{host:r,owner:i,name:a,homepage:`https://${r}/${i}/${a}`}},H=(e,t,n)=>{let r=U(),i=W(t),a=``,s=``,c=``;if(e===`all`)a=`{{firstCommit}}`,s=`HEAD`;else if(e===`unreleased`)a=i[0]??`{{firstCommit}}`,s=`HEAD`;else if(e===`latest-release`)a=i[1]??`{{firstCommit}}`,s=i[0]??`HEAD`;else if(typeof e==`object`){let t=i.indexOf(e.releaseTag);if(t===-1)throw Error(`Release tag '${e.releaseTag}' not found`);a=i[t+1]??`{{firstCommit}}`,s=i[t]}else c=e;return a&&s&&(c=a===`{{firstCommit}}`?`"${a}^!" ${s}`:`"${a}..${s}"`),c=c.replace(`{{firstCommit}}`,r),[...o(`git log ${c} --pretty="##COMMIT##%n#HASH# %h%n#MSG# %B%n#REFS# %d%n#AUTHOR-NAME# %an%n#AUTHOR-EMAIL# %ae%n#AUTHOR-DATE# %at%n#COMMITTER-NAME# %cn%n#COMMITTER-EMAIL# %ce%n#COMMITTER-DATE# %ct%n#GPGSIG-CODE# %G?%n#GPGSIG-KEYID# %GK%n" -- ${n??`.`}`,{encoding:`utf8`}).matchAll(z)].map(e=>e.groups)},U=()=>o(`git rev-list --max-parents=0 HEAD`,{encoding:`utf8`}).trim(),W=e=>{e??=c;let t=e.toString();if(B.has(t))return B.get(t)??[];let n=o(`git tag --sort=-creatordate`,{encoding:`utf8`}).split(`
34
+ `).filter(t=>e.test(t));return B.set(t,n),n};let G=`info`;const K=e=>G=e,q=(...e)=>{G!==`silent`&&console.log(...e)},J=(...e)=>{G===`info`&&console.warn(...e)},Y={...l,pick(...e){return Object.fromEntries(e.map(e=>[e,this[e]]))},omit(...e){let t=new Set(e);return Object.fromEntries(Object.entries(this).filter(([e])=>!t.has(e)))},modify(e,t){return{...this,[e]:t(this[e])}}};var X=`{{~#>header~}}
35
35
  ## &ensp; [\` 📦 {{tag}} \`]({{>compareLink}}){{>br}}
36
36
  {{/header}}
37
37
 
@@ -73,4 +73,4 @@ import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import
73
73
 
74
74
  {{~#>footer~}}
75
75
  ##### &emsp;&ensp;&nbsp;&nbsp; {{#if footerChangelogUrl}}[_Release Changelog_]({{>changelogUrl}}) &ensp;•&ensp; {{/if}}[_All Release Commits_]({{>compareLink}}) &ensp;•&ensp; _{{date}}_{{>br}}{{>br}}
76
- {{/footer}}`;const Z=(e,n)=>{let i,a,o=Object.keys(e.partials).find(t=>e.partials[t]===`from-file`);if(e.extractFromFile||o){i=t(e.file,`utf-8`);let r=typeof e.extractFromFile==`boolean`||e.extractFromFile===`latest-release`?``:e.extractFromFile;if(a=new RegExp(e.releasePattern.source.replace(`{{version}}`,r),e.releasePattern.flags).exec(i)?.groups??{},e.extractFromFile)return Q(Object.values(a).join(``),n,e.commitRefLinkPattern)}let s=Object.fromEntries(Object.entries(e.partials).map(([t,r])=>{let i;if(typeof r==`function`)i=te(t,r);else if(r===`from-file`){if(i=a?.[t]??``,!i)throw Error(`Partial '${t}' not found in the latest release changelog.`);i=Q(i,n,e.commitRefLinkPattern)}else i=r;return[t,i]}));return Object.fromEntries(Object.entries(s).map(([e,t])=>[e,r.compile(t)]))},Q=(e,t,n)=>(t.commitRefLinks===!1&&(e=e.replace(n,`$1`)),e),te=(e,t)=>{let n=RegExp(`${e}.*?}}\\s*(.*?){{~?/${e}`,`s`).exec(X)?.[1];if(!n)throw Error(`Partial "${e}" not found in the release template.`);return t(n)},ne=async e=>{let t=s.createInterface({input:process.stdin,output:process.stdout});await new Promise(n=>{t.question(e,()=>{t.close(),n()})})},re=e=>{if(!e.bump)return null;let r=e.bump,i=e.context.newVersion;r.forEach(r=>{let a=t(r.file,`utf8`).replace(r.pattern,r.replacement.replace(`{{newVersion}}`,i));e.dryRun||n(r.file,a,`utf8`),q(`Updated version in '${r.file}' to '${i}'`)})},ie=async e=>{if(!e.changelog)return null;let t=e.changelog.extractFromFile?e.changelog.compiledPartials:ae(e);return t&&await oe(e.changelog,e,t),t},ae=e=>{let t=e.changelog,n=e.context.releases;if(!n)return null;let i=W(e.prevReleaseTagPattern),a=r.create();a.registerPartial(t.compiledPartials),a.registerHelper(t.helpers);let o=t.header;return n.forEach((t,r)=>{let s=n[r+1];if(!s){let n=i.indexOf(t.tag);if(n!==-1){let t=i[n+1];s={tag:t,version:t&&T(t,e.prevReleaseTagPattern)}}else s={tag:e.context.currentTag,version:e.context.currentVersion}}let c={...t,...e.context,prevRelease:s},l=a.compile(X)(c);o+=l}),o},oe=async(e,t,n)=>{e.output===`stdout`||t.dryRun?(q(`Generated changelog:`),console.log(n)):(q(`Writing changelog to file '${e.file}'`),$(e.file,n,e.latestReleasePattern)),e.review&&e.output===`file`&&(t.commit||t.tag)&&await ne(`Please review the changelog and press Enter to continue...`)},$=(r,i,a)=>{let o=e(r)?t(r,{encoding:`utf8`}):``,s=o.search(a);n(r,i+o.slice(s),{encoding:`utf8`})},se=e=>{if(!e.commit)return null;let t=e.commit,n=[t.stageAll&&`git add -A &&`,`git commit -m "${t.message}"`,t.signOff&&`-s`,t.gpgSign&&`-S`,t.extraArgs].filter(Boolean).join(` `);return q(`Committing with command: '${n}'`),e.dryRun||o(n,{stdio:`inherit`}),n},ce=e=>{if(!e.tag)return null;let t=e.tag,n=[`git tag -a ${t.name}`,`-m "${t.message}"`,t.gpgSign&&`-s`,t.force&&`-f`,t.extraArgs].filter(Boolean).join(` `);return q(`Tagging with command: '${n}'`),e.dryRun||o(n,{stdio:`inherit`}),n};async function le(e){K((e.logLevel??(!!e.profile&&e[`_${e.profile}`]?.logLevel))||`info`);let t=m(e),n,r,i;for(let e of t.lifecycle)await{bump:()=>re(t),changelog:async()=>n=await ie(t),commit:()=>r=se(t),tag:()=>i=ce(t)}[e]();return{resolvedConfig:t,generatedChangelog:n,commitCommand:r,tagCommand:i}}const ue=e=>e;export{le as default,ue as defineConfig,Y as sectionsSelector};
76
+ {{/footer}}`;const Z=(e,n)=>{let i,a,o=Object.keys(e.partials).find(t=>typeof e.partials[t]==`string`&&e.partials[t].includes(`{{fromFile}}`));if(e.extractFromFile||o){i=t(e.file,`utf-8`);let r=typeof e.extractFromFile==`boolean`||e.extractFromFile===`latest-release`?``:e.extractFromFile;if(a=new RegExp(e.releasePattern.source.replace(`{{version}}`,r),e.releasePattern.flags).exec(i)?.groups??{},e.extractFromFile)return Q(Object.values(a).join(``),n,e.commitRefLinkPattern)}let s=Object.fromEntries(Object.entries(e.partials).map(([t,r])=>{let i;if(typeof r==`function`)i=ne(t,r);else if(r.includes(`{{fromFile}}`)){let o=a?.[t]??``;if(!o)throw Error(`Partial '${t}' not found in the changelog file for the specified release.`);i=r.replace(`{{fromFile}}`,o).replace(/{{/g,`\\$&`),i=Q(i,n,e.commitRefLinkPattern)}else i=r;return[t,i]}));return Object.fromEntries(Object.entries(s).map(([e,t])=>[e,r.compile(t)]))},Q=(e,t,n)=>(t.commitRefLinks===!1&&(e=e.replace(n,`$1`)),e),ne=(e,t)=>{let n=RegExp(`${e}.*?}}\\s*(.*?){{~?/${e}`,`s`).exec(X)?.[1];if(!n)throw Error(`Partial "${e}" not found in the release template.`);return t(n)},re=async e=>{let t=s.createInterface({input:process.stdin,output:process.stdout});await new Promise(n=>{t.question(e,()=>{t.close(),n()})})},ie=e=>{if(!e.bump)return null;let r=e.bump,i=e.context.newVersion;r.forEach(r=>{let a=t(r.file,`utf8`).replace(r.pattern,r.replacement.replace(`{{newVersion}}`,i));e.dryRun||n(r.file,a,`utf8`),q(`Updated version in '${r.file}' to '${i}'`)})},ae=async e=>{if(!e.changelog)return null;let t=e.changelog.extractFromFile?e.changelog.compiledPartials:oe(e);return t&&await $(e.changelog,e,t),t},oe=e=>{let t=e.changelog,n=e.context.releases;if(!n)return null;let i=W(e.prevReleaseTagPattern),a=r.create();a.registerPartial(t.compiledPartials),a.registerHelper(t.helpers);let o=t.header;return n.forEach((t,r)=>{let s=n[r+1];if(!s){let n=i.indexOf(t.tag);if(n!==-1){let t=i[n+1];s={tag:t,version:t&&E(t,e.prevReleaseTagPattern)}}else s={tag:e.context.currentTag,version:e.context.currentVersion}}let c={...t,...e.context,prevRelease:s},l=a.compile(X)(c);o+=l}),o},$=async(e,t,n)=>{e.output===`stdout`||t.dryRun?(q(`Generated changelog:`),console.log(n)):(q(`Writing changelog to file '${e.file}'`),se(e.file,n,e.latestReleasePattern)),e.review&&e.output===`file`&&(t.commit||t.tag)&&await re(`Please review the changelog and press Enter to continue...`)},se=(r,i,a)=>{let o=e(r)?t(r,{encoding:`utf8`}):``,s=o.search(a),c=o.slice(s).trim();c||(i=i.trim()),n(r,i+c,{encoding:`utf8`})},ce=e=>{if(!e.commit)return null;let t=e.commit,n=[t.stageAll&&`git add -A &&`,`git commit -m "${t.message}"`,t.signOff&&`-s`,t.gpgSign&&`-S`,t.extraArgs].filter(Boolean).join(` `);return q(`Committing with command: '${n}'`),e.dryRun||o(n,{stdio:`inherit`}),n},le=e=>{if(!e.tag)return null;let t=e.tag,n=[`git tag -a ${t.name}`,`-m "${t.message}"`,t.gpgSign&&`-s`,t.force&&`-f`,t.extraArgs].filter(Boolean).join(` `);return q(`Tagging with command: '${n}'`),e.dryRun||o(n,{stdio:`inherit`}),n};async function ue(e){K((e.logLevel??(!!e.profile&&e[`_${e.profile}`]?.logLevel))||`info`);let t=h(e),n,r,i;for(let e of t.lifecycle)await{bump:()=>ie(t),changelog:async()=>n=await ae(t),commit:()=>r=ce(t),tag:()=>i=le(t)}[e]();return{resolvedConfig:t,generatedChangelog:n,commitCommand:r,tagCommand:i}}const de=e=>e;export{ue as default,de as defineConfig,Y as sectionsSelector};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relion",
3
- "version": "0.26.0",
3
+ "version": "0.28.0",
4
4
  "description": "Release workflow helper.",
5
5
  "author": "Kh4f <kh4f.dev@gmail.com>",
6
6
  "license": "MIT",
@@ -38,17 +38,17 @@
38
38
  "devDependencies": {
39
39
  "@eslint/js": "^9.38.0",
40
40
  "@stylistic/eslint-plugin": "^5.5.0",
41
- "@types/node": "^24.8.1",
41
+ "@types/node": "^24.9.1",
42
42
  "@types/semver": "^7.7.1",
43
43
  "eslint": "^9.38.0",
44
44
  "globals": "^16.4.0",
45
- "lint-staged": "^16.2.4",
45
+ "lint-staged": "^16.2.6",
46
46
  "simple-git-hooks": "^2.13.1",
47
- "tsdown": "^0.15.8",
47
+ "tsdown": "^0.15.9",
48
48
  "typescript": "^5.9.3",
49
49
  "tsx": "^4.20.6",
50
- "typescript-eslint": "^8.46.1",
51
- "vitest": "^4.0.1"
50
+ "typescript-eslint": "^8.46.2",
51
+ "vitest": "^4.0.3"
52
52
  },
53
53
  "simple-git-hooks": {
54
54
  "pre-commit": "pnpm lint-staged"