diff --git a/dist/index.mjs b/dist/index.mjs
index 540deea..db12b8b 100644
--- a/dist/index.mjs
+++ b/dist/index.mjs
@@ -23,7 +23,14 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
-var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
+var __esmMin = (fn, res, err) => () => {
+ if (err) throw err[0];
+ try {
+ return fn && (res = fn(fn = 0)), res;
+ } catch (e) {
+ throw err = [e], e;
+ }
+};
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
var __exportAll = (all, no_symbols) => {
let target = {};
@@ -49,7 +56,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
enumerable: true
}) : target, mod));
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
-var __require$1 = /* @__PURE__ */ createRequire(import.meta.url);
+var __require$1 = /* #__PURE__ */ (() => createRequire(import.meta.url))();
//#endregion
//#region node_modules/.pnpm/@actions+core@3.0.1/node_modules/@actions/core/lib/utils.js
/**
@@ -6616,7 +6623,8 @@ var require_client = /* @__PURE__ */ __commonJSMin(((exports, module) => {
this.once("connect", cb);
}
[kDispatch](opts, handler) {
- const request = new Request(opts.origin || this[kUrl].origin, opts, handler);
+ const origin = opts.origin || this[kUrl].origin;
+ const request = new Request(origin, opts, handler);
this[kQueue].push(request);
if (this[kResuming]) {} else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) {
this[kResuming] = 1;
@@ -8024,7 +8032,7 @@ var require_readable = /* @__PURE__ */ __commonJSMin(((exports, module) => {
* @returns {Uint8Array}
*/
function chunksConcat(chunks, length) {
- if (chunks.length === 0 || length === 0) return new Uint8Array(0);
+ if (chunks.length === 0 || length === 0) return /* @__PURE__ */ new Uint8Array(0);
if (chunks.length === 1) return new Uint8Array(chunks[0]);
const buffer = new Uint8Array(Buffer.allocUnsafeSlow(length).buffer);
let offset = 0;
@@ -8914,7 +8922,10 @@ var require_mock_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== "undefined" ? matchValue(body, key.body) : true);
if (matchedMockDispatches.length === 0) throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}' on path '${resolvedPath}'`);
matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => matchHeaders(mockDispatch, key.headers));
- if (matchedMockDispatches.length === 0) throw new MockNotMatchedError(`Mock dispatch not matched for headers '${typeof key.headers === "object" ? JSON.stringify(key.headers) : key.headers}' on path '${resolvedPath}'`);
+ if (matchedMockDispatches.length === 0) {
+ const headers = typeof key.headers === "object" ? JSON.stringify(key.headers) : key.headers;
+ throw new MockNotMatchedError(`Mock dispatch not matched for headers '${headers}' on path '${resolvedPath}'`);
+ }
return matchedMockDispatches[0];
}
function addMockDispatch(mockDispatches, key, data) {
@@ -10233,7 +10244,8 @@ var require_response = /* @__PURE__ */ __commonJSMin(((exports, module) => {
static json(data, init = {}) {
webidl.argumentLengthCheck(arguments, 1, "Response.json");
if (init !== null) init = webidl.converters.ResponseInit(init);
- const body = extractBody(textEncoder.encode(serializeJavascriptValueToJSONString(data)));
+ const bytes = textEncoder.encode(serializeJavascriptValueToJSONString(data));
+ const body = extractBody(bytes);
const responseObject = fromInnerResponse(makeResponse({}), "response");
initializeResponse(responseObject, init, {
body: body[0],
@@ -11202,7 +11214,8 @@ var require_fetch$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
taskDestination = request.client.globalObject;
crossOriginIsolatedCapability = request.client.crossOriginIsolatedCapability;
}
- const timingInfo = createOpaqueTimingInfo({ startTime: coarsenedSharedCurrentTime(crossOriginIsolatedCapability) });
+ const currentTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability);
+ const timingInfo = createOpaqueTimingInfo({ startTime: currentTime });
const fetchParams = {
controller: new Fetch(dispatcher),
request,
@@ -11310,7 +11323,8 @@ var require_fetch$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
response.headersList.set("content-type", type, true);
} else {
response.rangeRequested = true;
- const rangeValue = simpleRangeHeaderValue(request.headersList.get("range", true), true);
+ const rangeHeader = request.headersList.get("range", true);
+ const rangeValue = simpleRangeHeaderValue(rangeHeader, true);
if (rangeValue === "failure") return Promise.resolve(makeNetworkError("failed to fetch the data URL"));
let { rangeStartValue: rangeStart, rangeEndValue: rangeEnd } = rangeValue;
if (rangeStart === null) {
@@ -11333,7 +11347,8 @@ var require_fetch$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
return Promise.resolve(response);
}
case "data:": {
- const dataURLStruct = dataURLProcessor(requestCurrentURL(request));
+ const currentURL = requestCurrentURL(request);
+ const dataURLStruct = dataURLProcessor(currentURL);
if (dataURLStruct === "failure") return Promise.resolve(makeNetworkError("failed to fetch the data URL"));
const mimeType = serializeAMimeType(dataURLStruct.mimeType);
return Promise.resolve(makeResponse({
@@ -12692,8 +12707,10 @@ var require_cache = /* @__PURE__ */ __commonJSMin(((exports, module) => {
});
const clonedResponse = cloneResponse(innerResponse);
const bodyReadPromise = createDeferredPromise();
- if (innerResponse.body != null) readAllBytes(innerResponse.body.stream.getReader()).then(bodyReadPromise.resolve, bodyReadPromise.reject);
- else bodyReadPromise.resolve(void 0);
+ if (innerResponse.body != null) {
+ const reader = innerResponse.body.stream.getReader();
+ readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject);
+ } else bodyReadPromise.resolve(void 0);
/** @type {CacheBatchOperation[]} */
const operations = [];
/** @type {CacheBatchOperation} */
@@ -12985,7 +13002,10 @@ var require_cachestorage = /* @__PURE__ */ __commonJSMin(((exports, module) => {
request = webidl.converters.RequestInfo(request);
options = webidl.converters.MultiCacheQueryOptions(options);
if (options.cacheName != null) {
- if (this.#caches.has(options.cacheName)) return await new Cache(kConstruct, this.#caches.get(options.cacheName)).match(request, options);
+ if (this.#caches.has(options.cacheName)) {
+ const cacheList = this.#caches.get(options.cacheName);
+ return await new Cache(kConstruct, cacheList).match(request, options);
+ }
} else for (const cacheList of this.#caches.values()) {
const response = await new Cache(kConstruct, cacheList).match(request, options);
if (response !== void 0) return response;
@@ -13013,7 +13033,10 @@ var require_cachestorage = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const prefix = "CacheStorage.open";
webidl.argumentLengthCheck(arguments, 1, prefix);
cacheName = webidl.converters.DOMString(cacheName, prefix, "cacheName");
- if (this.#caches.has(cacheName)) return new Cache(kConstruct, this.#caches.get(cacheName));
+ if (this.#caches.has(cacheName)) {
+ const cache = this.#caches.get(cacheName);
+ return new Cache(kConstruct, cache);
+ }
const cache = [];
this.#caches.set(cacheName, cache);
return new Cache(kConstruct, cache);
@@ -21137,7 +21160,8 @@ var require_parse$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
};
const extglobClose = (token) => {
const literal = input.slice(token.startIndex, state.index + 1);
- const analysis = analyzeRepeatedExtglob(input.slice(token.startIndex + 2, state.index), opts);
+ const body = input.slice(token.startIndex + 2, state.index);
+ const analysis = analyzeRepeatedExtglob(body, opts);
if ((token.type === "plus" || token.type === "star") && analysis.risky) {
const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : void 0;
const open = tokens[token.tokensIndex];
@@ -21263,7 +21287,8 @@ var require_parse$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
if (inner.includes(":")) {
const idx = prev.value.lastIndexOf("[");
const pre = prev.value.slice(0, idx);
- const posix = POSIX_REGEX_SOURCE[prev.value.slice(idx + 2)];
+ const rest = prev.value.slice(idx + 2);
+ const posix = POSIX_REGEX_SOURCE[rest];
if (posix) {
prev.value = pre + posix;
state.backtrack = true;
@@ -22552,9 +22577,9 @@ function camelCase(input, options) {
return leadingPrefix + postProcess(input, toUpperCase, options);
}
//#endregion
-//#region node_modules/.pnpm/marked@18.0.5/node_modules/marked/lib/marked.esm.js
+//#region node_modules/.pnpm/marked@18.0.7/node_modules/marked/lib/marked.esm.js
/**
-* marked v18.0.5 - a markdown parser
+* marked v18.0.7 - a markdown parser
* Copyright (c) 2018-2026, MarkedJS. (MIT License)
* Copyright (c) 2011-2018, Christopher Jeffrey. (MIT License)
* https://github.com/markedjs/marked
@@ -22563,7 +22588,7 @@ function camelCase(input, options) {
* DO NOT EDIT THIS FILE
* The code in this file is generated from files in ./src/
*/
-function M() {
+function z() {
return {
async: !1,
breaks: !1,
@@ -22577,7 +22602,7 @@ function M() {
walkTokens: null
};
}
-var T = M();
+var T = z();
function N(l) {
T = l;
}
@@ -22605,7 +22630,8 @@ var Te = ((l = "") => {
} catch {
return !1;
}
-})(), m = {
+})();
+var m = {
codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm,
outputLinkReplace: /\\([\[\]])/g,
indentCodeCompensation: /^(\s+)(?:```)/,
@@ -22662,26 +22688,50 @@ var Te = ((l = "") => {
headingBeginRegex: E((l) => new RegExp(`^ {0,${l}}#`)),
htmlBeginRegex: E((l) => new RegExp(`^ {0,${l}}<(?:[a-z].*>|!--)`, "i")),
blockquoteBeginRegex: E((l) => new RegExp(`^ {0,${l}}>`))
-}, Oe = /^(?:[ \t]*(?:\n|$))+/, we = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/, ye = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/, B = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, Pe = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, j = / {0,3}(?:[*+-]|\d{1,9}[.)])/, oe = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/, ae = d(oe).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex(), Se = d(oe).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(), F = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, $e = /^[^\n]+/, U = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/, Le = d(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", U).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(), _e = d(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g, j).getRegex(), H = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul", K = /|$))/, ze = d("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", K).replace("tag", H).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(), le = d(F).replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html", "?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex(), W = {
- blockquote: d(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", le).getRegex(),
+};
+var Oe = /^(?:[ \t]*(?:\n|$))+/;
+var we = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
+var ye = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
+var B = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
+var Pe = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
+var j = / {0,3}(?:[*+-]|\d{1,9}[.)])/;
+var oe = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
+var ae = d(oe).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}(?:\s|$)/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex();
+var Se = d(oe).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}(?:\s|$)/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex();
+var F = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \t]+\n)[^\n]+)*)/;
+var $e = /^[^\n]+/;
+var U = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/;
+var Le = d(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", U).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
+var _e = d(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g, j).getRegex();
+var H = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
+var K = /|$))/;
+var Me = d("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:\\1>[^\\n]*\\n*|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>[^\\n]*\\n*|$)|[^\\n]*\\n*|$)|[^\\n]*\\n*|$)|?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", K).replace("tag", H).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
+var le = (l) => d(F).replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~~~)[^\\n]*\\n").replace("list", l).replace("html", "?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex();
+var ze = le(/ {0,3}(?:[*+-]|1[.)])[ \t]+[^ \t\n]/);
+var Ee = le(/ {0,3}(?:[*+-]|\d{1,9}[.)])(?:[ \t]|\n|$)/);
+var W = {
+ blockquote: d(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", Ee).getRegex(),
code: we,
def: Le,
fences: ye,
heading: Pe,
hr: B,
- html: ze,
+ html: Me,
lheading: ae,
list: _e,
newline: Oe,
- paragraph: le,
+ paragraph: ze,
table: _,
text: $e
-}, se = d("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex(), Ee = {
+};
+var se = d("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~~~)[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex();
+var Ae = {
...W,
lheading: Se,
table: se,
- paragraph: d(F).replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html", "?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex()
-}, Ie = {
+ paragraph: d(F).replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~~~)[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html", "?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex()
+};
+var Ie = {
...W,
html: d(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?\\1> *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", K).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),
def: /^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
@@ -22690,63 +22740,101 @@ var Te = ((l = "") => {
lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
paragraph: d(F).replace("hr", B).replace("heading", ` *#{1,6} *[^
]`).replace("lheading", ae).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex()
-}, Ae = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, Ce = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, ue = /^( {2,}|\\)\n(?!\s*$)/, Be = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\`+)[^`]+\k(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", Te ? "(?`+)[^`]+\k(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex(), ce = /^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/, Ze = d(ce, "u").replace(/punct/g, I).getRegex(), Ge = d(ce, "u").replace(/punct/g, pe).getRegex(), he = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)", Ne = d(he, "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, I).getRegex(), Qe = d(he, "gu").replace(/notPunctSpace/g, ve).replace(/punctSpace/g, qe).replace(/punct/g, pe).getRegex(), je = d("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, I).getRegex(), Fe = d(/^~~?(?:((?!~)punct)|[^\s~])/, "u").replace(/punct/g, I).getRegex(), Ke = d("^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)", "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, I).getRegex(), We = d(/\\(punct)/, "gu").replace(/punct/g, I).getRegex(), Xe = d(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(), Je = d(K).replace("(?:-->|$)", "-->").getRegex(), Ve = d("^comment|^[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^").replace("comment", Je).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(), v = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/, Ye = d(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", v).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(), ke = d(/^!?\[(label)\]\[(ref)\]/).replace("label", v).replace("ref", U).getRegex(), de = d(/^!?\[(ref)\](?:\[\])?/).replace("ref", U).getRegex(), et = d("reflink|nolink(?!\\()", "g").replace("reflink", ke).replace("nolink", de).getRegex(), ie = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/, J = {
+};
+var Be = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
+var qe = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
+var ue = /^( {2,}|\\)\n(?!\s*$)/;
+var De = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\`+)[^`]+\k(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", Te ? "(?`+)[^`]+\k(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
+var ce = /^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/;
+var Ne = d(ce, "u").replace(/punct/g, C).getRegex();
+var Qe = d(ce, "u").replace(/punct/g, pe).getRegex();
+var he = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
+var je = d(he, "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, C).getRegex();
+var Fe = d(he, "gu").replace(/notPunctSpace/g, Ze).replace(/punctSpace/g, He).replace(/punct/g, pe).getRegex();
+var Ue = d("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, C).getRegex();
+var Ke = d(/^~~?(?:((?!~)punct)|[^\s~])/, "u").replace(/punct/g, C).getRegex();
+var Xe = d("^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)", "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, C).getRegex();
+var Je = d(/\\(punct)/, "gu").replace(/punct/g, C).getRegex();
+var Ve = d(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex();
+var Ye = d(K).replace("(?:-->|$)", "-->").getRegex();
+var et = d("^comment|^[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^").replace("comment", Ye).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
+var v = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/;
+var tt = d(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", v).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]+|(?=\))/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
+var ke = d(/^!?\[(label)\]\[(ref)\]/).replace("label", v).replace("ref", U).getRegex();
+var de = d(/^!?\[(ref)\](?:\[\])?/).replace("ref", U).getRegex();
+var nt = d("reflink|nolink(?!\\()", "g").replace("reflink", ke).replace("nolink", de).getRegex();
+var ie = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
+var J = {
_backpedal: _,
- anyPunctuation: We,
- autolink: Xe,
- blockSkip: He,
+ anyPunctuation: Je,
+ autolink: Ve,
+ blockSkip: Ge,
br: ue,
- code: Ce,
+ code: qe,
del: _,
delLDelim: _,
delRDelim: _,
- emStrongLDelim: Ze,
- emStrongRDelimAst: Ne,
- emStrongRDelimUnd: je,
- escape: Ae,
- link: Ye,
+ emStrongLDelim: Ne,
+ emStrongRDelimAst: je,
+ emStrongRDelimUnd: Ue,
+ escape: Be,
+ link: tt,
nolink: de,
- punctuation: De,
+ punctuation: ve,
reflink: ke,
- reflinkSearch: et,
- tag: Ve,
- text: Be,
+ reflinkSearch: nt,
+ tag: et,
+ text: De,
url: _
-}, tt = {
+};
+var rt = {
...J,
link: d(/^!?\[(label)\]\((.*?)\)/).replace("label", v).getRegex(),
reflink: d(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", v).getRegex()
-}, Q = {
+};
+var Q = {
...J,
- emStrongRDelimAst: Qe,
- emStrongLDelim: Ge,
- delLDelim: Fe,
- delRDelim: Ke,
+ emStrongRDelimAst: Fe,
+ emStrongLDelim: Qe,
+ delLDelim: Ke,
+ delRDelim: Xe,
url: d(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ie).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),
_backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/,
- text: d(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\": ">",
"\"": """,
"'": "'"
-}, ge = (l) => rt[l];
+};
+var ge = (l) => it[l];
function O(l, e) {
if (e) {
if (m.escapeTest.test(l)) return l.replace(m.escapeReplace, ge);
@@ -22820,7 +22908,7 @@ function xe(l, e, t, n, s) {
};
return n.state.inLink = !1, u;
}
-function st(l, e, t) {
+function ot(l, e, t) {
let n = l.match(t.other.indentCodeCompensation);
if (n === null) return e;
let s = n[1];
@@ -22862,7 +22950,7 @@ var w = class {
fences(e) {
let t = this.rules.block.fences.exec(e);
if (t) {
- let n = t[0], s = st(n, t[3] || "", this.rules);
+ let n = t[0], s = ot(n, t[3] || "", this.rules);
return {
type: "code",
raw: n,
@@ -22909,27 +22997,27 @@ var w = class {
else if (!o) u.push(n[a]);
else break;
n = n.slice(a);
- let c = u.join(`
-`), p = c.replace(this.rules.other.blockquoteSetextReplace, `
+ let p = u.join(`
+`), c = p.replace(this.rules.other.blockquoteSetextReplace, `
$1`).replace(this.rules.other.blockquoteSetextReplace2, "");
s = s ? `${s}
-${c}` : c, r = r ? `${r}
-${p}` : p;
- let k = this.lexer.state.top;
- if (this.lexer.state.top = !0, this.lexer.blockTokens(p, i, !0), this.lexer.state.top = k, n.length === 0) break;
- let h = i.at(-1);
- if (h?.type === "code") break;
- if (h?.type === "blockquote") {
- let R = h, f = R.raw + `
+${p}` : p, r = r ? `${r}
+${c}` : c;
+ let h = this.lexer.state.top;
+ if (this.lexer.state.top = !0, this.lexer.blockTokens(c, i, !0), this.lexer.state.top = h, n.length === 0) break;
+ let k = i.at(-1);
+ if (k?.type === "code") break;
+ if (k?.type === "blockquote") {
+ let R = k, f = R.raw + `
` + n.join(`
`), S = this.blockquote(f);
i[i.length - 1] = S, s = s.substring(0, s.length - R.raw.length) + S.raw, r = r.substring(0, r.length - R.text.length) + S.text;
break;
- } else if (h?.type === "list") {
- let R = h, f = R.raw + `
+ } else if (k?.type === "list") {
+ let R = k, f = R.raw + `
` + n.join(`
`), S = this.list(f);
- i[i.length - 1] = S, s = s.substring(0, s.length - h.raw.length) + S.raw, r = r.substring(0, r.length - R.raw.length) + S.raw, n = f.substring(i.at(-1).raw.length).split(`
+ i[i.length - 1] = S, s = s.substring(0, s.length - k.raw.length) + S.raw, r = r.substring(0, r.length - R.raw.length) + S.raw, n = f.substring(i.at(-1).raw.length).split(`
`);
continue;
}
@@ -22956,38 +23044,38 @@ ${p}` : p;
n = s ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = s ? n : "[*+-]");
let i = this.rules.other.listItemRegex(n), o = !1;
for (; e;) {
- let a = !1, c = "", p = "";
+ let a = !1, p = "", c = "";
if (!(t = i.exec(e)) || this.rules.block.hr.test(e)) break;
- c = t[0], e = e.substring(c.length);
- let k = me(t[2].split(`
-`, 1)[0], t[1].length), h = e.split(`
-`, 1)[0], R = !k.trim(), f = 0;
- if (this.options.pedantic ? (f = 2, p = k.trimStart()) : R ? f = t[1].length + 1 : (f = k.search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, p = k.slice(f), f += t[1].length), R && this.rules.other.blankLine.test(h) && (c += h + `
-`, e = e.substring(h.length + 1), a = !0), !a) {
+ p = t[0], e = e.substring(p.length);
+ let h = me(t[2].split(`
+`, 1)[0], t[1].length), k = e.split(`
+`, 1)[0], R = !h.trim(), f = 0;
+ if (this.options.pedantic ? (f = 2, c = h.trimStart()) : R ? f = t[1].length + 1 : (f = h.search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, c = h.slice(f), f += t[1].length), R && this.rules.other.blankLine.test(k) && (p += k + `
+`, e = e.substring(k.length + 1), a = !0), !a) {
let S = this.rules.other.nextBulletRegex(f), te = this.rules.other.hrRegex(f), ne = this.rules.other.fencesBeginRegex(f), re = this.rules.other.headingBeginRegex(f), be = this.rules.other.htmlBeginRegex(f), Re = this.rules.other.blockquoteBeginRegex(f);
for (; e;) {
let G = e.split(`
-`, 1)[0], C;
- if (h = G, this.options.pedantic ? (h = h.replace(this.rules.other.listReplaceNesting, " "), C = h) : C = h.replace(this.rules.other.tabCharGlobal, " "), ne.test(h) || re.test(h) || be.test(h) || Re.test(h) || S.test(h) || te.test(h)) break;
- if (C.search(this.rules.other.nonSpaceChar) >= f || !h.trim()) p += `
-` + C.slice(f);
+`, 1)[0], I;
+ if (k = G, this.options.pedantic ? (k = k.replace(this.rules.other.listReplaceNesting, " "), I = k) : I = k.replace(this.rules.other.tabCharGlobal, " "), ne.test(k) || re.test(k) || be.test(k) || Re.test(k) || S.test(k) || te.test(k)) break;
+ if (I.search(this.rules.other.nonSpaceChar) >= f || !k.trim()) c += `
+` + I.slice(f);
else {
- if (R || k.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ne.test(k) || re.test(k) || te.test(k)) break;
- p += `
-` + h;
+ if (R || h.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ne.test(h) || re.test(h) || te.test(h)) break;
+ c += `
+` + k;
}
- R = !h.trim(), c += G + `
-`, e = e.substring(G.length + 1), k = C.slice(f);
+ R = !k.trim(), p += G + `
+`, e = e.substring(G.length + 1), h = I.slice(f);
}
}
- r.loose || (o ? r.loose = !0 : this.rules.other.doubleBlankLine.test(c) && (o = !0)), r.items.push({
+ r.loose || (o ? r.loose = !0 : this.rules.other.doubleBlankLine.test(p) && (o = !0)), r.items.push({
type: "list_item",
- raw: c,
- task: !!this.options.gfm && this.rules.other.listIsTask.test(p),
+ raw: p,
+ task: !!this.options.gfm && this.rules.other.listIsTask.test(c),
loose: !1,
- text: p,
+ text: c,
tokens: []
- }), r.raw += c;
+ }), r.raw += p;
}
let u = r.items.at(-1);
if (u) u.raw = u.raw.trimEnd(), u.text = u.text.trimEnd();
@@ -22995,36 +23083,36 @@ ${p}` : p;
r.raw = r.raw.trimEnd();
for (let a of r.items) {
this.lexer.state.top = !1, a.tokens = this.lexer.blockTokens(a.text, []);
- let c = a.tokens[0];
- if (a.task && (c?.type === "text" || c?.type === "paragraph")) {
- a.text = a.text.replace(this.rules.other.listReplaceTask, ""), c.raw = c.raw.replace(this.rules.other.listReplaceTask, ""), c.text = c.text.replace(this.rules.other.listReplaceTask, "");
- for (let k = this.lexer.inlineQueue.length - 1; k >= 0; k--) if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[k].src)) {
- this.lexer.inlineQueue[k].src = this.lexer.inlineQueue[k].src.replace(this.rules.other.listReplaceTask, "");
+ let p = a.tokens[0];
+ if (a.task && (p?.type === "text" || p?.type === "paragraph")) {
+ a.text = a.text.replace(this.rules.other.listReplaceTask, ""), p.raw = p.raw.replace(this.rules.other.listReplaceTask, ""), p.text = p.text.replace(this.rules.other.listReplaceTask, "");
+ for (let h = this.lexer.inlineQueue.length - 1; h >= 0; h--) if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[h].src)) {
+ this.lexer.inlineQueue[h].src = this.lexer.inlineQueue[h].src.replace(this.rules.other.listReplaceTask, "");
break;
}
- let p = this.rules.other.listTaskCheckbox.exec(a.raw);
- if (p) {
- let k = {
+ let c = this.rules.other.listTaskCheckbox.exec(a.raw);
+ if (c) {
+ let h = {
type: "checkbox",
- raw: p[0] + " ",
- checked: p[0] !== "[ ]"
+ raw: c[0] + " ",
+ checked: c[0] !== "[ ]"
};
- a.checked = k.checked, r.loose ? a.tokens[0] && ["paragraph", "text"].includes(a.tokens[0].type) && "tokens" in a.tokens[0] && a.tokens[0].tokens ? (a.tokens[0].raw = k.raw + a.tokens[0].raw, a.tokens[0].text = k.raw + a.tokens[0].text, a.tokens[0].tokens.unshift(k)) : a.tokens.unshift({
+ a.checked = h.checked, r.loose ? a.tokens[0] && ["paragraph", "text"].includes(a.tokens[0].type) && "tokens" in a.tokens[0] && a.tokens[0].tokens ? (a.tokens[0].raw = h.raw + a.tokens[0].raw, a.tokens[0].text = h.raw + a.tokens[0].text, a.tokens[0].tokens.unshift(h)) : a.tokens.unshift({
type: "paragraph",
- raw: k.raw,
- text: k.raw,
- tokens: [k]
- }) : a.tokens.unshift(k);
+ raw: h.raw,
+ text: h.raw,
+ tokens: [h]
+ }) : a.tokens.unshift(h);
}
} else a.task && (a.task = !1);
if (!r.loose) {
- let p = a.tokens.filter((h) => h.type === "space");
- r.loose = p.length > 0 && p.some((h) => this.rules.other.anyLine.test(h.raw));
+ let c = a.tokens.filter((k) => k.type === "space");
+ r.loose = c.length > 0 && c.some((k) => this.rules.other.anyLine.test(k.raw));
}
}
if (r.loose) for (let a of r.items) {
a.loose = !0;
- for (let c of a.tokens) c.type === "text" && (c.type = "paragraph");
+ for (let p of a.tokens) p.type === "text" && (p.type = "paragraph");
}
return r;
}
@@ -23186,32 +23274,32 @@ ${p}` : p;
let s = this.rules.inline.emStrongLDelim.exec(e);
if (!s || !s[1] && !s[2] && !s[3] && !s[4] || s[4] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
if (!(s[1] || s[3] || "") || !n || this.rules.inline.punctuation.exec(n)) {
- let i = [...s[0]].length - 1, o, u, a = i, c = 0, p = s[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
- for (p.lastIndex = 0, t = t.slice(-1 * e.length + i); (s = p.exec(t)) !== null;) {
+ let i = [...s[0]].length - 1, o, u, a = i, p = 0, c = s[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
+ for (c.lastIndex = 0, t = t.slice(-1 * e.length + i); (s = c.exec(t)) !== null;) {
if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o) continue;
if (u = [...o].length, s[3] || s[4]) {
a += u;
continue;
} else if ((s[5] || s[6]) && i % 3 && !((i + u) % 3)) {
- c += u;
+ p += u;
continue;
}
if (a -= u, a > 0) continue;
- u = Math.min(u, u + a + c);
- let k = [...s[0]][0].length, h = e.slice(0, i + s.index + k + u);
+ u = Math.min(u, u + a + p);
+ let h = [...s[0]][0].length, k = e.slice(0, i + s.index + h + u);
if (Math.min(i, u) % 2) {
- let f = h.slice(1, -1);
+ let f = k.slice(1, -1);
return {
type: "em",
- raw: h,
+ raw: k,
text: f,
tokens: this.lexer.inlineTokens(f)
};
}
- let R = h.slice(2, -2);
+ let R = k.slice(2, -2);
return {
type: "strong",
- raw: h,
+ raw: k,
text: R,
tokens: this.lexer.inlineTokens(R)
};
@@ -23240,8 +23328,8 @@ ${p}` : p;
let s = this.rules.inline.delLDelim.exec(e);
if (!s) return;
if (!(s[1] || "") || !n || this.rules.inline.punctuation.exec(n)) {
- let i = [...s[0]].length - 1, o, u, a = i, c = this.rules.inline.delRDelim;
- for (c.lastIndex = 0, t = t.slice(-1 * e.length + i); (s = c.exec(t)) !== null;) {
+ let i = [...s[0]].length - 1, o, u, a = i, p = this.rules.inline.delRDelim;
+ for (p.lastIndex = 0, t = t.slice(-1 * e.length + i); (s = p.exec(t)) !== null;) {
if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o || (u = [...o].length, u !== i)) continue;
if (s[3] || s[4]) {
a += u;
@@ -23249,12 +23337,12 @@ ${p}` : p;
}
if (a -= u, a > 0) continue;
u = Math.min(u, u + a);
- let p = [...s[0]][0].length, k = e.slice(0, i + s.index + p + u), h = k.slice(i, -i);
+ let c = [...s[0]][0].length, h = e.slice(0, i + s.index + c + u), k = h.slice(i, -i);
return {
type: "del",
- raw: k,
- text: h,
- tokens: this.lexer.inlineTokens(h)
+ raw: h,
+ text: k,
+ tokens: this.lexer.inlineTokens(k)
};
}
}
@@ -23328,14 +23416,14 @@ var x = class l {
};
let t = {
other: m,
- block: D.normal,
+ block: q.normal,
inline: A.normal
};
- this.options.pedantic ? (t.block = D.pedantic, t.inline = A.pedantic) : this.options.gfm && (t.block = D.gfm, this.options.breaks ? t.inline = A.breaks : t.inline = A.gfm), this.tokenizer.rules = t;
+ this.options.pedantic ? (t.block = q.pedantic, t.inline = A.pedantic) : this.options.gfm && (t.block = q.gfm, this.options.breaks ? t.inline = A.breaks : t.inline = A.gfm), this.tokenizer.rules = t;
}
static get rules() {
return {
- block: D,
+ block: q,
inline: A
};
}
@@ -23428,8 +23516,8 @@ var x = class l {
let i = e;
if (this.options.extensions?.startBlock) {
let o = Infinity, u = e.slice(1), a;
- this.options.extensions.startBlock.forEach((c) => {
- a = c.call({ lexer: this }, u), typeof a == "number" && a >= 0 && (o = Math.min(o, a));
+ this.options.extensions.startBlock.forEach((p) => {
+ a = p.call({ lexer: this }, u), typeof a == "number" && a >= 0 && (o = Math.min(o, a));
}), o < Infinity && o >= 0 && (i = e.substring(0, o + 1));
}
if (this.state.top && (r = this.tokenizer.paragraph(i))) {
@@ -23464,78 +23552,78 @@ var x = class l {
}
inlineTokens(e, t = []) {
this.tokenizer.lexer = this;
- let n = e, s = null;
+ let n = e;
if (this.tokens.links) {
- let a = Object.keys(this.tokens.links);
- if (a.length > 0) for (; (s = this.tokenizer.rules.inline.reflinkSearch.exec(n)) !== null;) a.includes(s[0].slice(s[0].lastIndexOf("[") + 1, -1)) && (n = n.slice(0, s.index) + "[" + "a".repeat(s[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex));
- }
- for (; (s = this.tokenizer.rules.inline.anyPunctuation.exec(n)) !== null;) n = n.slice(0, s.index) + "++" + n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
- let r;
- for (; (s = this.tokenizer.rules.inline.blockSkip.exec(n)) !== null;) r = s[2] ? s[2].length : 0, n = n.slice(0, s.index + r) + "[" + "a".repeat(s[0].length - r - 2) + "]" + n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
- n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
- let i = !1, o = "", u = Infinity;
+ let o = Object.keys(this.tokens.links);
+ o.length > 0 && (n = n.replace(this.tokenizer.rules.inline.reflinkSearch, (u) => o.includes(u.slice(u.lastIndexOf("[") + 1, -1)) ? "[" + "a".repeat(u.length - 2) + "]" : u));
+ }
+ n = n.replace(this.tokenizer.rules.inline.anyPunctuation, "++"), n = n.replace(this.tokenizer.rules.inline.blockSkip, (o, u, a) => {
+ let p = a ? a.length : 0;
+ return o.slice(0, p) + "[" + "a".repeat(o.length - p - 2) + "]";
+ }), n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
+ let s = !1, r = "", i = Infinity;
for (; e;) {
- if (e.length < u) u = e.length;
+ if (e.length < i) i = e.length;
else {
this.infiniteLoopError(e.charCodeAt(0));
break;
}
- i || (o = ""), i = !1;
- let a;
- if (this.options.extensions?.inline?.some((p) => (a = p.call({ lexer: this }, e, t)) ? (e = e.substring(a.raw.length), t.push(a), !0) : !1)) continue;
- if (a = this.tokenizer.escape(e)) {
- e = e.substring(a.raw.length), t.push(a);
+ s || (r = ""), s = !1;
+ let o;
+ if (this.options.extensions?.inline?.some((a) => (o = a.call({ lexer: this }, e, t)) ? (e = e.substring(o.raw.length), t.push(o), !0) : !1)) continue;
+ if (o = this.tokenizer.escape(e)) {
+ e = e.substring(o.raw.length), t.push(o);
continue;
}
- if (a = this.tokenizer.tag(e)) {
- e = e.substring(a.raw.length), t.push(a);
+ if (o = this.tokenizer.tag(e)) {
+ e = e.substring(o.raw.length), t.push(o);
continue;
}
- if (a = this.tokenizer.link(e)) {
- e = e.substring(a.raw.length), t.push(a);
+ if (o = this.tokenizer.link(e)) {
+ e = e.substring(o.raw.length), t.push(o);
continue;
}
- if (a = this.tokenizer.reflink(e, this.tokens.links)) {
- e = e.substring(a.raw.length);
- let p = t.at(-1);
- a.type === "text" && p?.type === "text" ? (p.raw += a.raw, p.text += a.text) : t.push(a);
+ if (o = this.tokenizer.reflink(e, this.tokens.links)) {
+ e = e.substring(o.raw.length);
+ let a = t.at(-1);
+ o.type === "text" && a?.type === "text" ? (a.raw += o.raw, a.text += o.text) : t.push(o);
continue;
}
- if (a = this.tokenizer.emStrong(e, n, o)) {
- e = e.substring(a.raw.length), t.push(a);
+ if (o = this.tokenizer.emStrong(e, n, r)) {
+ e = e.substring(o.raw.length), t.push(o);
continue;
}
- if (a = this.tokenizer.codespan(e)) {
- e = e.substring(a.raw.length), t.push(a);
+ if (o = this.tokenizer.codespan(e)) {
+ e = e.substring(o.raw.length), t.push(o);
continue;
}
- if (a = this.tokenizer.br(e)) {
- e = e.substring(a.raw.length), t.push(a);
+ if (o = this.tokenizer.br(e)) {
+ e = e.substring(o.raw.length), t.push(o);
continue;
}
- if (a = this.tokenizer.del(e, n, o)) {
- e = e.substring(a.raw.length), t.push(a);
+ if (o = this.tokenizer.del(e, n, r)) {
+ e = e.substring(o.raw.length), t.push(o);
continue;
}
- if (a = this.tokenizer.autolink(e)) {
- e = e.substring(a.raw.length), t.push(a);
+ if (o = this.tokenizer.autolink(e)) {
+ e = e.substring(o.raw.length), t.push(o);
continue;
}
- if (!this.state.inLink && (a = this.tokenizer.url(e))) {
- e = e.substring(a.raw.length), t.push(a);
+ if (!this.state.inLink && (o = this.tokenizer.url(e))) {
+ e = e.substring(o.raw.length), t.push(o);
continue;
}
- let c = e;
+ let u = e;
if (this.options.extensions?.startInline) {
- let p = Infinity, k = e.slice(1), h;
- this.options.extensions.startInline.forEach((R) => {
- h = R.call({ lexer: this }, k), typeof h == "number" && h >= 0 && (p = Math.min(p, h));
- }), p < Infinity && p >= 0 && (c = e.substring(0, p + 1));
- }
- if (a = this.tokenizer.inlineText(c)) {
- e = e.substring(a.raw.length), a.raw.slice(-1) !== "_" && (o = a.raw.slice(-1)), i = !0;
- let p = t.at(-1);
- p?.type === "text" ? (p.raw += a.raw, p.text += a.text) : t.push(a);
+ let a = Infinity, p = e.slice(1), c;
+ this.options.extensions.startInline.forEach((h) => {
+ c = h.call({ lexer: this }, p), typeof c == "number" && c >= 0 && (a = Math.min(a, c));
+ }), a < Infinity && a >= 0 && (u = e.substring(0, a + 1));
+ }
+ if (o = this.tokenizer.inlineText(u)) {
+ e = e.substring(o.raw.length), o.raw.slice(-1) !== "_" && (r = o.raw.slice(-1)), s = !0;
+ let a = t.at(-1);
+ a?.type === "text" ? (a.raw += o.raw, a.text += o.text) : t.push(o);
continue;
}
if (e) {
@@ -23859,13 +23947,13 @@ var P = class {
constructor(e) {
this.options = e || T;
}
- static passThroughHooks = new Set([
+ static passThroughHooks = /* @__PURE__ */ new Set([
"preprocess",
"postprocess",
"processAllTokens",
"emStrongMask"
]);
- static passThroughHooksRespectAsync = new Set([
+ static passThroughHooksRespectAsync = /* @__PURE__ */ new Set([
"preprocess",
"postprocess",
"processAllTokens"
@@ -23889,8 +23977,8 @@ var P = class {
return e ? b.parse : b.parseInline;
}
};
-var q = class {
- defaults = M();
+var D = class {
+ defaults = z();
options = this.setOptions;
parse = this.parseMarkdown(!0);
parseInline = this.parseMarkdown(!1);
@@ -23955,9 +24043,9 @@ var q = class {
if (!(i in r)) throw new Error(`renderer '${i}' does not exist`);
if (["options", "parser"].includes(i)) continue;
let o = i, u = n.renderer[o], a = r[o];
- r[o] = (...c) => {
- let p = u.apply(r, c);
- return p === !1 && (p = a.apply(r, c)), p || "";
+ r[o] = (...p) => {
+ let c = u.apply(r, p);
+ return c === !1 && (c = a.apply(r, p)), c || "";
};
}
s.renderer = r;
@@ -23972,9 +24060,9 @@ var q = class {
"lexer"
].includes(i)) continue;
let o = i, u = n.tokenizer[o], a = r[o];
- r[o] = (...c) => {
- let p = u.apply(r, c);
- return p === !1 && (p = a.apply(r, c)), p;
+ r[o] = (...p) => {
+ let c = u.apply(r, p);
+ return c === !1 && (c = a.apply(r, p)), c;
};
}
s.tokenizer = r;
@@ -23985,20 +24073,20 @@ var q = class {
if (!(i in r)) throw new Error(`hook '${i}' does not exist`);
if (["options", "block"].includes(i)) continue;
let o = i, u = n.hooks[o], a = r[o];
- P.passThroughHooks.has(i) ? r[o] = (c) => {
+ P.passThroughHooks.has(i) ? r[o] = (p) => {
if (this.defaults.async && P.passThroughHooksRespectAsync.has(i)) return (async () => {
- let k = await u.call(r, c);
- return a.call(r, k);
+ let h = await u.call(r, p);
+ return a.call(r, h);
})();
- let p = u.call(r, c);
- return a.call(r, p);
- } : r[o] = (...c) => {
+ let c = u.call(r, p);
+ return a.call(r, c);
+ } : r[o] = (...p) => {
if (this.defaults.async) return (async () => {
- let k = await u.apply(r, c);
- return k === !1 && (k = await a.apply(r, c)), k;
+ let h = await u.apply(r, p);
+ return h === !1 && (h = await a.apply(r, p)), h;
})();
- let p = u.apply(r, c);
- return p === !1 && (p = a.apply(r, c)), p;
+ let c = u.apply(r, p);
+ return c === !1 && (c = a.apply(r, p)), c;
};
}
s.hooks = r;
@@ -24038,17 +24126,17 @@ var q = class {
if (typeof n > "u" || n === null) return o(/* @__PURE__ */ new Error("marked(): input parameter is undefined or null"));
if (typeof n != "string") return o(/* @__PURE__ */ new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
if (i.hooks && (i.hooks.options = i, i.hooks.block = e), i.async) return (async () => {
- let u = i.hooks ? await i.hooks.preprocess(n) : n, c = await (i.hooks ? await i.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(u, i), p = i.hooks ? await i.hooks.processAllTokens(c) : c;
- i.walkTokens && await Promise.all(this.walkTokens(p, i.walkTokens));
- let h = await (i.hooks ? await i.hooks.provideParser(e) : e ? b.parse : b.parseInline)(p, i);
- return i.hooks ? await i.hooks.postprocess(h) : h;
+ let u = i.hooks ? await i.hooks.preprocess(n) : n, p = await (i.hooks ? await i.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(u, i), c = i.hooks ? await i.hooks.processAllTokens(p) : p;
+ i.walkTokens && await Promise.all(this.walkTokens(c, i.walkTokens));
+ let k = await (i.hooks ? await i.hooks.provideParser(e) : e ? b.parse : b.parseInline)(c, i);
+ return i.hooks ? await i.hooks.postprocess(k) : k;
})().catch(o);
try {
i.hooks && (n = i.hooks.preprocess(n));
let a = (i.hooks ? i.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(n, i);
i.hooks && (a = i.hooks.processAllTokens(a)), i.walkTokens && this.walkTokens(a, i.walkTokens);
- let p = (i.hooks ? i.hooks.provideParser(e) : e ? b.parse : b.parseInline)(a, i);
- return i.hooks && (p = i.hooks.postprocess(p)), p;
+ let c = (i.hooks ? i.hooks.provideParser(e) : e ? b.parse : b.parseInline)(a, i);
+ return i.hooks && (c = i.hooks.postprocess(c)), c;
} catch (u) {
return o(u);
}
@@ -24066,22 +24154,22 @@ Please report this to https://github.com/markedjs/marked.`, e) {
};
}
};
-var z = new q();
+var M = new D();
function g(l, e) {
- return z.parse(l, e);
+ return M.parse(l, e);
}
g.options = g.setOptions = function(l) {
- return z.setOptions(l), g.defaults = z.defaults, N(g.defaults), g;
+ return M.setOptions(l), g.defaults = M.defaults, N(g.defaults), g;
};
-g.getDefaults = M;
+g.getDefaults = z;
g.defaults = T;
g.use = function(...l) {
- return z.use(...l), g.defaults = z.defaults, N(g.defaults), g;
+ return M.use(...l), g.defaults = M.defaults, N(g.defaults), g;
};
g.walkTokens = function(l, e) {
- return z.walkTokens(l, e);
+ return M.walkTokens(l, e);
};
-g.parseInline = z.parseInline;
+g.parseInline = M.parseInline;
g.Parser = b;
g.parser = b.parse;
g.Renderer = y;
@@ -24879,7 +24967,7 @@ var require_Collection = /* @__PURE__ */ __commonJSMin(((exports) => {
const a = [];
a[k] = v;
v = a;
- } else v = new Map([[k, v]]);
+ } else v = /* @__PURE__ */ new Map([[k, v]]);
}
return createNode.createNode(v, void 0, {
aliasDuplicateObjects: false,
@@ -25438,7 +25526,7 @@ var require_stringify$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
if (ctx.resolvedAliases?.has(item)) throw new TypeError(`Cannot stringify circular structure without alias nodes`);
else {
if (ctx.resolvedAliases) ctx.resolvedAliases.add(item);
- else ctx.resolvedAliases = new Set([item]);
+ else ctx.resolvedAliases = /* @__PURE__ */ new Set([item]);
item = item.resolve(ctx.doc);
}
}
@@ -26832,7 +26920,7 @@ var require_tags = /* @__PURE__ */ __commonJSMin(((exports) => {
var schema$2 = require_schema();
var set = require_set();
var timestamp = require_timestamp();
- const schemas = new Map([
+ const schemas = /* @__PURE__ */ new Map([
["core", schema.schema],
["failsafe", [
map.map,
@@ -30783,6 +30871,7 @@ const USE_PASCAL_CASE_REG = /^Use(?=[A-Z])/;
const RN_TO_LF_REG = /\r\n/g;
const COMMON_PR_REG = /\[common#\d+\]/;
const CONTRIBUTOR_WITH_SPACE_REG = /@.*\s$/;
+const GITHUB_COMMENT_MAX_LENGTH = 65536;
function pascalCase(str) {
if (str.toLowerCase() === "qrcode") return "QRCode";
const pascalCaseStr = camelCase(str, { pascalCase: true });
@@ -30828,30 +30917,42 @@ function extractChangelog(markdown, pkgNames) {
return pkgLogs;
}
/**
-* 提取 release 日志
+* 提取单条或合并后的 release 日志
*/
-function extractReleaseLog(markdown) {
- const md = parseMarkdown(markdown.replace(RN_TO_LF_REG, "\n"));
- let collectLogs = false;
- let pkgName = "";
- const changelog = [];
- md.forEach((token) => {
- if (token.type === "heading" && token.depth === 1) if (token.text.startsWith("🎉 Release")) {
- pkgName = token.text.replace("🎉 Release", "").trim();
- collectLogs = true;
- } else if (token.text.startsWith("🎉 发布")) {
- pkgName = token.text.replace("🎉 发布", "").trim();
- collectLogs = true;
- } else collectLogs = false;
- if (collectLogs) {
- if (token.type === "heading" && token.depth > 1) changelog.push(`${token.raw.trimEnd()}\n\n`);
- if (token.type === "list") changelog.push(`${token.raw.trimEnd()}\n\n`);
+function extractReleaseLogs(markdown) {
+ const releaseLogs = [];
+ let currentLog;
+ parseMarkdown(markdown.replace(RN_TO_LF_REG, "\n")).forEach((token) => {
+ if (token.type === "heading" && token.depth === 1) {
+ const pkgName = token.text.startsWith("🎉 Release") ? token.text.replace("🎉 Release", "").trim() : token.text.startsWith("🎉 发布") ? token.text.replace("🎉 发布", "").trim() : "";
+ currentLog = pkgName ? {
+ pkgName,
+ changelog: ""
+ } : void 0;
+ if (currentLog) releaseLogs.push(currentLog);
+ return;
}
+ if (currentLog && (token.type === "heading" && token.depth > 1 || token.type === "list")) currentLog.changelog += `${token.raw.trimEnd()}\n\n`;
});
- return {
- pkgName,
- changelog: changelog.join("")
- };
+ return releaseLogs;
+}
+function buildReleaseComments(logHead, sections, maxLength = GITHUB_COMMENT_MAX_LENGTH) {
+ const separator = "\n\n---\n\n";
+ const comments = [];
+ let body = logHead;
+ sections.forEach((section) => {
+ const addition = body === logHead ? section : `${separator}${section}`;
+ if (body.length + addition.length <= maxLength) {
+ body += addition;
+ return;
+ }
+ if (body === logHead) throw new Error("A release changelog section exceeds the GitHub comment length limit");
+ comments.push(body);
+ body = `${logHead}${section}`;
+ if (body.length > maxLength) throw new Error("A release changelog section exceeds the GitHub comment length limit");
+ });
+ if (body !== logHead) comments.push(body);
+ return comments;
}
function stashPackageChangelog(prData, packages, prChangelog) {
packages.forEach((pkg) => {
@@ -31388,9 +31489,10 @@ async function confirmReleaseLog(prNumber, log, token) {
if (!isReleaseHead) return false;
let changelogFileName = "CHANGELOG.md";
if (log.startsWith("# 🎉 Release")) changelogFileName = "CHANGELOG.en-US.md";
- const { pkgName, changelog } = extractReleaseLog(log);
- info(`pkgName: ${pkgName}`);
- info(`changelog: ${changelog}`);
+ const releaseLogs = extractReleaseLogs(log);
+ info(`releaseLogs: ${JSON.stringify(releaseLogs, null, 2)}`);
+ const changelogMap = new Map(releaseLogs.map((item) => [item.pkgName, item.changelog]));
+ if (changelogMap.size !== releaseLogs.length) throw new Error("Release log contains duplicate package names");
const { getPullRequestData, getPullRequestFiles } = useGithub(token);
const prData = await getPullRequestData(prNumber);
const { cloneRepo, checkoutBranch, isNeedCommit } = useGit(token);
@@ -31402,7 +31504,8 @@ async function confirmReleaseLog(prNumber, log, token) {
const releaseDirs = await getPullRequestReleaseDirs(changeFiles, getConfiguredPackages(cwd()));
info(`releaseDirs: ${JSON.stringify(releaseDirs, null, 2)}`);
for (const release of releaseDirs) {
- if (release.name !== pkgName) continue;
+ const changelog = changelogMap.get(release.name);
+ if (!changelog) continue;
globSync(`${release.dir}/.changelog/*.md`).forEach((file) => {
unlinkSync(file);
info(`delete file: ${file}`);
@@ -31427,18 +31530,19 @@ async function confirmReleaseLog(prNumber, log, token) {
if (index === -1) newData = pkgChangelog + changelog;
else newData = pkgChangelog.slice(0, index) + changelog + pkgChangelog.slice(index);
writeFileSync(`${release.dir}/${changelogFileName}`, newData, "utf8");
+ await exec("git", [
+ "add",
+ "-A",
+ "--",
+ release.dir
+ ]);
+ await exec("git", ["status"]);
+ if (await isNeedCommit()) await exec("git", [
+ "commit",
+ "-m",
+ `chore: update ${release.name} ${changelogFileName}`
+ ]);
}
- await exec("git", ["add", "**/*.md"]);
- await exec("git", ["status"]);
- if (!await isNeedCommit()) {
- info("无需提交");
- return true;
- }
- await exec("git", [
- "commit",
- "-m",
- `chore: update ${pkgName} ${changelogFileName}`
- ]);
await exec("git", ["pull"]);
await exec("git", [
"push",
@@ -32201,7 +32305,7 @@ var require_bignumber = /* @__PURE__ */ __commonJSMin(((exports, module) => {
for (; i < k;) {
v = a[i] * 131072 + (a[i + 1] >>> 11);
if (v >= 9e15) {
- b = crypto.getRandomValues(new Uint32Array(2));
+ b = crypto.getRandomValues(/* @__PURE__ */ new Uint32Array(2));
a[i] = b[0];
a[i + 1] = b[1];
} else {
@@ -41093,7 +41197,8 @@ var require_abort = /* @__PURE__ */ __commonJSMin(((exports, module) => {
//#endregion
//#region node_modules/.pnpm/asynckit@0.4.0/node_modules/asynckit/lib/iterate.js
var require_iterate = /* @__PURE__ */ __commonJSMin(((exports, module) => {
- var async = require_async(), abort = require_abort();
+ var async = require_async();
+ var abort = require_abort();
module.exports = iterate;
/**
* Iterates over each job object
@@ -41159,7 +41264,8 @@ var require_state = /* @__PURE__ */ __commonJSMin(((exports, module) => {
//#endregion
//#region node_modules/.pnpm/asynckit@0.4.0/node_modules/asynckit/lib/terminator.js
var require_terminator = /* @__PURE__ */ __commonJSMin(((exports, module) => {
- var abort = require_abort(), async = require_async();
+ var abort = require_abort();
+ var async = require_async();
module.exports = terminator;
/**
* Terminates jobs in the attached state context
@@ -41177,7 +41283,9 @@ var require_terminator = /* @__PURE__ */ __commonJSMin(((exports, module) => {
//#endregion
//#region node_modules/.pnpm/asynckit@0.4.0/node_modules/asynckit/parallel.js
var require_parallel = /* @__PURE__ */ __commonJSMin(((exports, module) => {
- var iterate = require_iterate(), initState = require_state(), terminator = require_terminator();
+ var iterate = require_iterate();
+ var initState = require_state();
+ var terminator = require_terminator();
module.exports = parallel;
/**
* Runs iterator over provided array elements in parallel
@@ -41208,7 +41316,9 @@ var require_parallel = /* @__PURE__ */ __commonJSMin(((exports, module) => {
//#endregion
//#region node_modules/.pnpm/asynckit@0.4.0/node_modules/asynckit/serialOrdered.js
var require_serialOrdered = /* @__PURE__ */ __commonJSMin(((exports, module) => {
- var iterate = require_iterate(), initState = require_state(), terminator = require_terminator();
+ var iterate = require_iterate();
+ var initState = require_state();
+ var terminator = require_terminator();
module.exports = serialOrdered;
module.exports.ascending = ascending;
module.exports.descending = descending;
@@ -78132,7 +78242,7 @@ var require_url_state_machine = /* @__PURE__ */ __commonJSMin(((exports, module)
function isC0ControlPercentEncode(c) {
return c <= 31 || c > 126;
}
- const extraPathPercentEncodeSet = new Set([
+ const extraPathPercentEncodeSet = /* @__PURE__ */ new Set([
32,
34,
35,
@@ -78146,7 +78256,7 @@ var require_url_state_machine = /* @__PURE__ */ __commonJSMin(((exports, module)
function isPathPercentEncode(c) {
return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c);
}
- const extraUserinfoPercentEncodeSet = new Set([
+ const extraUserinfoPercentEncodeSet = /* @__PURE__ */ new Set([
47,
58,
59,
@@ -78672,7 +78782,7 @@ var require_url_state_machine = /* @__PURE__ */ __commonJSMin(((exports, module)
}
return true;
};
- const fileOtherwiseCodePoints = new Set([
+ const fileOtherwiseCodePoints = /* @__PURE__ */ new Set([
47,
92,
63,
@@ -81299,7 +81409,8 @@ var require_src = /* @__PURE__ */ __commonJSMin(((exports, module) => {
req.onSocket(socket);
return;
}
- onerror(/* @__PURE__ */ new Error(`no Duplex stream was returned to agent-base for \`${req.method} ${req.path}\``));
+ const err = /* @__PURE__ */ new Error(`no Duplex stream was returned to agent-base for \`${req.method} ${req.path}\``);
+ onerror(err);
};
if (typeof this.callback !== "function") {
onerror(/* @__PURE__ */ new Error("`callback` is not defined"));
@@ -81819,7 +81930,7 @@ function rng() {
}
var rnds8Pool, poolPtr;
var init_rng = __esmMin((() => {
- rnds8Pool = new Uint8Array(256);
+ rnds8Pool = /* @__PURE__ */ new Uint8Array(256);
poolPtr = rnds8Pool.length;
}));
//#endregion
@@ -81909,7 +82020,7 @@ var init_v1 = __esmMin((() => {
function parse(uuid) {
if (!validate(uuid)) throw TypeError("Invalid UUID");
let v;
- const arr = new Uint8Array(16);
+ const arr = /* @__PURE__ */ new Uint8Array(16);
arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;
arr[1] = v >>> 16 & 255;
arr[2] = v >>> 8 & 255;
@@ -82745,27 +82856,33 @@ async function pull_request(token) {
info("没有更新发布版本");
return;
}
+ const zhComments = [];
+ const enComments = [];
+ const logHead = "(删除此行代表确认该日志): 修改并确认日志后删除这一行,机器人会提交到 本 PR 的 CHANGELOG.md 文件中\n";
+ const currentDate = /* @__PURE__ */ new Date();
+ const year = currentDate.getFullYear();
+ const month = String(currentDate.getMonth() + 1).padStart(2, "0");
+ const day = String(currentDate.getDate()).padStart(2, "0");
for (const release of releaseDirs) if (release.tag === "latest") {
const changelogs = getStashChangelog(release.dir, release.type);
info(`changelogs: ${JSON.stringify(changelogs, null, 2)}`);
const md = renderChangelogMarkdown(changelogs.changelogs);
info(`markdownChangelogs: ${md}`);
- const logHead = "(删除此行代表确认该日志): 修改并确认日志后删除这一行,机器人会提交到 本 PR 的 CHANGELOG.md 文件中\n";
- const currentDate = /* @__PURE__ */ new Date();
- const year = currentDate.getFullYear();
- const month = String(currentDate.getMonth() + 1).padStart(2, "0");
- const day = String(currentDate.getDate()).padStart(2, "0");
- await addComment(prNumber, `${logHead}# 🎉 发布 ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${md}`);
+ const zhBody = `# 🎉 发布 ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${md}`;
+ zhComments.push(zhBody);
const secretId = getInput("translate-secret-id", { trimWhitespace: true });
const secretKey = getInput("translate-secret-key", { trimWhitespace: true });
if (secretId && secretKey && md) try {
const text = await translateText(secretId, secretKey, md);
info(`en_md: ${text}`);
- await addComment(prNumber, `${logHead.replace("CHANGELOG.md", "CHANGELOG.en-US.md")}# 🎉 Release ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${text}`);
+ const enBody = `# 🎉 Release ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${text}`;
+ enComments.push(enBody);
} catch (err) {
info(`翻译失败,${err}`);
}
}
+ for (const comment of buildReleaseComments(logHead, zhComments)) await addComment(prNumber, comment);
+ for (const comment of buildReleaseComments(logHead.replace("CHANGELOG.md", "CHANGELOG.en-US.md"), enComments)) await addComment(prNumber, comment);
}
}
if (context.payload.action === "closed") {
diff --git a/fixtures/release_comment/confirm-merged.md b/fixtures/release_comment/confirm-merged.md
new file mode 100644
index 0000000..e0f5450
--- /dev/null
+++ b/fixtures/release_comment/confirm-merged.md
@@ -0,0 +1,40 @@
+
+# 🎉 Release pkg-a
+
+## 🌈 1.0.1 `2025-4-7`
+
+### 🚀 Features
+
+- Button:
+ - 新增属性c @liweijie0812 ([#4](https://github.com/liweijie0812/test-mono-log/pull/4))
+ - 新增属性a,新增属性b @liweijie0812 ([#2](https://github.com/liweijie0812/test-mono-log/pull/2))
+- Link: 新增属性c @liweijie0812 ([#2](https://github.com/liweijie0812/test-mono-log/pull/2))
+
+### 🐞 Bug Fixes
+
+- Button: 修复属性b @liweijie0812 ([#4](https://github.com/liweijie0812/test-mono-log/pull/4))
+
+---
+
+# 🎉 Release pkg-b
+
+## 🌈 2.0.0 `2025-4-7`
+
+### 🚀 Features
+
+- Input:
+ - 新增 size 属性 @liweijie0812 ([#5](https://github.com/liweijie0812/test-mono-log/pull/5))
+
+### 🐞 Bug Fixes
+
+- Select: 修复禁用态样式 @liweijie0812 ([#6](https://github.com/liweijie0812/test-mono-log/pull/6))
+
+---
+
+# 🎉 Release pkg-c
+
+## 🌈 3.0.0 `2025-4-7`
+
+### 📝 Documentation
+
+- 更新 README @liweijie0812 ([#7](https://github.com/liweijie0812/test-mono-log/pull/7))
diff --git a/src/github-event/issue-comment.ts b/src/github-event/issue-comment.ts
index 94c8c1f..5e32cea 100644
--- a/src/github-event/issue-comment.ts
+++ b/src/github-event/issue-comment.ts
@@ -5,7 +5,7 @@ import * as core from '@actions/core'
import { exec } from '@actions/exec'
import * as github from '@actions/github'
import { globSync } from 'tinyglobby'
-import { checkIsForkPr, extractChangelog, extractReleaseLog, getConfiguredPackages, getInputPkgs, getPrCommentWhitelist, getPullRequestNumber, getPullRequestReleaseDirs, stashPackageChangelog } from '../utils/common'
+import { checkIsForkPr, extractChangelog, extractReleaseLogs, getConfiguredPackages, getInputPkgs, getPrCommentWhitelist, getPullRequestNumber, getPullRequestReleaseDirs, stashPackageChangelog } from '../utils/common'
import useGit from '../utils/git'
import useGithub from '../utils/github'
@@ -152,10 +152,12 @@ async function confirmReleaseLog(prNumber: number, log: string, token: string) {
changelogFileName = 'CHANGELOG.en-US.md'
}
- const { pkgName, changelog } = extractReleaseLog(log)
-
- core.info(`pkgName: ${pkgName}`)
- core.info(`changelog: ${changelog}`)
+ const releaseLogs = extractReleaseLogs(log)
+ core.info(`releaseLogs: ${JSON.stringify(releaseLogs, null, 2)}`)
+ const changelogMap = new Map(releaseLogs.map(item => [item.pkgName, item.changelog]))
+ if (changelogMap.size !== releaseLogs.length) {
+ throw new Error('Release log contains duplicate package names')
+ }
const { getPullRequestData, getPullRequestFiles } = useGithub(token)
const prData = await getPullRequestData(prNumber) as PullRequestData
@@ -168,7 +170,8 @@ async function confirmReleaseLog(prNumber: number, log: string, token: string) {
const releaseDirs = await getPullRequestReleaseDirs(changeFiles, getConfiguredPackages(cwd()))
core.info(`releaseDirs: ${JSON.stringify(releaseDirs, null, 2)}`)
for (const release of releaseDirs) {
- if (release.name !== pkgName) {
+ const changelog = changelogMap.get(release.name)
+ if (!changelog) {
continue
}
const files = globSync(`${release.dir}/.changelog/*.md`)
@@ -194,16 +197,15 @@ async function confirmReleaseLog(prNumber: number, log: string, token: string) {
newData = pkgChangelog.slice(0, index) + changelog + pkgChangelog.slice(index)
}
writeFileSync(`${release.dir}/${changelogFileName}`, newData, 'utf8')
- }
- await exec('git', ['add', '**/*.md'])
- await exec('git', ['status'])
- if (!await isNeedCommit()) {
- core.info('无需提交')
- return true
+ await exec('git', ['add', '-A', '--', release.dir])
+ await exec('git', ['status'])
+ if (await isNeedCommit()) {
+ const commitMsg = `chore: update ${release.name} ${changelogFileName}`
+ await exec('git', ['commit', '-m', commitMsg])
+ }
}
- const commitMsg = `chore: update ${pkgName} ${changelogFileName}`
- await exec('git', ['commit', '-m', commitMsg])
+
await exec('git', ['pull'])
await exec('git', ['push', 'origin', prData.head.ref])
}
diff --git a/src/github-event/pull-request.ts b/src/github-event/pull-request.ts
index 5219fcb..fbfebaa 100644
--- a/src/github-event/pull-request.ts
+++ b/src/github-event/pull-request.ts
@@ -2,7 +2,7 @@ import type { PullRequestData } from '../types'
import { cwd } from 'node:process'
import { getInput, info, setOutput } from '@actions/core'
import * as github from '@actions/github'
-import { extractChangelog, getConfiguredPackages, getInputPkgs, getPullRequestNumber, getPullRequestReleaseDirs, getStashChangelog, publishRelease, renderChangelogMarkdown, sortReleasePackages } from '../utils'
+import { buildReleaseComments, extractChangelog, getConfiguredPackages, getInputPkgs, getPullRequestNumber, getPullRequestReleaseDirs, getStashChangelog, publishRelease, renderChangelogMarkdown, sortReleasePackages } from '../utils'
import useGit from '../utils/git'
import useGithub from '../utils/github'
import { translateText } from '../utils/translate'
@@ -54,19 +54,24 @@ export async function pull_request(token: string) {
info('没有更新发布版本')
return
}
+ const zhComments: string[] = []
+ const enComments: string[] = []
+ const logHead = '(删除此行代表确认该日志): 修改并确认日志后删除这一行,机器人会提交到 本 PR 的 CHANGELOG.md 文件中\n'
+ const currentDate = new Date()
+ const year = currentDate.getFullYear()
+ const month = String(currentDate.getMonth() + 1).padStart(2, '0')
+ const day = String(currentDate.getDate()).padStart(2, '0')
+
for (const release of releaseDirs) {
if (release.tag === 'latest') {
const changelogs = getStashChangelog(release.dir, release.type)
info(`changelogs: ${JSON.stringify(changelogs, null, 2)}`)
const md = renderChangelogMarkdown(changelogs.changelogs)
info(`markdownChangelogs: ${md}`)
- const logHead = '(删除此行代表确认该日志): 修改并确认日志后删除这一行,机器人会提交到 本 PR 的 CHANGELOG.md 文件中\n'
- const currentDate = new Date()
- const year = currentDate.getFullYear()
- const month = String(currentDate.getMonth() + 1).padStart(2, '0')
- const day = String(currentDate.getDate()).padStart(2, '0')
// 中文日志
- await addComment(prNumber, `${logHead}# 🎉 发布 ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${md}`)
+ const zhBody = `# 🎉 发布 ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${md}`
+ zhComments.push(zhBody)
+
const secretId = getInput('translate-secret-id', { trimWhitespace: true })
const secretKey = getInput('translate-secret-key', { trimWhitespace: true })
if (secretId && secretKey && md) {
@@ -74,7 +79,8 @@ export async function pull_request(token: string) {
try {
const text = await translateText(secretId, secretKey, md)
info(`en_md: ${text}`)
- await addComment(prNumber, `${logHead.replace('CHANGELOG.md', 'CHANGELOG.en-US.md')}# 🎉 Release ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${text}`)
+ const enBody = `# 🎉 Release ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${text}`
+ enComments.push(enBody)
}
catch (err) {
info(`翻译失败,${err}`)
@@ -82,6 +88,13 @@ export async function pull_request(token: string) {
}
}
}
+
+ for (const comment of buildReleaseComments(logHead, zhComments)) {
+ await addComment(prNumber, comment)
+ }
+ for (const comment of buildReleaseComments(logHead.replace('CHANGELOG.md', 'CHANGELOG.en-US.md'), enComments)) {
+ await addComment(prNumber, comment)
+ }
}
}
diff --git a/src/utils/common.ts b/src/utils/common.ts
index 06e5870..875b47a 100644
--- a/src/utils/common.ts
+++ b/src/utils/common.ts
@@ -18,6 +18,7 @@ const USE_PASCAL_CASE_REG = /^Use(?=[A-Z])/
const RN_TO_LF_REG = /\r\n/g
const COMMON_PR_REG = /\[common#\d+\]/
const CONTRIBUTOR_WITH_SPACE_REG = /@.*\s$/
+const GITHUB_COMMENT_MAX_LENGTH = 65536
export function pascalCase(str: string) {
if (str.toLowerCase() === 'qrcode') {
@@ -102,34 +103,63 @@ export function extractChangelog(markdown: string, pkgNames: string[]) {
* 提取 release 日志
*/
export function extractReleaseLog(markdown: string) {
- const md = parseMarkdown(markdown.replace(RN_TO_LF_REG, '\n'))
- let collectLogs = false
- let pkgName = ''
- const changelog: string[] = []
- md.forEach((token) => {
+ return extractReleaseLogs(markdown)[0] || { pkgName: '', changelog: '' }
+}
+
+/**
+ * 提取单条或合并后的 release 日志
+ */
+export function extractReleaseLogs(markdown: string) {
+ const releaseLogs: Array<{ pkgName: string, changelog: string }> = []
+ let currentLog: { pkgName: string, changelog: string } | undefined
+
+ parseMarkdown(markdown.replace(RN_TO_LF_REG, '\n')).forEach((token) => {
if (token.type === 'heading' && token.depth === 1) {
- if (token.text.startsWith('🎉 Release')) {
- pkgName = token.text.replace('🎉 Release', '').trim()
- collectLogs = true
- }
- else if (token.text.startsWith('🎉 发布')) {
- pkgName = token.text.replace('🎉 发布', '').trim()
- collectLogs = true
- }
- else {
- collectLogs = false
+ const pkgName = token.text.startsWith('🎉 Release')
+ ? token.text.replace('🎉 Release', '').trim()
+ : token.text.startsWith('🎉 发布')
+ ? token.text.replace('🎉 发布', '').trim()
+ : ''
+ currentLog = pkgName ? { pkgName, changelog: '' } : undefined
+ if (currentLog) {
+ releaseLogs.push(currentLog)
}
+ return
}
- if (collectLogs) {
- if (token.type === 'heading' && token.depth > 1) {
- changelog.push(`${token.raw.trimEnd()}\n\n`)
- }
- if (token.type === 'list') {
- changelog.push(`${token.raw.trimEnd()}\n\n`)
- }
+
+ if (currentLog && ((token.type === 'heading' && token.depth > 1) || token.type === 'list')) {
+ currentLog.changelog += `${token.raw.trimEnd()}\n\n`
+ }
+ })
+
+ return releaseLogs
+}
+
+export function buildReleaseComments(logHead: string, sections: string[], maxLength = GITHUB_COMMENT_MAX_LENGTH) {
+ const separator = '\n\n---\n\n'
+ const comments: string[] = []
+ let body = logHead
+
+ sections.forEach((section) => {
+ const addition = body === logHead ? section : `${separator}${section}`
+ if (body.length + addition.length <= maxLength) {
+ body += addition
+ return
+ }
+ if (body === logHead) {
+ throw new Error('A release changelog section exceeds the GitHub comment length limit')
+ }
+ comments.push(body)
+ body = `${logHead}${section}`
+ if (body.length > maxLength) {
+ throw new Error('A release changelog section exceeds the GitHub comment length limit')
}
})
- return { pkgName, changelog: changelog.join('') }
+
+ if (body !== logHead) {
+ comments.push(body)
+ }
+ return comments
}
export function stashPackageChangelog(prData: PullRequestData, packages: Package[], prChangelog: PackagesChangelog) {
diff --git a/test/__snapshots__/utils.test.ts.snap b/test/__snapshots__/utils.test.ts.snap
index eae6904..f5c3ebd 100644
--- a/test/__snapshots__/utils.test.ts.snap
+++ b/test/__snapshots__/utils.test.ts.snap
@@ -72,6 +72,53 @@ exports[`utils > extractReleaseLog 1`] = `
}
`;
+exports[`utils > extractReleaseLogs (merged) 1`] = `
+[
+ {
+ "changelog": "## 🌈 1.0.1 \`2025-4-7\`
+
+### 🚀 Features
+
+- Button:
+ - 新增属性c @liweijie0812 ([#4](https://github.com/liweijie0812/test-mono-log/pull/4))
+ - 新增属性a,新增属性b @liweijie0812 ([#2](https://github.com/liweijie0812/test-mono-log/pull/2))
+- Link: 新增属性c @liweijie0812 ([#2](https://github.com/liweijie0812/test-mono-log/pull/2))
+
+### 🐞 Bug Fixes
+
+- Button: 修复属性b @liweijie0812 ([#4](https://github.com/liweijie0812/test-mono-log/pull/4))
+
+",
+ "pkgName": "pkg-a",
+ },
+ {
+ "changelog": "## 🌈 2.0.0 \`2025-4-7\`
+
+### 🚀 Features
+
+- Input:
+ - 新增 size 属性 @liweijie0812 ([#5](https://github.com/liweijie0812/test-mono-log/pull/5))
+
+### 🐞 Bug Fixes
+
+- Select: 修复禁用态样式 @liweijie0812 ([#6](https://github.com/liweijie0812/test-mono-log/pull/6))
+
+",
+ "pkgName": "pkg-b",
+ },
+ {
+ "changelog": "## 🌈 3.0.0 \`2025-4-7\`
+
+### 📝 Documentation
+
+- 更新 README @liweijie0812 ([#7](https://github.com/liweijie0812/test-mono-log/pull/7))
+
+",
+ "pkgName": "pkg-c",
+ },
+]
+`;
+
exports[`utils > getMergedPullRequestReleaseDirs 1`] = `
[
{
diff --git a/test/issue-comment.test.ts b/test/issue-comment.test.ts
index f03b00d..7ea3a49 100644
--- a/test/issue-comment.test.ts
+++ b/test/issue-comment.test.ts
@@ -2,6 +2,17 @@ import type { PullRequestData } from '../src/types'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { issue_comment } from '../src/github-event/issue-comment'
+vi.mock('node:fs', () => ({
+ existsSync: vi.fn().mockReturnValue(false),
+ writeFileSync: vi.fn(),
+ readFileSync: vi.fn().mockReturnValue(''),
+ unlinkSync: vi.fn(),
+}))
+
+vi.mock('tinyglobby', () => ({
+ globSync: vi.fn().mockReturnValue([]),
+}))
+
interface IssueCommentPayload {
action: string
changes?: { body: { from: string } }
@@ -31,6 +42,7 @@ const mocks = vi.hoisted(() => ({
getPrCommentWhitelist: vi.fn(),
getOpenPullRequestByHead: vi.fn(),
getPullRequestData: vi.fn(),
+ getPullRequestFiles: vi.fn(),
gitPush: vi.fn(),
isNeedCommit: vi.fn(),
stashPackageChangelog: vi.fn(),
@@ -42,12 +54,12 @@ vi.mock('@actions/github', () => ({ context: mocks.context }))
vi.mock('../src/utils/common', () => ({
checkIsForkPr: () => false,
extractChangelog: mocks.extractChangelog,
- extractReleaseLog: vi.fn(),
+ extractReleaseLogs: vi.fn().mockReturnValue([]),
getConfiguredPackages: () => [],
getInputPkgs: () => ['pkg-a'],
getPrCommentWhitelist: mocks.getPrCommentWhitelist,
getPullRequestNumber: () => 42,
- getPullRequestReleaseDirs: vi.fn(),
+ getPullRequestReleaseDirs: vi.fn().mockReturnValue([]),
stashPackageChangelog: mocks.stashPackageChangelog,
}))
vi.mock('../src/utils/git', () => ({
@@ -66,6 +78,7 @@ vi.mock('../src/utils/github', () => ({
createPullRequest: mocks.createPullRequest,
getOpenPullRequestByHead: mocks.getOpenPullRequestByHead,
getPullRequestData: mocks.getPullRequestData,
+ getPullRequestFiles: mocks.getPullRequestFiles,
}),
}))
@@ -200,4 +213,81 @@ describe('issue_comment', () => {
expect(mocks.cloneRepo).toHaveBeenCalledOnce()
expect(mocks.stashPackageChangelog).toHaveBeenCalledOnce()
})
+
+ it('confirms merged release log with multiple packages', async () => {
+ const { extractReleaseLogs, getPullRequestReleaseDirs } = await import('../src/utils/common')
+
+ vi.mocked(extractReleaseLogs).mockReturnValue([
+ { pkgName: 'pkg-a', changelog: '## 🌈 1.0.1\n\n### 🚀 Features\n\n- feat: add loading\n\n' },
+ { pkgName: 'pkg-b', changelog: '## 🌈 2.0.0\n\n### 🐞 Bug Fixes\n\n- fix: input border\n\n' },
+ ])
+
+ vi.mocked(getPullRequestReleaseDirs).mockReturnValue([
+ { dir: 'packages/pkg-a', name: 'pkg-a', private: false, version: '1.0.1', type: 'node', tag: 'latest', changelog: '' },
+ { dir: 'packages/pkg-b', name: 'pkg-b', private: false, version: '2.0.0', type: 'node', tag: 'latest', changelog: '' },
+ ])
+
+ mocks.context.payload = {
+ action: 'edited',
+ changes: { body: { from: 'draft body' } },
+ comment: { body: '# 🎉 发布 pkg-a\n\n## 🌈 1.0.1\n\n### 🚀 Features\n- feat: add loading\n\n---\n\n# 🎉 发布 pkg-b\n\n## 🌈 2.0.0\n\n### 🐞 Bug Fixes\n- fix: input border' },
+ issue: { number: 42, pull_request: {} },
+ }
+
+ mocks.isNeedCommit.mockResolvedValue(true)
+
+ await issue_comment('token')
+
+ expect(mocks.exec).toHaveBeenCalledWith('git', ['add', '-A', '--', 'packages/pkg-a'])
+ expect(mocks.exec).toHaveBeenCalledWith('git', ['commit', '-m', 'chore: update pkg-a CHANGELOG.md'])
+ expect(mocks.exec).toHaveBeenCalledWith('git', ['add', '-A', '--', 'packages/pkg-b'])
+ expect(mocks.exec).toHaveBeenCalledWith('git', ['commit', '-m', 'chore: update pkg-b CHANGELOG.md'])
+ expect(mocks.exec).toHaveBeenCalledWith('git', ['push', 'origin', 'feat/loading'])
+ })
+
+ it('confirms single release log (backward compat)', async () => {
+ const { extractReleaseLogs, getPullRequestReleaseDirs } = await import('../src/utils/common')
+
+ vi.mocked(extractReleaseLogs).mockReturnValue([
+ { pkgName: 'pkg-a', changelog: '## 🌈 1.0.1\n\n### 🚀 Features\n\n- feat: add loading\n\n' },
+ ])
+
+ vi.mocked(getPullRequestReleaseDirs).mockReturnValue([
+ { dir: 'packages/pkg-a', name: 'pkg-a', private: false, version: '1.0.1', type: 'node', tag: 'latest', changelog: '' },
+ { dir: 'packages/pkg-b', name: 'pkg-b', private: false, version: '2.0.0', type: 'node', tag: 'latest', changelog: '' },
+ ])
+
+ mocks.context.payload = {
+ action: 'edited',
+ changes: { body: { from: 'draft body' } },
+ comment: { body: '# 🎉 发布 pkg-a\n\n## 🌈 1.0.1\n\n### 🚀 Features\n- feat: add loading' },
+ issue: { number: 42, pull_request: {} },
+ }
+
+ mocks.isNeedCommit.mockResolvedValue(true)
+
+ await issue_comment('token')
+
+ expect(mocks.exec).toHaveBeenCalledWith('git', ['add', '-A', '--', 'packages/pkg-a'])
+ expect(mocks.exec).toHaveBeenCalledWith('git', ['commit', '-m', 'chore: update pkg-a CHANGELOG.md'])
+ expect(mocks.exec).not.toHaveBeenCalledWith('git', ['commit', '-m', 'chore: update pkg-b CHANGELOG.md'])
+ expect(mocks.exec).toHaveBeenCalledWith('git', ['push', 'origin', 'feat/loading'])
+ })
+
+ it('rejects duplicate package release logs', async () => {
+ const { extractReleaseLogs } = await import('../src/utils/common')
+ vi.mocked(extractReleaseLogs).mockReturnValue([
+ { pkgName: 'pkg-a', changelog: 'first log' },
+ { pkgName: 'pkg-a', changelog: 'second log' },
+ ])
+ mocks.context.payload = {
+ action: 'edited',
+ changes: { body: { from: 'draft body' } },
+ comment: { body: '# 🎉 发布 pkg-a\n\n# 🎉 发布 pkg-a' },
+ issue: { number: 42, pull_request: {} },
+ }
+
+ await expect(issue_comment('token')).rejects.toThrow('duplicate package names')
+ expect(mocks.cloneRepo).not.toHaveBeenCalled()
+ })
})
diff --git a/test/utils.test.ts b/test/utils.test.ts
index 99c18a3..f91c9da 100644
--- a/test/utils.test.ts
+++ b/test/utils.test.ts
@@ -4,8 +4,10 @@ import { existsSync, readFileSync } from 'node:fs'
import { describe, expect, it } from 'vitest'
import { flutter_pull_request_files, merged_pull_request_files, merged_pull_request_files2, merged_pull_request_files3, pull_request_data, pull_request_files } from '../fixtures/pull_request_data'
import {
+ buildReleaseComments,
extractChangelog,
extractReleaseLog,
+ extractReleaseLogs,
getInputPkgs,
getPackages,
getPullRequestReleaseDirs,
@@ -250,4 +252,45 @@ describe('utils', () => {
const releaseLog = extractReleaseLog(body)
expect(releaseLog).toMatchSnapshot()
})
+
+ it('extractReleaseLogs (merged)', () => {
+ const body = readFileSync('fixtures/release_comment/confirm-merged.md', 'utf8').replaceAll('\n', '\r\n')
+ const releaseLogs = extractReleaseLogs(body)
+ expect(releaseLogs).toMatchSnapshot()
+ expect(releaseLogs).toHaveLength(3)
+ expect(releaseLogs.map(l => l.pkgName)).toEqual(['pkg-a', 'pkg-b', 'pkg-c'])
+ })
+
+ it('extractReleaseLogs (single - backward compat)', () => {
+ const body = readFileSync('fixtures/release_comment/confirm.md', 'utf8').replaceAll('\n', '\r\n')
+ const releaseLogs = extractReleaseLogs(body)
+ expect(releaseLogs).toHaveLength(1)
+ expect(releaseLogs[0].pkgName).toBe('pkg-a')
+ })
+
+ it('extractReleaseLogs tolerates edited separators', () => {
+ const body = '# 🎉 发布 pkg-a\n## 🌈 1.0.0\n\n- feature a\n---\n# 🎉 发布 pkg-b\n## 🌈 2.0.0\n\n- feature b'
+
+ expect(extractReleaseLogs(body)).toEqual([
+ { pkgName: 'pkg-a', changelog: '## 🌈 1.0.0\n\n- feature a\n\n' },
+ { pkgName: 'pkg-b', changelog: '## 🌈 2.0.0\n\n- feature b\n\n' },
+ ])
+ })
+
+ it('buildReleaseComments merges sections within the limit', () => {
+ expect(buildReleaseComments('head\n', ['section-a', 'section-b'], 40)).toEqual([
+ 'head\nsection-a\n\n---\n\nsection-b',
+ ])
+ })
+
+ it('buildReleaseComments splits comments at section boundaries', () => {
+ expect(buildReleaseComments('head\n', ['section-a', 'section-b'], 20)).toEqual([
+ 'head\nsection-a',
+ 'head\nsection-b',
+ ])
+ })
+
+ it('buildReleaseComments rejects an oversized package section', () => {
+ expect(() => buildReleaseComments('head\n', ['section-a'], 10)).toThrow('exceeds the GitHub comment length limit')
+ })
})