githublogen 0.3.2 → 0.3.4

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/cli.mjs CHANGED
@@ -1,12 +1,592 @@
1
- import S from"cac";import{cyan as v,green as T,red as b,yellow as u,dim as f,blue as $,bold as F}from"kolorist";import{getChangelogMarkdown as I}from"@soybeanjs/changelog";import{ofetch as g}from"ofetch";const a={silent:Number.NEGATIVE_INFINITY,fatal:0,error:0,warn:1,log:2,info:3,success:3,fail:3,ready:3,start:3,box:3,debug:4,trace:5,verbose:Number.POSITIVE_INFINITY},L={silent:{level:-1},fatal:{level:a.fatal},error:{level:a.error},warn:{level:a.warn},log:{level:a.log},info:{level:a.info},success:{level:a.success},fail:{level:a.fail},ready:{level:a.info},start:{level:a.info},box:{level:a.info},debug:{level:a.debug},trace:{level:a.trace},verbose:{level:a.verbose}};function d(s){return s!==null&&typeof s=="object"}function y(s,t,e=".",r){if(!d(t))return y(s,{},e,r);const o=Object.assign({},t);for(const i in s){if(i==="__proto__"||i==="constructor")continue;const n=s[i];n!=null&&(r&&r(o,i,n,e)||(Array.isArray(n)&&Array.isArray(o[i])?o[i]=[...n,...o[i]]:d(n)&&d(o[i])?o[i]=y(n,o[i],(e?`${e}.`:"")+i.toString(),r):o[i]=n))}return o}function R(s){return(...t)=>t.reduce((e,r)=>y(e,r,"",s),{})}const A=R();function x(s){return Object.prototype.toString.call(s)==="[object Object]"}function N(s){return!(!x(s)||!s.message&&!s.args||s.stack)}let m=!1;const k=[];class l{constructor(t={}){const e=t.types||L;this.options=A({...t,defaults:{...t.defaults},level:_(t.level,e),reporters:[...t.reporters||[]]},{types:L,throttle:1e3,throttleMin:5,formatOptions:{date:!0,colors:!1,compact:!0}});for(const r in e){const o={type:r,...this.options.defaults,...e[r]};this[r]=this._wrapLogFn(o),this[r].raw=this._wrapLogFn(o,!0)}this.options.mockFn&&this.mockTypes(),this._lastLog={}}get level(){return this.options.level}set level(t){this.options.level=_(t,this.options.types,this.options.level)}prompt(t,e){if(!this.options.prompt)throw new Error("prompt is not supported!");return this.options.prompt(t,e)}create(t){const e=new l({...this.options,...t});return this._mockFn&&e.mockTypes(this._mockFn),e}withDefaults(t){return this.create({...this.options,defaults:{...this.options.defaults,...t}})}withTag(t){return this.withDefaults({tag:this.options.defaults.tag?this.options.defaults.tag+":"+t:t})}addReporter(t){return this.options.reporters.push(t),this}removeReporter(t){if(t){const e=this.options.reporters.indexOf(t);if(e>=0)return this.options.reporters.splice(e,1)}else this.options.reporters.splice(0);return this}setReporters(t){return this.options.reporters=Array.isArray(t)?t:[t],this}wrapAll(){this.wrapConsole(),this.wrapStd()}restoreAll(){this.restoreConsole(),this.restoreStd()}wrapConsole(){for(const t in this.options.types)console["__"+t]||(console["__"+t]=console[t]),console[t]=this[t].raw}restoreConsole(){for(const t in this.options.types)console["__"+t]&&(console[t]=console["__"+t],delete console["__"+t])}wrapStd(){this._wrapStream(this.options.stdout,"log"),this._wrapStream(this.options.stderr,"log")}_wrapStream(t,e){t&&(t.__write||(t.__write=t.write),t.write=r=>{this[e].raw(String(r).trim())})}restoreStd(){this._restoreStream(this.options.stdout),this._restoreStream(this.options.stderr)}_restoreStream(t){t&&t.__write&&(t.write=t.__write,delete t.__write)}pauseLogs(){m=!0}resumeLogs(){m=!1;const t=k.splice(0);for(const e of t)e[0]._logFn(e[1],e[2])}mockTypes(t){const e=t||this.options.mockFn;if(this._mockFn=e,typeof e=="function")for(const r in this.options.types)this[r]=e(r,this.options.types[r])||this[r],this[r].raw=this[r]}_wrapLogFn(t,e){return(...r)=>{if(m){k.push([this,t,r,e]);return}return this._logFn(t,r,e)}}_logFn(t,e,r){if((t.level||0)>this.level)return!1;const o={date:new Date,args:[],...t,level:_(t.level,this.options.types)};!r&&e.length===1&&N(e[0])?Object.assign(o,e[0]):o.args=[...e],o.message&&(o.args.unshift(o.message),delete o.message),o.additional&&(Array.isArray(o.additional)||(o.additional=o.additional.split(`
2
- `)),o.args.push(`
3
- `+o.additional.join(`
4
- `)),delete o.additional),o.type=typeof o.type=="string"?o.type.toLowerCase():"log",o.tag=typeof o.tag=="string"?o.tag:"";const i=(p=!1)=>{const c=(this._lastLog.count||0)-this.options.throttleMin;if(this._lastLog.object&&c>0){const w=[...this._lastLog.object.args];c>1&&w.push(`(repeated ${c} times)`),this._log({...this._lastLog.object,args:w}),this._lastLog.count=1}p&&(this._lastLog.object=o,this._log(o))};clearTimeout(this._lastLog.timeout);const n=this._lastLog.time&&o.date?o.date.getTime()-this._lastLog.time.getTime():0;if(this._lastLog.time=o.date,n<this.options.throttle)try{const p=JSON.stringify([o.type,o.tag,o.args]),c=this._lastLog.serialized===p;if(this._lastLog.serialized=p,c&&(this._lastLog.count=(this._lastLog.count||0)+1,this._lastLog.count>this.options.throttleMin)){this._lastLog.timeout=setTimeout(i,this.options.throttle);return}}catch{}i(!0)}_log(t){for(const e of this.options.reporters)e.log(t,{options:this.options})}}function _(s,t={},e=3){return s===void 0?e:typeof s=="number"?s:t[s]&&t[s].level!==void 0?t[s].level:e}l.prototype.add=l.prototype.addReporter,l.prototype.remove=l.prototype.removeReporter,l.prototype.clear=l.prototype.removeReporter,l.prototype.withScope=l.prototype.withTag,l.prototype.mock=l.prototype.mockTypes,l.prototype.pause=l.prototype.pauseLogs,l.prototype.resume=l.prototype.resumeLogs;function j(s={}){return new l(s)}class M{constructor(t){this.options={...t},this.defaultColor="#7f8c8d",this.levelColorMap={0:"#c0392b",1:"#f39c12",3:"#00BCD4"},this.typeColorMap={success:"#2ecc71"}}_getLogFn(t){return t<1?console.__error||console.error:t===1?console.__warn||console.warn:console.__log||console.log}log(t){const e=this._getLogFn(t.level),r=t.type==="log"?"":t.type,o=t.tag||"",n=`
5
- background: ${this.typeColorMap[t.type]||this.levelColorMap[t.level]||this.defaultColor};
1
+ #!/usr/bin/env node
2
+ import cac from 'cac';
3
+ import { cyan, green, red, yellow, dim, blue, bold } from 'kolorist';
4
+ import { getChangelogMarkdown } from '@soybeanjs/changelog';
5
+ import { ofetch } from 'ofetch';
6
+
7
+ const LogLevels = {
8
+ silent: Number.NEGATIVE_INFINITY,
9
+ fatal: 0,
10
+ error: 0,
11
+ warn: 1,
12
+ log: 2,
13
+ info: 3,
14
+ success: 3,
15
+ fail: 3,
16
+ ready: 3,
17
+ start: 3,
18
+ box: 3,
19
+ debug: 4,
20
+ trace: 5,
21
+ verbose: Number.POSITIVE_INFINITY
22
+ };
23
+ const LogTypes = {
24
+ // Silent
25
+ silent: {
26
+ level: -1
27
+ },
28
+ // Level 0
29
+ fatal: {
30
+ level: LogLevels.fatal
31
+ },
32
+ error: {
33
+ level: LogLevels.error
34
+ },
35
+ // Level 1
36
+ warn: {
37
+ level: LogLevels.warn
38
+ },
39
+ // Level 2
40
+ log: {
41
+ level: LogLevels.log
42
+ },
43
+ // Level 3
44
+ info: {
45
+ level: LogLevels.info
46
+ },
47
+ success: {
48
+ level: LogLevels.success
49
+ },
50
+ fail: {
51
+ level: LogLevels.fail
52
+ },
53
+ ready: {
54
+ level: LogLevels.info
55
+ },
56
+ start: {
57
+ level: LogLevels.info
58
+ },
59
+ box: {
60
+ level: LogLevels.info
61
+ },
62
+ // Level 4
63
+ debug: {
64
+ level: LogLevels.debug
65
+ },
66
+ // Level 5
67
+ trace: {
68
+ level: LogLevels.trace
69
+ },
70
+ // Verbose
71
+ verbose: {
72
+ level: LogLevels.verbose
73
+ }
74
+ };
75
+
76
+ function isObject(value) {
77
+ return value !== null && typeof value === "object";
78
+ }
79
+ function _defu(baseObject, defaults, namespace = ".", merger) {
80
+ if (!isObject(defaults)) {
81
+ return _defu(baseObject, {}, namespace, merger);
82
+ }
83
+ const object = Object.assign({}, defaults);
84
+ for (const key in baseObject) {
85
+ if (key === "__proto__" || key === "constructor") {
86
+ continue;
87
+ }
88
+ const value = baseObject[key];
89
+ if (value === null || value === void 0) {
90
+ continue;
91
+ }
92
+ if (merger && merger(object, key, value, namespace)) {
93
+ continue;
94
+ }
95
+ if (Array.isArray(value) && Array.isArray(object[key])) {
96
+ object[key] = [...value, ...object[key]];
97
+ } else if (isObject(value) && isObject(object[key])) {
98
+ object[key] = _defu(
99
+ value,
100
+ object[key],
101
+ (namespace ? `${namespace}.` : "") + key.toString(),
102
+ merger
103
+ );
104
+ } else {
105
+ object[key] = value;
106
+ }
107
+ }
108
+ return object;
109
+ }
110
+ function createDefu(merger) {
111
+ return (...arguments_) => (
112
+ // eslint-disable-next-line unicorn/no-array-reduce
113
+ arguments_.reduce((p, c) => _defu(p, c, "", merger), {})
114
+ );
115
+ }
116
+ const defu = createDefu();
117
+
118
+ function isPlainObject(obj) {
119
+ return Object.prototype.toString.call(obj) === "[object Object]";
120
+ }
121
+ function isLogObj(arg) {
122
+ if (!isPlainObject(arg)) {
123
+ return false;
124
+ }
125
+ if (!arg.message && !arg.args) {
126
+ return false;
127
+ }
128
+ if (arg.stack) {
129
+ return false;
130
+ }
131
+ return true;
132
+ }
133
+
134
+ let paused = false;
135
+ const queue = [];
136
+ class Consola {
137
+ constructor(options = {}) {
138
+ const types = options.types || LogTypes;
139
+ this.options = defu(
140
+ {
141
+ ...options,
142
+ defaults: { ...options.defaults },
143
+ level: _normalizeLogLevel(options.level, types),
144
+ reporters: [...options.reporters || []]
145
+ },
146
+ {
147
+ types: LogTypes,
148
+ throttle: 1e3,
149
+ throttleMin: 5,
150
+ formatOptions: {
151
+ date: true,
152
+ colors: false,
153
+ compact: true
154
+ }
155
+ }
156
+ );
157
+ for (const type in types) {
158
+ const defaults = {
159
+ type,
160
+ ...this.options.defaults,
161
+ ...types[type]
162
+ };
163
+ this[type] = this._wrapLogFn(defaults);
164
+ this[type].raw = this._wrapLogFn(
165
+ defaults,
166
+ true
167
+ );
168
+ }
169
+ if (this.options.mockFn) {
170
+ this.mockTypes();
171
+ }
172
+ this._lastLog = {};
173
+ }
174
+ get level() {
175
+ return this.options.level;
176
+ }
177
+ set level(level) {
178
+ this.options.level = _normalizeLogLevel(
179
+ level,
180
+ this.options.types,
181
+ this.options.level
182
+ );
183
+ }
184
+ prompt(message, opts) {
185
+ if (!this.options.prompt) {
186
+ throw new Error("prompt is not supported!");
187
+ }
188
+ return this.options.prompt(message, opts);
189
+ }
190
+ create(options) {
191
+ const instance = new Consola({
192
+ ...this.options,
193
+ ...options
194
+ });
195
+ if (this._mockFn) {
196
+ instance.mockTypes(this._mockFn);
197
+ }
198
+ return instance;
199
+ }
200
+ withDefaults(defaults) {
201
+ return this.create({
202
+ ...this.options,
203
+ defaults: {
204
+ ...this.options.defaults,
205
+ ...defaults
206
+ }
207
+ });
208
+ }
209
+ withTag(tag) {
210
+ return this.withDefaults({
211
+ tag: this.options.defaults.tag ? this.options.defaults.tag + ":" + tag : tag
212
+ });
213
+ }
214
+ addReporter(reporter) {
215
+ this.options.reporters.push(reporter);
216
+ return this;
217
+ }
218
+ removeReporter(reporter) {
219
+ if (reporter) {
220
+ const i = this.options.reporters.indexOf(reporter);
221
+ if (i >= 0) {
222
+ return this.options.reporters.splice(i, 1);
223
+ }
224
+ } else {
225
+ this.options.reporters.splice(0);
226
+ }
227
+ return this;
228
+ }
229
+ setReporters(reporters) {
230
+ this.options.reporters = Array.isArray(reporters) ? reporters : [reporters];
231
+ return this;
232
+ }
233
+ wrapAll() {
234
+ this.wrapConsole();
235
+ this.wrapStd();
236
+ }
237
+ restoreAll() {
238
+ this.restoreConsole();
239
+ this.restoreStd();
240
+ }
241
+ wrapConsole() {
242
+ for (const type in this.options.types) {
243
+ if (!console["__" + type]) {
244
+ console["__" + type] = console[type];
245
+ }
246
+ console[type] = this[type].raw;
247
+ }
248
+ }
249
+ restoreConsole() {
250
+ for (const type in this.options.types) {
251
+ if (console["__" + type]) {
252
+ console[type] = console["__" + type];
253
+ delete console["__" + type];
254
+ }
255
+ }
256
+ }
257
+ wrapStd() {
258
+ this._wrapStream(this.options.stdout, "log");
259
+ this._wrapStream(this.options.stderr, "log");
260
+ }
261
+ _wrapStream(stream, type) {
262
+ if (!stream) {
263
+ return;
264
+ }
265
+ if (!stream.__write) {
266
+ stream.__write = stream.write;
267
+ }
268
+ stream.write = (data) => {
269
+ this[type].raw(String(data).trim());
270
+ };
271
+ }
272
+ restoreStd() {
273
+ this._restoreStream(this.options.stdout);
274
+ this._restoreStream(this.options.stderr);
275
+ }
276
+ _restoreStream(stream) {
277
+ if (!stream) {
278
+ return;
279
+ }
280
+ if (stream.__write) {
281
+ stream.write = stream.__write;
282
+ delete stream.__write;
283
+ }
284
+ }
285
+ pauseLogs() {
286
+ paused = true;
287
+ }
288
+ resumeLogs() {
289
+ paused = false;
290
+ const _queue = queue.splice(0);
291
+ for (const item of _queue) {
292
+ item[0]._logFn(item[1], item[2]);
293
+ }
294
+ }
295
+ mockTypes(mockFn) {
296
+ const _mockFn = mockFn || this.options.mockFn;
297
+ this._mockFn = _mockFn;
298
+ if (typeof _mockFn !== "function") {
299
+ return;
300
+ }
301
+ for (const type in this.options.types) {
302
+ this[type] = _mockFn(type, this.options.types[type]) || this[type];
303
+ this[type].raw = this[type];
304
+ }
305
+ }
306
+ _wrapLogFn(defaults, isRaw) {
307
+ return (...args) => {
308
+ if (paused) {
309
+ queue.push([this, defaults, args, isRaw]);
310
+ return;
311
+ }
312
+ return this._logFn(defaults, args, isRaw);
313
+ };
314
+ }
315
+ _logFn(defaults, args, isRaw) {
316
+ if ((defaults.level || 0) > this.level) {
317
+ return false;
318
+ }
319
+ const logObj = {
320
+ date: /* @__PURE__ */ new Date(),
321
+ args: [],
322
+ ...defaults,
323
+ level: _normalizeLogLevel(defaults.level, this.options.types)
324
+ };
325
+ if (!isRaw && args.length === 1 && isLogObj(args[0])) {
326
+ Object.assign(logObj, args[0]);
327
+ } else {
328
+ logObj.args = [...args];
329
+ }
330
+ if (logObj.message) {
331
+ logObj.args.unshift(logObj.message);
332
+ delete logObj.message;
333
+ }
334
+ if (logObj.additional) {
335
+ if (!Array.isArray(logObj.additional)) {
336
+ logObj.additional = logObj.additional.split("\n");
337
+ }
338
+ logObj.args.push("\n" + logObj.additional.join("\n"));
339
+ delete logObj.additional;
340
+ }
341
+ logObj.type = typeof logObj.type === "string" ? logObj.type.toLowerCase() : "log";
342
+ logObj.tag = typeof logObj.tag === "string" ? logObj.tag : "";
343
+ const resolveLog = (newLog = false) => {
344
+ const repeated = (this._lastLog.count || 0) - this.options.throttleMin;
345
+ if (this._lastLog.object && repeated > 0) {
346
+ const args2 = [...this._lastLog.object.args];
347
+ if (repeated > 1) {
348
+ args2.push(`(repeated ${repeated} times)`);
349
+ }
350
+ this._log({ ...this._lastLog.object, args: args2 });
351
+ this._lastLog.count = 1;
352
+ }
353
+ if (newLog) {
354
+ this._lastLog.object = logObj;
355
+ this._log(logObj);
356
+ }
357
+ };
358
+ clearTimeout(this._lastLog.timeout);
359
+ const diffTime = this._lastLog.time && logObj.date ? logObj.date.getTime() - this._lastLog.time.getTime() : 0;
360
+ this._lastLog.time = logObj.date;
361
+ if (diffTime < this.options.throttle) {
362
+ try {
363
+ const serializedLog = JSON.stringify([
364
+ logObj.type,
365
+ logObj.tag,
366
+ logObj.args
367
+ ]);
368
+ const isSameLog = this._lastLog.serialized === serializedLog;
369
+ this._lastLog.serialized = serializedLog;
370
+ if (isSameLog) {
371
+ this._lastLog.count = (this._lastLog.count || 0) + 1;
372
+ if (this._lastLog.count > this.options.throttleMin) {
373
+ this._lastLog.timeout = setTimeout(
374
+ resolveLog,
375
+ this.options.throttle
376
+ );
377
+ return;
378
+ }
379
+ }
380
+ } catch {
381
+ }
382
+ }
383
+ resolveLog(true);
384
+ }
385
+ _log(logObj) {
386
+ for (const reporter of this.options.reporters) {
387
+ reporter.log(logObj, {
388
+ options: this.options
389
+ });
390
+ }
391
+ }
392
+ }
393
+ function _normalizeLogLevel(input, types = {}, defaultLevel = 3) {
394
+ if (input === void 0) {
395
+ return defaultLevel;
396
+ }
397
+ if (typeof input === "number") {
398
+ return input;
399
+ }
400
+ if (types[input] && types[input].level !== void 0) {
401
+ return types[input].level;
402
+ }
403
+ return defaultLevel;
404
+ }
405
+ Consola.prototype.add = Consola.prototype.addReporter;
406
+ Consola.prototype.remove = Consola.prototype.removeReporter;
407
+ Consola.prototype.clear = Consola.prototype.removeReporter;
408
+ Consola.prototype.withScope = Consola.prototype.withTag;
409
+ Consola.prototype.mock = Consola.prototype.mockTypes;
410
+ Consola.prototype.pause = Consola.prototype.pauseLogs;
411
+ Consola.prototype.resume = Consola.prototype.resumeLogs;
412
+ function createConsola$1(options = {}) {
413
+ return new Consola(options);
414
+ }
415
+
416
+ class BrowserReporter {
417
+ constructor(options) {
418
+ this.options = { ...options };
419
+ this.defaultColor = "#7f8c8d";
420
+ this.levelColorMap = {
421
+ 0: "#c0392b",
422
+ // Red
423
+ 1: "#f39c12",
424
+ // Yellow
425
+ 3: "#00BCD4"
426
+ // Cyan
427
+ };
428
+ this.typeColorMap = {
429
+ success: "#2ecc71"
430
+ // Green
431
+ };
432
+ }
433
+ _getLogFn(level) {
434
+ if (level < 1) {
435
+ return console.__error || console.error;
436
+ }
437
+ if (level === 1) {
438
+ return console.__warn || console.warn;
439
+ }
440
+ return console.__log || console.log;
441
+ }
442
+ log(logObj) {
443
+ const consoleLogFn = this._getLogFn(logObj.level);
444
+ const type = logObj.type === "log" ? "" : logObj.type;
445
+ const tag = logObj.tag || "";
446
+ const color = this.typeColorMap[logObj.type] || this.levelColorMap[logObj.level] || this.defaultColor;
447
+ const style = `
448
+ background: ${color};
6
449
  border-radius: 0.5em;
7
450
  color: white;
8
451
  font-weight: bold;
9
452
  padding: 2px 0.5em;
10
- `,p=`%c${[o,r].filter(Boolean).join(":")}`;typeof t.args[0]=="string"?e(`${p}%c ${t.args[0]}`,n,"",...t.args.slice(1)):e(p,n,...t.args)}}function P(s={}){return j({reporters:s.reporters||[new M({})],prompt(e,r={}){return r.type==="confirm"?Promise.resolve(confirm(e)):Promise.resolve(prompt(e))},...s})}const h=P(),z="0.3.2";function C(s){return{accept:"application/vnd.github.v3+json",authorization:`token ${s}`}}async function D(s,t,e){try{return await g(`https://api.github.com/repos/${t}/git/ref/tags/${s}`,{headers:C(e)}),!0}catch{return!1}}async function O(s,t){const e=C(s.github.token),r=s.github.repo;let o=`https://api.github.com/repos/${r}/releases`,i="POST";try{const c=await g(`https://api.github.com/repos/${r}/releases/tags/${s.to}`,{headers:e});c.url&&(o=c.url,i="PATCH")}catch{}const n={body:t,draft:!1,name:s.to,prerelease:s.prerelease,tag_name:s.to},p=`https://github.com/${r}/releases/new?title=${encodeURIComponent(String(n.name))}&body=${encodeURIComponent(String(n.body))}&tag=${encodeURIComponent(String(s.to))}&prerelease=${s.prerelease}`;try{h.log(v(i==="POST"?"Creating release notes...":"Updating release notes..."));const c=await g(o,{method:i,body:JSON.stringify(n),headers:e});h.log(T(`Released on ${c.html_url}`))}catch(c){throw h.error(b("Failed to create the release. Using the following link to create it manually:")),h.error(u(p)),c}}async function U(s,t){const{execa:e}=await import("execa");return(await e(s,t)).stdout.trim()}async function E(){return(await U("git",["rev-parse","--is-shallow-repository"])).trim()==="true"}function G(){const s=S("githublogen");s.version(z).option("-t, --token <path>","GitHub Token").help(),s.command("").action(async t=>{try{const e=process.cwd(),{options:r,commits:o,markdown:i}=await I({cwd:e,...t},!1);if(h.log(v(r.from)+f(" -> ")+$(r.to)+f(` (${o.length} commits)`)),await D(r.to,r.github.repo,r.github.token)||(h.error(u(`Current ref "${F(r.to)}" is not available as tags on GitHub. Release skipped.`)),process.exitCode&&(process.exitCode=1)),!o.length&&await E()){h.error(u("The repo seems to be clone shallowly, which make changelog failed to generate. You might want to specify `fetch-depth: 0` in your CI config.")),process.exitCode&&(process.exitCode=1);return}await O(r,i)}catch(e){h.error(b(String(e))),e?.stack&&h.error(f(e.stack?.split(`
11
- `).slice(1).join(`
12
- `))),process.exit(1)}}),s.parse()}G();
453
+ `;
454
+ const badge = `%c${[tag, type].filter(Boolean).join(":")}`;
455
+ if (typeof logObj.args[0] === "string") {
456
+ consoleLogFn(
457
+ `${badge}%c ${logObj.args[0]}`,
458
+ style,
459
+ // Empty string as style resets to default console style
460
+ "",
461
+ ...logObj.args.slice(1)
462
+ );
463
+ } else {
464
+ consoleLogFn(badge, style, ...logObj.args);
465
+ }
466
+ }
467
+ }
468
+
469
+ function createConsola(options = {}) {
470
+ const consola2 = createConsola$1({
471
+ reporters: options.reporters || [new BrowserReporter({})],
472
+ prompt(message, options2 = {}) {
473
+ if (options2.type === "confirm") {
474
+ return Promise.resolve(confirm(message));
475
+ }
476
+ return Promise.resolve(prompt(message));
477
+ },
478
+ ...options
479
+ });
480
+ return consola2;
481
+ }
482
+ const consola = createConsola();
483
+
484
+ const version = "0.3.4";
485
+
486
+ function getHeaders(githubToken) {
487
+ return {
488
+ accept: "application/vnd.github.v3+json",
489
+ authorization: `token ${githubToken}`
490
+ };
491
+ }
492
+ async function hasTagOnGitHub(tag, repo, githubToken) {
493
+ try {
494
+ await ofetch(`https://api.github.com/repos/${repo}/git/ref/tags/${tag}`, {
495
+ headers: getHeaders(githubToken)
496
+ });
497
+ return true;
498
+ } catch (e) {
499
+ return false;
500
+ }
501
+ }
502
+ async function sendRelease(options, content) {
503
+ const headers = getHeaders(options.github.token);
504
+ const github = options.github.repo;
505
+ let url = `https://api.github.com/repos/${github}/releases`;
506
+ let method = "POST";
507
+ try {
508
+ const exists = await ofetch(`https://api.github.com/repos/${github}/releases/tags/${options.to}`, {
509
+ headers
510
+ });
511
+ if (exists.url) {
512
+ url = exists.url;
513
+ method = "PATCH";
514
+ }
515
+ } catch (e) {
516
+ }
517
+ const body = {
518
+ body: content,
519
+ draft: false,
520
+ name: options.to,
521
+ prerelease: options.prerelease,
522
+ tag_name: options.to
523
+ };
524
+ const webUrl = `https://github.com/${github}/releases/new?title=${encodeURIComponent(
525
+ String(body.name)
526
+ )}&body=${encodeURIComponent(String(body.body))}&tag=${encodeURIComponent(String(options.to))}&prerelease=${options.prerelease}`;
527
+ try {
528
+ consola.log(cyan(method === "POST" ? "Creating release notes..." : "Updating release notes..."));
529
+ const res = await ofetch(url, {
530
+ method,
531
+ body: JSON.stringify(body),
532
+ headers
533
+ });
534
+ consola.log(green(`Released on ${res.html_url}`));
535
+ } catch (e) {
536
+ consola.error(red("Failed to create the release. Using the following link to create it manually:"));
537
+ consola.error(yellow(webUrl));
538
+ throw e;
539
+ }
540
+ }
541
+ async function execCommand(cmd, args) {
542
+ const { execa } = await import('execa');
543
+ const res = await execa(cmd, args);
544
+ return res.stdout.trim();
545
+ }
546
+ async function isRepoShallow() {
547
+ return (await execCommand("git", ["rev-parse", "--is-shallow-repository"])).trim() === "true";
548
+ }
549
+
550
+ function setupCli() {
551
+ const cli = cac("githublogen");
552
+ cli.version(version).option("-t, --token <path>", "GitHub Token").help();
553
+ cli.command("").action(async (args) => {
554
+ try {
555
+ const cwd = process.cwd();
556
+ const { options, commits, markdown } = await getChangelogMarkdown(
557
+ {
558
+ cwd,
559
+ ...args
560
+ },
561
+ false
562
+ );
563
+ consola.log(cyan(options.from) + dim(" -> ") + blue(options.to) + dim(` (${commits.length} commits)`));
564
+ if (!await hasTagOnGitHub(options.to, options.github.repo, options.github.token)) {
565
+ consola.error(yellow(`Current ref "${bold(options.to)}" is not available as tags on GitHub. Release skipped.`));
566
+ if (process.exitCode) {
567
+ process.exitCode = 1;
568
+ }
569
+ }
570
+ if (!commits.length && await isRepoShallow()) {
571
+ consola.error(
572
+ yellow(
573
+ "The repo seems to be clone shallowly, which make changelog failed to generate. You might want to specify `fetch-depth: 0` in your CI config."
574
+ )
575
+ );
576
+ if (process.exitCode) {
577
+ process.exitCode = 1;
578
+ }
579
+ return;
580
+ }
581
+ await sendRelease(options, markdown);
582
+ } catch (e) {
583
+ consola.error(red(String(e)));
584
+ if (e?.stack) {
585
+ consola.error(dim(e.stack?.split("\n").slice(1).join("\n")));
586
+ }
587
+ process.exit(1);
588
+ }
589
+ });
590
+ cli.parse();
591
+ }
592
+ setupCli();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "githublogen",
3
3
  "type": "module",
4
- "version": "0.3.2",
4
+ "version": "0.3.4",
5
5
  "sideEffects": false,
6
6
  "author": {
7
7
  "name": "Soybean",
@@ -34,14 +34,14 @@
34
34
  "cac": "6.7.14",
35
35
  "execa": "8.0.1",
36
36
  "kolorist": "1.8.0",
37
- "ofetch": "1.2.0",
38
- "@soybeanjs/changelog": "0.3.2"
37
+ "ofetch": "1.2.1",
38
+ "@soybeanjs/changelog": "0.3.4"
39
39
  },
40
40
  "devDependencies": {
41
- "@soybeanjs/cli": "0.6.7",
42
- "@types/node": "20.5.2",
41
+ "@soybeanjs/cli": "0.7.1",
42
+ "@types/node": "20.5.3",
43
43
  "typescript": "5.1.6",
44
- "unbuild": "1.2.1"
44
+ "unbuild": "2.0.0"
45
45
  },
46
46
  "scripts": {
47
47
  "build": "pnpm typecheck && unbuild",
package/dist/cli.cjs DELETED
@@ -1,12 +0,0 @@
1
- "use strict";const l=require("cac"),kolorist=require("kolorist"),changelog=require("@soybeanjs/changelog"),ofetch=require("ofetch");function _interopDefaultCompat(o){return o&&typeof o=="object"&&"default"in o?o.default:o}const l__default=_interopDefaultCompat(l),LogLevels={silent:Number.NEGATIVE_INFINITY,fatal:0,error:0,warn:1,log:2,info:3,success:3,fail:3,ready:3,start:3,box:3,debug:4,trace:5,verbose:Number.POSITIVE_INFINITY},LogTypes={silent:{level:-1},fatal:{level:LogLevels.fatal},error:{level:LogLevels.error},warn:{level:LogLevels.warn},log:{level:LogLevels.log},info:{level:LogLevels.info},success:{level:LogLevels.success},fail:{level:LogLevels.fail},ready:{level:LogLevels.info},start:{level:LogLevels.info},box:{level:LogLevels.info},debug:{level:LogLevels.debug},trace:{level:LogLevels.trace},verbose:{level:LogLevels.verbose}};function isObject(o){return o!==null&&typeof o=="object"}function _defu(o,t,e=".",r){if(!isObject(t))return _defu(o,{},e,r);const s=Object.assign({},t);for(const i in o){if(i==="__proto__"||i==="constructor")continue;const n=o[i];n!=null&&(r&&r(s,i,n,e)||(Array.isArray(n)&&Array.isArray(s[i])?s[i]=[...n,...s[i]]:isObject(n)&&isObject(s[i])?s[i]=_defu(n,s[i],(e?`${e}.`:"")+i.toString(),r):s[i]=n))}return s}function createDefu(o){return(...t)=>t.reduce((e,r)=>_defu(e,r,"",o),{})}const defu=createDefu();function isPlainObject(o){return Object.prototype.toString.call(o)==="[object Object]"}function isLogObj(o){return!(!isPlainObject(o)||!o.message&&!o.args||o.stack)}let paused=!1;const queue=[];class Consola{constructor(t={}){const e=t.types||LogTypes;this.options=defu({...t,defaults:{...t.defaults},level:_normalizeLogLevel(t.level,e),reporters:[...t.reporters||[]]},{types:LogTypes,throttle:1e3,throttleMin:5,formatOptions:{date:!0,colors:!1,compact:!0}});for(const r in e){const s={type:r,...this.options.defaults,...e[r]};this[r]=this._wrapLogFn(s),this[r].raw=this._wrapLogFn(s,!0)}this.options.mockFn&&this.mockTypes(),this._lastLog={}}get level(){return this.options.level}set level(t){this.options.level=_normalizeLogLevel(t,this.options.types,this.options.level)}prompt(t,e){if(!this.options.prompt)throw new Error("prompt is not supported!");return this.options.prompt(t,e)}create(t){const e=new Consola({...this.options,...t});return this._mockFn&&e.mockTypes(this._mockFn),e}withDefaults(t){return this.create({...this.options,defaults:{...this.options.defaults,...t}})}withTag(t){return this.withDefaults({tag:this.options.defaults.tag?this.options.defaults.tag+":"+t:t})}addReporter(t){return this.options.reporters.push(t),this}removeReporter(t){if(t){const e=this.options.reporters.indexOf(t);if(e>=0)return this.options.reporters.splice(e,1)}else this.options.reporters.splice(0);return this}setReporters(t){return this.options.reporters=Array.isArray(t)?t:[t],this}wrapAll(){this.wrapConsole(),this.wrapStd()}restoreAll(){this.restoreConsole(),this.restoreStd()}wrapConsole(){for(const t in this.options.types)console["__"+t]||(console["__"+t]=console[t]),console[t]=this[t].raw}restoreConsole(){for(const t in this.options.types)console["__"+t]&&(console[t]=console["__"+t],delete console["__"+t])}wrapStd(){this._wrapStream(this.options.stdout,"log"),this._wrapStream(this.options.stderr,"log")}_wrapStream(t,e){t&&(t.__write||(t.__write=t.write),t.write=r=>{this[e].raw(String(r).trim())})}restoreStd(){this._restoreStream(this.options.stdout),this._restoreStream(this.options.stderr)}_restoreStream(t){t&&t.__write&&(t.write=t.__write,delete t.__write)}pauseLogs(){paused=!0}resumeLogs(){paused=!1;const t=queue.splice(0);for(const e of t)e[0]._logFn(e[1],e[2])}mockTypes(t){const e=t||this.options.mockFn;if(this._mockFn=e,typeof e=="function")for(const r in this.options.types)this[r]=e(r,this.options.types[r])||this[r],this[r].raw=this[r]}_wrapLogFn(t,e){return(...r)=>{if(paused){queue.push([this,t,r,e]);return}return this._logFn(t,r,e)}}_logFn(t,e,r){if((t.level||0)>this.level)return!1;const s={date:new Date,args:[],...t,level:_normalizeLogLevel(t.level,this.options.types)};!r&&e.length===1&&isLogObj(e[0])?Object.assign(s,e[0]):s.args=[...e],s.message&&(s.args.unshift(s.message),delete s.message),s.additional&&(Array.isArray(s.additional)||(s.additional=s.additional.split(`
2
- `)),s.args.push(`
3
- `+s.additional.join(`
4
- `)),delete s.additional),s.type=typeof s.type=="string"?s.type.toLowerCase():"log",s.tag=typeof s.tag=="string"?s.tag:"";const i=(c=!1)=>{const a=(this._lastLog.count||0)-this.options.throttleMin;if(this._lastLog.object&&a>0){const p=[...this._lastLog.object.args];a>1&&p.push(`(repeated ${a} times)`),this._log({...this._lastLog.object,args:p}),this._lastLog.count=1}c&&(this._lastLog.object=s,this._log(s))};clearTimeout(this._lastLog.timeout);const n=this._lastLog.time&&s.date?s.date.getTime()-this._lastLog.time.getTime():0;if(this._lastLog.time=s.date,n<this.options.throttle)try{const c=JSON.stringify([s.type,s.tag,s.args]),a=this._lastLog.serialized===c;if(this._lastLog.serialized=c,a&&(this._lastLog.count=(this._lastLog.count||0)+1,this._lastLog.count>this.options.throttleMin)){this._lastLog.timeout=setTimeout(i,this.options.throttle);return}}catch{}i(!0)}_log(t){for(const e of this.options.reporters)e.log(t,{options:this.options})}}function _normalizeLogLevel(o,t={},e=3){return o===void 0?e:typeof o=="number"?o:t[o]&&t[o].level!==void 0?t[o].level:e}Consola.prototype.add=Consola.prototype.addReporter,Consola.prototype.remove=Consola.prototype.removeReporter,Consola.prototype.clear=Consola.prototype.removeReporter,Consola.prototype.withScope=Consola.prototype.withTag,Consola.prototype.mock=Consola.prototype.mockTypes,Consola.prototype.pause=Consola.prototype.pauseLogs,Consola.prototype.resume=Consola.prototype.resumeLogs;function createConsola$1(o={}){return new Consola(o)}class BrowserReporter{constructor(t){this.options={...t},this.defaultColor="#7f8c8d",this.levelColorMap={0:"#c0392b",1:"#f39c12",3:"#00BCD4"},this.typeColorMap={success:"#2ecc71"}}_getLogFn(t){return t<1?console.__error||console.error:t===1?console.__warn||console.warn:console.__log||console.log}log(t){const e=this._getLogFn(t.level),r=t.type==="log"?"":t.type,s=t.tag||"",n=`
5
- background: ${this.typeColorMap[t.type]||this.levelColorMap[t.level]||this.defaultColor};
6
- border-radius: 0.5em;
7
- color: white;
8
- font-weight: bold;
9
- padding: 2px 0.5em;
10
- `,c=`%c${[s,r].filter(Boolean).join(":")}`;typeof t.args[0]=="string"?e(`${c}%c ${t.args[0]}`,n,"",...t.args.slice(1)):e(c,n,...t.args)}}function createConsola(o={}){return createConsola$1({reporters:o.reporters||[new BrowserReporter({})],prompt(e,r={}){return r.type==="confirm"?Promise.resolve(confirm(e)):Promise.resolve(prompt(e))},...o})}const consola=createConsola(),version="0.3.2";function g(o){return{accept:"application/vnd.github.v3+json",authorization:`token ${o}`}}async function hasTagOnGitHub(o,t,e){try{return await ofetch.ofetch(`https://api.github.com/repos/${t}/git/ref/tags/${o}`,{headers:g(e)}),!0}catch{return!1}}async function sendRelease(o,t){const e=g(o.github.token),r=o.github.repo;let s=`https://api.github.com/repos/${r}/releases`,i="POST";try{const a=await ofetch.ofetch(`https://api.github.com/repos/${r}/releases/tags/${o.to}`,{headers:e});a.url&&(s=a.url,i="PATCH")}catch{}const n={body:t,draft:!1,name:o.to,prerelease:o.prerelease,tag_name:o.to},c=`https://github.com/${r}/releases/new?title=${encodeURIComponent(String(n.name))}&body=${encodeURIComponent(String(n.body))}&tag=${encodeURIComponent(String(o.to))}&prerelease=${o.prerelease}`;try{consola.log(kolorist.cyan(i==="POST"?"Creating release notes...":"Updating release notes..."));const a=await ofetch.ofetch(s,{method:i,body:JSON.stringify(n),headers:e});consola.log(kolorist.green(`Released on ${a.html_url}`))}catch(a){throw consola.error(kolorist.red("Failed to create the release. Using the following link to create it manually:")),consola.error(kolorist.yellow(c)),a}}async function y(o,t){const{execa:e}=await import("execa");return(await e(o,t)).stdout.trim()}async function isRepoShallow(){return(await y("git",["rev-parse","--is-shallow-repository"])).trim()==="true"}function k(){const o=l__default("githublogen");o.version(version).option("-t, --token <path>","GitHub Token").help(),o.command("").action(async t=>{try{const e=process.cwd(),{options:r,commits:s,markdown:i}=await changelog.getChangelogMarkdown({cwd:e,...t},!1);if(consola.log(kolorist.cyan(r.from)+kolorist.dim(" -> ")+kolorist.blue(r.to)+kolorist.dim(` (${s.length} commits)`)),await hasTagOnGitHub(r.to,r.github.repo,r.github.token)||(consola.error(kolorist.yellow(`Current ref "${kolorist.bold(r.to)}" is not available as tags on GitHub. Release skipped.`)),process.exitCode&&(process.exitCode=1)),!s.length&&await isRepoShallow()){consola.error(kolorist.yellow("The repo seems to be clone shallowly, which make changelog failed to generate. You might want to specify `fetch-depth: 0` in your CI config.")),process.exitCode&&(process.exitCode=1);return}await sendRelease(r,i)}catch(e){consola.error(kolorist.red(String(e))),e?.stack&&consola.error(kolorist.dim(e.stack?.split(`
11
- `).slice(1).join(`
12
- `))),process.exit(1)}}),o.parse()}k();