From e62f2a612fff8ef0650aa1c183f0926ad9ab9476 Mon Sep 17 00:00:00 2001
From: xbc5 <87829033+xbc5@users.noreply.github.com>
Date: Fri, 10 Jun 2022 08:23:37 +0100
Subject: [PATCH 01/15] feat(tag/post_link): throw on post_link error (#4938)
---
lib/plugins/tag/post_link.js | 9 ++++++---
test/scripts/tags/post_link.js | 8 ++++----
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/lib/plugins/tag/post_link.js b/lib/plugins/tag/post_link.js
index f27cec0c4e..d70ada3726 100644
--- a/lib/plugins/tag/post_link.js
+++ b/lib/plugins/tag/post_link.js
@@ -12,9 +12,10 @@ const { postFindOneFactory } = require('./');
*/
module.exports = ctx => {
return function postLinkTag(args) {
- const error = `Post not found: ${args.join(' ') || 'Invalid post_link'}`;
const slug = args.shift();
- if (!slug) return error;
+ if (!slug) {
+ throw new Error(`Post not found: "${slug}" doesn't exist for {% post_link %}`);
+ }
let escape = args[args.length - 1];
if (escape === 'true' || escape === 'false') {
@@ -24,7 +25,9 @@ module.exports = ctx => {
}
const post = postFindOneFactory(ctx)({ slug });
- if (!post) return error;
+ if (!post) {
+ throw new Error(`Post not found: post_link ${slug}.`);
+ }
let title = args.length ? args.join(' ') : post.title;
const attrTitle = escapeHTML(title);
diff --git a/test/scripts/tags/post_link.js b/test/scripts/tags/post_link.js
index e0a9d3c6a5..473edd5f41 100644
--- a/test/scripts/tags/post_link.js
+++ b/test/scripts/tags/post_link.js
@@ -57,11 +57,11 @@ describe('post_link', () => {
.should.eql('This is a Bold "statement"');
});
- it('no slug', () => {
- postLink([]).should.eql('Post not found: Invalid post_link');
+ it('should throw if no slug', () => {
+ should.throw(() => postLink([]), Error, /Post not found: "undefined" doesn't exist for \{% post_link %\}/);
});
- it('post not found', () => {
- postLink(['bar']).should.eql('Post not found: bar');
+ it('should throw if post not found', () => {
+ should.throw(() => postLink(['bar']), Error, /Post not found: post_link bar\./);
});
});
From ff5d85ea8c913037775ef2cdb7670f737e1e83d8 Mon Sep 17 00:00:00 2001
From: Mimi <1119186082@qq.com>
Date: Fri, 10 Jun 2022 16:06:00 +0800
Subject: [PATCH 02/15] fix(#4993): correct `db.json` path in debug logging
(#4994)
---
lib/hexo/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/hexo/index.js b/lib/hexo/index.js
index 332080396f..30a1f78956 100644
--- a/lib/hexo/index.js
+++ b/lib/hexo/index.js
@@ -151,7 +151,7 @@ class Hexo extends EventEmitter {
const dbPath = args.output || base;
if (/^(init|new|g|publish|s|deploy|render|migrate)/.test(this.env.cmd)) {
- this.log.d(`Writing database to ${dbPath}/db.json`);
+ this.log.d(`Writing database to ${join(dbPath, 'db.json')}`);
}
this.database = new Database({
From d449acc5bfc98ae099a13472cd86440f2cd81bc3 Mon Sep 17 00:00:00 2001
From: neilnaveen <42328488+neilnaveen@users.noreply.github.com>
Date: Sat, 11 Jun 2022 03:09:34 -0500
Subject: [PATCH 03/15] chore: set permissions for GitHub actions (#4947)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Restrict the GitHub token permissions only to the required ones; this way, even if the attackers will succeed in compromising your workflow, they won’t be able to do much.
- Included permissions for the action. https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions
https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
[Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)
Signed-off-by: neilnaveen <42328488+neilnaveen@users.noreply.github.com>
---
.github/workflows/commenter.yml | 5 +++++
.github/workflows/linter.yml | 3 +++
.github/workflows/release-drafter.yml | 6 ++++++
.github/workflows/tester.yml | 6 ++++++
4 files changed, 20 insertions(+)
diff --git a/.github/workflows/commenter.yml b/.github/workflows/commenter.yml
index 480f01b595..f449809a30 100644
--- a/.github/workflows/commenter.yml
+++ b/.github/workflows/commenter.yml
@@ -2,8 +2,13 @@ name: Commenter
on: [pull_request_target]
+permissions:
+ contents: read
+
jobs:
commenter:
+ permissions:
+ pull-requests: write # for marocchino/sticky-pull-request-comment to create or update PR comment
runs-on: ubuntu-latest
steps:
- name: Comment PR
diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml
index 6273035b57..d3d9678043 100644
--- a/.github/workflows/linter.yml
+++ b/.github/workflows/linter.yml
@@ -2,6 +2,9 @@ name: Linter
on: [push, pull_request]
+permissions:
+ contents: read
+
jobs:
linter:
runs-on: ubuntu-latest
diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml
index 17fdb961dd..d1955effff 100644
--- a/.github/workflows/release-drafter.yml
+++ b/.github/workflows/release-drafter.yml
@@ -5,8 +5,14 @@ on:
branches:
- master
+permissions:
+ contents: read
+
jobs:
update_release_draft:
+ permissions:
+ contents: write # for release-drafter/release-drafter to create a github release
+ pull-requests: write # for release-drafter/release-drafter to add label to PR
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@v5
diff --git a/.github/workflows/tester.yml b/.github/workflows/tester.yml
index 64f7130856..e94651c609 100644
--- a/.github/workflows/tester.yml
+++ b/.github/workflows/tester.yml
@@ -2,6 +2,9 @@ name: Tester
on: [push, pull_request]
+permissions:
+ contents: read
+
jobs:
tester:
runs-on: ${{ matrix.os }}
@@ -23,6 +26,9 @@ jobs:
env:
CI: true
coverage:
+ permissions:
+ checks: write # for coverallsapp/github-action to create new checks
+ contents: read # for actions/checkout to fetch code
runs-on: ${{ matrix.os }}
strategy:
matrix:
From aa6c3c5fea61a13acd3e7a8d8070ad043df11ac4 Mon Sep 17 00:00:00 2001
From: Mimi <1119186082@qq.com>
Date: Wed, 15 Jun 2022 12:21:57 +0800
Subject: [PATCH 04/15] feat(tag/include_code): robust for url compuation of
`view raw` (#4996)
---
lib/plugins/tag/include_code.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/plugins/tag/include_code.js b/lib/plugins/tag/include_code.js
index 59e4436a16..a7cd9f6c3a 100644
--- a/lib/plugins/tag/include_code.js
+++ b/lib/plugins/tag/include_code.js
@@ -1,7 +1,7 @@
'use strict';
const { exists, readFile } = require('hexo-fs');
-const { basename, extname, join } = require('path');
+const { basename, extname, join, posix } = require('path');
// Lazy require highlight.js & prismjs
let highlight, prismHighlight;
@@ -55,7 +55,7 @@ module.exports = ctx => function includeCodeTag(args) {
// If the title is not defined, use file name instead
const title = match[1] || basename(path);
- const caption = `${title}view raw`;
+ const caption = `${title}view raw`;
const hljsCfg = ctx.config.highlight || {};
const prismjsCfg = ctx.config.prismjs || {};
From 81935501ce4403c2c5b8539bd22b198a6e0209c5 Mon Sep 17 00:00:00 2001
From: Baoshuo Ren
Date: Wed, 22 Jun 2022 11:46:33 +0800
Subject: [PATCH 05/15] feat(paginator): custom class name (#5001)
---
lib/plugins/helper/paginator.js | 38 +++++++++++++++++++++++-------
test/scripts/helpers/paginator.js | 39 +++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+), 9 deletions(-)
diff --git a/lib/plugins/helper/paginator.js b/lib/plugins/helper/paginator.js
index 7dbff7d8c8..662c61022c 100644
--- a/lib/plugins/helper/paginator.js
+++ b/lib/plugins/helper/paginator.js
@@ -10,13 +10,19 @@ const createLink = (options, ctx) => {
const createPageTag = (options, ctx) => {
const link = createLink(options, ctx);
- const { current, escape, transform } = options;
+ const {
+ current,
+ escape,
+ transform,
+ page_class: pageClass,
+ current_class: currentClass
+ } = options;
return i => {
if (i === current) {
- return htmlTag('span', { class: 'page-number current' }, transform ? transform(i) : i, escape);
+ return htmlTag('span', { class: pageClass + ' ' + currentClass }, transform ? transform(i) : i, escape);
}
- return htmlTag('a', { class: 'page-number', href: link(i) }, transform ? transform(i) : i, escape);
+ return htmlTag('a', { class: pageClass, href: link(i) }, transform ? transform(i) : i, escape);
};
};
@@ -36,14 +42,15 @@ const pagenasionPartShow = (tags, options, ctx) => {
total,
space,
end_size: endSize,
- mid_size: midSize
+ mid_size: midSize,
+ space_class: spaceClass
} = options;
const leftEnd = Math.min(endSize, current - 1);
const rightEnd = Math.max(total - endSize + 1, current + 1);
const leftMid = Math.max(leftEnd + 1, current - midSize);
const rightMid = Math.min(rightEnd - 1, current + midSize);
- const spaceHtml = htmlTag('span', { class: 'space' }, space, false);
+ const spaceHtml = htmlTag('span', { class: spaceClass }, space, false);
const pageTag = createPageTag(options, ctx);
@@ -93,7 +100,13 @@ function paginatorHelper(options = {}) {
next_text: 'Next',
prev_text: 'Prev',
prev_next: true,
- escape: true
+ escape: true,
+ page_class: 'page-number',
+ current_class: 'current',
+ space_class: 'space',
+ prev_class: 'extend prev',
+ next_class: 'extend next',
+ force_prev_next: false
}, options);
const {
@@ -102,7 +115,10 @@ function paginatorHelper(options = {}) {
prev_text: prevText,
next_text: nextText,
prev_next: prevNext,
- escape
+ escape,
+ prev_class: prevClass,
+ next_class: nextClass,
+ force_prev_next: forcePrevNext
} = options;
if (!current) return '';
@@ -113,7 +129,9 @@ function paginatorHelper(options = {}) {
// Display the link to the previous page
if (prevNext && current > 1) {
- tags.push(htmlTag('a', { class: 'extend prev', rel: 'prev', href: link(current - 1)}, prevText, escape));
+ tags.push(htmlTag('a', { class: prevClass, rel: 'prev', href: link(current - 1)}, prevText, escape));
+ } else if (forcePrevNext) {
+ tags.push(htmlTag('span', { class: prevClass, rel: 'prev' }, prevText, escape));
}
if (options.show_all) {
@@ -124,7 +142,9 @@ function paginatorHelper(options = {}) {
// Display the link to the next page
if (prevNext && current < total) {
- tags.push(htmlTag('a', { class: 'extend next', rel: 'next', href: link(current + 1) }, nextText, escape));
+ tags.push(htmlTag('a', { class: nextClass, rel: 'next', href: link(current + 1) }, nextText, escape));
+ } else if (forcePrevNext) {
+ tags.push(htmlTag('span', { class: nextClass, rel: 'next' }, nextText, escape));
}
return tags.join('');
diff --git a/test/scripts/helpers/paginator.js b/test/scripts/helpers/paginator.js
index ea738d509c..f1aeb63390 100644
--- a/test/scripts/helpers/paginator.js
+++ b/test/scripts/helpers/paginator.js
@@ -302,4 +302,43 @@ describe('paginator', () => {
''
].join(''));
});
+
+ it('custom_class', () => {
+ const result = paginator({
+ current: 2,
+ current_class: 'current-class',
+ space_class: 'space-class',
+ page_class: 'page-class',
+ prev_class: 'prev-class',
+ next_class: 'next-class'
+ });
+
+ result.should.eql([
+ 'Prev',
+ '1',
+ '2',
+ '3',
+ '4',
+ '…',
+ '10',
+ 'Next'
+ ].join(''));
+ });
+
+ it('force_prev_next', () => {
+ const result = paginator({
+ current: 1,
+ force_prev_next: true
+ });
+
+ result.should.eql([
+ 'Prev',
+ '1',
+ '2',
+ '3',
+ '…',
+ '10',
+ 'Next'
+ ].join(''));
+ });
});
From 24db105e17643d2206893c7eb769ab2fed71b584 Mon Sep 17 00:00:00 2001
From: Baoshuo Ren
Date: Wed, 22 Jun 2022 14:43:48 +0800
Subject: [PATCH 06/15] refactor(mail_to): use native URLSearchParams (#5002)
and the package "querystring" is deprecated.
---
lib/plugins/helper/mail_to.js | 3 +--
test/scripts/helpers/mail_to.js | 10 ++++------
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/lib/plugins/helper/mail_to.js b/lib/plugins/helper/mail_to.js
index 8eb51a8944..9752f0055d 100644
--- a/lib/plugins/helper/mail_to.js
+++ b/lib/plugins/helper/mail_to.js
@@ -1,7 +1,6 @@
'use strict';
const { htmlTag } = require('hexo-util');
-const qs = require('querystring');
const { default: moize } = require('moize');
function mailToHelper(path, text, options = {}) {
@@ -28,7 +27,7 @@ function mailToHelper(path, text, options = {}) {
}
});
- const querystring = qs.stringify(data);
+ const querystring = new URLSearchParams(data).toString();
if (querystring) attrs.href += `?${querystring}`;
return htmlTag('a', attrs, text);
diff --git a/test/scripts/helpers/mail_to.js b/test/scripts/helpers/mail_to.js
index 4d961709bc..bcac9970c7 100644
--- a/test/scripts/helpers/mail_to.js
+++ b/test/scripts/helpers/mail_to.js
@@ -1,7 +1,5 @@
'use strict';
-const qs = require('querystring');
-
describe('mail_to', () => {
const Hexo = require('../../../lib/hexo');
const hexo = new Hexo(__dirname);
@@ -33,7 +31,7 @@ describe('mail_to', () => {
it('cc (string)', () => {
const data = {cc: 'abc@abc.com'};
- const querystring = qs.stringify(data);
+ const querystring = new URLSearchParams(data).toString();
mailto('abc@example.com', 'Email', {cc: 'abc@abc.com'})
.should.eql('Email');
@@ -41,7 +39,7 @@ describe('mail_to', () => {
it('cc (array)', () => {
const data = {cc: 'abc@abc.com,bcd@bcd.com'};
- const querystring = qs.stringify(data);
+ const querystring = new URLSearchParams(data).toString();
mailto('abc@example.com', 'Email', {cc: ['abc@abc.com', 'bcd@bcd.com']})
.should.eql('Email');
@@ -49,7 +47,7 @@ describe('mail_to', () => {
it('bcc (string)', () => {
const data = {bcc: 'abc@abc.com'};
- const querystring = qs.stringify(data);
+ const querystring = new URLSearchParams(data).toString();
mailto('abc@example.com', 'Email', {bcc: 'abc@abc.com'})
.should.eql('Email');
@@ -57,7 +55,7 @@ describe('mail_to', () => {
it('bcc (array)', () => {
const data = {bcc: 'abc@abc.com,bcd@bcd.com'};
- const querystring = qs.stringify(data);
+ const querystring = new URLSearchParams(data).toString();
mailto('abc@example.com', 'Email', {bcc: ['abc@abc.com', 'bcd@bcd.com']})
.should.eql('Email');
From 3bd5f2bdb230956dbf1211a6679b1e22a415143b Mon Sep 17 00:00:00 2001
From: Baoshuo Ren
Date: Fri, 24 Jun 2022 09:12:20 +0800
Subject: [PATCH 07/15] refactor(helper/open_graph): use whatwg url api (#5007)
Co-authored-by: Sukka
Co-authored-by: Sukka
---
lib/plugins/helper/open_graph.js | 16 ++--------------
test/scripts/helpers/open_graph.js | 7 +++----
2 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/lib/plugins/helper/open_graph.js b/lib/plugins/helper/open_graph.js
index 9506bb00e3..35d8beb12e 100644
--- a/lib/plugins/helper/open_graph.js
+++ b/lib/plugins/helper/open_graph.js
@@ -1,6 +1,5 @@
'use strict';
-const { parse, resolve } = require('url');
const { isMoment, isDate } = require('moment');
const { encodeURL, prettyUrls, htmlTag, stripHTML, escapeHTML } = require('hexo-util');
const { default: moize } = require('moize');
@@ -56,7 +55,6 @@ const og = (name, content, escape) => {
};
function openGraphHelper(options = {}) {
-
const { config, page } = this;
const { content } = page;
let images = options.image || options.images || page.photos || [];
@@ -117,15 +115,7 @@ function openGraphHelper(options = {}) {
result += og('og:locale', localeToTerritory(language), false);
}
- images = images.map(path => {
- if (!parse(path).host) {
- // resolve `path`'s absolute path relative to current page's url
- // `path` can be both absolute (starts with `/`) or relative.
- return resolve(url || config.url, path);
- }
-
- return path;
- });
+ images = images.map(path => new URL(path, url || config.url).toString());
images.forEach(path => {
result += og('og:image', path, false);
@@ -161,9 +151,7 @@ function openGraphHelper(options = {}) {
if (options.twitter_image) {
let twitter_image = options.twitter_image;
- if (!parse(twitter_image).host) {
- twitter_image = resolve(url || config.url, twitter_image);
- }
+ twitter_image = new URL(twitter_image, url || config.url);
result += meta('twitter:image', twitter_image, false);
} else if (images.length) {
result += meta('twitter:image', images[0], false);
diff --git a/test/scripts/helpers/open_graph.js b/test/scripts/helpers/open_graph.js
index f8b78ffb61..c709e7fa17 100644
--- a/test/scripts/helpers/open_graph.js
+++ b/test/scripts/helpers/open_graph.js
@@ -301,11 +301,10 @@ describe('open_graph', () => {
});
it('images - resolve relative path when site is hosted in subdirectory', () => {
- const urlFn = require('url');
const config = hexo.config;
- config.url = urlFn.resolve(config.url, 'blog');
+ config.url = new URL('blog', config.url).toString();
config.root = 'blog';
- const postUrl = urlFn.resolve(config.url, '/foo/bar/index.html');
+ const postUrl = new URL('/foo/bar/index.html', config.url).toString();
const result = openGraph.call({
page: {},
@@ -314,7 +313,7 @@ describe('open_graph', () => {
url: postUrl
}, {images: 'test.jpg'});
- result.should.have.string(meta({property: 'og:image', content: urlFn.resolve(config.url, '/foo/bar/test.jpg')}));
+ result.should.have.string(meta({property: 'og:image', content: new URL('/foo/bar/test.jpg', config.url).toString()}));
});
it('twitter_image - default same as og:image', () => {
From ccbed65681f84c7f0ede37ebf7822a38cc94c175 Mon Sep 17 00:00:00 2001
From: Baoshuo Ren
Date: Thu, 30 Jun 2022 20:56:46 +0800
Subject: [PATCH 08/15] feat(helper/is): add `is_home_first_page()` helper
(#5006)
---
lib/plugins/helper/index.js | 1 +
lib/plugins/helper/is.js | 5 +++++
test/scripts/helpers/is.js | 7 +++++++
3 files changed, 13 insertions(+)
diff --git a/lib/plugins/helper/index.js b/lib/plugins/helper/index.js
index c7dc22b531..fc86aa6074 100644
--- a/lib/plugins/helper/index.js
+++ b/lib/plugins/helper/index.js
@@ -31,6 +31,7 @@ module.exports = ctx => {
const is = require('./is');
helper.register('is_current', is.current);
helper.register('is_home', is.home);
+ helper.register('is_home_first_page', is.home_first_page);
helper.register('is_post', is.post);
helper.register('is_page', is.page);
helper.register('is_archive', is.archive);
diff --git a/lib/plugins/helper/is.js b/lib/plugins/helper/is.js
index 2724428aef..9f74f3b6d6 100644
--- a/lib/plugins/helper/is.js
+++ b/lib/plugins/helper/is.js
@@ -23,6 +23,10 @@ function isHomeHelper() {
return Boolean(this.page.__index);
}
+function isHomeFirstPageHelper() {
+ return Boolean(this.page.__index) && this.page.current === 1;
+}
+
function isPostHelper() {
return Boolean(this.page.__post);
}
@@ -79,6 +83,7 @@ function isTagHelper(tag) {
exports.current = isCurrentHelper;
exports.home = isHomeHelper;
+exports.home_first_page = isHomeFirstPageHelper;
exports.post = isPostHelper;
exports.page = isPageHelper;
exports.archive = isArchiveHelper;
diff --git a/test/scripts/helpers/is.js b/test/scripts/helpers/is.js
index 02a43808f9..fa8acd9551 100644
--- a/test/scripts/helpers/is.js
+++ b/test/scripts/helpers/is.js
@@ -25,6 +25,13 @@ describe('is', () => {
await is.home.call({page: {}}).should.be.false;
});
+ it('is_home_first_page', async () => {
+ await is.home_first_page.call({page: {__index: true, current: 1}}).should.be.true;
+ await is.home_first_page.call({page: {__index: true, current: 2}}).should.be.false;
+ await is.home_first_page.call({page: {__index: true}}).should.be.false;
+ await is.home_first_page.call({page: {}}).should.be.false;
+ });
+
it('is_post', async () => {
await is.post.call({page: {__post: true}}).should.be.true;
await is.post.call({page: {}}).should.be.false;
From 104b72139078b2682ede67f5b4c2148625cd7ebe Mon Sep 17 00:00:00 2001
From: Baoshuo Ren
Date: Thu, 30 Jun 2022 20:57:23 +0800
Subject: [PATCH 09/15] chore(test/extend/tag): async function (#3328) (#5003)
---
test/scripts/extend/tag.js | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/test/scripts/extend/tag.js b/test/scripts/extend/tag.js
index 193ee64890..a89f6f7c8b 100644
--- a/test/scripts/extend/tag.js
+++ b/test/scripts/extend/tag.js
@@ -1,7 +1,6 @@
'use strict';
const { spy } = require('sinon');
-const Promise = require('bluebird');
describe('Tag', () => {
const Tag = require('../../../lib/extend/tag');
@@ -19,7 +18,7 @@ describe('Tag', () => {
it('register() - async', async () => {
const tag = new Tag();
- tag.register('test', (args, content) => Promise.resolve(args.join(' ')), { async: true });
+ tag.register('test', async (args, content) => args.join(' '), { async: true });
const result = await tag.render('{% test foo bar %}');
result.should.eql('foo bar');
@@ -43,7 +42,7 @@ describe('Tag', () => {
it('register() - async block', async () => {
const tag = new Tag();
- tag.register('test', (args, content) => Promise.resolve(args.join(' ') + ' ' + content), { ends: true, async: true });
+ tag.register('test', async (args, content) => args.join(' ') + ' ' + content, { ends: true, async: true });
const str = [
'{% test foo bar %}',
@@ -81,9 +80,7 @@ describe('Tag', () => {
const tag = new Tag();
tag.register('test', (args, content) => content, {ends: true, async: true});
- tag.register('async', (args, content) => {
- return Promise.resolve(args.join(' ') + ' ' + content);
- }, { ends: true, async: true });
+ tag.register('async', async (args, content) => args.join(' ') + ' ' + content, { ends: true, async: true });
const str = [
'{% test %}',
@@ -136,7 +133,7 @@ describe('Tag', () => {
it('unregister()', () => {
const tag = new Tag();
- tag.register('test', (args, content) => Promise.resolve(args.join(' ')), {async: true});
+ tag.register('test', async (args, content) => args.join(' '), {async: true});
tag.unregister('test');
return tag.render('{% test foo bar %}')
From 6c29971eb4482108e452120b4ab36a8fae0add62 Mon Sep 17 00:00:00 2001
From: Baoshuo Ren
Date: Thu, 30 Jun 2022 23:49:42 +0800
Subject: [PATCH 10/15] feat(helper/toc): more flexible class name (#5010)
---
lib/plugins/helper/toc.js | 24 ++++++++---
test/scripts/helpers/toc.js | 79 +++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 6 deletions(-)
diff --git a/lib/plugins/helper/toc.js b/lib/plugins/helper/toc.js
index e6e4fa8c7b..e055ffd6f2 100644
--- a/lib/plugins/helper/toc.js
+++ b/lib/plugins/helper/toc.js
@@ -7,6 +7,12 @@ function tocHelper(str, options = {}) {
min_depth: 1,
max_depth: 6,
class: 'toc',
+ class_item: '',
+ class_link: '',
+ class_text: '',
+ class_child: '',
+ class_number: '',
+ class_level: '',
list_number: true
}, options);
@@ -15,6 +21,12 @@ function tocHelper(str, options = {}) {
if (!data.length) return '';
const className = escapeHTML(options.class);
+ const itemClassName = escapeHTML(options.class_item || options.class + '-item');
+ const linkClassName = escapeHTML(options.class_link || options.class + '-link');
+ const textClassName = escapeHTML(options.class_text || options.class + '-text');
+ const childClassName = escapeHTML(options.class_child || options.class + '-child');
+ const numberClassName = escapeHTML(options.class_number || options.class + '-number');
+ const levelClassName = escapeHTML(options.class_level || options.class + '-level');
const listNumber = options.list_number;
let result = ``;
@@ -42,7 +54,7 @@ function tocHelper(str, options = {}) {
}
if (level > lastLevel) {
- result += ``;
+ result += ``;
} else {
result += '';
}
@@ -50,15 +62,15 @@ function tocHelper(str, options = {}) {
firstLevel = level;
}
- result += `- `;
+ result += `
- `;
if (href) {
- result += ``;
+ result += ``;
} else {
- result += ``;
+ result += ``;
}
if (listNumber && !el.unnumbered) {
- result += ``;
+ result += ``;
for (let i = firstLevel - 1; i < level; i++) {
result += `${lastNumber[i]}.`;
@@ -67,7 +79,7 @@ function tocHelper(str, options = {}) {
result += ' ';
}
- result += `${text}`;
+ result += `${text}`;
lastLevel = level;
}
diff --git a/test/scripts/helpers/toc.js b/test/scripts/helpers/toc.js
index 08d7c3ebeb..47f0014790 100644
--- a/test/scripts/helpers/toc.js
+++ b/test/scripts/helpers/toc.js
@@ -476,4 +476,83 @@ describe('toc', () => {
toc(input, { list_number: true, class: className }).should.eql(expected);
});
+
+ it('custom class', () => {
+ const className = 'foo';
+ const childClassName = 'bar';
+ const expected = [
+ '
',
+ '- ',
+ '',
+ '1. ', // list_number enabled
+ 'Title 1',
+ '',
+ '
',
+ '- ',
+ '',
+ '1.1. ', // list_number enabled
+ 'Title 1.1',
+ '',
+ '
',
+ '- ',
+ '',
+ '1.1.1. ', // list_number enabled
+ 'Title 1.1.1',
+ '',
+ '
',
+ '
',
+ ' ',
+ '- ',
+ '',
+ '1.2. ', // list_number enabled
+ 'Title 1.2',
+ '',
+ '
',
+ '- ',
+ '',
+ '1.3. ', // list_number enabled
+ 'Title 1.3',
+ '',
+ '
',
+ '- ',
+ '',
+ '1.3.1. ', // list_number enabled
+ 'Title 1.3.1',
+ '',
+ '
',
+ '
',
+ ' ',
+ '
',
+ ' ',
+ '- ',
+ '',
+ '2. ', // list_number enabled
+ 'Title 2',
+ '',
+ '
',
+ '- ',
+ '',
+ '2.1. ', // list_number enabled
+ 'Title 2.1',
+ '',
+ '
',
+ '
',
+ ' ',
+ '- ',
+ '',
+ '3. ', // list_number enabled
+ 'Title should escape &, <, ', and "',
+ '',
+ '
',
+ '- ',
+ '',
+ '4. ', // list_number enabled
+ 'Chapter 1 should be printed to toc',
+ '',
+ '
',
+ '
'
+ ].join('');
+
+ toc(html, { class: 'foo', class_child: 'bar' }).should.eql(expected);
+ });
});
From 8a08bb9e4637aa982bf823c629d5791be2d2b6ef Mon Sep 17 00:00:00 2001
From: Baoshuo Ren
Date: Wed, 6 Jul 2022 22:41:12 +0800
Subject: [PATCH 11/15] chore: improved benchmark result in github actions
(#5013)
---
test/benchmark.js | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/test/benchmark.js b/test/benchmark.js
index 5993632f6d..1dad3c008d 100644
--- a/test/benchmark.js
+++ b/test/benchmark.js
@@ -4,6 +4,7 @@ const { performance, PerformanceObserver } = require('perf_hooks');
const { spawn } = require('child_process');
const { spawn: spawnAsync } = require('hexo-util');
const { rmdir, exists } = require('hexo-fs');
+const { appendFileSync: appendFile } = require('fs');
const { join, resolve } = require('path');
const log = require('hexo-log')();
const { red } = require('picocolors');
@@ -26,6 +27,8 @@ const zeroEksDir = process.env.TRAVIS_BUILD_DIR
: resolve(testDir, '0x');
const hexoBin = resolve(testDir, 'node_modules/.bin/hexo');
+const isGitHubActions = process.env.GITHUB_ACTIONS;
+
const zeroEks = require('0x');
let isProfiling = process.argv.join(' ').includes('--profiling');
@@ -41,6 +44,12 @@ if (!isProfiling && !isBenchmark) {
if (isBenchmark) {
log.info('Running benchmark');
+
+ if (isGitHubActions) {
+ log.info('Running in GitHub Actions.');
+ appendFile(process.env.GITHUB_STEP_SUMMARY, '# Benchmark Result\n');
+ }
+
await cleanUp();
await run_benchmark('Cold processing');
await run_benchmark('Hot processing');
@@ -76,8 +85,14 @@ async function run_benchmark(name) {
if (measureFinished) {
obs.disconnect();
+
+ if (isGitHubActions) {
+ appendFile(process.env.GITHUB_STEP_SUMMARY, `\n## ${name}\n\n| Step | Cost time (s) |\n| --- | --- |\n${Object.keys(result).map(name => `| ${name} | ${result[name]['Cost time (s)']} |`).join('\n')}\n`);
+ }
+
console.log(name);
console.table(result);
+
resolve(result);
}
});
From 29884d85cbbf4c24244df39118d8df39c11f55a6 Mon Sep 17 00:00:00 2001
From: yoshinorin
Date: Tue, 9 Aug 2022 01:57:56 +0900
Subject: [PATCH 12/15] chore(deps): bump hexo-util and warehouse (#5028)
---
package.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index f566b4e5e7..b2c2a960e1 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,7 @@
"hexo-fs": "^3.1.0",
"hexo-i18n": "^1.0.0",
"hexo-log": "^3.0.0",
- "hexo-util": "^2.6.1",
+ "hexo-util": "^2.7.0",
"js-yaml": "^4.1.0",
"js-yaml-js-types": "^1.0.0",
"micromatch": "^4.0.4",
@@ -62,7 +62,7 @@
"text-table": "^0.2.0",
"tildify": "^2.0.0",
"titlecase": "^1.1.3",
- "warehouse": "^4.0.1"
+ "warehouse": "^4.0.2"
},
"devDependencies": {
"@easyops/git-exec-and-restage": "^1.0.4",
From bbf09ac00f67a7f943d6be2e473e1242da9383e6 Mon Sep 17 00:00:00 2001
From: yoshinorin
Date: Wed, 10 Aug 2022 08:46:45 +0900
Subject: [PATCH 13/15] chore: update issue template (#5030)
---
.github/ISSUE_TEMPLATE/other.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/ISSUE_TEMPLATE/other.md b/.github/ISSUE_TEMPLATE/other.md
index a59e50ad6a..6d0d667285 100644
--- a/.github/ISSUE_TEMPLATE/other.md
+++ b/.github/ISSUE_TEMPLATE/other.md
@@ -24,6 +24,8 @@ Please take extra precaution not to attach any secret environment variables (lik
Please check followings before submitting a new issue.
- [ ] I have already confirmed other issue template and they are not different my want
+- [ ] Not a question, feature-request, bug
+ - Please submit to [discussion](https://github.com/hexojs/hexo/discussions) if your issue is a question.
## Information
From b48f0950efd0608bb29ad79792950458b8afe018 Mon Sep 17 00:00:00 2001
From: Ming Di Leom <43627182+curbengh@users.noreply.github.com>
Date: Sun, 14 Aug 2022 02:47:02 +0930
Subject: [PATCH 14/15] fix(tag): show source file in unformatted error message
(#5031)
* fix(tag): show source file in error stack
* fix(tag): show source file in error message
---
lib/extend/tag.js | 8 ++++++--
test/scripts/extend/tag_errors.js | 22 ++++++++++++++++++++++
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/lib/extend/tag.js b/lib/extend/tag.js
index 4334240278..f633781513 100644
--- a/lib/extend/tag.js
+++ b/lib/extend/tag.js
@@ -160,13 +160,15 @@ const getContext = (lines, errLine, location, type) => {
* @return {Error} New error object with embedded context
*/
const formatNunjucksError = (err, input, source = '') => {
+ err.message = err.message.replace('(unknown path)', source ? magenta(source) : '');
+
const match = err.message.match(/Line (\d+), Column \d+/);
if (!match) return err;
const errLine = parseInt(match[1], 10);
if (isNaN(errLine)) return err;
// trim useless info from Nunjucks Error
- const splited = err.message.replace('(unknown path)', source ? magenta(source) : '').split('\n');
+ const splited = err.message.split('\n');
const e = new Error();
e.name = 'Nunjucks Error';
@@ -243,7 +245,9 @@ class Tag {
options,
cb
);
- }).catch(err => Promise.reject(formatNunjucksError(err, str, source)))
+ }).catch(err => {
+ return Promise.reject(formatNunjucksError(err, str, source));
+ })
.asCallback(callback);
}
}
diff --git a/test/scripts/extend/tag_errors.js b/test/scripts/extend/tag_errors.js
index 1b616f2cfc..6a674430b8 100644
--- a/test/scripts/extend/tag_errors.js
+++ b/test/scripts/extend/tag_errors.js
@@ -124,4 +124,26 @@ describe('Tag Errors', () => {
err.message.should.contains(source);
}
});
+
+ it('source file path 2', async () => {
+ const source = '_posts/hello-world.md';
+ const tag = new Tag();
+
+ tag.register('test',
+ (args, content) => {},
+ { ends: true });
+
+ const body = [
+ '{% test %}',
+ '${#var}',
+ '{% endtest %}'
+ ].join('\n');
+
+ try {
+ await tag.render(body, { source });
+ } catch (err) {
+ err.should.have.property('message');
+ err.message.should.contains(source);
+ }
+ });
});
From a2fc8c0f9bb9288d0dc106b1361ec0de63f50672 Mon Sep 17 00:00:00 2001
From: Mimi <1119186082@qq.com>
Date: Thu, 25 Aug 2022 02:56:57 +0800
Subject: [PATCH 15/15] test: replace nyc with c8 (#5040)
---
package.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/package.json b/package.json
index b2c2a960e1..176f0c351e 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
"scripts": {
"eslint": "eslint .",
"test": "mocha test/index.js",
- "test-cov": "nyc --reporter=lcovonly npm test -- --no-parallel",
+ "test-cov": "c8 --reporter=lcovonly npm test -- --no-parallel",
"prepare": "husky install"
},
"directories": {
@@ -54,8 +54,8 @@
"moize": "^6.1.0",
"moment": "^2.29.1",
"moment-timezone": "^0.5.34",
- "picocolors": "^1.0.0",
"nunjucks": "^3.2.3",
+ "picocolors": "^1.0.0",
"pretty-hrtime": "^1.0.3",
"resolve": "^1.22.0",
"strip-ansi": "^6.0.0",
@@ -67,6 +67,7 @@
"devDependencies": {
"@easyops/git-exec-and-restage": "^1.0.4",
"0x": "^5.1.2",
+ "c8": "^7.12.0",
"chai": "^4.3.6",
"cheerio": "0.22.0",
"decache": "^4.6.1",
@@ -76,7 +77,6 @@
"husky": "^7.0.4",
"lint-staged": "^11.0.0",
"mocha": "^10.0.0",
- "nyc": "^15.1.0",
"sinon": "^13.0.2"
},
"engines": {