@jeromefitz/release-notes-generator 4.0.3 → 4.1.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/index.d.mts CHANGED
@@ -1,5 +1,117 @@
1
+ import { CommitNote, CommitReference } from "conventional-commits-parser";
2
+
3
+ //#region src/types.d.ts
4
+ interface TypeSpec {
5
+ code: string;
6
+ description: string;
7
+ emoji: string;
8
+ semver: 'breaking' | 'feature' | 'fix' | 'major' | 'minor' | 'patch' | null;
9
+ type: string;
10
+ value: string;
11
+ }
12
+ type ParsedCommit = {
13
+ author?: {
14
+ email: string;
15
+ name: string;
16
+ };
17
+ body: string | null;
18
+ committerDate?: string;
19
+ footer: string | null;
20
+ hash?: string;
21
+ header: string | null;
22
+ mentions: string[];
23
+ merge: string | null;
24
+ message: string;
25
+ notes: CommitNote[];
26
+ references: CommitReference[];
27
+ revert?: Record<string, string> | null;
28
+ scope: string | null;
29
+ subject: string | null;
30
+ type: string | null;
31
+ } & Record<string, unknown>;
32
+ type TransformedCommit = ParsedCommit & {
33
+ hash: string;
34
+ raw?: ParsedCommit;
35
+ type: string;
36
+ typeSpec: TypeSpec;
37
+ typeSpecIndex: number;
38
+ };
39
+ interface PluginConfig {
40
+ commit?: string;
41
+ config?: string;
42
+ host?: string;
43
+ issue?: string;
44
+ linkCompare?: boolean;
45
+ linkReferences?: boolean;
46
+ }
47
+ interface SRCommit {
48
+ author?: {
49
+ email: string;
50
+ name: string;
51
+ };
52
+ committerDate?: string;
53
+ hash?: string;
54
+ message: string;
55
+ revert?: Record<string, string> | null;
56
+ }
57
+ interface SRRelease {
58
+ gitHead: string;
59
+ gitTag: string;
60
+ }
61
+ interface SROptions {
62
+ contributorsProhibitList?: {
63
+ email: string[];
64
+ login: string[];
65
+ };
66
+ repositoryUrl: string;
67
+ }
68
+ interface SRContext {
69
+ commits: SRCommit[];
70
+ cwd: string;
71
+ lastRelease: SRRelease;
72
+ nextRelease: SRRelease & {
73
+ version: string;
74
+ };
75
+ options: SROptions;
76
+ }
77
+ interface CommitGroup {
78
+ commits: TransformedCommit[];
79
+ order: number;
80
+ title: false | string;
81
+ }
82
+ interface Note extends CommitNote {
83
+ commit?: TransformedCommit;
84
+ scope?: string;
85
+ }
86
+ interface NoteGroup {
87
+ notes: Note[];
88
+ title: string;
89
+ }
90
+ interface RenderMeta {
91
+ repositoryUrl: string;
92
+ }
93
+ interface MarkdownContext {
94
+ commit: string;
95
+ commitGroups: CommitGroup[];
96
+ currentTag: string;
97
+ date?: string;
98
+ host: string;
99
+ isPatch?: boolean;
100
+ issue: string;
101
+ linkCompare: boolean;
102
+ linkReferences?: boolean;
103
+ noteGroups: NoteGroup[];
104
+ options?: SROptions;
105
+ owner: string;
106
+ packageData?: unknown;
107
+ previousTag: string;
108
+ repository: string;
109
+ title?: string;
110
+ version: string;
111
+ }
112
+ //#endregion
1
113
  //#region src/index.d.ts
2
- declare function generateNotes(pluginConfig: any, context: any): Promise<string | false>;
114
+ declare function generateNotes(pluginConfig: PluginConfig, context: SRContext): Promise<string>;
3
115
  //#endregion
4
116
  export { generateNotes };
5
117
  //# sourceMappingURL=index.d.mts.map
package/index.d.mts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";iBAgCe,aAAA,CAAc,YAAA,OAAc,OAAA,QAAO,OAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/index.ts"],"mappings":";;;UAEU,QAAA;EACR,IAAA;EACA,WAAA;EACA,KAAA;EACA,MAAA;EACA,IAAA;EACA,KAAA;AAAA;AAAA,KAGG,YAAA;EACH,MAAA;IAAW,KAAA;IAAe,IAAA;EAAA;EAC1B,IAAA;EACA,aAAA;EACA,MAAA;EACA,IAAA;EACA,MAAA;EACA,QAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA,EAAO,UAAA;EACP,UAAA,EAAY,eAAA;EACZ,MAAA,GAAS,MAAA;EACT,KAAA;EACA,OAAA;EACA,IAAA;AAAA,IACE,MAAA;AAAA,KAEC,iBAAA,GAAoB,YAAA;EACvB,IAAA;EACA,GAAA,GAAM,YAAA;EACN,IAAA;EACA,QAAA,EAAU,QAAA;EACV,aAAA;AAAA;AAAA,UAGQ,YAAA;EACR,MAAA;EACA,MAAA;EACA,IAAA;EACA,KAAA;EACA,WAAA;EACA,cAAA;AAAA;AAAA,UAGQ,QAAA;EACR,MAAA;IAAW,KAAA;IAAe,IAAA;EAAA;EAC1B,aAAA;EACA,IAAA;EACA,OAAA;EACA,MAAA,GAAS,MAAM;AAAA;AAAA,UAGP,SAAA;EACR,OAAA;EACA,MAAM;AAAA;AAAA,UAGE,SAAA;EACR,wBAAA;IAA6B,KAAA;IAAiB,KAAA;EAAA;EAC9C,aAAA;AAAA;AAAA,UAGQ,SAAA;EACR,OAAA,EAAS,QAAA;EACT,GAAA;EACA,WAAA,EAAa,SAAA;EACb,WAAA,EAAa,SAAA;IAAc,OAAA;EAAA;EAC3B,OAAA,EAAS,SAAA;AAAA;AAAA,UAGD,WAAA;EACR,OAAA,EAAS,iBAAiB;EAC1B,KAAA;EACA,KAAA;AAAA;AAAA,UAGQ,IAAA,SAAa,UAAU;EAC/B,MAAA,GAAS,iBAAA;EACT,KAAA;AAAA;AAAA,UAGQ,SAAA;EACR,KAAA,EAAO,IAAI;EACX,KAAA;AAAA;AAAA,UAGQ,UAAA;EACR,aAAa;AAAA;AAAA,UAGL,eAAA;EACR,MAAA;EACA,YAAA,EAAc,WAAA;EACd,UAAA;EACA,IAAA;EACA,IAAA;EACA,OAAA;EACA,KAAA;EACA,WAAA;EACA,cAAA;EACA,UAAA,EAAY,SAAA;EACZ,OAAA,GAAU,SAAA;EACV,KAAA;EACA,WAAA;EACA,WAAA;EACA,UAAA;EACA,KAAA;EACA,OAAA;AAAA;;;iBClCa,aAAA,CACb,YAAA,EAAc,YAAA,EACd,OAAA,EAAS,SAAA,GACR,OAAA"}
package/index.mjs CHANGED
@@ -1,16 +1,16 @@
1
- import{URL as e,fileURLToPath as t,format as n}from"node:url";import{filterRevertedCommitsSync as r}from"conventional-commits-filter";import{CommitParser as i}from"conventional-commits-parser";import{clone as a,cloneDeep as o,findIndex as s,forEach as c,get as l,groupBy as u,isFunction as d,isPlainObject as f,map as p,merge as m,orderBy as h,sample as g,set as _,size as v,uniqBy as y}from"lodash-es";import{readPackageUp as b}from"read-package-up";import{patch as x,valid as S}from"semver";import{dirname as C}from"node:path";import{promisify as w}from"node:util";import T from"import-from-esm";import{Octokit as E}from"@octokit/rest";import{format as D}from"date-fns";function O(e,t,n,r){let i=[];return c(u(t,t=>t[e]||``),(e,t)=>{t===``&&(t=!1);let n=e;r&&(n=h(n,r));let a=n[0].typeSpec.semver,o=99;[`fix`,`patch`].includes(a)&&(o=20),[`feature`,`minor`].includes(a)&&(o=10),[`breaking`,`major`].includes(a)&&(o=0),i.push({commits:n,order:o,title:t})}),n&&(i=h(i,n)),i}function k(e,t,n){let r=[];return c(e,e=>{let t=e.title,n=!1;c(r,r=>{if(r.title===t)return n=!0,r.notes.push(e),!1}),n||r.push({notes:[e],title:t})}),r}function A(e,t,n){let r={};return r.commitGroups=O(n.groupBy,e,n.commitGroupsSort,n.commitsSort),r.noteGroups=k(t,n.noteGroupsSort,n.notesSort),r}function j(e,t,n,i){let o=[],s;if(e.ignoreReverted)for(let e of r(t))s.push(e);else s=a(t);return c(s,e=>{p(e.notes,t=>(t.commit=e,t)),o=o.concat(e.notes)}),n=m({},n,i,A(s,o,e)),i?.committerDate&&(n.date=i.committerDate),n.version&&S(n.version)&&(n.isPatch=n.isPatch||x(n.version)!==0),n={commits:t,context:n,filteredCommits:s,keyCommit:i,options:e},n}const M=C(t(import.meta.url)),N=async(e,t)=>{let{config:n,parserOpts:r,preset:i,presetConfig:a,writerOpts:o}=e,{cwd:s}=t,c;if(i){let e=`conventional-changelog-${i.toLowerCase()}`;c=await(await T.silent(M,e)||await T(s,e))(a)}else c=n?await(await T.silent(M,n)||await T(s,n))():{};return c=await(typeof c==`function`?f(a)?c(a):w(c)():c),{parserOpts:{...c.parserOpts,...r},writerOpts:{...c.writerOpts,...o}}},P=(e,t,n)=>{let{commit:r,commitGroups:i,linkReferences:a}=e,{repositoryUrl:o}=n,s=``,c=e=>e?a?` [ \`${e}\` ](${` ${o}/${r}/${e}`})`:` ${e}`:``,l=e=>{if(!e||v(e)===0)return``;let t=`, closes `,n=[];return e.map(e=>{e.issue&&n.push(`[ #${e.issue} ]`)}),t+=n.join(` `),t};return i.map(e=>{let n=e?.commits[0]?.typeSpec?.type;s+=`#### ${e?.commits[0]?.type}\n`,t.map(e=>{let{hash:t,header:r,references:i,scope:a,subject:o}=e;if(n===e.typeSpec.type){let e=`- {scope}{subject}{hash}{references}
2
- `.replace(/\{scope\}/g,a?`**${a}**: `:``).replace(/\{subject\}/g,o||r).replace(/\{hash\}/g,c(t)).replace(/\{references\}/g,l(i));s+=e}}),s+=`
3
- `}),s},F=new E({auth:process.env.GH_TOKEN}),I={email:[`noreply@github.com`,`users.noreply.github.com`,`semantic-release-bot@martynus.net`],login:[`dependabot`,`dependabot[bot]`,`kodiakhq`,`kodiakhq[bot]`,`renovate`,`renovate[bot]`,`semantic-release-bot`]},L=[`Props to`,`Kudos to`,`Thanks to`,`Brought to you by`],R=async(e,t,n)=>{let r=y(t.map(e=>({email:e.author.email,name:e.author.name})),`name`),{options:{contributorsProhibitList:i}}=e;await Promise.all(r.map((e,t)=>F.request(`GET /search/users`,{q:e.email}).then(({data:e})=>{let n=e.items[0]?.login;return n?(r[t].login=n,n):``}))),[...I.login,...i.login].map(e=>{let t=s(r,[`login`,e]);t!==-1&&r.splice(t)}),[...I.email,...i.email].map(e=>{let t=s(r,t=>t.email.includes(e));t!==-1&&r.splice(t)});let a=``;if(r.length>0){a+=`#### 🥳️ Contributors
4
- `;let e=r.map(e=>`@${e.login}`).join(`, `);a+=`- ${g(L)} ${e}\n`,a+=`
5
- `}return a},z=(e,t,n)=>{let{noteGroups:r}=e,i=``;return r.map(e=>{let{notes:t}=e,n=t[0].title;i+=`#### ${n}\n`,t.map(e=>{let{scope:t,text:n}=e,r=`- {scope}{text}
6
- `.replace(/\{scope\}/g,t?`**${t}**: `:``).replace(/\{text\}/g,n||``);i+=r}),i+=`
7
- `}),i},B=(e,t,n)=>{let{currentTag:r,date:i,linkCompare:a,previousTag:o,title:s}=e,{repositoryUrl:c}=n,l=`
1
+ import{URL as e,format as t}from"node:url";import{parserOpts as n,writerOpts as r}from"@jeromefitz/conventional-gitmoji";import{filterRevertedCommitsSync as i}from"conventional-commits-filter";import{CommitParser as a}from"conventional-commits-parser";import{readPackageUp as o}from"read-package-up";import{patch as s,valid as c}from"semver";import{Octokit as l}from"@octokit/rest";import{format as u}from"date-fns";import{get as d,set as f}from"lodash-es";function p(e){return(t,n)=>{let r=t,i=n;for(let t of e){let e=r[t]??0,n=i[t]??0;if(e<n)return-1;if(e>n)return 1}return 0}}function m(e){return e&&[`breaking`,`major`].includes(e)?0:e&&[`feature`,`minor`].includes(e)?10:e&&[`fix`,`patch`].includes(e)?20:99}function h(e,t,n){let r=n.length>0?[...t??[]].sort(p(n)):[...t??[]];return{commits:r,order:m(r[0]?.typeSpec?.semver),title:e===``?!1:e}}function g(e,t,n,r){let i=Object.groupBy(t,t=>t[e]??``),a=Object.entries(i).map(([e,t])=>h(e,t,r));return n.length>0?a.sort(p(n)):a}const _=(e,t,n)=>{let{commit:r,commitGroups:i,linkReferences:a}=e,{repositoryUrl:o}=n,s=e=>e?a?` [ \`${e}\` ](${o}/${r}/${e})`:` ${e}`:``,c=e=>{if(e.length===0)return``;let t=e.filter(e=>e.issue).map(e=>`[ #${e.issue} ]`);return t.length>0?`, closes ${t.join(` `)}`:``},l=``;for(let e of i){let n=e.commits[0]?.typeSpec?.type;l+=`#### ${e.commits[0]?.type}\n`;for(let e of t){if(n!==e.typeSpec?.type)continue;let{hash:t,header:r,references:i=[],scope:a,subject:o}=e;l+=`- {scope}{subject}{hash}{references}
2
+ `.replace(/\{scope\}/g,a?`**${a}**: `:``).replace(/\{subject\}/g,o??r??``).replace(/\{hash\}/g,s(t)).replace(/\{references\}/g,c(i))}l+=`
3
+ `}return l},v=new l({auth:process.env.GH_TOKEN}),y={email:[`noreply@github.com`,`users.noreply.github.com`,`semantic-release-bot@martynus.net`],login:[`dependabot`,`dependabot[bot]`,`kodiakhq`,`kodiakhq[bot]`,`renovate`,`renovate[bot]`,`semantic-release-bot`]},b=[`Props to`,`Kudos to`,`Thanks to`,`Brought to you by`],x=e=>e[Math.floor(Math.random()*e.length)],S=e=>{let t=new Map;for(let n of e)t.has(n.name)||t.set(n.name,n);return[...t.values()]},C=async(e,t,n)=>{let r=S(t.map(e=>({email:e.author?.email??``,name:e.author?.name??``})));await Promise.all(r.map((e,t)=>v.request(`GET /search/users`,{q:e.email}).then(({data:e})=>{let n=e.items[0]?.login;n&&(r[t].login=n)})));let i=e.options?.contributorsProhibitList??{email:[],login:[]},a=[...y.login,...i.login];for(let e of a){let t=r.findIndex(t=>t.login===e);t!==-1&&r.splice(t,1)}let o=[...y.email,...i.email];for(let e of o){let t=r.findIndex(t=>t.email.includes(e));t!==-1&&r.splice(t,1)}if(r.length===0)return``;let s=r.map(e=>`@${e.login}`).join(`, `),c=`#### 🥳️ Contributors
4
+ `;return c+=`- ${x(b)} ${s}\n`,c+=`
5
+ `,c},w=(e,t,n)=>{let{noteGroups:r}=e,i=``;for(let e of r){let{notes:t}=e;i+=`#### ${t[0].title}\n`;for(let e of t){let{scope:t,text:n}=e;i+=`- {scope}{text}
6
+ `.replace(/\{scope\}/g,t?`**${t}**: `:``).replace(/\{text\}/g,n??``)}i+=`
7
+ `}return i},T=(e,t,n)=>{let{currentTag:r,date:i,linkCompare:a,previousTag:o,title:s}=e,{repositoryUrl:c}=n,l=`
8
8
  | 🔖️ | Release Information |
9
9
  | ----------- | --------------- |
10
- | Current | **\`${r}\`** |\n`;if(a){let e=c+`/compare/`+o+`...`+r;l+=`| Previous | **[\`${o}\`](${e})** |\n`}return s&&(l+=`| Title | **\`${s}\`** |\n`),i&&(l+=`| Date | **\`${D(i,`yyyy-MM-dd`)}\`** |\n`),l+=`
11
- `,l},V=async(e,t)=>{let{commitGroups:n,currentTag:r,date:i,host:a,issue:o,lastRelease:s,linkCompare:c,linkReferences:l,mentions:u,nextRelease:d,noteGroups:f,notes:p,options:m,owner:h,previousTag:g,references:_,repository:v,repoUrl:y,revert:b,version:x}=e,S={commitGroups:n,currentTag:r,date:i,host:a,issue:o,lastRelease:s,linkCompare:c,linkReferences:l,mentions:u,nextRelease:d,noteGroups:f,notes:p,options:m,owner:h,previousTag:g,references:_,repository:v,repoUrl:y,revert:b,version:x},C={repositoryUrl:v?a+`/`+h+`/`+v:y},w=``;return w+=B(S,t,C),w+=`
12
- `,w+=P(S,t,C),w+=`
13
- `,w+=await R(S,t,C),w+=`
14
- `,w+=z(S,t,C),w+=`
15
- `,w};function H(e,t,n){let r;try{e=JSON.parse(e)}catch{}return r=o(e),d(t)?(r=t(r,n),r&&(r.raw=e),r):(c(t,(e,t)=>{let n=l(r,t);n=d(e)?e(n,t):e,_(r,t,n)}),r.raw=e,r)}const U={commit:`commit`,hostname:`github.com`,issue:`issues`,issuePrefixes:[`#`,`gh-`],referenceActions:[`close`,`closes`,`closed`,`fix`,`fixes`,`fixed`,`resolve`,`resolves`,`resolved`]};async function W(t,a){let{parserOpts:o,writerOpts:s}=await N(t,a),{commits:c,cwd:l,lastRelease:u,nextRelease:d,options:f}=a,{commit:p,issue:h,issuePrefixes:g,referenceActions:_}=U,v=u.gitTag||u.gitHead,y=d.gitTag||d.gitHead,{commit:x,host:S,issue:C,linkCompare:w,linkReferences:T}=t,E=f.repositoryUrl.replace(/\.git$/i,``),[D,O,k,A]=/^(?!.+:\/\/)(?:(?<auth>.*)@)?(?<host>.*?):(?<path>.*)$/.exec(E)||[],{hostname:M,pathname:P,port:F,protocol:I}=new e(D?`ssh://${O?`${O}@`:``}${k}/${A}`:E);F=I.includes(`ssh`)?``:F,I=I&&/http[^s]/.test(I)?`http`:`https`;let[,L,R]=/^\/(?<owner>[^/]+)?\/?(?<repository>.+)?$/.exec(P)??[],z=m({commit:p,currentTag:y,host:n({hostname:M,port:F,protocol:I}),issue:h,linkCompare:y&&v,owner:L,packageData:(await b({cwd:l,normalize:!1}))?.packageJson,previousTag:v,repository:R,version:d.version},{commit:x,host:S,issue:C,linkCompare:w,linkReferences:T}),B=[],W=new i({issuePrefixes:g,referenceActions:_,...o});for(let e of r(c)){let t=e;if(!t?.message.trim())return!1;let n={...t,...W.parse(t?.message)};B.push(n)}let G=[];await B.map(async e=>{let t=await H(e,s.transform,a);G.push(t)}),G=await G.filter(e=>e!==void 0);let K=m({},z,f,s),q=G[0],J=H(q,s.transform,a)||q,{context:Y}=await j(K,G,a,J);return V(m({},z,Y),G)}export{W as generateNotes};
10
+ | Current | **\`${r}\`** |\n`;if(a){let e=`${c}/compare/${o}...${r}`;l+=`| Previous | **[\`${o}\`](${e})** |\n`}return s&&(l+=`| Title | **\`${s}\`** |\n`),i&&(l+=`| Date | **\`${u(i,`yyyy-MM-dd`)}\`** |\n`),l+=`
11
+ `,l},E=async(e,t)=>{let n={repositoryUrl:e.repository?`${e.host}/${e.owner}/${e.repository}`:``},r=T(e,t,n);return r+=`
12
+ `,r+=_(e,t,n),r+=`
13
+ `,r+=await C(e,t,n),r+=`
14
+ `,r+=w(e,t,n),r+=`
15
+ `,r};function D(e){let t=new Map;for(let n of e){let e=t.get(n.title);e?e.notes.push(n):t.set(n.title,{notes:[n],title:n.title})}return[...t.values()]}function O(e,t,n){let r=structuredClone(e);if(typeof t==`function`){let i=t(r,n);return i&&(i.raw=e),i}for(let[e,n]of Object.entries(t)){let t=d(r,e);t=typeof n==`function`?n(t,e):n,f(r,e,t)}return r.raw=e,r}function k(t){let n=t.replace(/\.git$/i,``),[r,i,a,o]=/^(?!.+:\/\/)(?:(?<auth>.*)@)?(?<host>.*?):(?<path>.*)$/.exec(n)??[],{hostname:s,pathname:c,port:l,protocol:u}=new e(r?`ssh://${i?`${i}@`:``}${a}/${o}`:n);l=u.includes(`ssh`)?``:l,u=/http[^s]/.test(u)?`http`:`https`;let[,d=``,f=``]=/^\/(?<owner>[^/]+)?\/?(?<repository>.+)?$/.exec(c)??[];return{hostname:s,owner:d,port:l,protocol:u,repository:f}}function A(e,t,n){let a=[];for(let o of i(e)){if(!o.message?.trim())continue;let e=O({...o,...t.parse(o.message),message:o.message},r.transform,n);e&&a.push(e)}return a}function j(e){let t=[];for(let n of e)for(let e of n.notes)t.push({...e,commit:n});return t}async function M(e,i){let{commits:l,cwd:u,lastRelease:d,nextRelease:f,options:p}=i,m=d.gitTag||d.gitHead,h=f.gitTag||f.gitHead,{hostname:_,owner:v,port:y,protocol:b,repository:x}=k(p.repositoryUrl),S=A(l,new a(n),i),C=j(S),w=f.version,T=(await o({cwd:u,normalize:!1}))?.packageJson;return E({commit:e.commit??`commit`,commitGroups:g(r.groupBy,S,r.commitGroupsSort,r.commitsSort),currentTag:h,date:S[0]?.committerDate,host:t({hostname:_,port:y,protocol:b}),isPatch:c(w)?(s(w)??0)!==0:void 0,issue:e.issue??`issues`,linkCompare:e.linkCompare??!!(h&&m),linkReferences:e.linkReferences,noteGroups:D(C),options:p,owner:v,packageData:T,previousTag:m,repository:x,version:w},S)}export{M as generateNotes};
16
16
  //# sourceMappingURL=index.mjs.map
package/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["_groupBy","groupBy","_orderBy","_clone","_merge","semverValid","semverPatch","_isPlainObject","_size","_uniqBy","_findIndex","_sample","_format","_cloneDeep","_isFunction","_get","_merge"],"sources":["../src/utils/getCommitGroups.ts","../src/utils/getNoteGroups.ts","../src/utils/getExtraContent.ts","../src/utils/generate.ts","../src/utils/getChangelogConfig.ts","../src/templates/commit.ts","../src/templates/contributor.ts","../src/templates/footer.ts","../src/templates/header.ts","../src/utils/getMarkdown.ts","../src/utils/processCommit.ts","../src/index.ts"],"sourcesContent":["import {\n forEach as _forEach,\n groupBy as _groupBy,\n orderBy as _orderBy,\n} from 'lodash-es'\n\nfunction getCommitGroups(groupBy, commits, commitGroupsSort, commitsSort) {\n let commitGroups: any = []\n\n const commitGroupsObj = _groupBy(commits, (commit) => commit[groupBy] || '')\n\n _forEach(commitGroupsObj, (commits, title: boolean | string) => {\n if (title === '') {\n title = false\n }\n\n let commitsSorted: any = commits\n\n if (commitsSort) {\n commitsSorted = _orderBy(commitsSorted, commitsSort)\n }\n\n const semver = commitsSorted[0].typeSpec.semver\n\n let order = 99\n if (['fix', 'patch'].includes(semver)) {\n order = 20\n }\n if (['feature', 'minor'].includes(semver)) {\n order = 10\n }\n if (['breaking', 'major'].includes(semver)) {\n order = 0\n }\n\n commitGroups.push({\n commits: commitsSorted,\n order,\n title: title,\n })\n })\n\n if (commitGroupsSort) {\n commitGroups = _orderBy(commitGroups, commitGroupsSort)\n // // @todo(#744) analytics -vs- deps-dev\n // console.dir(`>> commitGroupsSort`)\n // console.dir(commitGroups)\n }\n\n return commitGroups\n}\n\nexport default getCommitGroups\n","import { forEach as _forEach } from 'lodash-es'\n\nfunction getNoteGroups(notes, _noteGroupsSort, _notesSort) {\n const noteGroups: any = []\n\n // console.dir(`> getNoteGroups`)\n // console.dir(notes)\n _forEach(notes, (note) => {\n // console.dir(`> _forEach`)\n // console.dir(note)\n const title = note.title\n let titleExists = false\n\n _forEach(noteGroups, (group) => {\n if (group.title === title) {\n titleExists = true\n group.notes.push(note)\n return false\n }\n return\n })\n\n if (!titleExists) {\n noteGroups.push({\n notes: [note],\n title: title,\n })\n }\n })\n\n return noteGroups\n}\n\nexport default getNoteGroups\n","import getCommitGroups from './getCommitGroups'\nimport getNoteGroups from './getNoteGroups'\n\nfunction getExtraContext(commits, notes, options) {\n const context: any = {}\n\n context.commitGroups = getCommitGroups(\n options.groupBy,\n commits,\n options.commitGroupsSort,\n options.commitsSort,\n )\n\n context.noteGroups = getNoteGroups(\n notes,\n options.noteGroupsSort,\n options.notesSort,\n )\n\n return context\n}\n\nexport default getExtraContext\n","import { filterRevertedCommitsSync } from 'conventional-commits-filter'\nimport {\n clone as _clone,\n forEach as _forEach,\n map as _map,\n merge as _merge,\n} from 'lodash-es'\nimport { patch as semverPatch, valid as semverValid } from 'semver'\n\nimport getExtraContext from './getExtraContent'\n\nfunction generate(options, commits, context, keyCommit) {\n let notes = []\n let filteredCommits: any\n\n if (options.ignoreReverted) {\n for (const commit of filterRevertedCommitsSync(commits)) {\n filteredCommits.push(commit)\n }\n } else {\n filteredCommits = _clone(commits)\n }\n\n _forEach(filteredCommits, (commit) => {\n _map(commit.notes, (note) => {\n note.commit = commit\n\n return note\n })\n\n notes = notes.concat(commit.notes)\n })\n // console.dir(`notes:`)\n // console.dir(notes)\n\n context = _merge(\n {},\n context,\n keyCommit,\n getExtraContext(filteredCommits, notes, options),\n )\n\n if (keyCommit?.committerDate) {\n context.date = keyCommit.committerDate\n }\n\n if (context.version && semverValid(context.version)) {\n context.isPatch = context.isPatch || semverPatch(context.version) !== 0\n }\n\n // @note this is/was a pass-through function, okay with \"skipping\"\n // context = options.finalizeContext(\n // context,\n // options,\n // filteredCommits,\n // keyCommit,\n // commits\n // )\n\n // @question should this be merge/extend? i.e, `...context` specifically?\n context = {\n commits,\n context,\n filteredCommits,\n keyCommit,\n options,\n }\n\n return context\n}\n\nexport default generate\n","/**\n * @copyright https://github.com/semantic-release/release-notes-generator\n */\nimport { dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { promisify } from 'node:util'\n\n// import conventionalChangelogAngular from 'conventional-changelog-angular'\nimport importFrom from 'import-from-esm'\nimport { isPlainObject as _isPlainObject } from 'lodash-es'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst getChangelogConfig = async (pluginConfig, context) => {\n const { config, parserOpts, preset, presetConfig, writerOpts } = pluginConfig\n const { cwd } = context\n\n let loadedConfig: any\n\n if (preset) {\n const presetPackage = `conventional-changelog-${preset.toLowerCase()}`\n /**\n * @todo(semantic)\n * UNKNOWN\n * https://github.com/semantic-release/commit-analyzer/commit/f3b88d3e7409b0bac38cb58bd04f19506f2f6159\n */\n // @ts-ignore\n loadedConfig = await (\n (await importFrom.silent(__dirname, presetPackage)) ||\n (await importFrom(cwd, presetPackage))\n )(presetConfig)\n } else if (config) {\n // @ts-ignore\n loadedConfig = await (\n (await importFrom.silent(__dirname, config)) || (await importFrom(cwd, config))\n )()\n } else {\n // loadedConfig = conventionalChangelogAngular\n loadedConfig = {}\n }\n\n loadedConfig = await (typeof loadedConfig === 'function'\n ? _isPlainObject(presetConfig)\n ? loadedConfig(presetConfig)\n : promisify(loadedConfig)()\n : loadedConfig)\n\n const changelogConfig = {\n parserOpts: { ...loadedConfig.parserOpts, ...parserOpts },\n writerOpts: { ...loadedConfig.writerOpts, ...writerOpts },\n }\n\n return changelogConfig\n}\n\nexport { getChangelogConfig }\n","import { size as _size } from 'lodash-es'\n\nconst commit = (context, commits, meta) => {\n const { commit, commitGroups, linkReferences } = context\n const { repositoryUrl } = meta\n\n // @todo(release-notes) make variable\n const commitFormat = `- {scope}{subject}{hash}{references}\\n`\n\n let markdown = ``\n\n const getHash = (hash) => {\n if (!hash) return ''\n if (linkReferences) {\n const url = ` ${repositoryUrl}/${commit}/${hash}`\n return ` [ \\`${hash}\\` ](${url})`\n }\n return ` ${hash}`\n }\n\n const getReferences = (references) => {\n if (!references || _size(references) === 0) return ''\n let markdownReference = `, closes `\n const markdownReferenceArray: any = []\n references.map((reference: any) => {\n // markdownReferenceArray.push(\n // `[ ${reference.issue} ](${repositoryUrl}/${reference.issue})`\n // )\n\n // biome-ignore lint/complexity/noExtraBooleanCast: migrate\n if (!!reference.issue) {\n markdownReferenceArray.push(`[ #${reference.issue} ]`)\n }\n })\n markdownReference += markdownReferenceArray.join(' ')\n return markdownReference\n }\n\n commitGroups.map((commitGroup) => {\n const type = commitGroup?.commits[0]?.typeSpec?.type\n\n markdown += `#### ${commitGroup?.commits[0]?.type}\\n`\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: 11\n commits.map((commit) => {\n const { hash, header, references, scope, subject } = commit\n if (type === commit.typeSpec.type) {\n const commitMarkdown = commitFormat\n .replace(/\\{scope\\}/g, scope ? `**${scope}**: ` : '')\n .replace(/\\{subject\\}/g, subject ? subject : header)\n .replace(/\\{hash\\}/g, getHash(hash))\n .replace(/\\{references\\}/g, getReferences(references))\n\n markdown += commitMarkdown\n }\n })\n markdown += `\\n`\n })\n\n return markdown\n}\n\nexport { commit }\n","import { Octokit } from '@octokit/rest'\nimport {\n findIndex as _findIndex,\n sample as _sample,\n uniqBy as _uniqBy,\n} from 'lodash-es'\n\nconst gh = new Octokit({ auth: process.env.GH_TOKEN })\n\ninterface IAuthor {\n email: string\n login?: string\n name: string\n}\n\n/**\n * @hack\n * remove these logins from contributors\n *\n * reason JeromeFitz is here is because most of the time\n * they are the only one making them in this repo ,haha\n *\n * maybe these should be a configuration setting?\n *\n */\nconst contributorsProhibitListDefault = {\n email: [\n 'noreply@github.com',\n 'users.noreply.github.com',\n 'semantic-release-bot@martynus.net',\n ],\n login: [\n 'dependabot',\n 'dependabot[bot]',\n 'kodiakhq',\n 'kodiakhq[bot]',\n 'renovate',\n 'renovate[bot]',\n 'semantic-release-bot',\n ],\n}\n\nconst contributorsSubtitle = [\n 'Props to',\n 'Kudos to',\n 'Thanks to',\n 'Brought to you by',\n]\n\nconst contributor = async (context, commits, _meta) => {\n const authors = _uniqBy(\n commits.map(\n (commit): IAuthor => ({\n email: commit.author.email,\n name: commit.author.name,\n }),\n ),\n 'name',\n )\n\n const {\n options: { contributorsProhibitList },\n } = context\n\n // console.dir(`> context`)\n // console.dir(context)\n\n await Promise.all(\n authors.map((author: any, authorIdx) =>\n gh\n .request('GET /search/users', {\n q: author.email,\n })\n .then(({ data }) => {\n const login = data.items[0]?.login\n // biome-ignore lint/complexity/noExtraBooleanCast: migrate\n if (!!login) {\n // biome-ignore lint/complexity/useLiteralKeys: migrate\n authors[authorIdx]['login'] = login\n return login\n }\n return ''\n }),\n ),\n )\n\n // @note could we lift this better somehow and reduce API calls?\n const contributorsProhibitListLogin = [\n ...contributorsProhibitListDefault.login,\n ...contributorsProhibitList.login,\n ]\n contributorsProhibitListLogin.map((eject) => {\n const ejectIndex = _findIndex(authors, ['login', eject])\n if (ejectIndex !== -1) authors.splice(ejectIndex)\n })\n const contributorsProhibitListEmail = [\n ...contributorsProhibitListDefault.email,\n ...contributorsProhibitList.email,\n ]\n contributorsProhibitListEmail.map((eject) => {\n const ejectIndex = _findIndex(authors, (author: any) =>\n author.email.includes(eject),\n )\n if (ejectIndex !== -1) authors.splice(ejectIndex)\n })\n\n let markdown = ``\n if (authors.length > 0) {\n // @todo(release-notes) pass title as configuration option\n markdown += `#### 🥳️ Contributors\\n`\n const authorsString = authors.map((author: any) => `@${author.login}`).join(', ')\n markdown += `- ${_sample(contributorsSubtitle)} ${authorsString}\\n`\n // markdown += `\\n---\\n`\n // markdown += _sample(contributorKudos)!(\n // authors.map((author: any) => author.login).join(',')\n // )\n markdown += `\\n`\n }\n\n return markdown\n}\n\nexport { contributor }\n","const footer = (context, _commits, _meta) => {\n const { noteGroups } = context\n\n // @todo(release-notes) make variable\n const noteFormat = `- {scope}{text}\\n`\n\n let markdown = ``\n\n noteGroups.map((noteGroup) => {\n const { notes } = noteGroup\n const title = notes[0].title\n markdown += `#### ${title}\\n`\n notes.map((note) => {\n const { scope, text } = note\n const noteMarkdown = noteFormat\n .replace(/\\{scope\\}/g, scope ? `**${scope}**: ` : '')\n .replace(/\\{text\\}/g, text ? text : '')\n\n markdown += noteMarkdown\n })\n markdown += `\\n`\n })\n\n return markdown\n}\n\nexport { footer }\n","import { format as _format } from 'date-fns'\n\nconst header = (context, _commits, meta) => {\n // @todo(release-notes) pass as option\n const { currentTag, date, linkCompare, previousTag, title } = context\n const { repositoryUrl } = meta\n\n let markdown = `\n| 🔖️ | Release Information |\n| ----------- | --------------- |\n| Current | **\\`${currentTag}\\`** |\\n`\n\n if (linkCompare) {\n const linkCompareUrl =\n // biome-ignore lint/style/useTemplate: migrate\n repositoryUrl + '/compare/' + previousTag + '...' + currentTag\n markdown += `| Previous | **[\\`${previousTag}\\`](${linkCompareUrl})** |\\n`\n }\n if (title) {\n markdown += `| Title | **\\`${title}\\`** |\\n`\n }\n if (date) {\n markdown += `| Date | **\\`${_format(date, 'yyyy-MM-dd')}\\`** |\\n`\n }\n\n markdown += `\\n`\n return markdown\n}\n\nexport { header }\n","import { commit, contributor, footer, header } from '../templates/index'\n\nconst getMarkdown = async (context, commits) => {\n const {\n commitGroups,\n currentTag,\n date,\n host,\n issue,\n lastRelease,\n linkCompare,\n linkReferences,\n mentions,\n nextRelease,\n noteGroups,\n notes,\n options,\n owner,\n previousTag,\n references,\n repository,\n repoUrl,\n revert,\n version,\n } = context\n\n const markdownContext = {\n commitGroups, // // [{title|commits}]\n currentTag,\n date, // isoString\n host,\n issue, // string\n lastRelease, // version|gitTag|channels|gitHead|name\n linkCompare,\n linkReferences,\n mentions, // []\n nextRelease, // type|channel|gitHead|version|gitTag|name|notes\n noteGroups, // []\n notes,\n options, // from `release.config`\n owner,\n previousTag,\n references, // []\n repository,\n repoUrl,\n revert, // boolean\n version,\n }\n\n // Object.keys(markdownContext).map((key) => {\n // console.dir(`>> ${key}:`)\n // console.dir(markdownContext[key])\n // })\n\n // biome-ignore lint/style/useTemplate: migrate\n const repositoryUrl = repository ? host + '/' + owner + '/' + repository : repoUrl\n\n const meta = {\n repositoryUrl,\n }\n // const meta = {}\n\n let markdown = ``\n // TEMPLATE\n // HEADER\n markdown += header(markdownContext, commits, meta)\n markdown += `\\n`\n // COMMITS\n markdown += commit(markdownContext, commits, meta)\n markdown += `\\n`\n // CONTRIBUTORS\n markdown += await contributor(markdownContext, commits, meta)\n markdown += `\\n`\n // FOOTER (NOTES)\n markdown += footer(markdownContext, commits, meta)\n markdown += `\\n`\n\n return markdown\n}\n\nexport { getMarkdown }\n","import {\n cloneDeep as _cloneDeep,\n forEach as _forEach,\n get as _get,\n isFunction as _isFunction,\n set as _set,\n} from 'lodash-es'\n\n/**\n * @ref lifted from release-notes-generator\n */\nfunction processCommit(chunk, transform, context) {\n let commit: any\n\n try {\n chunk = JSON.parse(chunk)\n // biome-ignore lint/suspicious/noEmptyBlockStatements: migrate\n } catch (_error) {}\n\n commit = _cloneDeep(chunk)\n\n if (_isFunction(transform)) {\n commit = transform(commit, context)\n\n if (commit) {\n commit.raw = chunk\n }\n\n return commit\n }\n\n _forEach(transform, (el, path) => {\n let value = _get(commit, path)\n\n if (_isFunction(el)) {\n value = el(value, path)\n } else {\n value = el\n }\n\n _set(commit, path, value)\n })\n\n commit.raw = chunk\n\n return commit\n}\n\nexport { processCommit }\n","import { format, URL } from 'node:url'\n\nimport { filterRevertedCommitsSync } from 'conventional-commits-filter'\nimport { CommitParser } from 'conventional-commits-parser'\nimport { merge as _merge } from 'lodash-es'\nimport { readPackageUp } from 'read-package-up'\n\nimport generate from './utils/generate'\nimport { getChangelogConfig } from './utils/getChangelogConfig'\nimport { getMarkdown } from './utils/getMarkdown'\nimport { processCommit } from './utils/processCommit'\n\nconst configGithub = {\n commit: 'commit',\n hostname: 'github.com',\n issue: 'issues',\n issuePrefixes: ['#', 'gh-'],\n referenceActions: [\n 'close',\n 'closes',\n 'closed',\n 'fix',\n 'fixes',\n 'fixed',\n 'resolve',\n 'resolves',\n 'resolved',\n ],\n}\n\n// @todo(complexity) 17\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: migrate\nasync function generateNotes(pluginConfig, context) {\n const { parserOpts, writerOpts } = await getChangelogConfig(pluginConfig, context)\n const { commits: commitsPassed, cwd, lastRelease, nextRelease, options } = context\n\n const { commit, issue, issuePrefixes, referenceActions } = configGithub\n\n const previousTag = lastRelease.gitTag || lastRelease.gitHead\n const currentTag = nextRelease.gitTag || nextRelease.gitHead\n const {\n commit: commitConfig,\n host: hostConfig,\n issue: issueConfig,\n linkCompare,\n linkReferences,\n } = pluginConfig\n\n const repositoryUrl = options.repositoryUrl.replace(/\\.git$/i, '')\n const [match, auth, host, path] =\n /^(?!.+:\\/\\/)(?:(?<auth>.*)@)?(?<host>.*?):(?<path>.*)$/.exec(repositoryUrl) ||\n []\n let { hostname, pathname, port, protocol } = new URL(\n match ? `ssh://${auth ? `${auth}@` : ''}${host}/${path}` : repositoryUrl,\n )\n port = protocol.includes('ssh') ? '' : port\n protocol = protocol && /http[^s]/.test(protocol) ? 'http' : 'https'\n\n const [, owner, repository] =\n /^\\/(?<owner>[^/]+)?\\/?(?<repository>.+)?$/.exec(pathname) ?? []\n\n const changelogContext = _merge(\n {\n commit,\n currentTag,\n host: format({ hostname, port, protocol }),\n issue,\n linkCompare: currentTag && previousTag,\n owner,\n packageData: (await readPackageUp({ cwd, normalize: false }))?.packageJson,\n previousTag,\n repository,\n version: nextRelease.version,\n },\n {\n commit: commitConfig,\n host: hostConfig,\n issue: issueConfig,\n linkCompare,\n linkReferences,\n },\n )\n\n const commitsParsed: any = []\n const parser = new CommitParser({\n issuePrefixes,\n referenceActions,\n ...parserOpts,\n })\n\n for (const _commit of filterRevertedCommitsSync(commitsPassed)) {\n const commit: any = _commit\n if (!commit?.message.trim()) {\n return false\n }\n const commitPassed = {\n ...commit,\n ...parser.parse(commit?.message),\n }\n commitsParsed.push(commitPassed)\n }\n let commits: any = []\n await commitsParsed.map(async (commitParsed) => {\n const commitProcessed: any = await processCommit(\n commitParsed,\n writerOpts.transform,\n context,\n )\n commits.push(commitProcessed)\n })\n\n /**\n * @hack why is something being brought back as undefined?\n */\n commits = await commits.filter((commit) => commit !== undefined)\n\n const _options = _merge({}, changelogContext, options, writerOpts)\n\n /**\n * @note(release-notes-generator) oddly, `date` is pulled from here\n * could we do this differently? what other fields\n * are pulled for info purposes?\n */\n const _chunk = commits[0]\n const keyCommit = processCommit(_chunk, writerOpts.transform, context) || _chunk\n const { context: _context } = await generate(_options, commits, context, keyCommit)\n\n const markdownContext = _merge({}, changelogContext, _context)\n\n return getMarkdown(markdownContext, commits)\n}\n\nexport { generateNotes }\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["_format","_get","semverValid","semverPatch"],"sources":["../src/utils/getCommitGroups.ts","../src/templates/commit.ts","../src/templates/contributor.ts","../src/templates/footer.ts","../src/templates/header.ts","../src/utils/getMarkdown.ts","../src/utils/getNoteGroups.ts","../src/utils/processCommit.ts","../src/index.ts"],"sourcesContent":["import type { CommitGroup, TransformedCommit } from '../types'\n\nfunction multiKeySort<T>(keys: string[]): (a: T, b: T) => number {\n return (a, b) => {\n const ar = a as Record<string, unknown>\n const br = b as Record<string, unknown>\n for (const key of keys) {\n const av = ar[key] ?? 0\n const bv = br[key] ?? 0\n if (av < bv) return -1\n if (av > bv) return 1\n }\n return 0\n }\n}\n\nfunction semverToOrder(semver: string | null | undefined): number {\n if (semver && ['breaking', 'major'].includes(semver)) return 0\n if (semver && ['feature', 'minor'].includes(semver)) return 10\n if (semver && ['fix', 'patch'].includes(semver)) return 20\n return 99\n}\n\nfunction toCommitGroup(\n title: string,\n groupCommits: TransformedCommit[] | undefined,\n commitsSort: string[],\n): CommitGroup {\n const sorted =\n commitsSort.length > 0\n ? [...(groupCommits ?? [])].sort(multiKeySort<TransformedCommit>(commitsSort))\n : [...(groupCommits ?? [])]\n\n return {\n commits: sorted,\n order: semverToOrder(sorted[0]?.typeSpec?.semver),\n title: title === '' ? false : title,\n }\n}\n\nfunction getCommitGroups(\n groupBy: string,\n commits: TransformedCommit[],\n commitGroupsSort: string[],\n commitsSort: string[],\n): CommitGroup[] {\n const grouped = Object.groupBy(\n commits,\n (commit) => (commit[groupBy] as string | undefined) ?? '',\n )\n\n const commitGroups = Object.entries(grouped).map(([title, group]) =>\n toCommitGroup(title, group, commitsSort),\n )\n\n return commitGroupsSort.length > 0\n ? commitGroups.sort(multiKeySort<CommitGroup>(commitGroupsSort))\n : commitGroups\n}\n\nexport { getCommitGroups }\n","import type { CommitReference } from 'conventional-commits-parser'\n\nimport type { MarkdownContext, RenderMeta, TransformedCommit } from '../types'\n\nconst commit = (\n context: MarkdownContext,\n commits: TransformedCommit[],\n meta: RenderMeta,\n): string => {\n const { commit: commitPath, commitGroups, linkReferences } = context\n const { repositoryUrl } = meta\n\n const commitFormat = `- {scope}{subject}{hash}{references}\\n`\n\n const getHash = (hash: string | undefined): string => {\n if (!hash) return ''\n if (linkReferences) {\n return ` [ \\`${hash}\\` ](${repositoryUrl}/${commitPath}/${hash})`\n }\n return ` ${hash}`\n }\n\n const getReferences = (references: CommitReference[]): string => {\n if (references.length === 0) return ''\n const items = references\n .filter((ref) => ref.issue)\n .map((ref) => `[ #${ref.issue} ]`)\n return items.length > 0 ? `, closes ${items.join(' ')}` : ''\n }\n\n let markdown = ''\n\n for (const commitGroup of commitGroups) {\n const groupType = commitGroup.commits[0]?.typeSpec?.type\n markdown += `#### ${commitGroup.commits[0]?.type}\\n`\n\n for (const c of commits) {\n if (groupType !== c.typeSpec?.type) continue\n const { hash, header, references = [], scope, subject } = c\n markdown += commitFormat\n .replace(/\\{scope\\}/g, scope ? `**${scope}**: ` : '')\n .replace(/\\{subject\\}/g, subject ?? header ?? '')\n .replace(/\\{hash\\}/g, getHash(hash))\n .replace(/\\{references\\}/g, getReferences(references as CommitReference[]))\n }\n\n markdown += '\\n'\n }\n\n return markdown\n}\n\nexport { commit }\n","import type { MarkdownContext, RenderMeta, TransformedCommit } from '../types'\n\nimport { Octokit } from '@octokit/rest'\n\nconst gh = new Octokit({ auth: process.env.GH_TOKEN })\n\ninterface Author {\n email: string\n login?: string\n name: string\n}\n\nconst contributorsProhibitListDefault = {\n email: [\n 'noreply@github.com',\n 'users.noreply.github.com',\n 'semantic-release-bot@martynus.net',\n ],\n login: [\n 'dependabot',\n 'dependabot[bot]',\n 'kodiakhq',\n 'kodiakhq[bot]',\n 'renovate',\n 'renovate[bot]',\n 'semantic-release-bot',\n ],\n}\n\nconst contributorsSubtitle = [\n 'Props to',\n 'Kudos to',\n 'Thanks to',\n 'Brought to you by',\n]\n\nconst sample = <T>(arr: T[]): T => arr[Math.floor(Math.random() * arr.length)]\n\nconst uniqByName = (authors: Author[]): Author[] => {\n const seen = new Map<string, Author>()\n for (const a of authors) {\n if (!seen.has(a.name)) seen.set(a.name, a)\n }\n return [...seen.values()]\n}\n\nconst contributor = async (\n context: MarkdownContext,\n commits: TransformedCommit[],\n _meta: RenderMeta,\n): Promise<string> => {\n const authors = uniqByName(\n commits.map((c) => ({\n email: c.author?.email ?? '',\n name: c.author?.name ?? '',\n })),\n )\n\n await Promise.all(\n authors.map((author, idx) =>\n gh.request('GET /search/users', { q: author.email }).then(({ data }) => {\n const login = data.items[0]?.login\n if (login) authors[idx].login = login\n }),\n ),\n )\n\n const prohibitList = context.options?.contributorsProhibitList ?? {\n email: [],\n login: [],\n }\n\n const prohibitLogins = [\n ...contributorsProhibitListDefault.login,\n ...prohibitList.login,\n ]\n for (const ejectLogin of prohibitLogins) {\n const idx = authors.findIndex((a) => a.login === ejectLogin)\n if (idx !== -1) authors.splice(idx, 1)\n }\n\n const prohibitEmails = [\n ...contributorsProhibitListDefault.email,\n ...prohibitList.email,\n ]\n for (const ejectEmail of prohibitEmails) {\n const idx = authors.findIndex((a) => a.email.includes(ejectEmail))\n if (idx !== -1) authors.splice(idx, 1)\n }\n\n if (authors.length === 0) return ''\n\n const authorsString = authors.map((a) => `@${a.login}`).join(', ')\n let markdown = `#### 🥳️ Contributors\\n`\n markdown += `- ${sample(contributorsSubtitle)} ${authorsString}\\n`\n markdown += '\\n'\n\n return markdown\n}\n\nexport { contributor }\n","import type { MarkdownContext, RenderMeta, TransformedCommit } from '../types'\n\nconst footer = (\n context: MarkdownContext,\n _commits: TransformedCommit[],\n _meta: RenderMeta,\n): string => {\n const { noteGroups } = context\n const noteFormat = `- {scope}{text}\\n`\n\n let markdown = ''\n\n for (const noteGroup of noteGroups) {\n const { notes } = noteGroup\n markdown += `#### ${notes[0].title}\\n`\n for (const note of notes) {\n const { scope, text } = note\n markdown += noteFormat\n .replace(/\\{scope\\}/g, scope ? `**${scope}**: ` : '')\n .replace(/\\{text\\}/g, text ?? '')\n }\n markdown += '\\n'\n }\n\n return markdown\n}\n\nexport { footer }\n","import type { MarkdownContext, RenderMeta, TransformedCommit } from '../types'\n\nimport { format as _format } from 'date-fns'\n\nconst header = (\n context: MarkdownContext,\n _commits: TransformedCommit[],\n meta: RenderMeta,\n): string => {\n const { currentTag, date, linkCompare, previousTag, title } = context\n const { repositoryUrl } = meta\n\n let markdown = `\n| 🔖️ | Release Information |\n| ----------- | --------------- |\n| Current | **\\`${currentTag}\\`** |\\n`\n\n if (linkCompare) {\n const linkCompareUrl = `${repositoryUrl}/compare/${previousTag}...${currentTag}`\n markdown += `| Previous | **[\\`${previousTag}\\`](${linkCompareUrl})** |\\n`\n }\n if (title) {\n markdown += `| Title | **\\`${title}\\`** |\\n`\n }\n if (date) {\n markdown += `| Date | **\\`${_format(date, 'yyyy-MM-dd')}\\`** |\\n`\n }\n\n markdown += '\\n'\n return markdown\n}\n\nexport { header }\n","import type { MarkdownContext, RenderMeta, TransformedCommit } from '../types'\n\nimport { commit, contributor, footer, header } from '../templates/index'\n\nconst getMarkdown = async (\n context: MarkdownContext,\n commits: TransformedCommit[],\n): Promise<string> => {\n const repositoryUrl = context.repository\n ? `${context.host}/${context.owner}/${context.repository}`\n : ''\n\n const meta: RenderMeta = { repositoryUrl }\n\n let markdown = header(context, commits, meta)\n markdown += '\\n'\n markdown += commit(context, commits, meta)\n markdown += '\\n'\n markdown += await contributor(context, commits, meta)\n markdown += '\\n'\n markdown += footer(context, commits, meta)\n markdown += '\\n'\n\n return markdown\n}\n\nexport { getMarkdown }\n","import type { Note, NoteGroup } from '../types'\n\nfunction getNoteGroups(notes: Note[]): NoteGroup[] {\n const groups = new Map<string, NoteGroup>()\n\n for (const note of notes) {\n const existing = groups.get(note.title)\n if (existing) {\n existing.notes.push(note)\n } else {\n groups.set(note.title, { notes: [note], title: note.title })\n }\n }\n\n return [...groups.values()]\n}\n\nexport { getNoteGroups }\n","import type { ParsedCommit, TransformedCommit } from '../types'\n\nimport { get as _get, set as _set } from 'lodash-es'\n\ntype TransformFn = (\n commit: ParsedCommit,\n context: unknown,\n) => Record<string, unknown> | undefined\n\ntype TransformMap = Record<\n string,\n ((value: unknown, path: string) => unknown) | unknown\n>\n\ntype Transform = TransformFn | TransformMap\n\nfunction processCommit(\n chunk: ParsedCommit,\n transform: Transform,\n context: unknown,\n): TransformedCommit | undefined {\n const commit: ParsedCommit | TransformedCommit = structuredClone(chunk)\n\n if (typeof transform === 'function') {\n const result = transform(commit as ParsedCommit, context) as\n | TransformedCommit\n | undefined\n if (result) result.raw = chunk\n return result\n }\n\n for (const [path, el] of Object.entries(transform)) {\n let value = _get(commit, path)\n value = typeof el === 'function' ? el(value, path) : el\n _set(commit, path, value)\n }\n\n ;(commit as TransformedCommit).raw = chunk\n return commit as TransformedCommit\n}\n\nexport type { Transform, TransformFn, TransformMap }\nexport { processCommit }\n","import { format, URL } from 'node:url'\n\nimport type {\n MarkdownContext,\n Note,\n ParsedCommit,\n PluginConfig,\n SRContext,\n TransformedCommit,\n} from './types'\n\nimport { parserOpts, writerOpts } from '@jeromefitz/conventional-gitmoji'\n\nimport { filterRevertedCommitsSync } from 'conventional-commits-filter'\nimport { CommitParser } from 'conventional-commits-parser'\nimport { readPackageUp } from 'read-package-up'\nimport { patch as semverPatch, valid as semverValid } from 'semver'\n\nimport { getCommitGroups } from './utils/getCommitGroups'\nimport { getMarkdown } from './utils/getMarkdown'\nimport { getNoteGroups } from './utils/getNoteGroups'\nimport { processCommit } from './utils/processCommit'\n\nconst commitLinkDefault = 'commit'\nconst issueLinkDefault = 'issues'\n\nfunction parseRepositoryUrl(rawUrl: string): {\n hostname: string\n owner: string\n port: string\n protocol: string\n repository: string\n} {\n const url = rawUrl.replace(/\\.git$/i, '')\n const [match, auth, host, path] =\n /^(?!.+:\\/\\/)(?:(?<auth>.*)@)?(?<host>.*?):(?<path>.*)$/.exec(url) ?? []\n let { hostname, pathname, port, protocol } = new URL(\n match ? `ssh://${auth ? `${auth}@` : ''}${host}/${path}` : url,\n )\n port = protocol.includes('ssh') ? '' : port\n protocol = /http[^s]/.test(protocol) ? 'http' : 'https'\n const [, owner = '', repository = ''] =\n /^\\/(?<owner>[^/]+)?\\/?(?<repository>.+)?$/.exec(pathname) ?? []\n return { hostname, owner, port, protocol, repository }\n}\n\nfunction transformCommits(\n rawCommits: SRContext['commits'],\n parser: CommitParser,\n context: SRContext,\n): TransformedCommit[] {\n const commits: TransformedCommit[] = []\n for (const raw of filterRevertedCommitsSync(rawCommits)) {\n if (!raw.message?.trim()) continue\n const parsed = {\n ...raw,\n ...parser.parse(raw.message),\n message: raw.message,\n } as ParsedCommit\n const transformed = processCommit(parsed, writerOpts.transform, context)\n if (transformed) commits.push(transformed)\n }\n return commits\n}\n\nfunction collectNotes(commits: TransformedCommit[]): Note[] {\n const notes: Note[] = []\n for (const c of commits) {\n for (const note of c.notes) {\n notes.push({ ...note, commit: c })\n }\n }\n return notes\n}\n\nasync function generateNotes(\n pluginConfig: PluginConfig,\n context: SRContext,\n): Promise<string> {\n const { commits: rawCommits, cwd, lastRelease, nextRelease, options } = context\n\n const previousTag = lastRelease.gitTag || lastRelease.gitHead\n const currentTag = nextRelease.gitTag || nextRelease.gitHead\n const { hostname, owner, port, protocol, repository } = parseRepositoryUrl(\n options.repositoryUrl,\n )\n\n const parser = new CommitParser(parserOpts)\n const commits = transformCommits(rawCommits, parser, context)\n const notes = collectNotes(commits)\n\n const version = nextRelease.version\n const packageData = (await readPackageUp({ cwd, normalize: false }))?.packageJson\n\n const markdownContext: MarkdownContext = {\n commit: pluginConfig.commit ?? commitLinkDefault,\n commitGroups: getCommitGroups(\n writerOpts.groupBy,\n commits,\n writerOpts.commitGroupsSort,\n writerOpts.commitsSort,\n ),\n currentTag,\n date: commits[0]?.committerDate,\n host: format({ hostname, port, protocol }),\n isPatch: semverValid(version) ? (semverPatch(version) ?? 0) !== 0 : undefined,\n issue: pluginConfig.issue ?? issueLinkDefault,\n linkCompare: pluginConfig.linkCompare ?? !!(currentTag && previousTag),\n linkReferences: pluginConfig.linkReferences,\n noteGroups: getNoteGroups(notes),\n options,\n owner,\n packageData,\n previousTag,\n repository,\n version,\n }\n\n return getMarkdown(markdownContext, commits)\n}\n\nexport { generateNotes }\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jeromefitz/release-notes-generator",
3
- "version": "4.0.3",
3
+ "version": "4.1.0",
4
4
  "type": "module",
5
5
  "description": "Custom Release Note Generator for Semantic Release.",
6
6
  "repository": {
@@ -31,7 +31,8 @@
31
31
  "lint": "pnpm run lint:typescript",
32
32
  "lint:typescript": "tsc --noEmit --declaration",
33
33
  "semantic-release": "semantic-release",
34
- "semantic-release:dry": "semantic-release --dry-run"
34
+ "semantic-release:dry": "semantic-release --dry-run",
35
+ "test": "vitest run"
35
36
  },
36
37
  "peerDependencies": {
37
38
  "lodash-es": "^4.18.0"
@@ -40,8 +41,7 @@
40
41
  "@octokit/rest": "22.0.1",
41
42
  "conventional-commits-filter": "5.0.0",
42
43
  "conventional-commits-parser": "6.4.0",
43
- "date-fns": "4.3.0",
44
- "import-from-esm": "2.0.0",
44
+ "date-fns": "4.4.0",
45
45
  "read-package-up": "12.0.0",
46
46
  "semver": "7.8.1"
47
47
  },