relion 0.18.0 → 0.19.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
@@ -10,7 +10,7 @@ interface UserConfig {
10
10
  newTagPrefix?: string;
11
11
  newTagFormat?: string;
12
12
  versionSource?: 'versionSourceFile' | 'latest-release-tag';
13
- versionSourceFile?: string | VersionedFile;
13
+ versionSourceFile?: string | Bumper;
14
14
  releaseType?: ReleaseType;
15
15
  zeroMajorBreakingIsMinor?: boolean;
16
16
  context?: Context;
@@ -29,14 +29,14 @@ interface MergedConfig extends Omit<Required<UserConfig>, OptionalKeys>, Pick<Us
29
29
  commitsParser: CompleteCommitsParser;
30
30
  }
31
31
  interface TransformedConfig extends Omit<MergedConfig, 'changelog'> {
32
- versionSourceFile: VersionedFile;
33
- bump: FalseOrComplete<VersionedFile[]>;
32
+ versionSourceFile: Bumper;
33
+ bump: FalseOrComplete<Bumper[]>;
34
34
  changelog: false | ResolvedChangelogOptions;
35
35
  }
36
36
  interface ResolvedConfig extends TransformedConfig {
37
37
  context: ResolvedContext;
38
38
  }
39
- type BumpFiles = (string | VersionedFile)[];
39
+ type BumpFiles = (string | Bumper)[];
40
40
  interface ChangelogOptions {
41
41
  output?: 'stdout' | (string & {});
42
42
  commitRange?: CommitRange;
@@ -44,6 +44,7 @@ interface ChangelogOptions {
44
44
  header?: string;
45
45
  prevReleaseHeaderPattern?: RegExp;
46
46
  groupCommitsByScope?: boolean;
47
+ maxLinesPerRelease?: number;
47
48
  helpers?: HelperDeclareSpec;
48
49
  partials?: Record<string, string | ((fallback: string) => string)>;
49
50
  }
@@ -91,7 +92,7 @@ interface RepoInfo {
91
92
  homepage?: string;
92
93
  }
93
94
  interface Context {
94
- commits?: ParsedCommit[] | RawCommit[];
95
+ commits?: (ParsedCommit | RawCommit)[];
95
96
  currentVersion?: string;
96
97
  currentTag?: string;
97
98
  newVersion?: string;
@@ -108,12 +109,12 @@ type CommitRange = 'all' | 'unreleased' | 'latest-release' | {
108
109
  releaseTag: string;
109
110
  } | (string & {});
110
111
  type ReleaseType = 'major' | 'minor' | 'patch';
111
- interface VersionedFile {
112
+ interface Bumper {
112
113
  file: string;
113
114
  pattern: RegExp;
114
115
  replacement: string;
115
116
  }
116
- interface DefaultVersionedFile extends Omit<VersionedFile, 'file'> {
117
+ interface DefaultBumper extends Omit<Bumper, 'file'> {
117
118
  file: RegExp;
118
119
  }
119
120
  //#endregion
@@ -174,10 +175,11 @@ interface CommitMessage {
174
175
  }
175
176
  interface Reference {
176
177
  action: string;
178
+ raw: string;
179
+ number: string;
177
180
  type?: RefType;
178
181
  owner?: string;
179
182
  repo?: string;
180
- number: string;
181
183
  }
182
184
  type RefLabel = Pick<Reference, 'owner' | 'repo' | 'number'>;
183
185
  interface Contributor {
@@ -204,23 +206,36 @@ declare const defaultChangelogSections: {
204
206
  readonly breaking: {
205
207
  readonly title: "⚠️ BREAKING CHANGES";
206
208
  readonly commitType: "breaking";
209
+ readonly ignoreLimit: true;
207
210
  };
208
211
  readonly feat: {
209
212
  readonly title: "✨ Features";
210
213
  readonly commitType: "feat";
214
+ readonly ignoreLimit: true;
211
215
  };
212
216
  readonly fix: {
213
217
  readonly title: "🩹 Fixes";
214
218
  readonly commitType: "fix";
219
+ readonly ignoreLimit: true;
215
220
  };
216
221
  readonly perf: {
217
222
  readonly title: "⚡ Performance";
218
223
  readonly commitType: "perf";
224
+ readonly ignoreLimit: true;
225
+ };
226
+ readonly revert: {
227
+ readonly title: "♻️ Reverts";
228
+ readonly commitType: "revert";
229
+ readonly ignoreLimit: true;
219
230
  };
220
231
  readonly refactor: {
221
232
  readonly title: "🚜 Refactoring";
222
233
  readonly commitType: "refactor";
223
234
  };
235
+ readonly build: {
236
+ readonly title: "📦 Build";
237
+ readonly commitType: "build";
238
+ };
224
239
  readonly docs: {
225
240
  readonly title: "📚 Documentation";
226
241
  readonly commitType: "docs";
@@ -229,18 +244,14 @@ declare const defaultChangelogSections: {
229
244
  readonly title: "🎨 Style";
230
245
  readonly commitType: "style";
231
246
  };
232
- readonly build: {
233
- readonly title: "📦 Build";
234
- readonly commitType: "build";
247
+ readonly test: {
248
+ readonly title: "🧪 Tests";
249
+ readonly commitType: "test";
235
250
  };
236
251
  readonly ci: {
237
252
  readonly title: "🚀 CI";
238
253
  readonly commitType: "ci";
239
254
  };
240
- readonly revert: {
241
- readonly title: "♻️ Reverts";
242
- readonly commitType: "revert";
243
- };
244
255
  readonly types: {
245
256
  readonly title: "🏷️ Types";
246
257
  readonly commitType: "types";
@@ -254,10 +265,6 @@ declare const defaultChangelogSections: {
254
265
  readonly title: "🛠️ Chores";
255
266
  readonly commitType: "chore";
256
267
  };
257
- readonly test: {
258
- readonly title: "🧪 Tests";
259
- readonly commitType: "test";
260
- };
261
268
  readonly misc: {
262
269
  readonly title: "⚙️ Miscellaneous";
263
270
  readonly commitType: "*";
@@ -270,6 +277,7 @@ interface TypeGroupDefinition {
270
277
  title: string;
271
278
  commitType: 'breaking' | '*' | (string & {}) | string[];
272
279
  filter?: (commit: ResolvedCommit) => boolean;
280
+ ignoreLimit?: boolean;
273
281
  }
274
282
  type TypeGroupsMap = Record<string, TypeGroupDefinition>;
275
283
  interface ScopeGroup {
@@ -294,9 +302,10 @@ interface ReleaseContext extends ReleaseWithTypeGroups, ResolvedContext {
294
302
  prevRelease: Partial<ReleaseWithTypeGroups>;
295
303
  }
296
304
  type DefaultChangelogSections = typeof defaultChangelogSections;
297
- interface ChangelogSectionsSelector extends DefaultChangelogSections {
305
+ interface SectionsSelector extends DefaultChangelogSections {
298
306
  pick(...keys: (keyof DefaultChangelogSections)[]): Partial<DefaultChangelogSections>;
299
- omit(...keys: (keyof DefaultChangelogSections)[]): Partial<DefaultChangelogSections>;
307
+ omit(...keys: (keyof this)[]): SectionsSelector;
308
+ modify(key: keyof DefaultChangelogSections, modify: (section: TypeGroupDefinition) => TypeGroupDefinition): Partial<DefaultChangelogSections>;
300
309
  }
301
310
  //#endregion
302
311
  //#region src/types/result.d.ts
@@ -311,9 +320,9 @@ interface RelionResult {
311
320
  declare function relion(userConfig: UserConfig): RelionResult;
312
321
  //#endregion
313
322
  //#region src/utils/sections-selector.d.ts
314
- declare const changelogSectionsSelector: ChangelogSectionsSelector;
323
+ declare const sectionsSelector: SectionsSelector;
315
324
  //#endregion
316
325
  //#region src/index.d.ts
317
326
  declare const defineConfig: (config: UserConfig) => UserConfig;
318
327
  //#endregion
319
- export { BumpFiles, ChangelogOptions, ChangelogSectionsSelector, CommitMessage, CommitOptions, CommitRange, CommitsParser, CompleteChangelogOptions, CompleteCommitOptions, CompleteCommitsParser, CompleteTagOptions, Context, Contributor, DefaultChangelogSections, DefaultVersionedFile, FalseOrComplete, FilledTypeGroup, FilledTypeGroupMap, GithubUserInfo, GpgSig, GpgSigCode, LogLevel, MergedConfig, ParsedCommit, RawCommit, RawReference, RefLabel, Reference, ReleaseContext, ReleaseType, ReleaseWithFlatCommits, ReleaseWithTypeGroups, RelionResult, RepoInfo, ResolvedChangelogOptions, ResolvedCommit, ResolvedConfig, ResolvedContext, ScopeGroup, TagOptions, TransformedConfig, TypeGroupDefinition, TypeGroupsMap, UserConfig, VersionedFile, changelogSectionsSelector, relion as default, defineConfig };
328
+ export { BumpFiles, Bumper, ChangelogOptions, CommitMessage, CommitOptions, CommitRange, CommitsParser, CompleteChangelogOptions, CompleteCommitOptions, CompleteCommitsParser, CompleteTagOptions, Context, Contributor, DefaultBumper, DefaultChangelogSections, FalseOrComplete, FilledTypeGroup, FilledTypeGroupMap, GithubUserInfo, GpgSig, GpgSigCode, LogLevel, MergedConfig, ParsedCommit, RawCommit, RawReference, RefLabel, Reference, ReleaseContext, ReleaseType, ReleaseWithFlatCommits, ReleaseWithTypeGroups, RelionResult, RepoInfo, ResolvedChangelogOptions, ResolvedCommit, ResolvedConfig, ResolvedContext, ScopeGroup, SectionsSelector, TagOptions, TransformedConfig, TypeGroupDefinition, TypeGroupsMap, UserConfig, relion as default, defineConfig, sectionsSelector };
package/dist/index.js CHANGED
@@ -1,8 +1,28 @@
1
- import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import r from"semver";import{createHash as i}from"node:crypto";import{execSync as a}from"node:child_process";import o from"handlebars";const s={bump:!1,changelog:!1,commit:!1,tag:!1,versionSource:`versionSourceFile`,versionSourceFile:`./package.json`,newTagFormat:`v{{version}}`,prevReleaseTagPattern:/^v?(?<version>\d+\.\d+\.\d+)/,zeroMajorBreakingIsMinor:!0,dryRun:!1,logLevel:`info`,context:{commitHyperlink:!0,refHyperlink:!0},commitsParser:{headerPattern:/^(?<type>\w+)(?:\((?<scope>.+)\))?(?<bang>!)?: (?<subject>.+)/s,breakingChangesPattern:/BREAKING CHANGES?:\s*(?<content>.+)/s,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}},c={breaking:{title:`⚠️ BREAKING CHANGES`,commitType:`breaking`},feat:{title:`✨ Features`,commitType:`feat`},fix:{title:`🩹 Fixes`,commitType:`fix`},perf:{title:`⚡ Performance`,commitType:`perf`},refactor:{title:`🚜 Refactoring`,commitType:`refactor`},docs:{title:`📚 Documentation`,commitType:`docs`},style:{title:`🎨 Style`,commitType:`style`},build:{title:`📦 Build`,commitType:`build`},ci:{title:`🚀 CI`,commitType:`ci`},revert:{title:`♻️ Reverts`,commitType:`revert`},types:{title:`🏷️ Types`,commitType:`types`},deps:{title:`🧩 Dependencies`,commitType:`chore`,filter:e=>!!e.scope?.includes(`deps`)},chore:{title:`🛠️ Chores`,commitType:`chore`},test:{title:`🧪 Tests`,commitType:`test`},misc:{title:`⚙️ Miscellaneous`,commitType:`*`,filter:e=>e.type!==`release`}},l={output:`CHANGELOG.md`,commitRange:`unreleased`,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";const s={bump:!1,changelog:!1,commit:!1,tag:!1,versionSource:`versionSourceFile`,versionSourceFile:`./package.json`,newTagFormat:`v{{version}}`,prevReleaseTagPattern:/^v?(?<version>\d+\.\d+\.\d+)/,zeroMajorBreakingIsMinor:!0,dryRun:!1,logLevel:`info`,context:{commitHyperlink:!0,refHyperlink:!0,footerChangelogUrl:!1},commitsParser:{headerPattern:/^(?<type>\w+)(?:\((?<scope>.+)\))?(?<bang>!)?: (?<subject>.+)/s,breakingChangesPattern:/BREAKING CHANGES?:\s*(?<content>.+)/s,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}},c={breaking:{title:`⚠️ BREAKING CHANGES`,commitType:`breaking`,ignoreLimit:!0},feat:{title:`✨ Features`,commitType:`feat`,ignoreLimit:!0},fix:{title:`🩹 Fixes`,commitType:`fix`,ignoreLimit:!0},perf:{title:`⚡ Performance`,commitType:`perf`,ignoreLimit:!0},revert:{title:`♻️ Reverts`,commitType:`revert`,ignoreLimit:!0},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`}},l={output:`CHANGELOG.md`,commitRange:`unreleased`,sections:c,header:`# Changelog
2
2
 
3
3
 
4
- `,prevReleaseHeaderPattern:/^##.*?\d+\.\d+\.\d+/m,groupCommitsByScope:!0,helpers:{eq:(e,t)=>e===t,repeat:(e,t)=>e.repeat(t),isArray:e=>Array.isArray(e),isBreakingCommitInOtherTypeGroup:(e,t)=>Object.entries(t.data.root.commitTypeGroups).filter(([,{commitType:e}])=>e!==`breaking`).some(([,t])=>t.commits.includes(e)),isSingle:e=>e.length===1,or:(...e)=>e.slice(0,-1).some(Boolean),not:e=>!e},partials:{br:`
5
- `}},u={message:`release({{repo.name}}): {{newTag}}`,signOff:!1,gpgSign:!1,stageAll:!0,extraArgs:null},d={name:`{{newTag}}`,message:`release({{repo.name}}): {{newTag}}`,gpgSign:!1,force:!1,extraArgs:null},f=[{file:/package\.json$/,pattern:/(^.*?"version".*?")(.*?)(")/s,replacement:`$1{{newVersion}}$3`},{file:/package-lock\.json$/,pattern:/(^.*?"version".*?"|"packages".*?"".*"version".*?")(.*?)(")/gs,replacement:`$1{{newVersion}}$3`}],p=e=>{let t=m(e),n=h(t),r=g(n),i=_(r);return S(i)},m=e=>{let t=e.profile;if(!t)return e;let n=e[`_${t}`];if(!n)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`)}},h=e=>{let t=(e,t,n,...r)=>{if(t==null||t===!1)return!1;if(t===!0)return n;if(typeof t!=`object`)throw Error(`Invalid value for ${e}. It should be a boolean or an object.`);let i={...n,...t};return r.forEach(e=>i[e]={...n[e],...t[e]}),i};return{...s,...e,commitsParser:{...s.commitsParser,...e.commitsParser},changelog:t(`changelog`,e.changelog,l,`partials`,`helpers`),commit:t(`commit`,e.commit,u),tag:t(`tag`,e.tag,d)}},g=e=>{let t=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=e=>{if(e===!1)return!1;if(e===!0)return[r];if(Array.isArray(e))return e.map(e=>typeof e==`string`?t(e):e);throw Error(`Invalid value for bump. It should be a boolean or an array.`)},r=typeof e.versionSourceFile==`string`?t(e.versionSourceFile):e.versionSourceFile;return{...e,versionSourceFile:r,bump:n(e.bump),changelog:e.changelog===!1?!1:{...e.changelog,compiledPartials:Q(e.changelog.partials)}}},_=e=>{let t=e.context??{},n=V(e.commitsParser.remoteUrlPattern),r=t.currentVersion??(e.versionSource===`latest-release-tag`?w(W(e.prevReleaseTagPattern)[0],e.prevReleaseTagPattern)??`0.0.0`:C(e.versionSourceFile));q(`Current version (from ${e.versionSource===`latest-release-tag`?`latest release tag`:`'${e.versionSourceFile.file}'`}): '${r}'`);let i=t.currentTag??W(e.prevReleaseTagPattern)[0],a=t.newVersion??T(e,r),o=t.newTag??(e.newTagPrefix===void 0?e.newTagFormat.replace(`{{version}}`,a):e.newTagPrefix+a),s=e.changelog?e.changelog.commitRange:`unreleased`,c=t.commits?t.commits.map(t=>typeof t==`object`&&`message`in t||typeof t==`string`?M(t,e.commitsParser,e.prevReleaseTagPattern):t).filter(e=>e!=null):j(s,e.commitsParser,e.prevReleaseTagPattern),l=v(c,o,e.commitsParser.revertCommitBodyPattern),u=e.changelog?y(l,e.changelog.sections,e.prevReleaseTagPattern,e.changelog.groupCommitsByScope):null,{commits:d,...f}=t;return{...e,context:{currentVersion:r,currentTag:i,newVersion:a,newTag:o,commits:l,releases:u,...f,repo:{...n,...e.context?.repo}}}},v=(e,t,n)=>{let r=0;return e.map(i=>{let a=null,o=e.find(e=>e.type===`revert`&&n.exec(e.body??``)?.groups?.hash===i.hash);return o&&(a=o.associatedReleaseTag===i.associatedReleaseTag?`inTheSameRelease`:`inOtherRelease`),{...i,associatedReleaseTag:i.associatedReleaseTag??t,isReverted:i.isReverted??a,breakingChangeIndex:i.breakingChanges?++r:void 0}})},y=(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:w(t,n),date:e.date,commits:[e]}}),Object.values(i).map(({commits:e,...n})=>({...n,commitTypeGroups:b(e,t,r)})).filter(e=>Object.keys(e.commitTypeGroups).length)},b=(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:x(t.commits)}]):i)},x=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}))},S=e=>({...e,commit:e.commit?{...e.commit,message:Z(e.commit.message,e.context)}:e.commit,tag:e.tag?{...e.tag,name:Z(e.tag.name,e.context),message:Z(e.tag.message,e.context)}:e.tag}),C=e=>{let n=t(e.file,`utf8`),i=e.pattern.exec(n)?.[2];if(!i)throw Error(`Version not found in '${e.file}' with pattern '${e.pattern}'`);if(!r.valid(i))throw Error(`Invalid version format in '${e.file}': '${i}'`);return i},w=(e,t)=>t.exec(e)?.groups?.version,T=(e,t)=>{if(e.context?.newVersion){if(!r.valid(e.context.newVersion))throw Error(`Invalid release version format: '${e.context.newVersion}'`);return e.context.newVersion}let n;if(e.releaseType)n=e.releaseType;else{let i=j(`unreleased`,e.commitsParser,e.prevReleaseTagPattern);n=E(i),e.zeroMajorBreakingIsMinor&&r.major(t)===0&&n===`major`&&(n=`minor`)}let i=D(t,n);return q(`Determined new version: '${i}' (release type: '${n}')`),i},E=e=>e.some(e=>e.breakingChanges)?`major`:e.some(e=>e.type===`feat`)?`minor`:`patch`,D=(e,t)=>r.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)=>{let r=Array.isArray(e)?e:H(e,n),i=t,a=r.map(e=>M(e,i,n)).filter(e=>e!==null);return A=void 0,a},M=(e,t,n)=>{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,p=r?[...r.matchAll(t.tagPattern)].map(e=>e.groups?.tag??``):[],m=f?[...f.matchAll(t.signerPattern)].map(e=>e.groups):[],h=[],g=e=>{h.some(t=>t.email===e.email)||h.push(e)},_=e.authorName&&e.authorEmail?I({name:e.authorName,email:e.authorEmail},m):void 0;_&&g(_);let v=e.committerName&&e.committerEmail?I({name:e.committerName,email:e.committerEmail},m):void 0;v&&g(v),(f?[...f.matchAll(t.coAuthorPattern)].map(e=>e.groups).map(e=>I(e,m)):[]).forEach(e=>g(e));let y=L(f??``,t),b=e.gpgSigCode?{code:e.gpgSigCode,label:O[e.gpgSigCode],keyId:e.gpgSigKeyId}:void 0,x=e[t.dateSource===`committerDate`?`committerTs`:`authorTs`];typeof x==`string`&&(x=R(new Date(x*1e3),t.dateFormat));let S=p.find(e=>n.exec(e)),C=S??A;C&&(A=C);let w={hash:i,type:s,scope:c,subject:l,body:u,breakingChanges:d,footer:f,committer:v,gpgSig:b,date:x,releaseTag:S,associatedReleaseTag:C,tags:p.length?p:void 0,authors:h.length?h:void 0,refs:y.length?y:void 0};return i&&!k.has(i)&&k.set(i,w),w},N=e=>`fake_`+i(`sha256`).update(e,`utf8`).digest(`hex`).slice(0,7),P=(e,t)=>{let[n,...r]=e.split(`
4
+ `,prevReleaseHeaderPattern:/^##.*?\d+\.\d+\.\d+/m,groupCommitsByScope:!0,maxLinesPerRelease:20,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,``)}-`},partials:{br:`
5
+ `,scope:`{{#if scope}}**{{scope}}**: {{/if}}`,commit:`{{{subject}}} {{" "}}
6
+ {{~#if @root.commitHyperlink~}}
7
+ [\`{{hash}}\`]({{@root.repo.homepage}}/commit/{{hash}})
8
+ {{~else~}}
9
+ {{hash}}
10
+ {{~/if~}}
11
+ {{~#if breakingChanges}} ⚠️<sup>[{{breakingChangeIndex}}]</sup>{{/if}}
12
+ {{~#if refs}} {{>refs}}{{/if}}`,compareLink:`{{repo.homepage~}}
13
+ {{#if prevRelease.tag~}}
14
+ /compare/{{prevRelease.tag}}...
15
+ {{~else~}}
16
+ /commits/
17
+ {{~/if}}
18
+ {{~tag}}`,refs:`({{#each refs~}}
19
+ {{#if @root.refHyperlink~}}
20
+ [{{raw}}]({{@root.repo.homepage}}/issues/{{number}})
21
+ {{~else~}}
22
+ {{raw}}
23
+ {{~/if}}
24
+ {{~#if @last}}){{else}}, {{/if}}
25
+ {{~/each}}`,changelogUrl:`{{repo.homepage}}/blob/main/CHANGELOG.md#{{tagToUrlFragment tag}}`,breakingChangesIndicator:`<sup>[{{breakingChangeIndex}}]</sup>`}},u={message:`release({{repo.name}}): {{newTag}}`,signOff:!1,gpgSign:!1,stageAll:!0,extraArgs:null},d={name:`{{newTag}}`,message:`release({{repo.name}}): {{newTag}}`,gpgSign:!1,force:!1,extraArgs:null},f=[{file:/package\.json$/,pattern:/(^.*?"version".*?")(.*?)(")/s,replacement:`$1{{newVersion}}$3`},{file:/package-lock\.json$/,pattern:/(^.*?"version".*?"|"packages".*?"".*"version".*?")(.*?)(")/gs,replacement:`$1{{newVersion}}$3`}],p=e=>{let t=m(e),n=h(t),r=g(n),i=_(r);return S(i)},m=e=>{let t=e.profile;if(!t)return e;let n=e[`_${t}`];if(!n)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`)}},h=e=>{let t=(e,t,n,...r)=>{if(t==null||t===!1)return!1;if(t===!0)return n;if(typeof t!=`object`)throw Error(`Invalid value for ${e}. It should be a boolean or an object.`);let i={...n,...t};return r.forEach(e=>i[e]={...n[e],...t[e]}),i};return{...s,...e,commitsParser:{...s.commitsParser,...e.commitsParser},changelog:t(`changelog`,e.changelog,l,`partials`,`helpers`),commit:t(`commit`,e.commit,u),tag:t(`tag`,e.tag,d),context:{...s.context,...e.context}}},g=e=>{let t=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=e=>{if(e===!1)return!1;if(e===!0)return[r];if(Array.isArray(e))return e.map(e=>typeof e==`string`?t(e):e);throw Error(`Invalid value for bump. It should be a boolean or an array.`)},r=typeof e.versionSourceFile==`string`?t(e.versionSourceFile):e.versionSourceFile;return{...e,versionSourceFile:r,bump:n(e.bump),changelog:e.changelog===!1?!1:{...e.changelog,compiledPartials:Z(e.changelog.partials)}}},_=e=>{let t=e.context??{},n=V(e.commitsParser.remoteUrlPattern),r=t.currentVersion??(e.versionSource===`latest-release-tag`?w(W(e.prevReleaseTagPattern)[0],e.prevReleaseTagPattern)??`0.0.0`:C(e.versionSourceFile));q(`Current version (from ${e.versionSource===`latest-release-tag`?`latest release tag`:`'${e.versionSourceFile.file}'`}): '${r}'`);let i=t.currentTag??W(e.prevReleaseTagPattern)[0],a=t.newVersion??T(e,r),o=t.newTag??(e.newTagPrefix===void 0?e.newTagFormat.replace(`{{version}}`,a):e.newTagPrefix+a),s=e.changelog?e.changelog.commitRange:`unreleased`,c=t.commits?t.commits.map(t=>typeof t==`object`&&`message`in t||typeof t==`string`?M(t,e.commitsParser,e.prevReleaseTagPattern):t).filter(e=>e!=null):j(s,e.commitsParser,e.prevReleaseTagPattern),l=v(c,o,e.commitsParser.revertCommitBodyPattern),u=e.changelog?y(l,e.changelog.sections,e.prevReleaseTagPattern,{withScopeGroups:e.changelog.groupCommitsByScope,maxLinesPerRelease:e.changelog.maxLinesPerRelease}):null,{commits:d,...f}=t;return{...e,context:{currentVersion:r,currentTag:i,newVersion:a,newTag:o,commits:l,releases:u,...f,repo:{...n,...e.context?.repo}}}},v=(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))},y=(e,t,n,r)=>{let i=r?.maxLinesPerRelease??l.maxLinesPerRelease,a={};return e.forEach(e=>{let t=e.associatedReleaseTag;t in a?a[t].commits.push(e):a[t]={tag:t,version:w(t,n),date:e.date,commits:[e]}}),Object.values(a).map(({commits:e,...n})=>{let a=b(e,t,r?.withScopeGroups);if(Object.keys(a).length===0)return;let o=0,s=!1,c={};for(let[e,t]of Object.entries(a))o+t.commits.length>i&&(s=!0),!s||t.ignoreLimit?(c[e]=t,o+=t.commits.length):(t.commits=t.commits.filter(e=>!!e.breakingChanges),t.commits.length&&(t.scopeGroups=x(t.commits),c[e]=t,o+=t.commits.length));return{...n,commitTypeGroups:c}}).filter(e=>!!e)},b=(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:x(t.commits)}]):i)},x=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}))},S=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}),C=e=>{let n=t(e.file,`utf8`),r=e.pattern.exec(n)?.[2];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},w=(e,t)=>t.exec(e)?.groups?.version,T=(e,t)=>{if(e.context?.newVersion){if(!i.valid(e.context.newVersion))throw Error(`Invalid release version format: '${e.context.newVersion}'`);return e.context.newVersion}let n;if(e.releaseType)n=e.releaseType;else{let r=j(`unreleased`,e.commitsParser,e.prevReleaseTagPattern);n=E(r),e.zeroMajorBreakingIsMinor&&i.major(t)===0&&n===`major`&&(n=`minor`)}let r=D(t,n);return q(`Determined new version: '${r}' (release type: '${n}')`),r},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)=>{n??=s.prevReleaseTagPattern;let r=Array.isArray(e)?e:H(e,n),i=t??s.commitsParser,a=r.map(e=>M(e,i,n)).filter(e=>e!==null);return A=void 0,a},M=(e,t,n)=>{t??=s.commitsParser,n??=s.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:c,scope:l,subject:u,body:d,breakingChanges:f,footer:p}=o,m=r?[...r.matchAll(t.tagPattern)].map(e=>e.groups?.tag??``):[],h=p?[...p.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),(p?[...p.matchAll(t.coAuthorPattern)].map(e=>e.groups).map(e=>I(e,h)):[]).forEach(e=>_(e));let b=L(p??``,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:c,scope:l,subject:u,body:d,breakingChanges:f,footer:p,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(`
6
26
 
7
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(`
8
28
 
@@ -10,34 +30,9 @@ import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import
10
30
 
11
31
  `),r.slice(d).join(`
12
32
 
13
- `)];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=>e.groups).filter(e=>!!e.number).map(t=>({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=a(`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:o}=n.groups,s=`https://${r}/${i}/${o}`;return{host:r,owner:i,name:o,homepage:s}},H=(e,t)=>{let n=U(),r=W(t),i=``,o=``,s=``;if(e===`all`)i=`{{firstCommit}}`,o=`HEAD`;else if(e===`unreleased`)i=r[0]??`{{firstCommit}}`,o=`HEAD`;else if(e===`latest-release`)i=r[1]??`{{firstCommit}}`,o=r[0]??`HEAD`;else if(typeof e==`object`){let t=r.indexOf(e.releaseTag);if(t===-1)throw Error(`Release tag '${e.releaseTag}' not found`);i=r[t+1]??`{{firstCommit}}`,o=r[t]}else s=e;return i&&o&&(s=i===`{{firstCommit}}`?`"${i}^!" ${o}`:`"${i}..${o}"`),s=s.replace(`{{firstCommit}}`,n),[...a(`git log ${s} --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"`,{encoding:`utf8`}).matchAll(z)].map(e=>e.groups)},U=()=>a(`git rev-list --max-parents=0 HEAD`,{encoding:`utf8`}).trim(),W=e=>{let t=e.toString();if(B.has(t))return B.get(t)??[];let n=a(`git tag --sort=-creatordate`,{encoding:`utf8`}).split(`
14
- `).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)))}};var X=`{{#*inline "compareLink"~}}
15
- {{repo.homepage~}}
16
- {{#if prevRelease.tag~}}
17
- /compare/{{prevRelease.tag}}...
18
- {{~else~}}
19
- /commits/
20
- {{~/if}}
21
- {{~tag}}
22
- {{~/inline}}
23
-
24
- {{~#*inline "commit"~}}
25
- {{{subject}}} {{" "}}
26
- {{~#if @root.commitHyperlink~}}
27
- [\`{{hash}}\`]({{@root.repo.homepage}}/commit/{{hash}})
28
- {{~else~}}
29
- {{hash}}
30
- {{~/if~}}
31
- {{~#if breakingChanges}} ⚠️<sup>[{{breakingChangeIndex}}]</sup>{{/if}}
32
- {{~/inline}}
33
-
34
- {{~#*inline "scope"~}}
35
- {{#if scope}}**{{scope}}**: {{/if}}
36
- {{~/inline}}
37
-
38
- {{~#>header~}}
39
- ## &ensp; [\` 📦 {{tag}} \`]({{>compareLink}})
40
-
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,s=`https://${r}/${i}/${a}`;return{host:r,owner:i,name:a,homepage:s}},H=(e,t)=>{let n=U(),r=W(t),i=``,a=``,s=``;if(e===`all`)i=`{{firstCommit}}`,a=`HEAD`;else if(e===`unreleased`)i=r[0]??`{{firstCommit}}`,a=`HEAD`;else if(e===`latest-release`)i=r[1]??`{{firstCommit}}`,a=r[0]??`HEAD`;else if(typeof e==`object`){let t=r.indexOf(e.releaseTag);if(t===-1)throw Error(`Release tag '${e.releaseTag}' not found`);i=r[t+1]??`{{firstCommit}}`,a=r[t]}else s=e;return i&&a&&(s=i===`{{firstCommit}}`?`"${i}^!" ${a}`:`"${i}..${a}"`),s=s.replace(`{{firstCommit}}`,n),[...o(`git log ${s} --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"`,{encoding:`utf8`}).matchAll(z)].map(e=>e.groups)},U=()=>o(`git rev-list --max-parents=0 HEAD`,{encoding:`utf8`}).trim(),W=e=>{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~}}
35
+ ## &ensp; [\` 📦 {{tag}} \`]({{>compareLink}}){{>br}}
41
36
  {{/header}}
42
37
 
43
38
  {{~#>main~}}
@@ -47,10 +42,10 @@ import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import
47
42
  {{#each commits}}
48
43
  {{#if (isArray breakingChanges)}}
49
44
  {{~#each breakingChanges~}}
50
- - {{{this}}} {{#if (isBreakingCommitInOtherTypeGroup ../this)}}<sup>[{{../breakingChangeIndex}}]</sup>{{/if}}
45
+ - {{{this}}} {{>breakingChangesIndicator ../this}}
51
46
  {{/each}}
52
47
  {{else~}}
53
- - {{{breakingChanges}}} {{#if (isBreakingCommitInOtherTypeGroup this)}}<sup>[{{breakingChangeIndex}}]</sup>{{/if}}
48
+ - {{{breakingChanges}}} {{>breakingChangesIndicator}}
54
49
  {{/if}}
55
50
  {{/each}}
56
51
  {{else}}
@@ -77,7 +72,5 @@ import{existsSync as e,readFileSync as t,writeFileSync as n}from"node:fs";import
77
72
  {{/main}}
78
73
 
79
74
  {{~#>footer~}}
80
- ##### &emsp;&ensp;&nbsp;&nbsp; [_All Release Commits_]({{>compareLink}}) &ensp;•&ensp; _{{date}}_
81
-
82
-
83
- {{/footer}}`;const Z=(e,t)=>o.compile(e)(t),Q=e=>{let t=Object.fromEntries(Object.entries(e).map(([e,t])=>[e,typeof t==`function`?$(e,t):t]));return Object.fromEntries(Object.entries(t).map(([e,t])=>[e,o.compile(t)]))},$=(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)},ee=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}'`)})},te=e=>{if(!e.changelog)return null;let t=e.changelog,n=e.context.releases;if(!n)return null;let r=W(e.prevReleaseTagPattern);o.registerPartial(t.compiledPartials),o.registerHelper(t.helpers);let i=t.header;return n.forEach((t,a)=>{let o=n[a+1];if(!o){let n=r.indexOf(t.tag);if(n!==-1){let t=r[n+1];o={tag:t,version:t&&w(t,e.prevReleaseTagPattern)}}else o={tag:e.context.currentTag,version:e.context.currentVersion}}let s={...t,...e.context,prevRelease:o},c=Z(X,s);i+=c}),t.output===`stdout`||e.dryRun?(q(`Generated changelog:`),console.log(i)):(q(`Writing changelog to file '${t.output}'`),ne(t.output,i,t.prevReleaseHeaderPattern)),i},ne=(r,i,a)=>{let o=e(r)?t(r,{encoding:`utf8`}):``,s=o.search(a),c=o.slice(s),l=i+c;n(r,l,{encoding:`utf8`})},re=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||a(n,{stdio:`inherit`}),n},ie=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||a(n,{stdio:`inherit`}),n};function ae(e){K((e.logLevel??(!!e.profile&&e[`_${e.profile}`]?.logLevel))||`info`);let t=p(e);ee(t);let n=te(t),r=re(t),i=ie(t);return{resolvedConfig:t,generatedChangelog:n,commitCommand:r,tagCommand:i}}const oe=e=>e;export{Y as changelogSectionsSelector,ae as default,oe as defineConfig};
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=>{let t=Object.fromEntries(Object.entries(e).map(([e,t])=>[e,typeof t==`function`?Q(e,t):t]));return Object.fromEntries(Object.entries(t).map(([e,t])=>[e,r.compile(t)]))},Q=(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)},$=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}'`)})},ee=e=>{if(!e.changelog)return null;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&&w(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}),t.output===`stdout`||e.dryRun?(q(`Generated changelog:`),console.log(o)):(q(`Writing changelog to file '${t.output}'`),te(t.output,o,t.prevReleaseHeaderPattern)),o},te=(r,i,a)=>{let o=e(r)?t(r,{encoding:`utf8`}):``,s=o.search(a),c=o.slice(s),l=i+c;n(r,l,{encoding:`utf8`})},ne=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},re=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};function ie(e){K((e.logLevel??(!!e.profile&&e[`_${e.profile}`]?.logLevel))||`info`);let t=p(e);$(t);let n=ee(t),r=ne(t),i=re(t);return{resolvedConfig:t,generatedChangelog:n,commitCommand:r,tagCommand:i}}const ae=e=>e;export{ie as default,ae as defineConfig,Y as sectionsSelector};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relion",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Release workflow helper for Node.js projects.",
5
5
  "author": "Kh4f <kh4f.dev@gmail.com>",
6
6
  "license": "MIT",
@@ -38,16 +38,16 @@
38
38
  "devDependencies": {
39
39
  "@eslint/js": "^9.36.0",
40
40
  "@stylistic/eslint-plugin": "^5.4.0",
41
- "@types/node": "^24.5.2",
41
+ "@types/node": "^24.6.1",
42
42
  "@types/semver": "^7.7.1",
43
43
  "eslint": "^9.36.0",
44
44
  "globals": "^16.4.0",
45
45
  "lint-staged": "^16.2.3",
46
46
  "simple-git-hooks": "^2.13.1",
47
- "tsdown": "^0.15.5",
47
+ "tsdown": "^0.15.6",
48
48
  "tsx": "^4.20.6",
49
- "typescript": "^5.9.2",
50
- "typescript-eslint": "^8.44.1",
49
+ "typescript": "^5.9.3",
50
+ "typescript-eslint": "^8.45.0",
51
51
  "vitest": "^3.2.4"
52
52
  },
53
53
  "simple-git-hooks": {
@@ -65,7 +65,7 @@
65
65
  "test": "vitest run",
66
66
  "test:watch": "vitest",
67
67
  "release": "pnpm relion",
68
- "release:github": "pnpm relion --profile github --latest",
68
+ "release:github": "pnpm relion --profile github",
69
69
  "relion": "tsx scripts/relion-runner"
70
70
  }
71
71
  }